diff --git a/.github/workflows/ruby-ci.yml b/.github/workflows/ruby-ci.yml new file mode 100644 index 00000000000..654a004b643 --- /dev/null +++ b/.github/workflows/ruby-ci.yml @@ -0,0 +1,44 @@ +name: CI + +on: + pull_request: + branches: + - '**' + push: + branches: + - master + +jobs: + build: + name: Ruby ${{ matrix.version }} ${{ matrix.gemfile }} + runs-on: ubuntu-latest + env: + BUNDLE_GEMFILE: ${{ matrix.gemfile }} + strategy: + matrix: + version: + - 2.5 + - 2.6 + - 2.7 + gemfile: + - gemfiles/Gemfile.rails50 + - gemfiles/Gemfile.rails51 + - gemfiles/Gemfile.rails52 + - gemfiles/Gemfile.rails60 + - gemfiles/Gemfile.rails_master + exclude: + - version: 2.6 + gemfile: gemfiles/Gemfile.rails_master + - version: 2.5 + gemfile: gemfiles/Gemfile.rails_master + steps: + - uses: actions/checkout@v2 + + - name: Set up Ruby ${{ matrix.version }} + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.version }} + bundler-cache: true + + - name: Test + run: bundle exec rake test diff --git a/.rubocop.yml b/.rubocop.yml index f1deca38196..a747dd301f2 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -15,7 +15,7 @@ AllCops: - "lib/active_merchant/billing/gateways/paypal_express.rb" - "vendor/**/*" ExtraDetails: false - TargetRubyVersion: 2.3 + TargetRubyVersion: 2.5 # Active Merchant gateways are not amenable to length restrictions Metrics/ClassLength: @@ -32,3 +32,10 @@ Layout/DotPosition: Layout/CaseIndentation: EnforcedStyle: end + +Layout/IndentHash: + EnforcedStyle: consistent + +Naming/PredicateName: + Exclude: + - "lib/active_merchant/billing/gateways/payeezy.rb" diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 7cdc2615a7c..359bc075fb3 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -6,14 +6,6 @@ # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: Include, TreatCommentsAsGroupSeparators. -# Include: **/*.gemspec -Gemspec/OrderedDependencies: - Exclude: - - 'activemerchant.gemspec' - # Offense count: 1828 # Cop supports --auto-correct. # Configuration parameters: EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle. @@ -23,154 +15,6 @@ Gemspec/OrderedDependencies: Layout/AlignHash: Enabled: false -# Offense count: 167 -# Cop supports --auto-correct. -Layout/EmptyLineAfterGuardClause: - Enabled: false - -# Offense count: 173 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines, beginning_only, ending_only -Layout/EmptyLinesAroundClassBody: - Enabled: false - -# Offense count: 39 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleAlignWith, AutoCorrect, Severity. -# SupportedStylesAlignWith: keyword, variable, start_of_line -Layout/EndAlignment: - Enabled: false - -# Offense count: 174 -# Cop supports --auto-correct. -# Configuration parameters: AllowForAlignment, ForceEqualSignAlignment. -Layout/ExtraSpacing: - Enabled: false - -# Offense count: 105 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: consistent, consistent_relative_to_receiver, special_for_inner_method_call, special_for_inner_method_call_in_parentheses -Layout/FirstParameterIndentation: - Enabled: false - -# Offense count: 255 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: special_inside_parentheses, consistent, align_braces -Layout/IndentHash: - Enabled: false - -# Offense count: 392 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: auto_detection, squiggly, active_support, powerpack, unindent -Layout/IndentHeredoc: - Enabled: false - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: symmetrical, new_line, same_line -Layout/MultilineArrayBraceLayout: - Exclude: - - 'lib/active_merchant/billing/gateways/optimal_payment.rb' - -# Offense count: 36 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: symmetrical, new_line, same_line -Layout/MultilineHashBraceLayout: - Enabled: false - -# Offense count: 232 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: symmetrical, new_line, same_line -Layout/MultilineMethodCallBraceLayout: - Enabled: false - -# Offense count: 24 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: aligned, indented -Layout/MultilineOperationIndentation: - Exclude: - - 'lib/active_merchant/billing/credit_card_methods.rb' - - 'lib/active_merchant/billing/gateways/iridium.rb' - - 'lib/active_merchant/billing/gateways/moneris.rb' - - 'lib/active_merchant/billing/gateways/moneris_us.rb' - - 'lib/active_merchant/billing/gateways/orbital.rb' - - 'lib/active_merchant/billing/gateways/redsys.rb' - - 'test/unit/gateways/braintree_blue_test.rb' - - 'test/unit/gateways/skip_jack_test.rb' - -# Offense count: 15 -# Cop supports --auto-correct. -Layout/RescueEnsureAlignment: - Exclude: - - 'lib/active_merchant/billing/gateways/balanced.rb' - - 'lib/active_merchant/billing/gateways/clearhaus.rb' - - 'lib/active_merchant/billing/gateways/culqi.rb' - - 'lib/active_merchant/billing/gateways/eway_managed.rb' - - 'lib/active_merchant/billing/gateways/fat_zebra.rb' - - 'lib/active_merchant/billing/gateways/hps.rb' - - 'lib/active_merchant/billing/gateways/iveri.rb' - - 'lib/active_merchant/billing/gateways/kushki.rb' - - 'lib/active_merchant/billing/gateways/merchant_e_solutions.rb' - - 'lib/active_merchant/billing/gateways/netbanx.rb' - - 'lib/active_merchant/billing/gateways/opp.rb' - - 'lib/active_merchant/billing/gateways/orbital.rb' - - 'lib/active_merchant/billing/gateways/pay_junction_v2.rb' - - 'lib/active_merchant/billing/gateways/quickbooks.rb' - - 'lib/active_merchant/billing/gateways/trans_first_transaction_express.rb' - -# Offense count: 649 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: space, no_space -Layout/SpaceAroundEqualsInParameterDefault: - Enabled: false - -# Offense count: 104 -# Cop supports --auto-correct. -Layout/SpaceAroundKeyword: - Enabled: false - -# Offense count: 782 -# Cop supports --auto-correct. -# Configuration parameters: AllowForAlignment. -Layout/SpaceAroundOperators: - Enabled: false - -# Offense count: 118 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBrackets. -# SupportedStyles: space, no_space, compact -# SupportedStylesForEmptyBrackets: space, no_space -Layout/SpaceInsideArrayLiteralBrackets: - Enabled: false - -# Offense count: 12 -# Cop supports --auto-correct. -Layout/SpaceInsideArrayPercentLiteral: - Exclude: - - 'lib/active_merchant/billing/gateways/migs/migs_codes.rb' - -# Offense count: 1186 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. -# SupportedStyles: space, no_space, compact -# SupportedStylesForEmptyBraces: space, no_space -Layout/SpaceInsideHashLiteralBraces: - Enabled: false - -# Offense count: 115 -# Cop supports --auto-correct. -Layout/SpaceInsidePercentLiteralDelimiters: - Enabled: false - # Offense count: 150 # Configuration parameters: AllowSafeAssignment. Lint/AssignmentInCondition: @@ -192,12 +36,6 @@ Lint/RescueException: Exclude: - 'lib/active_merchant/billing/gateways/quantum.rb' -# Offense count: 1502 -# Cop supports --auto-correct. -# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments. -Lint/UnusedBlockArgument: - Enabled: false - # Offense count: 284 # Cop supports --auto-correct. # Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods. @@ -244,35 +82,6 @@ Naming/AccessorMethodName: - 'test/remote/gateways/remote_authorize_net_cim_test.rb' - 'test/unit/gateways/authorize_net_cim_test.rb' -# Offense count: 1 -Naming/ConstantName: - Exclude: - - 'test/test_helper.rb' - -# Offense count: 46 -# Configuration parameters: EnforcedStyle. -# SupportedStyles: lowercase, uppercase -Naming/HeredocDelimiterCase: - Exclude: - - 'test/unit/gateways/authorize_net_test.rb' - - 'test/unit/gateways/card_stream_test.rb' - - 'test/unit/gateways/hps_test.rb' - - 'test/unit/gateways/litle_test.rb' - - 'test/unit/gateways/moneris_test.rb' - -# Offense count: 85 -# Configuration parameters: Blacklist. -# Blacklist: (?-mix:(^|\s)(EO[A-Z]{1}|END)(\s|$)) -Naming/HeredocDelimiterNaming: - Enabled: false - -# Offense count: 1 -# Configuration parameters: EnforcedStyleForLeadingUnderscores. -# SupportedStylesForLeadingUnderscores: disallowed, required, optional -Naming/MemoizedInstanceVariableName: - Exclude: - - 'lib/active_merchant/billing/compatibility.rb' - # Offense count: 15 # Configuration parameters: EnforcedStyle. # SupportedStyles: snake_case, camelCase @@ -287,21 +96,6 @@ Naming/MethodName: - 'test/remote/gateways/remote_sage_pay_test.rb' - 'test/unit/gateways/sage_pay_test.rb' -# Offense count: 5 -# Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist, MethodDefinitionMacros. -# NamePrefix: is_, has_, have_ -# NamePrefixBlacklist: is_, has_, have_ -# NameWhitelist: is_a? -# MethodDefinitionMacros: define_method, define_singleton_method -Naming/PredicateName: - Exclude: - - 'spec/**/*' - - 'lib/active_merchant/billing/gateways/authorize_net.rb' - - 'lib/active_merchant/billing/gateways/payeezy.rb' - - 'lib/active_merchant/billing/gateways/paymill.rb' - - 'lib/active_merchant/billing/gateways/redsys.rb' - - 'lib/active_merchant/billing/gateways/sage_pay.rb' - # Offense count: 14 # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. # AllowedNames: io, id, to, by, on, in, at, ip, db @@ -334,42 +128,6 @@ Naming/VariableName: - 'test/unit/gateways/card_stream_test.rb' - 'test/unit/gateways/worldpay_online_payments_test.rb' -# Offense count: 11 -# Configuration parameters: EnforcedStyle. -# SupportedStyles: snake_case, normalcase, non_integer -Naming/VariableNumber: - Exclude: - - 'lib/active_merchant/billing/gateways/merchant_partners.rb' - - 'lib/active_merchant/billing/gateways/mercury.rb' - - 'lib/active_merchant/billing/gateways/orbital.rb' - - 'test/remote/gateways/remote_paypal_test.rb' - - 'test/unit/gateways/merchant_ware_test.rb' - - 'test/unit/gateways/merchant_ware_version_four_test.rb' - - 'test/unit/gateways/orbital_test.rb' - - 'test/unit/gateways/paypal/paypal_common_api_test.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -Performance/RedundantMatch: - Exclude: - - 'lib/active_merchant/billing/gateways/opp.rb' - - 'test/unit/gateways/payu_latam_test.rb' - -# Offense count: 11 -# Cop supports --auto-correct. -Performance/StringReplacement: - Exclude: - - 'lib/active_merchant/billing/compatibility.rb' - - 'lib/active_merchant/billing/gateways/card_connect.rb' - - 'lib/active_merchant/billing/gateways/firstdata_e4.rb' - - 'lib/active_merchant/billing/gateways/merchant_ware.rb' - - 'lib/active_merchant/billing/gateways/merchant_ware_version_four.rb' - - 'lib/active_merchant/billing/gateways/orbital.rb' - - 'lib/active_merchant/billing/gateways/quickbooks.rb' - - 'lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb' - - 'lib/active_merchant/billing/gateways/realex.rb' - - 'test/unit/gateways/nab_transact_test.rb' - # Offense count: 2 # Configuration parameters: EnforcedStyle. # SupportedStyles: inline, group @@ -378,36 +136,6 @@ Style/AccessModifierDeclarations: - 'test/unit/gateways/metrics_global_test.rb' - 'test/unit/gateways/optimal_payment_test.rb' -# Offense count: 11 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: prefer_alias, prefer_alias_method -Style/Alias: - Exclude: - - 'lib/active_merchant/billing/gateways/beanstream.rb' - - 'lib/active_merchant/billing/gateways/braintree_blue.rb' - - 'lib/active_merchant/billing/gateways/inspire.rb' - - 'lib/active_merchant/billing/gateways/migs.rb' - - 'lib/active_merchant/billing/gateways/smart_ps.rb' - - 'lib/active_merchant/billing/gateways/spreedly_core.rb' - - 'lib/active_merchant/post_data.rb' - - 'test/unit/gateways/bpoint_test.rb' - - 'test/unit/gateways/paymentez_test.rb' - -# Offense count: 12 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: always, conditionals -Style/AndOr: - Exclude: - - 'lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb' - - 'lib/active_merchant/billing/gateways/eway.rb' - - 'lib/active_merchant/billing/gateways/iridium.rb' - - 'lib/active_merchant/billing/gateways/pac_net_raven.rb' - - 'lib/active_merchant/billing/gateways/smart_ps.rb' - - 'lib/active_merchant/billing/gateways/stripe.rb' - - 'lib/active_merchant/billing/gateways/webpay.rb' - # Offense count: 47 # Configuration parameters: AllowedChars. Style/AsciiComments: @@ -426,12 +154,6 @@ Style/AsciiComments: - 'test/remote/gateways/remote_data_cash_test.rb' - 'test/remote/gateways/remote_nab_transact_test.rb' -# Offense count: 1 -# Cop supports --auto-correct. -Style/Attr: - Exclude: - - 'test/unit/gateways/forte_test.rb' - # Offense count: 2 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. @@ -441,14 +163,6 @@ Style/BarePercentLiterals: - 'test/unit/gateways/eway_rapid_test.rb' - 'test/unit/gateways/orbital_test.rb' -# Offense count: 3 -# Cop supports --auto-correct. -Style/BlockComments: - Exclude: - - 'test/remote/gateways/remote_barclays_epdq_extra_plus_test.rb' - - 'test/remote/gateways/remote_netpay_test.rb' - - 'test/remote/gateways/remote_payu_in_test.rb' - # Offense count: 77 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, IgnoredMethods. @@ -701,13 +415,6 @@ Style/GlobalVars: Style/GuardClause: Enabled: false -# Offense count: 7482 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols. -# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys -Style/HashSyntax: - Enabled: false - # Offense count: 6 Style/IdenticalConditionalBranches: Exclude: @@ -729,11 +436,6 @@ Style/IfInsideElse: - 'lib/active_merchant/billing/gateways/skip_jack.rb' - 'lib/active_merchant/billing/gateways/worldpay_online_payments.rb' -# Offense count: 128 -# Cop supports --auto-correct. -Style/IfUnlessModifier: - Enabled: false - # Offense count: 1 Style/IfUnlessModifierOfIfUnless: Exclude: @@ -1013,41 +715,6 @@ Style/SingleLineMethods: Exclude: - 'test/unit/gateways/paypal/paypal_common_api_test.rb' -# Offense count: 3 -# Cop supports --auto-correct. -# Configuration parameters: . -# SupportedStyles: use_perl_names, use_english_names -Style/SpecialGlobalVars: - EnforcedStyle: use_perl_names - -# Offense count: 27 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: single_quotes, double_quotes -Style/StringLiteralsInInterpolation: - Exclude: - - 'lib/active_merchant/billing/gateways/banwire.rb' - - 'lib/active_merchant/billing/gateways/cams.rb' - - 'lib/active_merchant/billing/gateways/checkout_v2.rb' - - 'lib/active_merchant/billing/gateways/credorax.rb' - - 'lib/active_merchant/billing/gateways/digitzs.rb' - - 'lib/active_merchant/billing/gateways/ebanx.rb' - - 'lib/active_merchant/billing/gateways/merchant_one.rb' - - 'lib/active_merchant/billing/gateways/micropayment.rb' - - 'lib/active_merchant/billing/gateways/pagarme.rb' - - 'lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb' - - 'lib/active_merchant/billing/gateways/stripe.rb' - - 'lib/active_merchant/billing/gateways/usa_epay_advanced.rb' - - 'lib/active_merchant/billing/gateways/worldpay.rb' - - 'test/unit/gateways/eway_managed_test.rb' - -# Offense count: 309 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, MinSize. -# SupportedStyles: percent, brackets -Style/SymbolArray: - Enabled: false - # Offense count: 7 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyleForMultiline. @@ -1058,26 +725,6 @@ Style/TrailingCommaInArrayLiteral: - 'test/unit/gateways/netaxept_test.rb' - 'test/unit/gateways/usa_epay_transaction_test.rb' -# Offense count: 160 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleForMultiline. -# SupportedStylesForMultiline: comma, consistent_comma, no_comma -Style/TrailingCommaInHashLiteral: - Enabled: false - -# Offense count: 38 -# Cop supports --auto-correct. -# Configuration parameters: AllowNamedUnderscoreVariables. -Style/TrailingUnderscoreVariable: - Enabled: false - -# Offense count: 119 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, MinSize, WordRegex. -# SupportedStyles: percent, brackets -Style/WordArray: - Enabled: false - # Offense count: 34 # Cop supports --auto-correct. Style/ZeroLengthPredicate: @@ -1088,3 +735,4 @@ Style/ZeroLengthPredicate: # URISchemes: http, https Metrics/LineLength: Max: 2602 + diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index a43b6cfc204..00000000000 --- a/.travis.yml +++ /dev/null @@ -1,33 +0,0 @@ -language: ruby -sudo: false -cache: bundler - -rvm: -- 2.5 -- 2.4 -- 2.3 - -gemfile: -- gemfiles/Gemfile.rails52 -- gemfiles/Gemfile.rails51 -- gemfiles/Gemfile.rails50 -- gemfiles/Gemfile.rails42 -- gemfiles/Gemfile.rails_master - -jobs: - include: - rvm: 2.5 - gemfile: Gemfile - script: bundle exec rubocop --parallel - -matrix: - exclude: - - rvm: 2.3 - gemfile: 'gemfiles/Gemfile.rails_master' - - rvm: 2.4 - gemfile: 'gemfiles/Gemfile.rails_master' - -notifications: - email: - on_success: never - on_failure: always diff --git a/CHANGELOG b/CHANGELOG index e6d6326fe58..0fc6fb7e3a3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,427 @@ = ActiveMerchant CHANGELOG == HEAD +* Stripe PI: ensure `setup_future_sage` and `off_session` work when using SetupIntents. +* Orbital: Update commit to accept retry_logic in params [jessiagee] #3890 +* Orbital: Update remote 3DS tests [jessiagee] #3892 +* Mercado Pago: support Creditel card type [therufs] #3893 +* Payeezy: Update error mapping [meagabeth] #3896 +* HPS: Add support for stored_credential [cdmackeyfree] #3894 +* Orbital: Ensure payment_detail sends for ECP [jessiagee] #3899 +* Payeezy: Update `error_code_from` method [meagabeth] #3900 +* Worldpay: Add support for `statementNarrative` field [meagabeth] #3901 +* Mercado Pago: Give ability to pass capture option in authorize txn field [naashton] #3897 +* Orbital: Ensure correct fields sent in refund [jessiagee] #3903 +* WorldPay: remove some defaults in billing address [carrigan] #3902 +* Adyen: Support for General Credit [naashton] #3904 +* Worldpay: reintroduce address1 and city defaults [carrigan] #3905 +* Stripe: ensure potentially nested data is scrubbed #3907 +* Stripe PI: Send Validate on Payment Method Attach [tatsianaclifton] #3909 +* Adyen: Update handling of authorization returned from gateway [meagabeth] #3910 +* Update gateway templates for Rubocop compliance [therufs] #3912 #3895 +* Orbital: Send AVSname for all eCheck transactions [jessiagee] #3911 +* Litle: update support of customerId field [cdmackeyfree] #3913 +* Payment Express: fix signature for `verify` [therufs] #3914 +* Forte: Send xdata fields [dsmcclain] #3915 +* PaywayDotCom: Add New Gateway [DanAtPayway] #3898 +* Orbital: Remove unnecessary requirements [jessiagee] #3917 +* SafeCharge (Nuvei): Add network tokenization support [DStoyanoff] #3847 +* Stripe PI: Enhance testing of SetupIntents API #3908 +* SafeCharge (Nuvei): Fix NT related bug [jimilpatel24] #3921 + +== Version 1.119.0 (February 9th, 2021) +* Payment Express: support verify/validate [therufs] #3874 +* GlobalCollect: Truncate address fields [meagabeth] #3878 +* Litle: Truncate address fields [meagabeth] #3877 +* Netbanx: Add-customer-information(name,email,IP)-to-a-transaction [rockyhakjoong] #3754 +* Netbanx: Adjust the avs and cvv return code in shopify [rockyhakjoong] #3833 +* Decidir: Improve error mapping [meagabeth] #3875 +* Worldpay: support `skip_capture` [therufs] #3879 +* Redsys: Add new response code text [britth] #3880 +* Orbital: Update ECP details to use payment source [jessiagee] #3881 +* Alelo: Add additional BIN ranges [meagabeth] #3882 +* HPS: Update Add support for general credit [naashton] #3885 +* Elavon: Fix issue with encoding data sent in the request [naashton] #3865 +* Orbital: Update ECP to use EWS verification [jessiagee] #3886 +* Eway: Add 3ds field when do direct payment [GavinSun9527] #3860 +* Support Creditel cardtype [therufs] #3883 +* Elavon: Remove ampersand char from fields [naashton] #3891 + +== Version 1.118.0 (January 22nd, 2021) +* Worldpay: Add support for challengeWindowSize [carrigan] #3823 +* Adyen: Update capitalization on subMerchantId field [cdmackeyfree] #3824 +* Maestro and Elo: Update BIN ranges [meagabeth] #3822 +* HPS: Truncate invoice numbers that are too long [curiousepic] #3825 +* Pass network_transaction_id attribute in Response [therufs] #3815 +* Elavon: support standardized stored credentials [therufs] #3816 +* Decidir: update fraud_detection field [cdmackeyfree] #3829 +* Paymentez: Add Olimpica cardtype [meagabeth] #3831 +* SafeCharge: 3DS external MPI data refinements [curiousepic] #3821 +* Credorax: Add support for 3DS Adviser [meagabeth] #3834 +* Adyen: Support subMerchant data [mymir][therufs] #3835 +* Decidir: add device_unique_identifier to card data [cdmackeyfree] #3839 +* BraintreeBlue: add support for account_type field [jimilpatel24] #3840 +* Redsys: Add support for stored_credential [meagabeth] #3844 +* Redsys: add_payment method solution [meagabeth] #3845 +* Stripe Payment Intents: Add support for error_on_requires_action option [tatsianaclifton] #3846 +* Add 3DS 2.0 values to paypal [nebdil] #3285 +* Redsys: Update Mpi Fields [tatsianaclifton] #3855 +* Paypal: Update AuthStatus3ds MPI field [curiousepic] #3857 +* Orbital: Update 3DS support for Mastercard [meagabeth] #3850 +* Payeezy: Support standardized stored credentials [therufs] #3861 +* CyberSource: Update `billing_address` override [meagabeth] #3862 +* Paymentez: Add 3DS MPI field support [carrigan] #3856 +* BlueSnap: Add support `fraud-session-id` field [meagabeth] #3863 +* BlueSnap: Update handling of `transaction-fraud-info` fields [meagabeth] #3866 +* Payeezy: Allow no stored credential transaction id [therufs] #3868 +* Orbital: eCheck processing added [ajawadmirza] #3870 +* FirsdataE4V27: Fixes some apple pay transaction issues [pi3r] #3872 + +== Version 1.117.0 (November 13th) +* Checkout V2: Pass attempt_n3d along with 3ds enabled [naashton] #3805 +* GlobalCollect: Add support for Third-party 3DS2 data [molbrown] #3801 +* Authorize.net: Pass stored credentials [therufs] #3804 +* Authorize.net: Don't pass isFirstRecurringPayment [therufs] #3805 +* Litle: Add support for general credit transactions [naashton] #3807 +* Redsys: Add 3DS2 Integration Support [esmitperez] #3794 +* Cybersource: Use firstname/lastname from address instead of the payment method [pi3r] #3798 +* Add MPI functionality for SafeCharge gateway [daniel] #3809 +* SafeCharge: Standardize MPI fields [curiousepic] #3809 +* Credorax: Adds AMEX to supported cards and adds 1A error code [LinTrieu] #3792 +* Stripe PI: Pass external 3DS auth data [curiousepic] #3811 +* Credorax: Allow 3DS1 normalized pass-through, ease version matching [britth] #3812 +* Redsys: Redsys: Harden 3DS v1/v2 check for External MPI [esmitperez] #3814 +* Add card types for Stripe, Worldpay, Checkout.com [LinTrieu] #3810 +* ActiveMerchant::Billing::Response: Include `network_transaction_id` attribute [therufs] #3815 + +== Version 1.116.0 (October 28th) +* Remove Braintree specific version dependency [pi3r] #3800 + +== Version 1.115.0 (October 27th) +* Checkout v2: $0 Auth on gateway [jessiagee] #3762 +* Adyen: Safely add execute_threeds: false [curiousepic] #3756 +* RuboCop: Fix Layout/SpaceAroundEqualsInParameterDefault [leila-alderman] #3720 +* iATS: Allow email to be passed outside of the billing_address context [naashton] #3750 +* Orbital: Don't pass xid for transactions using network tokens [britth] #3757 +* Forte: Add service_fee_amount field [meagabeth] #3751 +* WorldPay: Add support for idempotency_key[cdmackeyfree] #3759 +* Orbital: Handle line_tot key as a string [naashton] #3760 +* RuboCop: Fix Lint/UnusedMethodArgument [leila-alderman] #3721 +* RuboCop: Fix Naming/MemoizedInstanceVariableName [leila-alderman] #3722 +* RuboCop: Fix Style/BlockComments [leila-alderman] #3729 +* Checkout V2: Move to single-transaction Purchases [curiousepic] #3761 +* RuboCop: Fix Naming/ConstantName [leila-alderman] #3723 +* Orbital: Fix schema errors [britth] #3766 +* Checkout V2: Start testing via amount code [curiousepic] #3767 +* CyberSource: Don't include empty `mdd_` fields [arbianchi] #3758 +* RuboCop: Fix Naming/VariableNumber [leila-alderman] #3725 +* Update BIN ranges for Elo cardtype [cdmackeyfree] #3769 +* Orbital: Resolve CardIndicators issue [meagabeth] #3771 +* Adyen: Add subMerchant fields [naashton] #3772 +* PayPal Express: reduce param requirements [shasum] #3773 +* PayU Latam: Support partial refunds [leila-alderman] #3774 +* RuboCop: Fix Style/Alias [leila-alderman] #3727 +* Stripe PI: Allow `on_behalf_of` to be passed alone #3776 +* RuboCop: Fix Performance/RedundantMatch [leila-alderman] #3765 +* RuboCop: Fix Layout/MultilineMethodCallBraceLayout [leila-alderman] #3763 +* NMI: Add standardized 3DS fields [meagabeth] #3775 +* Mundipagg: Add support for SubMerchant fields [meagabeth] #3779 +* Stripe Payment Intents: Add request_three_d_secure option [molbrown] #3787 +* Decidir: Add support for csmdds fields [naashton] #3786 +* RuboCop: Fix Performance/StringReplacement [leila-alderman] #3782 +* RuboCop: Fix Naming/HeredocDelimiterCase & Naming [leila-alderman] #3781 +* BlueSnap: Add address fields to contact info [naashton] #3777 +* RuboCop: Fix Layout/SpaceInsideHashLiteralBraces [leila-alderman] #3780 +* RuboCop: Fix Style/AndOr [leila-alderman] #3783 +* Checkout V2: Support ability to pass attempt_n3d 3ds field [naashton] #3788 +* Elavon: Upgrade to `processxml.do` [therufs] #3784 +* Checkout V2: Support for attempt_n3d 3DS field [naashton] #3790 +* Elavon: Strip ampersands [therufs] #3795 +* Paybox: Add support for 3DS 1.0 values [jcpaybox] #3335 +* Decidir: Add additional fraud_detection options [cdmackeyfree] #3812 + +== Version 1.114.0 +* BlueSnap: Add address1,address2,phone,shipping_* support #3749 +* BlueSnap: Protect against `nil` metadata [carrigan] #3752 +* Cybersource: [CyberSource] Ensure the default address doesn't override `ActionController::Parameters` [pi3r] #3755 + +== Version 1.113.0 +* Orbital: Add cardIndicators field [meagabeth] #3734 +* Openpay: Add Colombia to supported countries [molbrown] #3740 +* Mercado Pago: Update Device Id Header field [cdmackeyfree] #3741 +* RuboCop: Fix Style/TrailingCommaInHashLiteral [leila-alderman] #3718 +* RuboCop: Fix Naming/PredicateName [leila-alderman] #3724 +* RuboCop: Fix Style/Attr [leila-alderman] #3728 +* Payflow: Use application_id to set buttonsource [britth] #3737 +* HPS: Enable refunds using capture transaction [britth] #3738 +* Quickbooks: Omit empty strings in address [leila-alderman] #3743 +* BlueSnap: Add transactionMetaData support #3745 +* Orbital: Fix typo in PC3DtlLineTot field [naashton] #3736 +* Credorax: Send first and last name parameters for CFT transactions [britth] #3748 +* Orbital: Update CardIndicators field to fix bug [meagabeth] #3746 +* CyberSource: Always send default address [leila-alderman] #3747 +* Netbanx: Reject partial refund on pending status [rockyhakjoong] #3735 + +== Version 1.112.0 +* Cybersource: add `maestro` and `diners_club` eci brand mapping [bbraschi] #3708 +* Cybersource: Ensure Partner Solution Id placement conforms to schema [britth] #3715 +* Adyen: Adyen: Pass `subMerchantId` as `additionalData` [naashton] #3714 +* Litle: Omit checkNum when nil [leila-alderman] #3719 +* PayU Latam: Improve error response [esmitperez] #3717 +* Vantiv: Vantiv Express - CardPresentCode, PaymentType, SubmissionType, DuplicateCheckDisableFlag [esmitperez] #3730,#3731 +* Cybersource: Ensure issueradditionaldata comes before partnerSolutionId [britth] #3733 + +== Version 1.111.0 +* Fat Zebra: standardized 3DS fields and card on file extra data for Visa scheme rules [montdidier] #3409 +* Realex: Change 3DSecure v1 message_version to a valid format [shuhala] #3702 +* Ingenico/ GlobalCollect: Add field for installments [cdmackeyfree] #3707 +* Cybersource: do not send 3DS fields if 'cavv` is missing and `commerceIndicator` is inferred [bbraschi] #3712 + +== Version 1.110.0 +* FirstData e4 v27+: Strip linebreaks from address [curiousepic] #3693 +* Adyen: Change shopper_email to email and shopper_ip to ip [rikterbeek] #3675 +* FirstData e4 v27+ Fix strip_line_breaks method [carrigan] #3695 +* Cybersource: Set authorization on the response even when in fraud review [pi3r] #3701 +* Cybersource: Add fields to override stored creds [leila-alderman] #3689 +* Cybersource: Conditionally find stored credentials [therufs] #3696 #3697 +* Cybersource: Update logic to send cavv as xid for 3DS2 [douglas] #3699 +* Credorax: Default 3ds_browsercolordepth to 32 when passed as 30 [britth] #3700 + +== Version 1.109.0 +* Remove reference to `Billing::Integrations` [pi3r] #3692 +* DLocal: Handle nil address1 [molbrown] #3661 +* Braintree: Add travel and lodging fields [leila-alderman] #3668 +* Stripe: strict_encode64 api key [britth] #3672 +* Stripe PI: Implement verify action [leila-alderman] #3662 +* Stripe, Stripe Payment Intents: Update supported countries [britth] #3684 +* Forte: Use underscore for unused arguments in test [wsmoak] #3605 +* Add Alia card type [therufs] #3673 +* Element: Fix unit tests [leila-alderman] #3676 +* PayU Latam: Fix store method [ccarruitero] #2590 +* Adyen: Allow for executeThreeD to be passed as false [naashton] #3681 +* WorldPay: Fix handling of `state` field for 3DS transactions [chinhle23] #3687 +* Alia: Skip Luhn validation [therufs] #3673 +* Diners Club: support 16 digit card numbers [therufs] #3682 +* Cybersource: Update supported countries [britth] #3683 +* Cybersource: pass reconciliation_id [therufs] #3688 +* RuboCop: Fix Style/SpecialGlobalVars [leila-alderman] #3669 +* RuboCop: Fix Style/StringLiteralsInInterpolation [leila-alderman] #3670 +* RuboCop: Fix Layout/HeredocIndentation [leila-alderman] #3685 +* RuboCop: Fix Gemspec/OrderedDependencies [leila-alderman] #3679 +* RuboCop: Fix Style/TrailingUnderscoreVariable [leila-alderman] #3663 +* RuboCop: Fix Style/WordArray [leila-alderman] #3664 +* RuboCop: Fix Style/SymbolArray [leila-alderman] #3665 +* Mercado-Pago: Notification url GSF [cdmackeyfree] #3678 +* Credorax: Update logic for setting 3ds_homephonecountry [britth] #3691 + +== Version 1.108.0 (Jun 9, 2020) +* Cybersource: Send cavv as xid is xid is missing [pi3r] #3658 +* Forte: Change default sec_code value to PPD [molbrown] #3653 +* Elavon: Add merchant initiated unscheduled field [leila-alderman] #3647 +* Decidir: Add aggregate data fields [leila-alderman] #3648 +* Vantiv: Vantiv(Element): add option to send terminal id in transactions [cdmackeyfree] #3654 +* Update supported Ruby and Rails versions [leila-alderman] #3656 +* CI: Drop unused sudo: false Travis directive [olleolleolle] #3616 +* PayU Latam: Prevent blank country in billing_address [britth] #3657 +* DLocal: Fix address field names [molbrown] #3651 + +== Version 1.107.4 (Jun 2, 2020) +* Elavon: Implement true verify action [leila-alderman] #3610 +* Vantiv Express: Implement true verify [leila-alderman] #3617 +* Litle: Pass expiration data for basis payment method [therufs] #3606 +* Stripe Payment Intents: Error handling and backwards compatibility within refund [britth] #3627 +* HPS: Prevent errors when account_type or account_holder_type are nil [britth] #3628 +* D Local: Handle invalid country code errors [curiousepic] #3626 +* Stripe Payment Intents: Utilize execute_threed flag to determine success [britth] #3625 +* Elavon: Add Level 3 fields [leila-alderman] #3632 +* CyberSource: Stored Credential fixes [curiousepic] #3624 +* CyberSource: Fix invalid and missing field tests [curiousepic] #3634 +* CyberSource: Pass stored credentials with purchase [curiousepic] #3636 +* Mercado Pago: Add payment_method_option_id field [schwarzgeist] #3635 +* Stripe: Provide error when attempting an authorize with ACH [britth] #3633 +* EBANX: Send original order id as merchant_payment_code metadata [miguelxpn] #3637 +* Element: Add card_present_code field [schwarzgeist] #3623 +* Orbital: Add support for Level 3 fields [leila-alderman] #3639 +* Firstdata: Strip newline characters from address [bittercoder] #3643 +* Forte: add sec_code attribute for echeck [wsmoak] #3640 + +== Version 1.107.3 (May 8, 2020) +* Realex: Ignore IPv6 unsupported addresses [elfassy] #3622 +* Cybersource: Set partnerSolutionID after the business rules, fixes 500 error [pi3r] #3621 + +== Version 1.107.2 (May 7, 2020) +* Cybersource: Send a specific card brand commerceIndicator for 3DS [pi3r] #3620 +* Cybersource: Send application_id as partnerSolutionID [pi3r] #3620 +* Iridium: Localize zero-decimal currencies [chinhle23] #3587 +* iVeri: Fix `verify` action [chinhle23] #3588 +* Ixopay: Properly support three-decimal currencies [chinhle23] #3589 +* Kushki: support `auth` and `capture` [therufs] #3591 +* PaymentExpress: Update references to Windcave to reflect rebranding [britth] #3595 +* Decidir: Improve handling of error responses from the gateway [naashton] #3594 +* CyberSource: Added support for MerchantInformation CyberSource-specific fields [apfranzen] #3592 +* ePay: Send unique order ids for remote tests [curiousepic] #3593 +* Checkout V2: Send more informative error messages for 4xx errors [britth] #3601 +* Elavon: Add ssl_dynamic_dba field [apfranzen] #3600 +* iATS Payments: Update gateway to v3 and add support for additional GSFs [naashton] #3599 +* Remove deprecated `rubyforge_project` attribute and tidy up unit test output [fatcatt316] #3598 +* Elavon: Cleanup inadvertant field removal (avs_address) in #3600 [apfranzen] #3602 +* EBANX: Fix transaction amount for verify transaction [miguelxpn] #3603 +* iATS Payments: Update gateway to accept `email`, `phone`, and `country` fields [naashton] #3607 +* Braintree: Fix response for failed refunds when falling back to voids [jasonwebster] #3608 +* Worldpay: Fix response for failed refunds when falling back to voids [jasonwebster] #3609 +* iATS Payments: Add support for Customer Code payment method [molbrown] #3611 +* HPS: Add Google Pay support [MSmedal] #3597 +* Adyen: Parse appropriate message for 3DS2 authorization calls [britth] #3619 +* CyberSource: Add error details response fields [schwarzgeist] #3629 + +== Version 1.107.1 (Apr 1, 2020) +* Add `allowed_push_host` to gemspec [mdeloupy] + +== Version 1.107.0 (Apr 1, 2020) +* Stripe Payment Intents: Early return failed `payment_methods` response [chinhle23] #3570 +* Borgun: Support `passengerItineraryData` [therufs] #3572 +* Ingenico GlobalCollect: support optional `requires_approval` field [fatcatt316] #3571 +* CenPOS: Update failing remote tests [britth] #3575 +* Realex: Update remote tests [britth] #3576 +* FirstData e4 v27: Properly tag stored credential initiation field in request [britth] #3578 +* Orbital: Fix stored credentials [chinhle23] #3579 +* Acapture(Opp): Update gateway credentials [molbrown] #3574 +* Ingenico GlobalCollect: support `requires_approval` field [fatcatt316] #3577 +* CyberSource: Fix `void` for `purchase` transactions [chinhle23] #3581 +* Checkout V2: Begin to add support for using network tokens for transactions. [arbianchi] #3580 +* Opp: Update remote test fixtures [ccarruitero] #3582 +* Optimal Payment: Add support for store [britth] #3585 +* SecurePay Australia : Update test URL (#3586) + +== Version 1.106.0 (Mar 10, 2020) +* PayJunctionV2: Send billing address in `auth` and `purchase` transactions [naashton] #3538 +* Adyen: Fix some remote tests [curiousepic] #3541 +* Redsys: Properly escape cardholder name and description fields in 3DS requests [britth] #3537 +* RuboCop: Fix Style/HashSyntax [leila-alderman] #3540 +* Paypal: Fix OrderTotal elements in `add_payment_details` [chinhle23] #3544 +* Stripe Payment Intents: Add tests for "Idempotency-Key" header [fatcatt316] #3542 +* Paypal: Fix RuboCop Style/HashSyntax violations [chinhle23] #3547 +* Rubocop corrections for space around operators [cdmackeyfree] #3543 +* Fat Zebra: Add `is_billing` in post for `store` call [chinhle23] #3551 +* SafeCharge: Adds four supported countries [carrigan] #3550 +* Ixopay: Support stored credentials [leila-alderman] #3549 +* BlueSnap: Adds localized currency support [carrigan] #3552 +* CheckoutV2: Use status as message for 3DS txns in progress [britth] #3545 +* Stripe Payment Intents: Prevent idempotency key errors for compound actions [britth] #3554 +* Adyen: Add tests for voiding with idempotency keys [jknipp] #3553 +* Fat Zebra: Fix `store` call [chinhle23] #3556 +* Update README to include Adyen [haolime] #3452 +* PayJunctionv2: Fix billing address fields [leila-alderman] #3557 +* Adyen: Fail unexpected 3DS responses [curiousepic] #3546 +* Merchant Warrior: Add support for setting soft descriptors [daBayrus] #3558 +* Adyen: Fix stored credentials [chinhle23] #3560 +* Update BIN ranges for Alelo and Maestro cards [leila-alderman] #3559 +* EBANX: Fix declines if order id is bigger than 40 chars [miguelxpn] #3563 +* Moneris US: Remove gateway [chinhle23] #3561 +* Decidir: Decidir: Improving the response message when encountering errors [naashton] #3564 +* PayBox: Added USERTrust RSA Certification Authority and Sectigo RSA Organization Validation Secure Server CA [baldowl] #3567 + +== Version 1.105.0 (Feb 20, 2020) +* Credorax: Fix `3ds_transtype` setting in post [chinhle23] #3531 +* Bambora Apac: Send void amount in options [leila-alderman] #3532 +* RuboCop: Fix Layout/IndentHash [leila-alderman] #3529 +* Stripe: Add connected account support [Carrigan] #3535 +* Redsys: Update scrub method to account for 3DS error responses [britth] #3534 +* Authorize.Net: Pass `account_type` to `check` payment types [chinhle23] #3530 +* Merchant Warrior: Send void amount in options [leila-alderman] #3525 +* Stripe: Add support for `statement_descriptor_suffix` field [Carrigan] #3528 +* Decidir: Add support for fraud_detection, site_id, and establishment_name [fatcatt316] #3527 +* HPS: support eCheck [therufs] #3500 +* EBANX: Add metadata information in post [miguelxpn] #3522 +* Worldpay: Add `riskData` GSF [fatcatt316] #3514 +* EBANX: Fix `scrub` [chinhle23] #3521 +* Worldpay: Remove unnecessary .tag! methods [leila-alderman] #3519 +* BPoint: Remove amount from void requests [leila-alderman] #3518 +* Authorize.net: Trim supported countries to AU, CA, US [fatcatt316] #3516 +* Credorax: Allow optional 3DS 2 fields [jeremywrowe] #3515 +* Stripe: Remove outdated 'customer options' deprecation [alexdunae] #3401 +* Added support for fraud review in CyberSource gateway [greg-burgoon] #3536 + +== Version 1.104.0 (Jan 29, 2020) +* Adyen: add `recurring_contract_type` GSF [therufs] #3460 +* Credorax: Only pass `3ds_version` parameter when required [britth] #3458 +* EBANX: Include Peru in supported countries [Ruanito] #3443 +* Bluesnap: include fraud data in response message [therufs] #3459 +* Ingenico GlobalCollect: support `airline_data` and related GSFs [therufs] #3461 +* Add UnionPay card type [leila-alderman] #3464 +* Braintree: Fix add_credit_card_to_customer in Store [molbrown] #3466 +* EBANX: Default to not send amount on capture [chinhle23] #3463 +* Latitude19: Convert money format to dollars [molbrown] #3468 +* Adyen: Fix response success for unstore [kheang] #3470 +* CyberSource: add several GSFs [therufs] #3465 +* Adyen: add `recurring_contract_type` GSF to auth [therufs] #3471 +* Stripe Payment Intents: Use localized_amount on capture [molbrown] #3475 +* dLocal: Add support for installments [kdelemme] #3456 +* Merchant Warrior: Add void operation [leila-alderman] #3474 +* Decidir: Update payment method IDs [leila-alderman] #3476 +* Adyen: Add delivery address [leila-alderman] #3477 +* Authorize.net: Correctly parse direct_response field with quotation marks [britth] #3479 +* Decidir: Add debit card payment method IDs [leila-alderman] #3480 +* CyberSource: Add issuer data+MDD to credit & void [leila-alderman] #3481 +* Credorax: add `authorization_type` and `multiple_capture_count` GSFs [therufs] #3478 +* CardStream: use localized_amount to correctly support zero-decimal currencies [britth] #3473 +* EBANX: Add additional data in post [Ruanito] #3482 +* Credorax: Omit phone when nil [leila-alderman] #3490 +* TransFirst TrExp: Remove hyphens from zip [leila-alderman] #3483 +* Mundipagg: Return acquirer code as the error code [leila-alderman] #3492 +* Braintree Blue: Remove customer hash when using a payment_method_nonce #3495 +* Credorax: Update non-standard currencies list [chinhle23] #3499 +* Redsys: Update production URL [britth] #3505 +* Moneris: include AVS and CoF fields when storing vault records [alexdunae] #3446 +* Moneris: Add support for temporary vault storage [alexdunae] #3446 +* Clearhaus: Update currencies without fractions list [chinhle23] #3506 +* Merchant Warrior: Add recurringFlag to purchase & authorize [carrigan] #3504 +* CardConnect: Remove domain port validation [leila-alderman] #3494 +* Paymentez: Correct refund and void message parsing [carrigan] #3509 +* Mercado Pago: Add taxes and net_amount gateway specific fields [carrigan] #3512 +* Moneris: use dedicated card_verification methods [alexdunae] #3428 +* Authorize.net: Trim down supported countries [fatcatt316] #3511 +* Stripe: Add support for `statement_descriptor_suffix` field [carrigan] #3528 +* Stripe: Add connected account support [carrigan] #3535 + +== Version 1.103.0 (Dec 2, 2019) +* Quickbooks: Mark transactions that returned `AuthorizationFailed` as failures [britth] #3447 +* Credorax: Add referral CFT transactions [leila-alderman] #3432 +* DLocal: Updates for version 2.1 [molbrown] #3449 +* CyberSource: Send MDD on capture [leila-alderman] #3453 +* Ixopay: Include extra_data gateway specific field [therufs] #3450 +* CyberSource: Fix XML error on capture [leila-alderman] #3454 +* Adyen: Add gateway specific field for splits [leila-alderman] #3448 +* Adyen: Add `unstore` and `storeToken` actions with '/Recurring' endpoint [deedeelavinder][davidsantoso] #3438 +* Barclaycard Smartpay: Add functionality to set 3DS exemptions via API [britth] #3457 +* Use null@cybersource.com when option[:email] is an empty string [pi3r] #3462 + +== Version 1.102.0 (Nov 14, 2019) +* Quickbooks: Make token refresh optional with allow_refresh flag [britth] #3419 +* Paymentez: Update supported countries [curiousepic] #3425 +* Ixopay: Add new gateway [jasonxp] #3426 +* Ixopay: Add support for currency option to refund method #3433 +* Ixopay: Remove default callback URL #3436 +* Ixopay: Refactor capture #3431 +* Update supported countries list. Add currencies without fractions / with 3 decimal places #3424 +* RuboCop: Fix Layout/EndAlignment [leila-alderman] #3427 +* RuboCop: Fix Layout/ExtraSpacing [leila-alderman] #3429 +* RuboCop: Fix Layout/MultilineOperationIndentation [leila-alderman] #3439 +* Worldpay: Update logic to set cardholderName for 3DS transactions [britth] #3444 +* Adopt new enrolled key for 3DS1 transactions. enrolled contains the 3… #3442 + +== Version 1.101.0 (Nov 4, 2019) +* Add UYI to list of currencies without fractions [curiousepic] #3416 +* Quickbooks: Add OAuth 2.0 support and void action [britth] #3397 +* Credorax: Stop always sending r1 parameter [molbrown] #3415 +* Rubocop: Layout/RescueEnsureAlignment fix [leila-alderman] #3411 +* CyberSource: Send issuer data on capture [leila-alderman] #3404 +* Rubocop: Style/IfUnlessModifier [nfarve] #3390 +* Redsys: Updates to parse method for non-3DS responses [britth] #3391 +* Netbanx: Add 3DS2 Support [Jujhar] #3394 + +== Version 1.100.0 (Oct 16, 2019) +* Stripe: Restore non-auto capture behaviour for card present transactions [PatrickFang] #3258 * Revert "Revert "Worldpay: Switch to Nokogiri"" [curiousepic] #3373 * Adyen: Fix `authorise3d` message for refusals [jeremywrowe] #3374 * Redsys: Set authorization field for 3DS transactions [britth] #3377 @@ -13,6 +434,11 @@ * BluePay: Add ability to pass doc_type in refunds and credits [britth] #3386 * Stripe Payment Intents: Fix fallback for Store [waaux] #3343 * Update Securionpay supported countries [hossamhossny] #2472 +* Visanet Peru: Add amount argument to Capture [curiousepic] #3389 +* Rubocop: Layout/MultilineHashBraceLayout [nfarve] #3385 +* CardConnect: Always include additional_data in purchase [therufs] #3387 +* CardConnect: Add user_fields GSF [therufs] #3388 +* Moneris: Add support for stored credentials [chinhle23] #3384 == Version 1.99.0 (Sep 26, 2019) * Adyen: Add functionality to set 3DS exemptions via API [britth] #3331 diff --git a/Gemfile b/Gemfile index fc9791f2719..8003e530f85 100644 --- a/Gemfile +++ b/Gemfile @@ -1,11 +1,11 @@ source 'https://rubygems.org' gemspec -gem 'jruby-openssl', :platforms => :jruby +gem 'jruby-openssl', platforms: :jruby gem 'rubocop', '~> 0.60.0', require: false group :test, :remote_test do # gateway-specific dependencies, keeping these gems out of the gemspec - gem 'braintree', '>= 2.98.0' + gem 'braintree', '>= 2.98.0', '< 3.0' gem 'mechanize' end diff --git a/README.md b/README.md index 00f528d3c3a..478d92d1195 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Active Merchant -[![Build Status](https://travis-ci.org/activemerchant/active_merchant.png?branch=master)](https://travis-ci.org/activemerchant/active_merchant) -[![Code Climate](https://codeclimate.com/github/activemerchant/active_merchant.png)](https://codeclimate.com/github/activemerchant/active_merchant) +[![Build Status](https://github.com/activemerchant/active_merchant/workflows/CI/badge.svg?branch=master)](https://github.com/activemerchant/active_merchant/actions?query=workflow%3ACI) +[![Code Climate](https://codeclimate.com/github/activemerchant/active_merchant.svg)](https://codeclimate.com/github/activemerchant/active_merchant) Active Merchant is an extraction from the ecommerce system [Shopify](http://www.shopify.com). Shopify's requirements for a simple and unified API to access dozens of different payment @@ -91,8 +91,9 @@ guide and [Standardized 3DS Fields](https://github.com/activemerchant/active_mer The [ActiveMerchant Wiki](https://github.com/activemerchant/active_merchant/wikis) contains a [table of features supported by each gateway](https://github.com/activemerchant/active_merchant/wiki/Gateway-Feature-Matrix). +* [Adyen](https://www.adyen.com/) - US, AT, AU, BE, BG, BR, CH, CY, CZ, DE, DK, EE, ES, FI, FR, GB, GI, GR, HK, HU, IE, IS, IT, LI, LT, LU, LV, MC, MT, MX, NL, NO, PL, PT, RO, SE, SG, SK, SI * [Authorize.Net CIM](http://www.authorize.net/) - US -* [Authorize.Net](http://www.authorize.net/) - AD, AT, AU, BE, BG, CA, CH, CY, CZ, DE, DK, ES, FI, FR, GB, GB, GI, GR, HU, IE, IT, LI, LU, MC, MT, NL, NO, PL, PT, RO, SE, SI, SK, SM, TR, US, VA +* [Authorize.Net](http://www.authorize.net/) - AU, CA, US * [Axcess MS](http://www.axcessms.com/) - AD, AT, BE, BG, BR, CA, CH, CY, CZ, DE, DK, EE, ES, FI, FO, FR, GB, GI, GR, HR, HU, IE, IL, IM, IS, IT, LI, LT, LU, LV, MC, MT, MX, NL, NO, PL, PT, RO, RU, SE, SI, SK, TR, US, VA * [Balanced](https://www.balancedpayments.com/) - US * [Bambora Asia-Pacific](http://www.bambora.com/) - AU, NZ @@ -112,7 +113,7 @@ The [ActiveMerchant Wiki](https://github.com/activemerchant/active_merchant/wiki * [Cecabank](http://www.ceca.es/es/) - ES * [Cenpos](https://www.cenpos.com/) - AD, AI, AG, AR, AU, AT, BS, BB, BE, BZ, BM, BR, BN, BG, CA, HR, CY, CZ, DK, DM, EE, FI, FR, DE, GR, GD, GY, HK, HU, IS, IN, IL, IT, JP, LV, LI, LT, LU, MY, MT, MX, MC, MS, NL, PA, PL, PT, KN, LC, MF, VC, SM, SG, SK, SI, ZA, ES, SR, SE, CH, TR, GB, US, UY * [CAMS: Central Account Management System](https://www.centralams.com/) - US -* [Checkout.com](https://www.checkout.com/) - AT, BE, BG, CY, CZ, DE, DK, EE, ES, FI, FR, GR, HR, HU, IE, IS, IT, LI, LT, LU, LV, MT, MU, NL, NO, PL, PT, RO, SE, SI, SK, US +* [Checkout.com](https://www.checkout.com/) - 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 * [Clearhaus](https://www.clearhaus.com) - AD, AT, BE, BG, CH, CY, CZ, DE, DK, EE, ES, FI, FO, FR, GB, GL, GR, HR, HU, IE, IS, IT, LI, LT, LU, LV, MT, NL, NO, PL, PT, RO, SE, SI, SK * [Commercegate](http://www.commercegate.com/) - AD, AT, AX, BE, BG, CH, CY, CZ, DE, DK, ES, FI, FR, GB, GG, GI, GR, HR, HU, IE, IM, IS, IT, JE, LI, LT, LU, LV, MC, MT, NL, NO, PL, PT, RO, SE, SI, SK, VA * [Conekta](https://conekta.io) - MX @@ -159,7 +160,6 @@ The [ActiveMerchant Wiki](https://github.com/activemerchant/active_merchant/wiki * [Modern Payments](http://www.modpay.com) - US * [MONEI](http://www.monei.net/) - AD, AT, BE, BG, CA, CH, CY, CZ, DE, DK, EE, ES, FI, FO, FR, GB, GI, GR, HU, IE, IL, IS, IT, LI, LT, LU, LV, MT, NL, NO, PL, PT, RO, SE, SI, SK, TR, US, VA * [Moneris](http://www.moneris.com/) - CA -* [Moneris (US)](http://www.monerisusa.com/) - US * [MoneyMovers](http://mmoa.us/) - US * [NAB Transact](http://transact.nab.com.au) - AU * [NELiX TransaX](https://www.nelixtransax.com/) - US @@ -183,7 +183,7 @@ The [ActiveMerchant Wiki](https://github.com/activemerchant/active_merchant/wiki * [Paybox Direct](http://www.paybox.com/) - FR * [Payeezy](https://developer.payeezy.com/) - CA, US * [Payex](http://payex.com/) - DK, FI, NO, SE -* [PaymentExpress](http://www.paymentexpress.com/) - AU, CA, DE, ES, FR, GB, HK, IE, MY, NL, NZ, SG, US, ZA +* [Windcave (formerly PaymentExpress)](https://www.windcave.com/) - AU, CA, DE, ES, FR, GB, HK, IE, MY, NL, NZ, SG, US, ZA * [PAYMILL](https://paymill.com) - AD, AT, BE, BG, CH, CY, CZ, DE, DK, EE, ES, FI, FO, FR, GB, GI, GR, HU, IE, IL, IS, IT, LI, LT, LU, LV, MT, NL, NO, PL, PT, RO, SE, SI, SK, TR, VA * [PayPal Express Checkout](https://www.paypal.com/webapps/mpp/express-checkout) - US, CA, SG, AU * [PayPal Express Checkout (UK)](https://www.paypal.com/uk/webapps/mpp/express-checkout) - GB @@ -244,4 +244,4 @@ Functionality or APIs that are deprecated will be marked as such. Deprecated fun ## Ruby and Rails compatibility policies -Because Active Merchant is a payment library, it needs to take security seriously. For this reason, Active Merchant guarantees compatibility only with actively supported versions of Ruby and Rails. At the time of this writing, that means that Ruby 2.3+ and Rails 4.2+ are supported. +Because Active Merchant is a payment library, it needs to take security seriously. For this reason, Active Merchant guarantees compatibility only with actively supported versions of Ruby and Rails. At the time of this writing, that means that Ruby 2.5+ and Rails 5.0+ are supported. diff --git a/Rakefile b/Rakefile index 5e92782a541..0334d839734 100644 --- a/Rakefile +++ b/Rakefile @@ -1,4 +1,4 @@ -$:.unshift File.expand_path('../lib', __FILE__) +$LOAD_PATH.unshift File.expand_path('../lib', __FILE__) require 'active_merchant/version' begin @@ -24,8 +24,8 @@ task :tag_release do end desc 'Run the unit test suite' -task :default => 'test:units' -task :test => 'test:units' +task default: 'test:units' +task test: 'test:units' RuboCop::RakeTask.new @@ -33,11 +33,11 @@ namespace :test do Rake::TestTask.new(:units) do |t| t.pattern = 'test/unit/**/*_test.rb' t.libs << 'test' - t.verbose = true + t.verbose = false end desc 'Run all tests that do not require network access' - task :local => ['test:units', 'rubocop'] + task local: ['test:units', 'rubocop'] Rake::TestTask.new(:remote) do |t| t.pattern = 'test/remote/**/*_test.rb' diff --git a/activemerchant.gemspec b/activemerchant.gemspec index 505bcfecd42..e72702e8afc 100644 --- a/activemerchant.gemspec +++ b/activemerchant.gemspec @@ -1,4 +1,4 @@ -$:.push File.expand_path('../lib', __FILE__) +$LOAD_PATH.push File.expand_path('../lib', __FILE__) require 'active_merchant/version' Gem::Specification.new do |s| @@ -12,23 +12,25 @@ Gem::Specification.new do |s| s.author = 'Tobias Luetke' s.email = 'tobi@leetsoft.com' s.homepage = 'http://activemerchant.org/' - s.rubyforge_project = 'activemerchant' - s.required_ruby_version = '>= 2.3' + s.required_ruby_version = '>= 2.5' s.files = Dir['CHANGELOG', 'README.md', 'MIT-LICENSE', 'CONTRIBUTORS', 'lib/**/*', 'vendor/**/*'] s.require_path = 'lib' + s.metadata['allowed_push_host'] = 'https://rubygems.org' + s.has_rdoc = true if Gem::VERSION < '1.7.0' s.add_dependency('activesupport', '>= 4.2') - s.add_dependency('i18n', '>= 0.6.9') s.add_dependency('builder', '>= 2.1.2', '< 4.0.0') + s.add_dependency('i18n', '>= 0.6.9') s.add_dependency('nokogiri', '~> 1.4') + s.add_development_dependency('mocha', '~> 1') + s.add_development_dependency('pry') + s.add_development_dependency('pry-byebug') s.add_development_dependency('rake') s.add_development_dependency('test-unit', '~> 3') - s.add_development_dependency('mocha', '~> 1') s.add_development_dependency('thor') - s.add_development_dependency('pry') end diff --git a/circle.yml b/circle.yml index 5d2a53e5abb..fcf9fe6fa42 100644 --- a/circle.yml +++ b/circle.yml @@ -1,6 +1,6 @@ machine: ruby: - version: '2.3.0' + version: '2.5.0' dependencies: cache_directories: diff --git a/gemfiles/Gemfile.rails60 b/gemfiles/Gemfile.rails60 new file mode 100644 index 00000000000..c9289b875eb --- /dev/null +++ b/gemfiles/Gemfile.rails60 @@ -0,0 +1,3 @@ +eval_gemfile '../Gemfile' + +gem 'activesupport', '~> 6.0.0' diff --git a/generators/gateway/templates/gateway.rb b/generators/gateway/templates/gateway.rb index f9f986176f8..671d5c22129 100644 --- a/generators/gateway/templates/gateway.rb +++ b/generators/gateway/templates/gateway.rb @@ -6,19 +6,19 @@ class <%= class_name %>Gateway < Gateway self.supported_countries = ['US'] self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://www.example.net/' self.display_name = 'New Gateway' STANDARD_ERROR_CODE_MAPPING = {} - def initialize(options={}) + def initialize(options = {}) requires!(options, :some_credential, :another_credential) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) post = {} add_invoice(post, money, options) add_payment(post, payment) @@ -28,7 +28,7 @@ def purchase(money, payment, options={}) commit('sale', post) end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) post = {} add_invoice(post, money, options) add_payment(post, payment) @@ -38,19 +38,19 @@ def authorize(money, payment, options={}) commit('authonly', post) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) commit('capture', post) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) commit('refund', post) end - def void(authorization, options={}) + def void(authorization, options = {}) commit('void', post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -67,19 +67,16 @@ def scrub(transcript) private - def add_customer_data(post, options) - end + def add_customer_data(post, options); end - def add_address(post, creditcard, options) - end + def add_address(post, creditcard, options); end def add_invoice(post, money, options) post[:amount] = amount(money) post[:currency] = (options[:currency] || currency(money)) end - def add_payment(post, payment) - end + def add_payment(post, payment); end def parse(body) {} @@ -94,24 +91,20 @@ def commit(action, parameters) message_from(response), response, authorization: authorization_from(response), - avs_result: AVSResult.new(code: response["some_avs_response_key"]), - cvv_result: CVVResult.new(response["some_cvv_response_key"]), + avs_result: AVSResult.new(code: response['some_avs_response_key']), + cvv_result: CVVResult.new(response['some_cvv_response_key']), test: test?, error_code: error_code_from(response) ) end - def success_from(response) - end + def success_from(response); end - def message_from(response) - end + def message_from(response); end - def authorization_from(response) - end + def authorization_from(response); end - def post_data(action, parameters = {}) - end + def post_data(action, parameters = {}); end def error_code_from(response) unless success_from(response) diff --git a/generators/gateway/templates/gateway_test.rb b/generators/gateway/templates/gateway_test.rb index 03f699b9641..38d9f0817e1 100644 --- a/generators/gateway/templates/gateway_test.rb +++ b/generators/gateway/templates/gateway_test.rb @@ -31,38 +31,27 @@ def test_failed_purchase assert_equal Gateway::STANDARD_ERROR_CODE[:card_declined], response.error_code end - def test_successful_authorize - end + def test_successful_authorize; end - def test_failed_authorize - end + def test_failed_authorize; end - def test_successful_capture - end + def test_successful_capture; end - def test_failed_capture - end + def test_failed_capture; end - def test_successful_refund - end + def test_successful_refund; end - def test_failed_refund - end + def test_failed_refund; end - def test_successful_void - end + def test_successful_void; end - def test_failed_void - end + def test_failed_void; end - def test_successful_verify - end + def test_successful_verify; end - def test_successful_verify_with_failed_void - end + def test_successful_verify_with_failed_void; end - def test_failed_verify - end + def test_failed_verify; end def test_scrub assert @gateway.supports_scrubbing? @@ -72,19 +61,19 @@ def test_scrub private def pre_scrubbed - %q( + ' Run the remote tests for this gateway, and then put the contents of transcript.log here. - ) + ' end def post_scrubbed - %q( + ' Put the scrubbed contents of transcript.log here after implementing your scrubbing function. Things to scrub: - Credit card number - CVV - Sensitive authentication details - ) + ' end def successful_purchase_response @@ -98,30 +87,21 @@ def successful_purchase_response ) end - def failed_purchase_response - end + def failed_purchase_response; end - def successful_authorize_response - end + def successful_authorize_response; end - def failed_authorize_response - end + def failed_authorize_response; end - def successful_capture_response - end + def successful_capture_response; end - def failed_capture_response - end + def failed_capture_response; end - def successful_refund_response - end + def successful_refund_response; end - def failed_refund_response - end + def failed_refund_response; end - def successful_void_response - end + def successful_void_response; end - def failed_void_response - end + def failed_void_response; end end diff --git a/generators/gateway/templates/remote_gateway_test.rb b/generators/gateway/templates/remote_gateway_test.rb index 08262a97c93..dbe34a57225 100644 --- a/generators/gateway/templates/remote_gateway_test.rb +++ b/generators/gateway/templates/remote_gateway_test.rb @@ -22,8 +22,8 @@ def test_successful_purchase def test_successful_purchase_with_more_options options = { order_id: '1', - ip: "127.0.0.1", - email: "joe@example.com" + ip: '127.0.0.1', + email: 'joe@example.com' } response = @gateway.purchase(@amount, @credit_card, options) @@ -56,7 +56,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -79,7 +79,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund end @@ -143,5 +143,4 @@ def test_transcript_scrubbing assert_scrubbed(@credit_card.verification_value, transcript) assert_scrubbed(@gateway.options[:password], transcript) end - end diff --git a/lib/active_merchant.rb b/lib/active_merchant.rb index 06ab2f0d19d..5634caae807 100644 --- a/lib/active_merchant.rb +++ b/lib/active_merchant.rb @@ -50,9 +50,9 @@ require 'active_merchant/country' module ActiveMerchant - def self.deprecated(message, caller=Kernel.caller[1]) + def self.deprecated(message, caller = Kernel.caller[1]) warning = caller + ': ' + message - if(respond_to?(:logger) && logger.present?) + if respond_to?(:logger) && logger.present? logger.warn(warning) else warn(warning) diff --git a/lib/active_merchant/billing/avs_result.rb b/lib/active_merchant/billing/avs_result.rb index 77f9ebf3727..c4bcf939dda 100644 --- a/lib/active_merchant/billing/avs_result.rb +++ b/lib/active_merchant/billing/avs_result.rb @@ -39,10 +39,10 @@ class AVSResult # Map vendor's AVS result code to a postal match code POSTAL_MATCH_CODE = { - 'Y' => %w( D H F H J L M P Q V W X Y Z ), - 'N' => %w( A C K N O ), - 'X' => %w( G S ), - nil => %w( B E I R T U ) + 'Y' => %w(D H F H J L M P Q V W X Y Z), + 'N' => %w(A C K N O), + 'X' => %w(G S), + nil => %w(B E I R T U) }.inject({}) do |map, (type, codes)| codes.each { |code| map[code] = type } map @@ -50,10 +50,10 @@ class AVSResult # Map vendor's AVS result code to a street match code STREET_MATCH_CODE = { - 'Y' => %w( A B D H J M O Q T V X Y ), - 'N' => %w( C K L N W Z ), - 'X' => %w( G S ), - nil => %w( E F I P R U ) + 'Y' => %w(A B D H J M O Q T V X Y), + 'N' => %w(C K L N W Z), + 'X' => %w(G S), + nil => %w(E F I P R U) }.inject({}) do |map, (type, codes)| codes.each { |code| map[code] = type } map @@ -88,8 +88,7 @@ def to_hash { 'code' => code, 'message' => message, 'street_match' => street_match, - 'postal_match' => postal_match - } + 'postal_match' => postal_match } end end end diff --git a/lib/active_merchant/billing/base.rb b/lib/active_merchant/billing/base.rb index 5392189e46b..269cf394512 100644 --- a/lib/active_merchant/billing/base.rb +++ b/lib/active_merchant/billing/base.rb @@ -39,19 +39,6 @@ def self.gateway(name) end end - # Return the matching integration module - # You can then get the notification from the module - # * bogus: Bogus - Does nothing (for testing) - # * chronopay: Chronopay - # * paypal: Paypal - # - # chronopay = ActiveMerchant::Billing::Base.integration('chronopay') - # notification = chronopay.notification(raw_post) - # - def self.integration(name) - Billing::Integrations.const_get(name.to_s.downcase.camelize) - end - # A check to see if we're in test mode def self.test? mode == :test diff --git a/lib/active_merchant/billing/check.rb b/lib/active_merchant/billing/check.rb index 6dcba4b0267..936e8fc3995 100644 --- a/lib/active_merchant/billing/check.rb +++ b/lib/active_merchant/billing/check.rb @@ -29,19 +29,15 @@ def name=(value) def validate errors = [] - [:name, :routing_number, :account_number].each do |attr| + %i[name routing_number account_number].each do |attr| errors << [attr, 'cannot be empty'] if empty?(self.send(attr)) end errors << [:routing_number, 'is invalid'] unless valid_routing_number? - if(!empty?(account_holder_type) && !%w[business personal].include?(account_holder_type.to_s)) - errors << [:account_holder_type, 'must be personal or business'] - end + errors << [:account_holder_type, 'must be personal or business'] if !empty?(account_holder_type) && !%w[business personal].include?(account_holder_type.to_s) - if(!empty?(account_type) && !%w[checking savings].include?(account_type.to_s)) - errors << [:account_type, 'must be checking or savings'] - end + errors << [:account_type, 'must be checking or savings'] if !empty?(account_type) && !%w[checking savings].include?(account_type.to_s) errors_hash(errors) end diff --git a/lib/active_merchant/billing/compatibility.rb b/lib/active_merchant/billing/compatibility.rb index 11103dcee68..319ec8a4350 100644 --- a/lib/active_merchant/billing/compatibility.rb +++ b/lib/active_merchant/billing/compatibility.rb @@ -28,7 +28,7 @@ def self.deprecated def self.humanize(lower_case_and_underscored_word) result = lower_case_and_underscored_word.to_s.dup result.gsub!(/_id$/, '') - result.gsub!(/_/, ' ') + result.tr!('_', ' ') result.gsub(/([a-z\d]*)/i, &:downcase).gsub(/^\w/) { $&.upcase } end end @@ -56,7 +56,7 @@ def valid? private def internal_errors - @errors ||= Errors.new + @internal_errors ||= Errors.new end class Errors < Hash @@ -75,7 +75,7 @@ def []=(key, value) end def empty? - all? { |k, v| v&.empty? } + all? { |_k, v| v&.empty? } end def on(field) @@ -98,7 +98,8 @@ def full_messages result = [] self.each do |key, messages| - next unless(messages && !messages.empty?) + next unless messages && !messages.empty? + if key == 'base' result << messages.first.to_s else diff --git a/lib/active_merchant/billing/credit_card.rb b/lib/active_merchant/billing/credit_card.rb index 983e3edc384..ef47b89364c 100644 --- a/lib/active_merchant/billing/credit_card.rb +++ b/lib/active_merchant/billing/credit_card.rb @@ -22,6 +22,9 @@ module Billing #:nodoc: # * Alelo # * Cabal # * Naranja + # * UnionPay + # * Alia + # * Olimpica # # For testing purposes, use the 'bogus' credit card brand. This skips the vast majority of # validations, allowing you to focus on your core concerns until you're ready to be more concerned @@ -96,6 +99,10 @@ def number=(value) # * +'alelo'+ # * +'cabal'+ # * +'naranja'+ + # * +'union_pay'+ + # * +'alia'+ + # * +'olimpica'+ + # * +'creditel'+ # # Or, if you wish to test your implementation, +'bogus'+. # @@ -186,7 +193,7 @@ def requires_verification_value? 'contactless' => 'Data was read by a Contactless EMV kernel. Issuer script results are not available.', 'contactless_magstripe' => 'Contactless data was read with a non-EMV protocol.', 'contact' => 'Data was read using the EMV protocol. Issuer script results may follow.', - 'contact_quickchip' => 'Data was read by the Quickchip EMV kernel. Issuer script results are not available.', + 'contact_quickchip' => 'Data was read by the Quickchip EMV kernel. Issuer script results are not available.' } # Returns the ciphertext of the card's encrypted PIN. @@ -327,7 +334,7 @@ def validate_essential_attributes #:nodoc: errors << [:last_name, 'cannot be empty'] if last_name.blank? end - if(empty?(month) || empty?(year)) + if empty?(month) || empty?(year) errors << [:month, 'is required'] if empty?(month) errors << [:year, 'is required'] if empty?(year) else @@ -336,7 +343,7 @@ def validate_essential_attributes #:nodoc: if expired? errors << [:year, 'expired'] else - errors << [:year, 'is not a valid year'] if !valid_expiry_year?(year) + errors << [:year, 'is not a valid year'] if !valid_expiry_year?(year) end end @@ -347,7 +354,7 @@ def validate_card_brand_and_number #:nodoc: errors = [] if !empty?(brand) - errors << [:brand, 'is invalid'] if !CreditCard.card_companies.include?(brand) + errors << [:brand, 'is invalid'] if !CreditCard.card_companies.include?(brand) end if empty?(number) @@ -367,9 +374,7 @@ def validate_verification_value #:nodoc: errors = [] if verification_value? - unless valid_card_verification_value?(verification_value, brand) - errors << [:verification_value, "should be #{card_verification_value_length(brand)} digits"] - end + errors << [:verification_value, "should be #{card_verification_value_length(brand)} digits"] unless valid_card_verification_value?(verification_value, brand) elsif requires_verification_value? && !valid_card_verification_value?(verification_value, brand) errors << [:verification_value, 'is required'] end diff --git a/lib/active_merchant/billing/credit_card_methods.rb b/lib/active_merchant/billing/credit_card_methods.rb index 8cf91c5297c..1222b1e8e3f 100644 --- a/lib/active_merchant/billing/credit_card_methods.rb +++ b/lib/active_merchant/billing/credit_card_methods.rb @@ -10,20 +10,29 @@ module CreditCardMethods 'discover' => ->(num) { num =~ /^(6011|65\d{2}|64[4-9]\d)\d{12,15}|(62\d{14,17})$/ }, 'american_express' => ->(num) { num =~ /^3[47]\d{13}$/ }, 'naranja' => ->(num) { num&.size == 16 && in_bin_range?(num.slice(0, 6), NARANJA_RANGES) }, - 'diners_club' => ->(num) { num =~ /^3(0[0-5]|[68]\d)\d{11}$/ }, + 'diners_club' => ->(num) { num =~ /^3(0[0-5]|[68]\d)\d{11,16}$/ }, 'jcb' => ->(num) { num =~ /^35(28|29|[3-8]\d)\d{12}$/ }, 'dankort' => ->(num) { num =~ /^5019\d{12}$/ }, - 'maestro' => ->(num) { (12..19).cover?(num&.size) && in_bin_range?(num.slice(0, 6), MAESTRO_RANGES) }, + 'maestro' => lambda { |num| + (12..19).cover?(num&.size) && ( + in_bin_range?(num.slice(0, 6), MAESTRO_RANGES) || + MAESTRO_BINS.any? { |bin| num.slice(0, bin.size) == bin } + ) + }, 'forbrugsforeningen' => ->(num) { num =~ /^600722\d{10}$/ }, 'sodexo' => ->(num) { num =~ /^(606071|603389|606070|606069|606068|600818)\d{10}$/ }, + 'alia' => ->(num) { num =~ /^(504997|505878|601030|601073|505874)\d{10}$/ }, 'vr' => ->(num) { num =~ /^(627416|637036)\d{10}$/ }, 'cabal' => ->(num) { num&.size == 16 && in_bin_range?(num.slice(0, 8), CABAL_RANGES) }, + 'unionpay' => ->(num) { (16..19).cover?(num&.size) && in_bin_range?(num.slice(0, 8), UNIONPAY_RANGES) }, 'carnet' => lambda { |num| num&.size == 16 && ( in_bin_range?(num.slice(0, 6), CARNET_RANGES) || CARNET_BINS.any? { |bin| num.slice(0, bin.size) == bin } ) - } + }, + 'olimpica' => ->(num) { num =~ /^636853\d{10}$/ }, + 'creditel' => ->(num) { num =~ /^601933\d{10}$/ } } # http://www.barclaycard.co.uk/business/files/bin_rules.pdf @@ -51,10 +60,10 @@ module CreditCardMethods ] CARNET_BINS = Set.new( - [ - '286900', '502275', '606333', '627535', '636318', '636379', '639388', - '639484', '639559', '50633601', '50633606', '58877274', '62753500', - '60462203', '60462204', '588772' + %w[ + 286900 502275 606333 627535 636318 636379 639388 + 639484 639559 50633601 50633606 58877274 62753500 + 60462203 60462204 588772 ] ) @@ -64,8 +73,58 @@ module CreditCardMethods (510000..559999), ] + MAESTRO_BINS = Set.new( + %w[ 500057 + 501018 501043 501045 501047 501049 501051 501072 501075 501087 501089 501095 + 501500 + 501879 502113 502301 503175 + 503645 503670 + 504310 504338 504363 504533 504587 504620 504639 504656 504738 504781 504910 + 507001 507002 507004 507082 507090 + 560014 560565 561033 + 572402 572610 572626 + 576904 + 578614 + 581149 + 585274 585697 + 586509 + 588729 588792 + 589244 589407 589471 589605 589633 589647 589671 + 590043 590206 590263 590265 590278 590361 590362 590379 590393 590590 + 591235 591420 591481 591620 591770 591948 591994 + 592024 592161 592184 592186 592201 592384 592393 592528 592566 592704 592735 592879 592884 + 593074 593264 593272 593355 593496 593556 593589 593666 593709 593825 593963 593994 + 594184 594409 594468 594475 594581 594665 594691 594710 594874 594968 + 595355 595364 595532 595547 595561 595568 595743 595929 + 596245 596289 596399 596405 596590 596608 596645 596646 596791 596808 596815 596846 + 597077 597094 597143 597370 597410 597765 597855 597862 + 598053 598054 598395 598585 598793 598794 598815 598835 598838 598880 598889 + 599000 599069 599089 599148 599191 599310 599741 599742 599867 + 601070 + 604983 + 606126 + 636380 636422 636502 636639 + 637046 637756 + 639130 + 690032] + ) + # https://www.mastercard.us/content/dam/mccom/global/documents/mastercard-rules.pdf, page 73 MAESTRO_RANGES = [ + (500032..500033), + (501015..501016), + (501020..501021), + (501023..501029), + (501038..501041), + (501053..501058), + (501060..501063), + (501066..501067), + (501080..501083), + (501091..501092), + (501104..501105), + (501107..501108), + (501104..501105), + (501107..501108), (561200..561269), (561271..561299), (561320..561356), @@ -90,14 +149,14 @@ module CreditCardMethods # https://dev.elo.com.br/apis/tabela-de-bins, download csv from left sidebar ELO_RANGES = [ - 506707..506708, 506715..506715, 506718..506722, 506724..506724, 506726..506736, 506739..506739, 506741..506743, - 506745..506747, 506753..506753, 506774..506776, 506778..506778, 509000..509001, 509003..509003, 509007..509007, - 509020..509022, 509035..509035, 509039..509042, 509045..509045, 509048..509048, 509051..509071, 509073..509074, - 509077..509080, 509084..509084, 509091..509094, 509098..509098, 509100..509100, 509104..509104, 509106..509109, - 627780..627780, 636368..636368, 650031..650033, 650035..650045, 650047..650047, 650406..650410, 650434..650436, - 650439..650439, 650485..650504, 650506..650530, 650577..650580, 650582..650591, 650721..650727, 650901..650922, - 650928..650928, 650938..650939, 650946..650948, 650954..650955, 650962..650963, 650967..650967, 650971..650971, - 651652..651667, 651675..651678, 655000..655010, 655012..655015, 655051..655052, 655056..655057 + 506707..506708, 506715..506715, 506717..506722, 506724..506736, 506739..506743, + 506745..506747, 506753..506753, 506774..506778, 509000..509007, 509009..509014, + 509020..509030, 509035..509042, 509044..509089, 509091..509101, 509104..509807, + 509831..509877, 509897..509900, 509918..509964, 509971..509986, 509995..509999, + 627780..627780, 636368..636368, 650031..650033, 650035..650051, 650057..650081, + 650406..650439, 650485..650504, 650506..650538, 650552..650598, 650720..650727, + 650901..650922, 650928..650928, 650938..650939, 650946..650978, 651652..651704, + 655000..655019, 655021..655057 ] # Alelo provides BIN ranges by e-mailing them out periodically. @@ -109,8 +168,9 @@ module CreditCardMethods 402588..402588, 404347..404347, 405876..405876, 405882..405882, 405884..405884, 405886..405886, 430471..430471, 438061..438061, 438064..438064, 470063..470066, 496067..496067, 506699..506704, 506706..506706, 506713..506714, 506716..506716, - 506749..506750, 506752..506752, 506754..506756, 506758..506762, 506764..506767, - 506770..506771, 509015..509019, 509880..509882, 509884..509885, 509987..509988 + 506749..506750, 506752..506752, 506754..506756, 506758..506767, 506770..506771, + 506773..506773, 509015..509019, 509880..509882, 509884..509885, 509887..509887, + 509987..509992 ] CABAL_RANGES = [ @@ -123,6 +183,14 @@ module CreditCardMethods 589562..589562 ] + # In addition to the BIN ranges listed here that all begin with 81, UnionPay cards + # include many ranges that start with 62. + # Prior to adding UnionPay, cards that start with 62 were all classified as Discover. + # Because UnionPay cards are able to run on Discover rails, this was kept the same. + UNIONPAY_RANGES = [ + 81000000..81099999, 81100000..81319999, 81320000..81519999, 81520000..81639999, 81640000..81719999 + ] + def self.included(base) base.extend(ClassMethods) end @@ -197,8 +265,8 @@ module ClassMethods def valid_number?(number) valid_test_mode_card_number?(number) || valid_card_number_length?(number) && - valid_card_number_characters?(number) && - valid_by_algorithm?(brand?(number), number) + valid_card_number_characters?(number) && + valid_by_algorithm?(brand?(number), number) end def card_companies @@ -238,6 +306,7 @@ def first_digits(number) def last_digits(number) return '' if number.nil? + number.length <= 4 ? number : number.slice(-4..-1) end @@ -259,11 +328,13 @@ def matching_type?(number, brand) def valid_card_number_length?(number) #:nodoc: return false if number.nil? + number.length >= 12 end def valid_card_number_characters?(number) #:nodoc: return false if number.nil? + !number.match(/\D/) end @@ -276,6 +347,10 @@ def valid_by_algorithm?(brand, numbers) #:nodoc: case brand when 'naranja' valid_naranja_algo?(numbers) + when 'creditel' + valid_creditel_algo?(numbers) + when 'alia' + true else valid_luhn?(numbers) end @@ -305,7 +380,7 @@ def valid_by_algorithm?(brand, numbers) #:nodoc: 54 => 3, # 6 * 2 - 9 55 => 5, # etc ... 56 => 7, - 57 => 9, + 57 => 9 }.freeze # Checks the validity of a card number by use of the Luhn Algorithm. @@ -328,15 +403,23 @@ def valid_luhn?(numbers) #:nodoc: sum % 10 == 0 end - # Checks the validity of a card number by use of Naranja's specific algorithm. + # Checks the validity of a card number by use of specific algorithms def valid_naranja_algo?(numbers) #:nodoc: num_array = numbers.to_s.chars.map(&:to_i) multipliers = [4, 3, 2, 7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2] - num_sum = num_array[0..14].zip(multipliers).map { |a, b| a*b }.reduce(:+) + num_sum = num_array[0..14].zip(multipliers).map { |a, b| a * b }.reduce(:+) intermediate = 11 - (num_sum % 11) final_num = intermediate > 9 ? 0 : intermediate final_num == num_array[15] end + + def valid_creditel_algo?(numbers) #:nodoc: + num_array = numbers.to_s.chars.map(&:to_i) + multipliers = [5, 4, 3, 2, 1, 9, 8, 7, 6, 5, 4, 3, 2, 1, 9] + num_sum = num_array[0..14].zip(multipliers).map { |a, b| a * b }.reduce(:+) + final_num = num_sum % 10 + final_num == num_array[15] + end end end end diff --git a/lib/active_merchant/billing/cvv_result.rb b/lib/active_merchant/billing/cvv_result.rb index 2fbbbb83c4b..e96eaf0889f 100644 --- a/lib/active_merchant/billing/cvv_result.rb +++ b/lib/active_merchant/billing/cvv_result.rb @@ -4,7 +4,6 @@ module Billing # http://www.bbbonline.org/eExport/doc/MerchantGuide_cvv2.pdf # Check additional codes from cybersource website class CVVResult - MESSAGES = { 'D' => 'CVV check flagged transaction as suspicious', 'I' => 'CVV failed data validation check', diff --git a/lib/active_merchant/billing/gateway.rb b/lib/active_merchant/billing/gateway.rb index c90e56e28c7..e49dd491755 100644 --- a/lib/active_merchant/billing/gateway.rb +++ b/lib/active_merchant/billing/gateway.rb @@ -80,22 +80,22 @@ class Gateway # as network tokenization. STANDARD_ERROR_CODE = { - :incorrect_number => 'incorrect_number', - :invalid_number => 'invalid_number', - :invalid_expiry_date => 'invalid_expiry_date', - :invalid_cvc => 'invalid_cvc', - :expired_card => 'expired_card', - :incorrect_cvc => 'incorrect_cvc', - :incorrect_zip => 'incorrect_zip', - :incorrect_address => 'incorrect_address', - :incorrect_pin => 'incorrect_pin', - :card_declined => 'card_declined', - :processing_error => 'processing_error', - :call_issuer => 'call_issuer', - :pickup_card => 'pick_up_card', - :config_error => 'config_error', - :test_mode_live_card => 'test_mode_live_card', - :unsupported_feature => 'unsupported_feature', + incorrect_number: 'incorrect_number', + invalid_number: 'invalid_number', + invalid_expiry_date: 'invalid_expiry_date', + invalid_cvc: 'invalid_cvc', + expired_card: 'expired_card', + incorrect_cvc: 'incorrect_cvc', + incorrect_zip: 'incorrect_zip', + incorrect_address: 'incorrect_address', + incorrect_pin: 'incorrect_pin', + card_declined: 'card_declined', + processing_error: 'processing_error', + call_issuer: 'call_issuer', + pickup_card: 'pick_up_card', + config_error: 'config_error', + test_mode_live_card: 'test_mode_live_card', + unsupported_feature: 'unsupported_feature' } cattr_reader :implementations @@ -123,8 +123,9 @@ def generate_unique_id class_attribute :supported_cardtypes self.supported_cardtypes = [] + # This default list of currencies without fractions are from https://en.wikipedia.org/wiki/ISO_4217 class_attribute :currencies_without_fractions, :currencies_with_three_decimal_places - self.currencies_without_fractions = %w(BIF BYR CLP CVE DJF GNF ISK JPY KMF KRW PYG RWF UGX VND VUV XAF XOF XPF) + self.currencies_without_fractions = %w(BIF BYR CLP CVE DJF GNF ISK JPY KMF KRW PYG RWF UGX UYI VND VUV XAF XOF XPF) self.currencies_with_three_decimal_places = %w() class_attribute :homepage_url @@ -155,9 +156,7 @@ def self.card_brand(source) def self.supported_countries=(country_codes) country_codes.each do |country_code| - unless ActiveMerchant::Country.find(country_code) - raise ActiveMerchant::InvalidCountryCodeError, "No country could be found for the country #{country_code}" - end + raise ActiveMerchant::InvalidCountryCodeError, "No country could be found for the country #{country_code}" unless ActiveMerchant::Country.find(country_code) end @supported_countries = country_codes.dup end @@ -224,11 +223,11 @@ def normalize(field) def user_agent @@ua ||= JSON.dump({ - :bindings_version => ActiveMerchant::VERSION, - :lang => 'ruby', - :lang_version => "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})", - :platform => RUBY_PLATFORM, - :publisher => 'active_merchant' + bindings_version: ActiveMerchant::VERSION, + lang: 'ruby', + lang_version: "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})", + platform: RUBY_PLATFORM, + publisher: 'active_merchant' }) end @@ -250,16 +249,16 @@ def name def amount(money) return nil if money.nil? - cents = if money.respond_to?(:cents) - ActiveMerchant.deprecated 'Support for Money objects is deprecated and will be removed from a future release of ActiveMerchant. Please use an Integer value in cents' - money.cents - else - money - end - if money.is_a?(String) - raise ArgumentError, 'money amount must be a positive Integer in cents.' - end + cents = + if money.respond_to?(:cents) + ActiveMerchant.deprecated 'Support for Money objects is deprecated and will be removed from a future release of ActiveMerchant. Please use an Integer value in cents' + money.cents + else + money + end + + raise ArgumentError, 'money amount must be a positive Integer in cents.' if money.is_a?(String) if self.money_format == :cents cents.to_s @@ -280,6 +279,7 @@ def localized_amount(money, currency) amount = amount(money) return amount unless non_fractional_currency?(currency) || three_decimal_currency?(currency) + if non_fractional_currency?(currency) if self.money_format == :cents sprintf('%.0f', amount.to_f / 100) @@ -301,6 +301,7 @@ def currency(money) def truncate(value, max_size) return nil unless value + value.to_s[0, max_size] end @@ -319,7 +320,7 @@ def requires!(hash, *params) raise ArgumentError.new("Missing required parameter: #{param.first}") unless hash.has_key?(param.first) valid_options = param[1..-1] - raise ArgumentError.new("Parameter: #{param.first} must be one of #{valid_options.to_sentence(:words_connector => 'or')}") unless valid_options.include?(hash[param.first]) + raise ArgumentError.new("Parameter: #{param.first} must be one of #{valid_options.to_sentence(words_connector: 'or')}") unless valid_options.include?(hash[param.first]) else raise ArgumentError.new("Missing required parameter: #{param}") unless hash.has_key?(param) end diff --git a/lib/active_merchant/billing/gateways/adyen.rb b/lib/active_merchant/billing/gateways/adyen.rb index 0f38d7006bf..46e145caa03 100644 --- a/lib/active_merchant/billing/gateways/adyen.rb +++ b/lib/active_merchant/billing/gateways/adyen.rb @@ -1,23 +1,23 @@ module ActiveMerchant #:nodoc: module Billing #:nodoc: class AdyenGateway < Gateway - # we recommend setting up merchant-specific endpoints. # https://docs.adyen.com/developers/api-manual#apiendpoints - self.test_url = 'https://pal-test.adyen.com/pal/servlet/Payment/' - self.live_url = 'https://pal-live.adyen.com/pal/servlet/Payment/' + self.test_url = 'https://pal-test.adyen.com/pal/servlet/' + self.live_url = 'https://pal-live.adyen.com/pal/servlet/' - self.supported_countries = ['AT', 'AU', 'BE', 'BG', 'BR', 'CH', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GB', 'GI', 'GR', 'HK', 'HU', 'IE', 'IS', 'IT', 'LI', 'LT', 'LU', 'LV', 'MC', 'MT', 'MX', 'NL', 'NO', 'PL', 'PT', 'RO', 'SE', 'SG', 'SK', 'SI', 'US'] + self.supported_countries = %w(AT AU BE BG BR CH CY CZ DE DK EE ES FI FR GB GI GR HK HU IE IS IT LI LT LU LV MC MT MX NL NO PL PT RO SE SG SK SI US) self.default_currency = 'USD' self.currencies_without_fractions = %w(CVE DJF GNF IDR JPY KMF KRW PYG RWF UGX VND VUV XAF XOF XPF) - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :jcb, :dankort, :maestro, :discover, :elo, :naranja, :cabal] + self.supported_cardtypes = %i[visa master american_express diners_club jcb dankort maestro discover elo naranja cabal unionpay] self.money_format = :cents self.homepage_url = 'https://www.adyen.com/' self.display_name = 'Adyen' - API_VERSION = 'v40' + PAYMENT_API_VERSION = 'v40' + RECURRING_API_VERSION = 'v30' STANDARD_ERROR_CODE_MAPPING = { '101' => STANDARD_ERROR_CODE[:incorrect_number], @@ -26,16 +26,16 @@ class AdyenGateway < Gateway '132' => STANDARD_ERROR_CODE[:incorrect_address], '133' => STANDARD_ERROR_CODE[:incorrect_address], '134' => STANDARD_ERROR_CODE[:incorrect_address], - '135' => STANDARD_ERROR_CODE[:incorrect_address], + '135' => STANDARD_ERROR_CODE[:incorrect_address] } - def initialize(options={}) + def initialize(options = {}) requires!(options, :username, :password, :merchant_account) @username, @password, @merchant_account = options.values_at(:username, :password, :merchant_account) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) if options[:execute_threed] || options[:threed_dynamic] authorize(money, payment, options) else @@ -46,41 +46,53 @@ def purchase(money, payment, options={}) end end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) requires!(options, :order_id) post = init_post(options) add_invoice(post, money, options) - add_payment(post, payment) + add_payment(post, payment, options) add_extra_data(post, payment, options) add_stored_credentials(post, payment, options) add_address(post, options) add_installments(post, options) if options[:installments] add_3ds(post, options) add_3ds_authenticated_data(post, options) + add_splits(post, options) + add_recurring_contract(post, options) commit('authorise', post, options) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) post = init_post(options) add_invoice_for_modification(post, money, options) add_reference(post, authorization, options) + add_splits(post, options) commit('capture', post, options) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) post = init_post(options) add_invoice_for_modification(post, money, options) add_original_reference(post, authorization, options) + add_splits(post, options) commit('refund', post, options) end - def void(authorization, options={}) + def credit(money, payment, options = {}) + post = init_post(options) + add_invoice(post, money, options) + add_payment(post, payment, options) + add_shopper_reference(post, options) + commit('refundWithData', post, options) + end + + def void(authorization, options = {}) post = init_post(options) add_reference(post, authorization, options) commit('cancel', post, options) end - def adjust(money, authorization, options={}) + def adjust(money, authorization, options = {}) post = init_post(options) add_invoice_for_modification(post, money, options) add_reference(post, authorization, options) @@ -88,17 +100,21 @@ def adjust(money, authorization, options={}) commit('adjustAuthorisation', post, options) end - def store(credit_card, options={}) + def store(credit_card, options = {}) requires!(options, :order_id) post = init_post(options) add_invoice(post, 0, options) - add_payment(post, credit_card) + add_payment(post, credit_card, options) add_extra_data(post, credit_card, options) add_stored_credentials(post, credit_card, options) - add_recurring_contract(post, options) add_address(post, options) - initial_response = commit('authorise', post, options) + options[:recurring_contract_type] ||= 'RECURRING' + add_recurring_contract(post, options) + + action = options[:tokenize_only] ? 'storeToken' : 'authorise' + + initial_response = commit(action, post, options) if initial_response.success? && card_not_stored?(initial_response) unsupported_failure_response(initial_response) @@ -107,7 +123,18 @@ def store(credit_card, options={}) end end - def verify(credit_card, options={}) + def unstore(options = {}) + requires!(options, :shopper_reference, :recurring_detail_reference) + post = {} + + add_shopper_reference(post, options) + add_merchant_account(post, options) + post[:recurringDetailReference] = options[:recurring_detail_reference] + + commit('disable', post, options) + end + + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(0, credit_card, options) } options[:idempotency_key] = nil @@ -177,10 +204,6 @@ def scrub(transcript) def add_extra_data(post, payment, options) post[:telephoneNumber] = options[:billing_address][:phone] if options.dig(:billing_address, :phone) - post[:shopperEmail] = options[:shopper_email] if options[:shopper_email] - post[:shopperIP] = options[:shopper_ip] if options[:shopper_ip] - post[:shopperReference] = options[:shopper_reference] if options[:shopper_reference] - post[:shopperStatement] = options[:shopper_statement] if options[:shopper_statement] post[:fraudOffset] = options[:fraud_offset] if options[:fraud_offset] post[:selectedBrand] = options[:selected_brand] if options[:selected_brand] post[:selectedBrand] ||= NETWORK_TOKENIZATION_CARD_SOURCE[payment.source.to_s] if payment.is_a?(NetworkTokenizationCreditCard) @@ -194,10 +217,34 @@ def add_extra_data(post, payment, options) post[:additionalData][:authorisationType] = options[:authorisation_type] if options[:authorisation_type] post[:additionalData][:adjustAuthorisationData] = options[:adjust_authorisation_data] if options[:adjust_authorisation_data] post[:additionalData][:industryUsage] = options[:industry_usage] if options[:industry_usage] - post[:additionalData][:updateShopperStatement] = options[:update_shopper_statement] if options[:update_shopper_statement] post[:additionalData][:RequestedTestAcquirerResponseCode] = options[:requested_test_acquirer_response_code] if options[:requested_test_acquirer_response_code] && test? post[:deviceFingerprint] = options[:device_fingerprint] if options[:device_fingerprint] + add_shopper_data(post, options) add_risk_data(post, options) + add_shopper_reference(post, options) + add_merchant_data(post, options) + end + + def add_shopper_data(post, options) + post[:shopperEmail] = options[:email] if options[:email] + post[:shopperEmail] = options[:shopper_email] if options[:shopper_email] + post[:shopperIP] = options[:ip] if options[:ip] + post[:shopperIP] = options[:shopper_ip] if options[:shopper_ip] + post[:shopperStatement] = options[:shopper_statement] if options[:shopper_statement] + post[:additionalData][:updateShopperStatement] = options[:update_shopper_statement] if options[:update_shopper_statement] + end + + def add_merchant_data(post, options) + post[:additionalData][:subMerchantID] = options[:sub_merchant_id] if options[:sub_merchant_id] + post[:additionalData][:subMerchantName] = options[:sub_merchant_name] if options[:sub_merchant_name] + post[:additionalData][:subMerchantStreet] = options[:sub_merchant_street] if options[:sub_merchant_street] + post[:additionalData][:subMerchantCity] = options[:sub_merchant_city] if options[:sub_merchant_city] + post[:additionalData][:subMerchantState] = options[:sub_merchant_state] if options[:sub_merchant_state] + post[:additionalData][:subMerchantPostalCode] = options[:sub_merchant_postal_code] if options[:sub_merchant_postal_code] + post[:additionalData][:subMerchantCountry] = options[:sub_merchant_country] if options[:sub_merchant_country] + post[:additionalData][:subMerchantTaxId] = options[:sub_merchant_tax_id] if options[:sub_merchant_tax_id] + post[:additionalData][:subMerchantMCC] = options[:sub_merchant_mcc] if options[:sub_merchant_mcc] + post[:additionalData] = post[:additionalData].merge(options[:sub_merchant_data]) if options[:sub_merchant_data] end def add_risk_data(post, options) @@ -207,13 +254,44 @@ def add_risk_data(post, options) end end + def add_splits(post, options) + return unless split_data = options[:splits] + + splits = [] + split_data.each do |split| + amount = { + value: split['amount']['value'] + } + amount[:currency] = split['amount']['currency'] if split['amount']['currency'] + + split_hash = { + amount: amount, + type: split['type'], + reference: split['reference'] + } + split_hash['account'] = split['account'] if split['account'] + splits.push(split_hash) + end + post[:splits] = splits + end + def add_stored_credentials(post, payment, options) add_shopper_interaction(post, payment, options) add_recurring_processing_model(post, options) end - def add_shopper_interaction(post, payment, options={}) - if options.dig(:stored_credential, :initial_transaction) || (payment.respond_to?(:verification_value) && payment.verification_value) || payment.is_a?(NetworkTokenizationCreditCard) + def add_merchant_account(post, options) + post[:merchantAccount] = options[:merchant_account] || @merchant_account + end + + def add_shopper_reference(post, options) + post[:shopperReference] = options[:shopper_reference] if options[:shopper_reference] + end + + def add_shopper_interaction(post, payment, options = {}) + if (options.dig(:stored_credential, :initial_transaction) && options.dig(:stored_credential, :initiator) == 'cardholder') || + (payment.respond_to?(:verification_value) && payment.verification_value && options.dig(:stored_credential, :initial_transaction).nil?) || + payment.is_a?(NetworkTokenizationCreditCard) shopper_interaction = 'Ecommerce' else shopper_interaction = 'ContAuth' @@ -224,8 +302,13 @@ def add_shopper_interaction(post, payment, options={}) def add_recurring_processing_model(post, options) return unless options.dig(:stored_credential, :reason_type) || options[:recurring_processing_model] - if options.dig(:stored_credential, :reason_type) && options[:stored_credential][:reason_type] == 'unscheduled' - recurring_processing_model = 'CardOnFile' + + if options.dig(:stored_credential, :reason_type) == 'unscheduled' + if options.dig(:stored_credential, :initiator) == 'merchant' + recurring_processing_model = 'UnscheduledCardOnFile' + else + recurring_processing_model = 'CardOnFile' + end else recurring_processing_model = 'Subscription' end @@ -234,7 +317,17 @@ def add_recurring_processing_model(post, options) end def add_address(post, options) + if address = options[:shipping_address] + post[:deliveryAddress] = {} + post[:deliveryAddress][:street] = address[:address1] || 'NA' + post[:deliveryAddress][:houseNumberOrName] = address[:address2] || 'NA' + post[:deliveryAddress][:postalCode] = address[:zip] if address[:zip] + post[:deliveryAddress][:city] = address[:city] || 'NA' + post[:deliveryAddress][:stateOrProvince] = get_state(address) + post[:deliveryAddress][:country] = address[:country] if address[:country] + end return unless post[:card]&.kind_of?(Hash) + if (address = options[:billing_address] || options[:address]) && address[:country] post[:billingAddress] = {} post[:billingAddress][:street] = address[:address1] || 'NA' @@ -268,11 +361,11 @@ def add_invoice_for_modification(post, money, options) post[:modificationAmount] = amount end - def add_payment(post, payment) + def add_payment(post, payment, options) if payment.is_a?(String) _, _, recurring_detail_reference = payment.split('#') post[:selectedRecurringDetailReference] = recurring_detail_reference - add_recurring_contract(post, options) + options[:recurring_contract_type] ||= 'RECURRING' else add_mpi_data_for_network_tokenization_card(post, payment) if payment.is_a?(NetworkTokenizationCreditCard) add_card(post, payment) @@ -288,7 +381,7 @@ def add_card(post, credit_card) cvc: credit_card.verification_value } - card.delete_if { |k, v| v.blank? } + card.delete_if { |_k, v| v.blank? } card[:holderName] ||= 'Not Provided' if credit_card.is_a?(NetworkTokenizationCreditCard) requires!(card, :expiryMonth, :expiryYear, :holderName, :number) post[:card] = card @@ -296,16 +389,21 @@ def add_card(post, credit_card) def capture_options(options) return options.merge(idempotency_key: "#{options[:idempotency_key]}-cap") if options[:idempotency_key] + options end def add_reference(post, authorization, options = {}) - _, psp_reference, _ = authorization.split('#') + _, psp_reference, = authorization.split('#') post[:originalReference] = single_reference(authorization) || psp_reference end def add_original_reference(post, authorization, options = {}) - original_psp_reference, _, _ = authorization.split('#') + if authorization.start_with?('#') + _, original_psp_reference, = authorization.split('#') + else + original_psp_reference, = authorization.split('#') + end post[:originalReference] = single_reference(authorization) || original_psp_reference end @@ -322,8 +420,10 @@ def single_reference(authorization) end def add_recurring_contract(post, options = {}) + return unless options[:recurring_contract_type] + recurring = { - contract: 'RECURRING' + contract: options[:recurring_contract_type] } post[:recurring] = recurring @@ -350,9 +450,11 @@ def add_3ds(post, options) post[:additionalData][:scaExemption] = options[:sca_exemption] if options[:sca_exemption] end else - return unless options[:execute_threed] || options[:threed_dynamic] - post[:browserInfo] = { userAgent: options[:user_agent], acceptHeader: options[:accept_header] } - post[:additionalData] = { executeThreeD: 'true' } if options[:execute_threed] + return unless !options[:execute_threed].nil? || !options[:threed_dynamic].nil? + + post[:browserInfo] = { userAgent: options[:user_agent], acceptHeader: options[:accept_header] } if options[:execute_threed] || options[:threed_dynamic] + post[:additionalData] ||= {} + post[:additionalData][:executeThreeD] = options[:execute_threed] if !options[:execute_threed].nil? end end @@ -371,7 +473,7 @@ def add_3ds1_authenticated_data(post, options) cavvAlgorithm: three_d_secure_options[:cavv_algorithm], eci: three_d_secure_options[:eci], xid: three_d_secure_options[:xid], - directoryResponse: three_d_secure_options[:directory_response_status], + directoryResponse: three_d_secure_options[:enrolled], authenticationResponse: three_d_secure_options[:authentication_response_status] } end @@ -379,7 +481,7 @@ def add_3ds1_authenticated_data(post, options) def add_3ds2_authenticated_data(post, options) three_d_secure_options = options[:three_d_secure] # If the transaction was authenticated in a frictionless flow, send the transStatus from the ARes. - if(three_d_secure_options[:authentication_response_status].nil?) + if three_d_secure_options[:authentication_response_status].nil? authentication_response = three_d_secure_options[:directory_response_status] else authentication_response = three_d_secure_options[:authentication_response_status] @@ -396,18 +498,19 @@ def add_3ds2_authenticated_data(post, options) def parse(body) return {} if body.blank? + JSON.parse(body) end def commit(action, parameters, options) begin - raw_response = ssl_post("#{url}/#{action}", post_data(action, parameters), request_headers(options)) + raw_response = ssl_post(url(action), post_data(action, parameters), request_headers(options)) response = parse(raw_response) rescue ResponseError => e raw_response = e.response.body response = parse(raw_response) end - success = success_from(action, response) + success = success_from(action, response, options) Response.new( success, message_from(action, response), @@ -415,7 +518,7 @@ def commit(action, parameters, options) authorization: authorization_from(action, parameters, response), test: test?, error_code: success ? nil : error_code_from(response), - avs_result: AVSResult.new(:code => avs_code_from(response)), + avs_result: AVSResult.new(code: avs_code_from(response)), cvv_result: CVVResult.new(cvv_result_from(response)) ) end @@ -428,13 +531,18 @@ def cvv_result_from(response) CVC_MAPPING[response['additionalData']['cvcResult'][0]] if response.dig('additionalData', 'cvcResult') end - def url + def endpoint(action) + recurring = %w(disable storeToken).include?(action) + recurring ? "Recurring/#{RECURRING_API_VERSION}/#{action}" : "Payment/#{PAYMENT_API_VERSION}/#{action}" + end + + def url(action) if test? - "#{test_url}#{API_VERSION}" + "#{test_url}#{endpoint(action)}" elsif @options[:subdomain] - "https://#{@options[:subdomain]}-pal-live.adyenpayments.com/pal/servlet/Payment/#{API_VERSION}" + "https://#{@options[:subdomain]}-pal-live.adyenpayments.com/pal/servlet/#{endpoint(action)}" else - "#{live_url}#{API_VERSION}" + "#{live_url}#{endpoint(action)}" end end @@ -451,41 +559,56 @@ def request_headers(options) headers end - def success_from(action, response) + def success_from(action, response, options) + if %w[RedirectShopper ChallengeShopper].include?(response.dig('resultCode')) && !options[:execute_threed] && !options[:threed_dynamic] + response['refusalReason'] = 'Received unexpected 3DS authentication response. Use the execute_threed and/or threed_dynamic options to initiate a proper 3DS flow.' + return false + end + case action.to_s when 'authorise', 'authorise3d' - ['Authorised', 'Received', 'RedirectShopper'].include?(response['resultCode']) + %w[Authorised Received RedirectShopper].include?(response['resultCode']) when 'capture', 'refund', 'cancel' response['response'] == "[#{action}-received]" when 'adjustAuthorisation' response['response'] == 'Authorised' || response['response'] == '[adjustAuthorisation-received]' + when 'storeToken' + response['result'] == 'Success' + when 'disable' + response['response'] == '[detail-successfully-disabled]' + when 'refundWithData' + response['resultCode'] == 'Received' else false end end def message_from(action, response) - return authorize_message_from(response) if action.to_s == 'authorise' || action.to_s == 'authorise3d' - response['response'] || response['message'] + return authorize_message_from(response) if %w(authorise authorise3d authorise3ds2).include?(action.to_s) + + response['response'] || response['message'] || response['result'] || response['resultCode'] end def authorize_message_from(response) if response['refusalReason'] && response['additionalData'] && response['additionalData']['refusalReasonRaw'] "#{response['refusalReason']} | #{response['additionalData']['refusalReasonRaw']}" else - response['refusalReason'] || response['resultCode'] || response['message'] + response['refusalReason'] || response['resultCode'] || response['message'] || response['result'] end end def authorization_from(action, parameters, response) return nil if response['pspReference'].nil? + recurring = response['additionalData']['recurring.recurringDetailReference'] if response['additionalData'] + recurring = response['recurringDetailReference'] if action == 'storeToken' + "#{parameters[:originalReference]}##{response['pspReference']}##{recurring}" end def init_post(options = {}) post = {} - post[:merchantAccount] = options[:merchant_account] || @merchant_account + add_merchant_account(post, options) post[:reference] = options[:order_id] if options[:order_id] post end @@ -500,6 +623,7 @@ def error_code_from(response) def add_browser_info(browser_info, post) return unless browser_info + post[:browserInfo] = { acceptHeader: browser_info[:accept_header], colorDepth: browser_info[:depth], diff --git a/lib/active_merchant/billing/gateways/allied_wallet.rb b/lib/active_merchant/billing/gateways/allied_wallet.rb index 8cdbd6f4eaa..68159fcf540 100644 --- a/lib/active_merchant/billing/gateways/allied_wallet.rb +++ b/lib/active_merchant/billing/gateways/allied_wallet.rb @@ -9,15 +9,15 @@ class AlliedWalletGateway < Gateway self.supported_countries = ['US'] self.default_currency = 'USD' self.money_format = :dollars - self.supported_cardtypes = [:visa, :master, :american_express, :discover, - :diners_club, :jcb, :maestro] + self.supported_cardtypes = %i[visa master american_express discover + diners_club jcb maestro] - def initialize(options={}) + def initialize(options = {}) requires!(options, :site_id, :merchant_id, :token) super end - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method) @@ -26,7 +26,7 @@ def purchase(amount, payment_method, options={}) commit(:purchase, post) end - def authorize(amount, payment_method, options={}) + def authorize(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method) @@ -35,7 +35,7 @@ def authorize(amount, payment_method, options={}) commit(:authorize, post) end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) post = {} add_invoice(post, amount, options) add_reference(post, authorization, :capture) @@ -44,14 +44,14 @@ def capture(amount, authorization, options={}) commit(:capture, post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} add_reference(post, authorization, :void) commit(:void, post) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) post = {} add_invoice(post, amount, options) add_reference(post, authorization, :refund) @@ -61,7 +61,7 @@ def refund(amount, authorization, options={}) commit(:refund, post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -113,7 +113,7 @@ def add_customer_data(post, options) post[:city] = billing_address[:city] post[:state] = billing_address[:state] post[:countryId] = billing_address[:country] - post[:postalCode] = billing_address[:zip] + post[:postalCode] = billing_address[:zip] post[:phone] = billing_address[:phone] end end @@ -141,7 +141,8 @@ def commit(action, post) raw_response = ssl_post(url(action), post.to_json, headers) response = parse(raw_response) rescue ResponseError => e - raise unless(e.response.code.to_s =~ /4\d\d/) + raise unless e.response.code.to_s =~ /4\d\d/ + response = parse(e.response.body) end @@ -151,8 +152,8 @@ def commit(action, post) message_from(succeeded, response), response, authorization: response['id'], - :avs_result => AVSResult.new(code: response['avs_response']), - :cvv_result => CVVResult.new(response['cvv2_response']), + avs_result: AVSResult.new(code: response['avs_response']), + cvv_result: CVVResult.new(response['cvv2_response']), test: test? ) rescue JSON::ParserError @@ -199,7 +200,6 @@ def message_from(succeeded, response) response['message'] || 'Unable to read error message' end end - end end end diff --git a/lib/active_merchant/billing/gateways/authorize_net.rb b/lib/active_merchant/billing/gateways/authorize_net.rb index ccc8794a05a..f0ee4bcdc00 100644 --- a/lib/active_merchant/billing/gateways/authorize_net.rb +++ b/lib/active_merchant/billing/gateways/authorize_net.rb @@ -8,10 +8,10 @@ class AuthorizeNetGateway < Gateway self.test_url = 'https://apitest.authorize.net/xml/v1/request.api' self.live_url = 'https://api2.authorize.net/xml/v1/request.api' - self.supported_countries = %w(AD AT AU BE BG CA CH CY CZ DE DK EE ES FI FR GB GI GR HU IE IL IS IT LI LT LU LV MC MT NL NO PL PT RO SE SI SK SM TR US VA) + self.supported_countries = %w(AU CA US) self.default_currency = 'USD' self.money_format = :dollars - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb, :maestro] + self.supported_cardtypes = %i[visa master american_express discover diners_club jcb maestro] self.homepage_url = 'http://www.authorize.net/' self.display_name = 'Authorize.Net' @@ -54,25 +54,25 @@ class AuthorizeNetGateway < Gateway '37' => STANDARD_ERROR_CODE[:invalid_expiry_date], '378' => STANDARD_ERROR_CODE[:invalid_cvc], '38' => STANDARD_ERROR_CODE[:expired_card], - '384' => STANDARD_ERROR_CODE[:config_error], + '384' => STANDARD_ERROR_CODE[:config_error] } MARKET_TYPE = { - :moto => '1', - :retail => '2' + moto: '1', + retail: '2' } DEVICE_TYPE = { - :unknown => '1', - :unattended_terminal => '2', - :self_service_terminal => '3', - :electronic_cash_register => '4', - :personal_computer_terminal => '5', - :airpay => '6', - :wireless_pos => '7', - :website => '8', - :dial_terminal => '9', - :virtual_terminal => '10' + unknown: '1', + unattended_terminal: '2', + self_service_terminal: '3', + electronic_cash_register: '4', + personal_computer_terminal: '5', + airpay: '6', + wireless_pos: '7', + website: '8', + dial_terminal: '9', + virtual_terminal: '10' } class_attribute :duplicate_window @@ -85,8 +85,8 @@ class AuthorizeNetGateway < Gateway AVS_REASON_CODES = %w(27 45) TRACKS = { - 1 => /^%(?.)(?[\d]{1,19}+)\^(?.{2,26})\^(?[\d]{0,4}|\^)(?[\d]{0,3}|\^)(?.*)\?\Z/, - 2 => /\A;(?[\d]{1,19}+)=(?[\d]{0,4}|=)(?[\d]{0,3}|=)(?.*)\?\Z/ + 1 => /^%(?.)(?[\d]{1,19}+)\^(?.{2,26})\^(?[\d]{0,4}|\^)(?[\d]{0,3}|\^)(?.*)\?\Z/, + 2 => /\A;(?[\d]{1,19}+)=(?[\d]{0,4}|=)(?[\d]{0,3}|=)(?.*)\?\Z/ }.freeze APPLE_PAY_DATA_DESCRIPTOR = 'COMMON.APPLE.INAPP.PAYMENT' @@ -94,7 +94,7 @@ class AuthorizeNetGateway < Gateway PAYMENT_METHOD_NOT_SUPPORTED_ERROR = '155' INELIGIBLE_FOR_ISSUING_CREDIT_ERROR = '54' - def initialize(options={}) + def initialize(options = {}) requires!(options, :login, :password) super end @@ -111,7 +111,7 @@ def purchase(amount, payment, options = {}) end end - def authorize(amount, payment, options={}) + def authorize(amount, payment, options = {}) if payment.is_a?(String) commit(:cim_authorize, options) do |xml| add_cim_auth_purchase(xml, 'profileTransAuthOnly', amount, payment, options) @@ -123,7 +123,7 @@ def authorize(amount, payment, options={}) end end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) if auth_was_for_cim?(authorization) cim_capture(amount, authorization, options) else @@ -131,12 +131,13 @@ def capture(amount, authorization, options={}) end end - def refund(amount, authorization, options={}) - response = if auth_was_for_cim?(authorization) - cim_refund(amount, authorization, options) - else - normal_refund(amount, authorization, options) - end + def refund(amount, authorization, options = {}) + response = + if auth_was_for_cim?(authorization) + cim_refund(amount, authorization, options) + else + normal_refund(amount, authorization, options) + end return response if response.success? return response unless options[:force_full_refund_if_unsettled] @@ -148,7 +149,7 @@ def refund(amount, authorization, options={}) end end - def void(authorization, options={}) + def void(authorization, options = {}) if auth_was_for_cim?(authorization) cim_void(authorization, options) else @@ -156,10 +157,8 @@ def void(authorization, options={}) end end - def credit(amount, payment, options={}) - if payment.is_a?(String) - raise ArgumentError, 'Reference credits are not supported. Please supply the original credit card or use the #refund method.' - end + def credit(amount, payment, options = {}) + raise ArgumentError, 'Reference credits are not supported. Please supply the original credit card or use the #refund method.' if payment.is_a?(String) commit(:credit) do |xml| add_order_id(xml, options) @@ -193,7 +192,7 @@ def store(credit_card, options = {}) end def unstore(authorization) - customer_profile_id, _, _ = split_authorization(authorization) + customer_profile_id, = split_authorization(authorization) delete_customer_profile(customer_profile_id) end @@ -222,13 +221,13 @@ def scrub(transcript) def supports_network_tokenization? card = Billing::NetworkTokenizationCreditCard.new({ - :number => '4111111111111111', - :month => 12, - :year => 20, - :first_name => 'John', - :last_name => 'Smith', - :brand => 'visa', - :payment_cryptogram => 'EHuWW9PiBkWvqE5juRwDzAUFBAk=' + number: '4111111111111111', + month: 12, + year: 20, + first_name: 'John', + last_name: 'Smith', + brand: 'visa', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=' }) request = post_data(:authorize) do |xml| @@ -258,6 +257,8 @@ def add_auth_purchase(xml, transaction_type, amount, payment, options) add_settings(xml, payment, options) add_user_fields(xml, amount, options) add_ship_from_address(xml, options) + add_processing_options(xml, options) + add_subsequent_auth_information(xml, options) end end @@ -312,7 +313,7 @@ def normal_capture(amount, authorization, options) end def cim_refund(amount, authorization, options) - transaction_id, card_number, _ = split_authorization(authorization) + transaction_id, card_number, = split_authorization(authorization) commit(:cim_refund, options) do |xml| add_order_id(xml, options) @@ -332,7 +333,7 @@ def cim_refund(amount, authorization, options) end def normal_refund(amount, authorization, options) - transaction_id, card_number, _ = split_authorization(authorization) + transaction_id, card_number, = split_authorization(authorization) commit(:refund) do |xml| xml.transactionRequest do @@ -391,6 +392,7 @@ def normal_void(authorization, options) def add_payment_source(xml, source, options, action = nil) return unless source + if source.is_a?(String) add_token_payment_method(xml, source, options) elsif card_brand(source) == 'check' @@ -408,7 +410,7 @@ def camel_case_lower(key) def add_settings(xml, source, options) xml.transactionSettings do - if options[:recurring] + if options[:recurring] || subsequent_recurring_transaction?(options) xml.setting do xml.settingName('recurringBilling') xml.settingValue('true') @@ -479,12 +481,8 @@ def add_credit_card(xml, credit_card, action) xml.creditCard do xml.cardNumber(truncate(credit_card.number, 16)) xml.expirationDate(format(credit_card.month, :two_digits) + '/' + format(credit_card.year, :four_digits)) - if credit_card.valid_card_verification_value?(credit_card.verification_value, credit_card.brand) - xml.cardCode(credit_card.verification_value) - end - if credit_card.is_a?(NetworkTokenizationCreditCard) && action != :credit - xml.cryptogram(credit_card.payment_cryptogram) - end + xml.cardCode(credit_card.verification_value) if credit_card.valid_card_verification_value?(credit_card.verification_value, credit_card.brand) + xml.cryptogram(credit_card.payment_cryptogram) if credit_card.is_a?(NetworkTokenizationCreditCard) && action != :credit end end end @@ -492,7 +490,7 @@ def add_credit_card(xml, credit_card, action) def add_swipe_data(xml, credit_card) TRACKS.each do |key, regex| - if regex.match(credit_card.track_data) + if regex.match?(credit_card.track_data) @valid_track_data = true xml.payment do xml.trackData do @@ -504,7 +502,7 @@ def add_swipe_data(xml, credit_card) end def add_token_payment_method(xml, token, options) - customer_profile_id, customer_payment_profile_id, _ = split_authorization(token) + customer_profile_id, customer_payment_profile_id, = split_authorization(token) customer_profile_id = options[:customer_profile_id] if options[:customer_profile_id] customer_payment_profile_id = options[:customer_payment_profile_id] if options[:customer_payment_profile_id] xml.customerProfileId(customer_profile_id) @@ -522,6 +520,7 @@ def add_apple_pay_payment_token(xml, apple_pay_payment_token) def add_market_type_device_type(xml, payment, options) return if payment.is_a?(String) || card_brand(payment) == 'check' || card_brand(payment) == 'apple_pay' + if valid_track_data xml.retail do xml.marketType(options[:market_type] || MARKET_TYPE[:retail]) @@ -547,6 +546,7 @@ def valid_track_data def add_check(xml, check) xml.payment do xml.bankAccount do + xml.accountType(check.account_type) xml.routingNumber(check.routing_number) xml.accountNumber(check.account_number) xml.nameOnAccount(truncate(check.name, 22)) @@ -570,9 +570,11 @@ def add_customer_data(xml, payment_source, options) xml.cardholderAuthentication do three_d_secure = options.fetch(:three_d_secure, {}) xml.authenticationIndicator( - options[:authentication_indicator] || three_d_secure[:eci]) + options[:authentication_indicator] || three_d_secure[:eci] + ) xml.cardholderAuthenticationValue( - options[:cardholder_authentication_value] || three_d_secure[:cavv]) + options[:cardholder_authentication_value] || three_d_secure[:cavv] + ) end end @@ -597,16 +599,17 @@ def add_billing_address(xml, payment_source, options) end end - def add_shipping_address(xml, options, root_node='shipTo') + def add_shipping_address(xml, options, root_node = 'shipTo') address = options[:shipping_address] || options[:address] return unless address xml.send(root_node) do - first_name, last_name = if address[:name] - split_names(address[:name]) - else - [address[:first_name], address[:last_name]] - end + first_name, last_name = + if address[:name] + split_names(address[:name]) + else + [address[:first_name], address[:last_name]] + end full_address = "#{address[:address1]} #{address[:address2]}".strip xml.firstName(truncate(first_name, 50)) unless empty?(first_name) @@ -620,7 +623,7 @@ def add_shipping_address(xml, options, root_node='shipTo') end end - def add_ship_from_address(xml, options, root_node='shipFrom') + def add_ship_from_address(xml, options, root_node = 'shipFrom') address = options[:ship_from_address] return unless address @@ -701,6 +704,30 @@ def add_extra_options_for_cim(xml, options) xml.extraOptions("x_delim_char=#{options[:delimiter]}") if options[:delimiter] end + def add_processing_options(xml, options) + return unless options[:stored_credential] + + xml.processingOptions do + if options[:stored_credential][:initial_transaction] + xml.isFirstSubsequentAuth 'true' + # xml.isFirstRecurringPayment 'true' if options[:stored_credential][:reason_type] == 'recurring' + elsif options[:stored_credential][:initiator] == 'cardholder' + xml.isStoredCredentials 'true' + else + xml.isSubsequentAuth 'true' + end + end + end + + def add_subsequent_auth_information(xml, options) + return unless options.dig(:stored_credential, :reason_type) == 'unscheduled' + + xml.subsequentAuthInformation do + xml.reason options[:stored_credential_reason_type_override] if options[:stored_credential_reason_type_override] + xml.originalNetworkTransId options[:stored_credential][:network_transaction_id] if options[:stored_credential][:network_transaction_id] + end + end + def create_customer_payment_profile(credit_card, options) commit(:cim_store_update, options) do |xml| xml.customerProfileId options[:customer_profile_id] @@ -756,13 +783,17 @@ def names_from(payment_source, address, options) end def state_from(address, options) - if ['US', 'CA'].include?(address[:country]) + if %w[US CA].include?(address[:country]) address[:state] || 'NC' else address[:state] || 'n/a' end end + def subsequent_recurring_transaction?(options) + options.dig(:stored_credential, :reason_type) == 'recurring' && !options.dig(:stored_credential, :initial_transaction) + end + def headers { 'Content-Type' => 'text/xml' } end @@ -772,7 +803,7 @@ def url end def parse(action, raw_response, options = {}) - if is_cim_action?(action) || action == :verify_credentials + if cim_action?(action) || action == :verify_credentials parse_cim(raw_response, options) else parse_normal(action, raw_response) @@ -803,7 +834,7 @@ def commit(action, options = {}, &payload) end end - def is_cim_action?(action) + def cim_action?(action) action.to_s.start_with?('cim') end @@ -825,7 +856,7 @@ def root_for(action) 'deleteCustomerProfileRequest' elsif action == :verify_credentials 'authenticateTestRequest' - elsif is_cim_action?(action) + elsif cim_action?(action) 'createCustomerProfileTransactionRequest' else 'createTransactionRequest' @@ -843,19 +874,19 @@ def parse_normal(action, body) doc = Nokogiri::XML(body) doc.remove_namespaces! - response = {action: action} + response = { action: action } - response[:response_code] = if(element = doc.at_xpath('//transactionResponse/responseCode')) - (empty?(element.content) ? nil : element.content.to_i) - end + response[:response_code] = if (element = doc.at_xpath('//transactionResponse/responseCode')) + empty?(element.content) ? nil : element.content.to_i + end - if(element = doc.at_xpath('//errors/error')) + if (element = doc.at_xpath('//errors/error')) response[:response_reason_code] = element.at_xpath('errorCode').content[/0*(\d+)$/, 1] response[:response_reason_text] = element.at_xpath('errorText').content.chomp('.') - elsif(element = doc.at_xpath('//transactionResponse/messages/message')) + elsif (element = doc.at_xpath('//transactionResponse/messages/message')) response[:response_reason_code] = element.at_xpath('code').content[/0*(\d+)$/, 1] response[:response_reason_text] = element.at_xpath('description').content.chomp('.') - elsif(element = doc.at_xpath('//messages/message')) + elsif (element = doc.at_xpath('//messages/message')) response[:response_reason_code] = element.at_xpath('code').content[/0*(\d+)$/, 1] response[:response_reason_text] = element.at_xpath('text').content.chomp('.') else @@ -863,37 +894,45 @@ def parse_normal(action, body) response[:response_reason_text] = '' end - response[:avs_result_code] = if(element = doc.at_xpath('//avsResultCode')) - (empty?(element.content) ? nil : element.content) - end + response[:avs_result_code] = + if (element = doc.at_xpath('//avsResultCode')) + empty?(element.content) ? nil : element.content + end - response[:transaction_id] = if(element = doc.at_xpath('//transId')) - (empty?(element.content) ? nil : element.content) - end + response[:transaction_id] = + if element = doc.at_xpath('//transId') + empty?(element.content) ? nil : element.content + end - response[:card_code] = if(element = doc.at_xpath('//cvvResultCode')) - (empty?(element.content) ? nil : element.content) - end + response[:card_code] = + if element = doc.at_xpath('//cvvResultCode') + empty?(element.content) ? nil : element.content + end - response[:authorization_code] = if(element = doc.at_xpath('//authCode')) - (empty?(element.content) ? nil : element.content) - end + response[:authorization_code] = + if element = doc.at_xpath('//authCode') + empty?(element.content) ? nil : element.content + end - response[:cardholder_authentication_code] = if(element = doc.at_xpath('//cavvResultCode')) - (empty?(element.content) ? nil : element.content) - end + response[:cardholder_authentication_code] = + if element = doc.at_xpath('//cavvResultCode') + empty?(element.content) ? nil : element.content + end - response[:account_number] = if(element = doc.at_xpath('//accountNumber')) - (empty?(element.content) ? nil : element.content[-4..-1]) - end + response[:account_number] = + if element = doc.at_xpath('//accountNumber') + empty?(element.content) ? nil : element.content[-4..-1] + end - response[:test_request] = if(element = doc.at_xpath('//testRequest')) - (empty?(element.content) ? nil : element.content) - end + response[:test_request] = + if element = doc.at_xpath('//testRequest') + empty?(element.content) ? nil : element.content + end - response[:full_response_code] = if(element = doc.at_xpath('//messages/message/code')) - (empty?(element.content) ? nil : element.content) - end + response[:full_response_code] = + if element = doc.at_xpath('//messages/message/code') + empty?(element.content) ? nil : element.content + end response end @@ -903,35 +942,41 @@ def parse_cim(body, options) doc = Nokogiri::XML(body).remove_namespaces! - if (element = doc.at_xpath('//messages/message')) + if element = doc.at_xpath('//messages/message') response[:message_code] = element.at_xpath('code').content[/0*(\d+)$/, 1] response[:message_text] = element.at_xpath('text').content.chomp('.') end - response[:result_code] = if(element = doc.at_xpath('//messages/resultCode')) - (empty?(element.content) ? nil : element.content) - end + response[:result_code] = + if element = doc.at_xpath('//messages/resultCode') + empty?(element.content) ? nil : element.content + end - response[:test_request] = if(element = doc.at_xpath('//testRequest')) - (empty?(element.content) ? nil : element.content) - end + response[:test_request] = + if element = doc.at_xpath('//testRequest') + empty?(element.content) ? nil : element.content + end - response[:customer_profile_id] = if(element = doc.at_xpath('//customerProfileId')) - (empty?(element.content) ? nil : element.content) - end + response[:customer_profile_id] = + if element = doc.at_xpath('//customerProfileId') + empty?(element.content) ? nil : element.content + end - response[:customer_payment_profile_id] = if(element = doc.at_xpath('//customerPaymentProfileIdList/numericString')) - (empty?(element.content) ? nil : element.content) - end + response[:customer_payment_profile_id] = + if element = doc.at_xpath('//customerPaymentProfileIdList/numericString') + empty?(element.content) ? nil : element.content + end - response[:customer_payment_profile_id] = if(element = doc.at_xpath('//customerPaymentProfileIdList/numericString') || - doc.at_xpath('//customerPaymentProfileId')) - (empty?(element.content) ? nil : element.content) - end + response[:customer_payment_profile_id] = + if element = doc.at_xpath('//customerPaymentProfileIdList/numericString') || + doc.at_xpath('//customerPaymentProfileId') + empty?(element.content) ? nil : element.content + end - response[:direct_response] = if(element = doc.at_xpath('//directResponse')) - (empty?(element.content) ? nil : element.content) - end + response[:direct_response] = + if element = doc.at_xpath('//directResponse') + empty?(element.content) ? nil : element.content + end response.merge!(parse_direct_response_elements(response, options)) @@ -950,7 +995,7 @@ def message_from(action, response, avs_result, cvv_result) if response[:response_code] == DECLINED if CARD_CODE_ERRORS.include?(cvv_result.code) return cvv_result.message - elsif(AVS_REASON_CODES.include?(response[:response_reason_code]) && AVS_ERRORS.include?(avs_result.code)) + elsif AVS_REASON_CODES.include?(response[:response_reason_code]) && AVS_ERRORS.include?(avs_result.code) return avs_result.message end end @@ -975,7 +1020,7 @@ def cim?(action) end def transaction_id_from(authorization) - transaction_id, _, _ = split_authorization(authorization) + transaction_id, = split_authorization(authorization) transaction_id end @@ -993,11 +1038,11 @@ def map_error_code(response_code, response_reason_code) def auth_was_for_cim?(authorization) _, _, action = split_authorization(authorization) - action && is_cim_action?(action) + action && cim_action?(action) end def parse_direct_response_elements(response, options) - params = response[:direct_response] + params = response[:direct_response]&.tr('"', '') return {} unless params parts = params.split(options[:delimiter] || ',') @@ -1046,10 +1091,9 @@ def parse_direct_response_elements(response, options) card_type: parts[51] || '', split_tender_id: parts[52] || '', requested_amount: parts[53] || '', - balance_on_card: parts[54] || '', + balance_on_card: parts[54] || '' } end - end end end diff --git a/lib/active_merchant/billing/gateways/authorize_net_arb.rb b/lib/active_merchant/billing/gateways/authorize_net_arb.rb index 406cc55e50e..5bcf08b8107 100644 --- a/lib/active_merchant/billing/gateways/authorize_net_arb.rb +++ b/lib/active_merchant/billing/gateways/authorize_net_arb.rb @@ -31,18 +31,18 @@ class AuthorizeNetArbGateway < Gateway self.default_currency = 'USD' - self.supported_countries = ['US', 'CA', 'GB'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb] + self.supported_countries = %w[US CA GB] + self.supported_cardtypes = %i[visa master american_express discover diners_club jcb] self.homepage_url = 'http://www.authorize.net/' self.display_name = 'Authorize.Net' AUTHORIZE_NET_ARB_NAMESPACE = 'AnetApi/xml/v1/schema/AnetApiSchema.xsd' RECURRING_ACTIONS = { - :create => 'ARBCreateSubscription', - :update => 'ARBUpdateSubscription', - :cancel => 'ARBCancelSubscription', - :status => 'ARBGetSubscriptionStatus' + create: 'ARBCreateSubscription', + update: 'ARBUpdateSubscription', + cancel: 'ARBCancelSubscription', + status: 'ARBGetSubscriptionStatus' } # Creates a new AuthorizeNetArbGateway @@ -82,9 +82,9 @@ def initialize(options = {}) # +:interval => { :unit => :months, :length => 3 }+ (REQUIRED) # * :duration -- A hash containing keys for the :start_date the subscription begins (also the date the # initial billing occurs) and the total number of billing :occurrences or payments for the subscription. (REQUIRED) - def recurring(money, creditcard, options={}) + def recurring(money, creditcard, options = {}) requires!(options, :interval, :duration, :billing_address) - requires!(options[:interval], :length, [:unit, :days, :months]) + requires!(options[:interval], :length, %i[unit days months]) requires!(options[:duration], :start_date, :occurrences) requires!(options[:billing_address], :first_name, :last_name) @@ -110,7 +110,7 @@ def recurring(money, creditcard, options={}) # # * :subscription_id -- A string containing the :subscription_id of the recurring payment already in place # for a given credit card. (REQUIRED) - def update_recurring(options={}) + def update_recurring(options = {}) requires!(options, :subscription_id) request = build_recurring_request(:update, options) recurring_commit(:update, request) @@ -126,7 +126,7 @@ def update_recurring(options={}) # * subscription_id -- A string containing the +subscription_id+ of the recurring payment already in place # for a given credit card. (REQUIRED) def cancel_recurring(subscription_id) - request = build_recurring_request(:cancel, :subscription_id => subscription_id) + request = build_recurring_request(:cancel, subscription_id: subscription_id) recurring_commit(:cancel, request) end @@ -139,7 +139,7 @@ def cancel_recurring(subscription_id) # * subscription_id -- A string containing the +subscription_id+ of the recurring payment already in place # for a given credit card. (REQUIRED) def status_recurring(subscription_id) - request = build_recurring_request(:status, :subscription_id => subscription_id) + request = build_recurring_request(:status, subscription_id: subscription_id) recurring_commit(:status, request) end @@ -147,13 +147,11 @@ def status_recurring(subscription_id) # Builds recurring billing request def build_recurring_request(action, options = {}) - unless RECURRING_ACTIONS.include?(action) - raise StandardError, "Invalid Automated Recurring Billing Action: #{action}" - end + raise StandardError, "Invalid Automated Recurring Billing Action: #{action}" unless RECURRING_ACTIONS.include?(action) - xml = Builder::XmlMarkup.new(:indent => 2) - xml.instruct!(:xml, :version => '1.0', :encoding => 'utf-8') - xml.tag!("#{RECURRING_ACTIONS[action]}Request", :xmlns => AUTHORIZE_NET_ARB_NAMESPACE) do + xml = Builder::XmlMarkup.new(indent: 2) + xml.instruct!(:xml, version: '1.0', encoding: 'utf-8') + xml.tag!("#{RECURRING_ACTIONS[action]}Request", xmlns: AUTHORIZE_NET_ARB_NAMESPACE) do add_merchant_authentication(xml) # Merchant-assigned reference ID for the request xml.tag!('refId', options[:ref_id]) if options[:ref_id] @@ -232,6 +230,7 @@ def add_subscription(xml, options) def add_interval(xml, options) interval = options[:interval] return unless interval + xml.tag!('interval') do # The measurement of time, in association with the Interval Unit, # that is used to define the frequency of the billing occurrences @@ -246,6 +245,7 @@ def add_interval(xml, options) def add_duration(xml, options) duration = options[:duration] return unless duration + # The date the subscription begins # (also the date the initial billing occurs) xml.tag!('startDate', duration[:start_date]) if duration[:start_date] @@ -255,6 +255,7 @@ def add_duration(xml, options) def add_payment_schedule(xml, options) return unless options[:interval] || options[:duration] + xml.tag!('paymentSchedule') do # Contains information about the interval of time between payments add_interval(xml, options) @@ -269,6 +270,7 @@ def add_payment_schedule(xml, options) # Adds customer's credit card or bank account payment information def add_payment(xml, options) return unless options[:credit_card] || options[:bank_account] + xml.tag!('payment') do # Contains the customer’s credit card information add_credit_card(xml, options) @@ -283,6 +285,7 @@ def add_payment(xml, options) def add_credit_card(xml, options) credit_card = options[:credit_card] return unless credit_card + xml.tag!('creditCard') do # The credit card number used for payment of the subscription xml.tag!('cardNumber', credit_card.number) @@ -297,6 +300,7 @@ def add_credit_card(xml, options) def add_bank_account(xml, options) bank_account = options[:bank_account] return unless bank_account + xml.tag!('bankAccount') do # The type of bank account used for payment of the subscription xml.tag!('accountType', bank_account[:account_type]) @@ -319,6 +323,7 @@ def add_bank_account(xml, options) def add_order(xml, options) order = options[:order] return unless order + xml.tag!('order') do # Merchant-assigned invoice number for the subscription (optional) xml.tag!('invoiceNumber', order[:invoice_number]) @@ -331,6 +336,7 @@ def add_order(xml, options) def add_customer(xml, options) customer = options[:customer] return unless customer + xml.tag!('customer') do xml.tag!('type', customer[:type]) if customer[:type] xml.tag!('id', customer[:id]) if customer[:id] @@ -346,6 +352,7 @@ def add_customer(xml, options) def add_drivers_license(xml, options) return unless customer = options[:customer] return unless drivers_license = customer[:drivers_license] + xml.tag!('driversLicense') do # The customer's driver's license number xml.tag!('number', drivers_license[:number]) @@ -359,6 +366,7 @@ def add_drivers_license(xml, options) # Adds address information def add_address(xml, container_name, address) return if address.blank? + xml.tag!(container_name) do xml.tag!('firstName', address[:first_name]) xml.tag!('lastName', address[:last_name]) @@ -386,9 +394,8 @@ def recurring_commit(action, request) success = response[:result_code] == 'Ok' Response.new(success, message, response, - :test => test_mode, - :authorization => response[:subscription_id] - ) + test: test_mode, + authorization: response[:subscription_id]) end def recurring_parse(action, xml) diff --git a/lib/active_merchant/billing/gateways/authorize_net_cim.rb b/lib/active_merchant/billing/gateways/authorize_net_cim.rb index fac2913ff37..bc00c93c637 100644 --- a/lib/active_merchant/billing/gateways/authorize_net_cim.rb +++ b/lib/active_merchant/billing/gateways/authorize_net_cim.rb @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- + module ActiveMerchant #:nodoc: module Billing #:nodoc: # ==== Customer Information Manager (CIM) @@ -33,55 +34,55 @@ class AuthorizeNetCimGateway < Gateway AUTHORIZE_NET_CIM_NAMESPACE = 'AnetApi/xml/v1/schema/AnetApiSchema.xsd' CIM_ACTIONS = { - :create_customer_profile => 'createCustomerProfile', - :create_customer_payment_profile => 'createCustomerPaymentProfile', - :create_customer_shipping_address => 'createCustomerShippingAddress', - :get_customer_profile => 'getCustomerProfile', - :get_customer_profile_ids => 'getCustomerProfileIds', - :get_customer_payment_profile => 'getCustomerPaymentProfile', - :get_customer_shipping_address => 'getCustomerShippingAddress', - :delete_customer_profile => 'deleteCustomerProfile', - :delete_customer_payment_profile => 'deleteCustomerPaymentProfile', - :delete_customer_shipping_address => 'deleteCustomerShippingAddress', - :update_customer_profile => 'updateCustomerProfile', - :update_customer_payment_profile => 'updateCustomerPaymentProfile', - :update_customer_shipping_address => 'updateCustomerShippingAddress', - :create_customer_profile_transaction => 'createCustomerProfileTransaction', - :validate_customer_payment_profile => 'validateCustomerPaymentProfile' + create_customer_profile: 'createCustomerProfile', + create_customer_payment_profile: 'createCustomerPaymentProfile', + create_customer_shipping_address: 'createCustomerShippingAddress', + get_customer_profile: 'getCustomerProfile', + get_customer_profile_ids: 'getCustomerProfileIds', + get_customer_payment_profile: 'getCustomerPaymentProfile', + get_customer_shipping_address: 'getCustomerShippingAddress', + delete_customer_profile: 'deleteCustomerProfile', + delete_customer_payment_profile: 'deleteCustomerPaymentProfile', + delete_customer_shipping_address: 'deleteCustomerShippingAddress', + update_customer_profile: 'updateCustomerProfile', + update_customer_payment_profile: 'updateCustomerPaymentProfile', + update_customer_shipping_address: 'updateCustomerShippingAddress', + create_customer_profile_transaction: 'createCustomerProfileTransaction', + validate_customer_payment_profile: 'validateCustomerPaymentProfile' } CIM_TRANSACTION_TYPES = { - :auth_capture => 'profileTransAuthCapture', - :auth_only => 'profileTransAuthOnly', - :capture_only => 'profileTransCaptureOnly', - :prior_auth_capture => 'profileTransPriorAuthCapture', - :refund => 'profileTransRefund', - :void => 'profileTransVoid' + auth_capture: 'profileTransAuthCapture', + auth_only: 'profileTransAuthOnly', + capture_only: 'profileTransCaptureOnly', + prior_auth_capture: 'profileTransPriorAuthCapture', + refund: 'profileTransRefund', + void: 'profileTransVoid' } CIM_VALIDATION_MODES = { - :none => 'none', - :test => 'testMode', - :live => 'liveMode', - :old => 'oldLiveMode' + none: 'none', + test: 'testMode', + live: 'liveMode', + old: 'oldLiveMode' } BANK_ACCOUNT_TYPES = { - :checking => 'checking', - :savings => 'savings', - :business_checking => 'businessChecking' + checking: 'checking', + savings: 'savings', + business_checking: 'businessChecking' } ECHECK_TYPES = { - :ccd => 'CCD', - :ppd => 'PPD', - :web => 'WEB' + ccd: 'CCD', + ppd: 'PPD', + web: 'WEB' } self.homepage_url = 'http://www.authorize.net/' self.display_name = 'Authorize.Net CIM' self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] # Creates a new AuthorizeNetCimGateway # @@ -485,13 +486,11 @@ def expdate(credit_card) end def build_request(action, options = {}) - unless CIM_ACTIONS.include?(action) - raise StandardError, "Invalid Customer Information Manager Action: #{action}" - end + raise StandardError, "Invalid Customer Information Manager Action: #{action}" unless CIM_ACTIONS.include?(action) - xml = Builder::XmlMarkup.new(:indent => 2) - xml.instruct!(:xml, :version => '1.0', :encoding => 'utf-8') - xml.tag!("#{CIM_ACTIONS[action]}Request", :xmlns => AUTHORIZE_NET_CIM_NAMESPACE) do + xml = Builder::XmlMarkup.new(indent: 2) + xml.instruct!(:xml, version: '1.0', encoding: 'utf-8') + xml.tag!("#{CIM_ACTIONS[action]}Request", xmlns: AUTHORIZE_NET_CIM_NAMESPACE) do add_merchant_authentication(xml) # Merchant-assigned reference ID for the request xml.tag!('refId', options[:ref_id]) if options[:ref_id] @@ -657,9 +656,7 @@ def add_profile(xml, profile, update = false) end def add_transaction(xml, transaction) - unless CIM_TRANSACTION_TYPES.include?(transaction[:type]) - raise StandardError, "Invalid Customer Information Manager Transaction Type: #{transaction[:type]}" - end + raise StandardError, "Invalid Customer Information Manager Transaction Type: #{transaction[:type]}" unless CIM_TRANSACTION_TYPES.include?(transaction[:type]) xml.tag!('transaction') do xml.tag!(CIM_TRANSACTION_TYPES[transaction[:type]]) do @@ -695,12 +692,10 @@ def add_transaction(xml, transaction) add_order(xml, transaction[:order]) if transaction[:order].present? end - if [:auth_capture, :auth_only, :capture_only].include?(transaction[:type]) + if %i[auth_capture auth_only capture_only].include?(transaction[:type]) xml.tag!('recurringBilling', transaction[:recurring_billing]) if transaction.has_key?(:recurring_billing) end - unless [:void, :refund, :prior_auth_capture].include?(transaction[:type]) - tag_unless_blank(xml, 'cardCode', transaction[:card_code]) - end + tag_unless_blank(xml, 'cardCode', transaction[:card_code]) unless %i[void refund prior_auth_capture].include?(transaction[:type]) end end end @@ -797,6 +792,7 @@ def add_address(xml, address) # when the payment method is credit card. def add_credit_card(xml, credit_card) return unless credit_card + xml.tag!('creditCard') do # The credit card number used for payment of the subscription xml.tag!('cardNumber', full_or_masked_card_number(credit_card.number)) @@ -857,7 +853,7 @@ def commit(action, request) response_params = parse(action, xml) - message_element= response_params['messages']['message'] + message_element = response_params['messages']['message'] first_error = message_element.is_a?(Array) ? message_element.first : message_element message = first_error['text'] test_mode = @options[:test_requests] || message =~ /Test Mode/ @@ -883,7 +879,7 @@ def format_extra_options(options) def parse_direct_response(params) delimiter = @options[:delimiter] || ',' - direct_response = {'raw' => params} + direct_response = { 'raw' => params } direct_response_fields = params.split(delimiter) direct_response.merge( { @@ -933,7 +929,7 @@ def parse_direct_response(params) 'card_type' => direct_response_fields[51] || '', 'split_tender_id' => direct_response_fields[52] || '', 'requested_amount' => direct_response_fields[53] || '', - 'balance_on_card' => direct_response_fields[54] || '', + 'balance_on_card' => direct_response_fields[54] || '' } ) end @@ -942,9 +938,7 @@ def parse(action, xml) xml = REXML::Document.new(xml) root = REXML::XPath.first(xml, "//#{CIM_ACTIONS[action]}Response") || REXML::XPath.first(xml, '//ErrorResponse') - if root - response = parse_element(root) - end + response = parse_element(root) if root response end diff --git a/lib/active_merchant/billing/gateways/axcessms.rb b/lib/active_merchant/billing/gateways/axcessms.rb index 7f9207ff6a2..b3e113338a6 100644 --- a/lib/active_merchant/billing/gateways/axcessms.rb +++ b/lib/active_merchant/billing/gateways/axcessms.rb @@ -8,7 +8,7 @@ class AxcessmsGateway < Gateway GI GR HR HU IE IL IM IS IT LI LT LU LV MC MT MX NL NO PL PT RO RU SE SI SK TR US VA) - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :maestro] + self.supported_cardtypes = %i[visa master american_express discover jcb maestro] self.homepage_url = 'http://www.axcessms.com/' self.display_name = 'Axcess MS' @@ -23,33 +23,33 @@ class AxcessmsGateway < Gateway PAYMENT_CODE_REFUND = 'CC.RF' PAYMENT_CODE_REBILL = 'CC.RB' - def initialize(options={}) + def initialize(options = {}) requires!(options, :sender, :login, :password, :channel) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) payment_code = payment.respond_to?(:number) ? PAYMENT_CODE_DEBIT : PAYMENT_CODE_REBILL commit(payment_code, money, payment, options) end - def authorize(money, authorization, options={}) + def authorize(money, authorization, options = {}) commit(PAYMENT_CODE_PREAUTHORIZATION, money, authorization, options) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) commit(PAYMENT_CODE_CAPTURE, money, authorization, options) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) commit(PAYMENT_CODE_REFUND, money, authorization, options) end - def void(authorization, options={}) + def void(authorization, options = {}) commit(PAYMENT_CODE_REVERSAL, nil, authorization, options) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -72,9 +72,8 @@ def commit(paymentcode, money, payment, options) authorization = response[:unique_id] Response.new(success, message, response, - :authorization => authorization, - :test => (response[:mode] != 'LIVE') - ) + authorization: authorization, + test: (response[:mode] != 'LIVE')) end def parse(body) @@ -93,9 +92,7 @@ def parse(body) end def parse_element(response, node) - if node.has_attributes? - node.attributes.each { |name, value| response["#{node.name}_#{name}".underscore.to_sym] = value } - end + node.attributes.each { |name, value| response["#{node.name}_#{name}".underscore.to_sym] = value } if node.has_attributes? if node.has_elements? node.elements.each { |element| parse_element(response, element) } @@ -105,7 +102,7 @@ def parse_element(response, node) end def build_request(payment_code, money, payment, options) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.instruct! xml.tag! 'Request', 'version' => API_VERSION do xml.tag! 'Header' do @@ -168,6 +165,7 @@ def add_payment(xml, payment) def add_address(xml, address) raise ArgumentError.new('Address is required') unless address + xml.tag! 'Address' do xml.tag! 'Street', "#{address[:address1]} #{address[:address2]}".strip xml.tag! 'City', address[:city] diff --git a/lib/active_merchant/billing/gateways/balanced.rb b/lib/active_merchant/billing/gateways/balanced.rb index f9b7accff02..a3ecf3792e7 100644 --- a/lib/active_merchant/billing/gateways/balanced.rb +++ b/lib/active_merchant/billing/gateways/balanced.rb @@ -22,7 +22,7 @@ class BalancedGateway < Gateway self.live_url = 'https://api.balancedpayments.com' self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'https://www.balancedpayments.com/' self.display_name = 'Balanced' self.money_format = :cents @@ -44,12 +44,13 @@ def purchase(money, payment_method, options = {}) add_common_params(post, options) MultiResponse.run do |r| - identifier = if(payment_method.respond_to?(:number)) - r.process { store(payment_method, options) } - r.authorization - else - payment_method - end + identifier = + if payment_method.respond_to?(:number) + r.process { store(payment_method, options) } + r.authorization + else + payment_method + end r.process { commit('debits', "cards/#{card_identifier_from(identifier)}/debits", post) } end end @@ -61,12 +62,13 @@ def authorize(money, payment_method, options = {}) add_common_params(post, options) MultiResponse.run do |r| - identifier = if(payment_method.respond_to?(:number)) - r.process { store(payment_method, options) } - r.authorization - else - payment_method - end + identifier = + if payment_method.respond_to?(:number) + r.process { store(payment_method, options) } + r.authorization + else + payment_method + end r.process { commit('card_holds', "cards/#{card_identifier_from(identifier)}/card_holds", post) } end end @@ -97,7 +99,7 @@ def refund(money, identifier, options = {}) commit('refunds', "debits/#{reference_identifier_from(identifier)}/refunds", post) end - def store(credit_card, options={}) + def store(credit_card, options = {}) post = {} post[:number] = credit_card.number @@ -137,7 +139,7 @@ def add_amount(post, money) def add_address(post, options) address = (options[:billing_address] || options[:address]) - if(address && address[:zip].present?) + if address && address[:zip].present? post[:address] = {} post[:address][:line1] = address[:address1] if address[:address1] post[:address][:line2] = address[:address2] if address[:address2] @@ -154,18 +156,22 @@ def add_common_params(post, options) post[:meta] = options[:meta] end - def commit(entity_name, path, post, method=:post) - raw_response = begin - parse(ssl_request( - method, - live_url + "/#{path}", - post_data(post), - headers - )) - rescue ResponseError => e - raise unless(e.response.code.to_s =~ /4\d\d/) - parse(e.response.body) - end + def commit(entity_name, path, post, method = :post) + raw_response = + begin + parse( + ssl_request( + method, + live_url + "/#{path}", + post_data(post), + headers + ) + ) + rescue ResponseError => e + raise unless e.response.code.to_s =~ /4\d\d/ + + parse(e.response.body) + end Response.new( success_from(entity_name, raw_response), @@ -178,13 +184,13 @@ def commit(entity_name, path, post, method=:post) def success_from(entity_name, raw_response) entity = (raw_response[entity_name] || []).first - if(!entity) + if !entity false - elsif((entity_name == 'refunds') && entity.include?('status')) + elsif (entity_name == 'refunds') && entity.include?('status') %w(succeeded pending).include?(entity['status']) - elsif(entity.include?('status')) + elsif entity.include?('status') (entity['status'] == 'succeeded') - elsif(entity_name == 'cards') + elsif entity_name == 'cards' !!entity['id'] else false @@ -192,7 +198,7 @@ def success_from(entity_name, raw_response) end def message_from(raw_response) - if(raw_response['errors']) + if raw_response['errors'] error = raw_response['errors'].first (error['additional'] || error['message'] || error['description']) else @@ -222,6 +228,7 @@ def post_data(params) params.map do |key, value| next if value.blank? + if value.is_a?(Hash) h = {} value.each do |k, v| @@ -245,10 +252,10 @@ def headers ) { - 'Authorization' => 'Basic ' + Base64.encode64(@options[:login].to_s + ':').strip, - 'User-Agent' => "Balanced/v1.1 ActiveMerchantBindings/#{ActiveMerchant::VERSION}", - 'Accept' => 'application/vnd.api+json;revision=1.1', - 'X-Balanced-User-Agent' => @@ua, + 'Authorization' => 'Basic ' + Base64.encode64(@options[:login].to_s + ':').strip, + 'User-Agent' => "Balanced/v1.1 ActiveMerchantBindings/#{ActiveMerchant::VERSION}", + 'Accept' => 'application/vnd.api+json;revision=1.1', + 'X-Balanced-User-Agent' => @@ua } end end diff --git a/lib/active_merchant/billing/gateways/bambora_apac.rb b/lib/active_merchant/billing/gateways/bambora_apac.rb index 6cfe3a82bdc..596007e1a1b 100644 --- a/lib/active_merchant/billing/gateways/bambora_apac.rb +++ b/lib/active_merchant/billing/gateways/bambora_apac.rb @@ -6,8 +6,8 @@ class BamboraApacGateway < Gateway self.live_url = 'https://www.bambora.co.nz/interface/api' self.test_url = 'https://demo.bambora.co.nz/interface/api' - self.supported_countries = ['AU', 'NZ'] - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :jcb] + self.supported_countries = %w[AU NZ] + self.supported_cardtypes = %i[visa master american_express diners_club jcb] self.homepage_url = 'http://www.bambora.com/' self.display_name = 'Bambora Asia-Pacific' @@ -18,19 +18,19 @@ class BamboraApacGateway < Gateway '05' => STANDARD_ERROR_CODE[:card_declined], '06' => STANDARD_ERROR_CODE[:processing_error], '14' => STANDARD_ERROR_CODE[:invalid_number], - '54' => STANDARD_ERROR_CODE[:expired_card], + '54' => STANDARD_ERROR_CODE[:expired_card] } - def initialize(options={}) + def initialize(options = {}) requires!(options, :username, :password) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) commit('SubmitSinglePayment') do |xml| xml.Transaction do xml.CustRef options[:order_id] - add_amount(xml, money) + xml.Amount amount(money) xml.TrnType '1' add_payment(xml, payment) add_credentials(xml, options) @@ -39,11 +39,11 @@ def purchase(money, payment, options={}) end end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) commit('SubmitSinglePayment') do |xml| xml.Transaction do xml.CustRef options[:order_id] - add_amount(xml, money) + xml.Amount amount(money) xml.TrnType '2' add_payment(xml, payment) add_credentials(xml, options) @@ -52,37 +52,37 @@ def authorize(money, payment, options={}) end end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) commit('SubmitSingleCapture') do |xml| xml.Capture do xml.Receipt authorization - add_amount(xml, money) + xml.Amount amount(money) add_credentials(xml, options) end end end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) commit('SubmitSingleRefund') do |xml| xml.Refund do xml.Receipt authorization - add_amount(xml, money) + xml.Amount amount(money) add_credentials(xml, options) end end end - def void(money, authorization, options={}) + def void(authorization, options = {}) commit('SubmitSingleVoid') do |xml| xml.Void do xml.Receipt authorization - add_amount(xml, money) + xml.Amount amount(options[:amount]) add_credentials(xml, options) end end end - def store(payment, options={}) + def store(payment, options = {}) commit('TokeniseCreditCard') do |xml| xml.TokeniseCreditCard do xml.CardNumber payment.number @@ -116,10 +116,6 @@ def add_credentials(xml, options) end end - def add_amount(xml, money) - xml.Amount amount(money) - end - def add_payment(xml, payment) if payment.is_a?(String) add_token(xml, payment) @@ -136,7 +132,7 @@ def add_token(xml, payment) end def add_credit_card(xml, payment) - xml.CreditCard :Registered => 'False' do + xml.CreditCard Registered: 'False' do xml.CardNumber payment.number xml.ExpM format(payment.month, :two_digits) xml.ExpY format(payment.year, :four_digits) diff --git a/lib/active_merchant/billing/gateways/bank_frick.rb b/lib/active_merchant/billing/gateways/bank_frick.rb index 8a35089978c..3bdd3cb2a0d 100644 --- a/lib/active_merchant/billing/gateways/bank_frick.rb +++ b/lib/active_merchant/billing/gateways/bank_frick.rb @@ -9,9 +9,9 @@ class BankFrickGateway < Gateway self.test_url = 'https://test.ctpe.io/payment/ctpe' self.live_url = 'https://ctpe.io/payment/ctpe' - self.supported_countries = ['LI', 'US'] + self.supported_countries = %w[LI US] self.default_currency = 'EUR' - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://www.bankfrickacquiring.com/' self.display_name = 'Bank Frick' @@ -24,15 +24,15 @@ class BankFrickGateway < Gateway 'authonly' => 'CC.PA', 'capture' => 'CC.CP', 'refund' => 'CC.RF', - 'void' => 'CC.RV', + 'void' => 'CC.RV' } - def initialize(options={}) + def initialize(options = {}) requires!(options, :sender, :channel, :userid, :userpwd) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) post = {} add_invoice(post, money, options) add_payment(post, payment) @@ -42,7 +42,7 @@ def purchase(money, payment, options={}) commit('sale', post) end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) post = {} add_invoice(post, money, options) add_payment(post, payment) @@ -52,7 +52,7 @@ def authorize(money, payment, options={}) commit('authonly', post) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) post = {} post[:authorization] = authorization add_invoice(post, money, options) @@ -60,7 +60,7 @@ def capture(money, authorization, options={}) commit('capture', post) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) post = {} post[:authorization] = authorization add_invoice(post, money, options) @@ -68,14 +68,14 @@ def refund(money, authorization, options={}) commit('refund', post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} post[:authorization] = authorization commit('void', post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -97,7 +97,7 @@ def add_address(post, creditcard, options) post[:zip] = address[:zip].to_s post[:city] = address[:city].to_s post[:country] = address[:country].to_s - post[:state] = address[:state].blank? ? 'n/a' : address[:state] + post[:state] = address[:state].blank? ? 'n/a' : address[:state] end end @@ -119,7 +119,7 @@ def add_payment(post, payment) end def parse(body) - results = {} + results = {} xml = Nokogiri::XML(body) resp = xml.xpath('//Response/Transaction/Identification') resp.children.each do |element| @@ -166,7 +166,7 @@ def post_data(action, parameters = {}) end def build_xml_request(action, data) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.Request(version: '1.0') do xml.Header do xml.Security(sender: @options[:sender], type: 'MERCHANT') diff --git a/lib/active_merchant/billing/gateways/banwire.rb b/lib/active_merchant/billing/gateways/banwire.rb index 99d3e683e34..6e669c8eef1 100644 --- a/lib/active_merchant/billing/gateways/banwire.rb +++ b/lib/active_merchant/billing/gateways/banwire.rb @@ -4,7 +4,7 @@ class BanwireGateway < Gateway URL = 'https://banwire.com/api.pago_pro' self.supported_countries = ['MX'] - self.supported_cardtypes = [:visa, :master, :american_express] + self.supported_cardtypes = %i[visa master american_express] self.homepage_url = 'http://www.banwire.com/' self.display_name = 'Banwire' @@ -63,7 +63,7 @@ def add_creditcard(post, creditcard) post[:card_num] = creditcard.number post[:card_name] = creditcard.name post[:card_type] = card_brand(creditcard) - post[:card_exp] = "#{sprintf("%02d", creditcard.month)}/#{creditcard.year.to_s[-2, 2]}" + post[:card_exp] = "#{sprintf('%02d', creditcard.month)}/#{creditcard.year.to_s[-2, 2]}" post[:card_ccv2] = creditcard.verification_value end @@ -74,7 +74,7 @@ def add_amount(post, money, options) def card_brand(card) brand = super - ({'master' => 'mastercard', 'american_express' => 'amex'}[brand] || brand) + ({ 'master' => 'mastercard', 'american_express' => 'amex' }[brand] || brand) end def parse(body) @@ -92,8 +92,8 @@ def commit(money, parameters) Response.new(success?(response), response['message'], response, - :test => test?, - :authorization => response['code_auth']) + test: test?, + authorization: response['code_auth']) end def success?(response) diff --git a/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb b/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb index 1788954da3b..fb657adb72c 100644 --- a/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +++ b/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb @@ -4,11 +4,11 @@ class BarclaycardSmartpayGateway < Gateway self.test_url = 'https://pal-test.barclaycardsmartpay.com/pal/servlet' self.live_url = 'https://pal-live.barclaycardsmartpay.com/pal/servlet' - self.supported_countries = ['AL', 'AD', 'AM', 'AT', 'AZ', 'BY', 'BE', 'BA', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'HU', 'IS', 'IE', 'IT', 'KZ', 'LV', 'LI', 'LT', 'LU', 'MK', 'MT', 'MD', 'MC', 'ME', 'NL', 'NO', 'PL', 'PT', 'RO', 'RU', 'SM', 'RS', 'SK', 'SI', 'ES', 'SE', 'CH', 'TR', 'UA', 'GB', 'VA'] + self.supported_countries = %w[AL AD AM AT AZ BY BE BA BG HR CY CZ DK EE FI FR DE GR HU IS IE IT KZ LV LI LT LU MK MT MD MC ME NL NO PL PT RO RU SM RS SK SI ES SE CH TR UA GB VA] self.default_currency = 'EUR' self.currencies_with_three_decimal_places = %w(BHD KWD OMR RSD TND) self.money_format = :cents - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb, :dankort, :maestro] + self.supported_cardtypes = %i[visa master american_express discover diners_club jcb dankort maestro] self.homepage_url = 'https://www.barclaycardsmartpay.com/' self.display_name = 'Barclaycard Smartpay' @@ -71,21 +71,23 @@ def credit(money, creditcard, options = {}) post[:shopperName] = options[:shopper_name] if options[:shopper_name] if options[:third_party_payout] - post[:recurring] = options[:recurring_contract] || {contract: 'PAYOUT'} + post[:recurring] = options[:recurring_contract] || { contract: 'PAYOUT' } MultiResponse.run do |r| r.process { commit( 'storeDetailAndSubmitThirdParty', post, @options[:store_payout_account], - @options[:store_payout_password]) + @options[:store_payout_password] + ) } r.process { commit( 'confirmThirdParty', modification_request(r.authorization, @options), @options[:review_payout_account], - @options[:review_payout_password]) + @options[:review_payout_password] + ) } end else @@ -108,7 +110,7 @@ def verify(creditcard, options = {}) def store(creditcard, options = {}) post = store_request(options) post[:card] = credit_card_hash(creditcard) - post[:recurring] = {:contract => 'RECURRING'} + post[:recurring] = { contract: 'RECURRING' } commit('store', post) end @@ -129,25 +131,25 @@ def scrub(transcript) # Smartpay may return AVS codes not covered by standard AVSResult codes. # Smartpay's descriptions noted below. AVS_MAPPING = { - '0' => 'R', # Unknown - '1' => 'A', # Address matches, postal code doesn't - '2' => 'N', # Neither postal code nor address match - '3' => 'R', # AVS unavailable - '4' => 'E', # AVS not supported for this card type - '5' => 'U', # No AVS data provided - '6' => 'Z', # Postal code matches, address doesn't match - '7' => 'D', # Both postal code and address match - '8' => 'U', # Address not checked, postal code unknown - '9' => 'B', # Address matches, postal code unknown - '10' => 'N', # Address doesn't match, postal code unknown - '11' => 'U', # Postal code not checked, address unknown - '12' => 'B', # Address matches, postal code not checked - '13' => 'U', # Address doesn't match, postal code not checked - '14' => 'P', # Postal code matches, address unknown - '15' => 'P', # Postal code matches, address not checked - '16' => 'N', # Postal code doesn't match, address unknown - '17' => 'U', # Postal code doesn't match, address not checked - '18' => 'I' # Neither postal code nor address were checked + '0' => 'R', # Unknown + '1' => 'A', # Address matches, postal code doesn't + '2' => 'N', # Neither postal code nor address match + '3' => 'R', # AVS unavailable + '4' => 'E', # AVS not supported for this card type + '5' => 'U', # No AVS data provided + '6' => 'Z', # Postal code matches, address doesn't match + '7' => 'D', # Both postal code and address match + '8' => 'U', # Address not checked, postal code unknown + '9' => 'B', # Address matches, postal code unknown + '10' => 'N', # Address doesn't match, postal code unknown + '11' => 'U', # Postal code not checked, address unknown + '12' => 'B', # Address matches, postal code not checked + '13' => 'U', # Address doesn't match, postal code not checked + '14' => 'P', # Postal code matches, address unknown + '15' => 'P', # Postal code matches, address not checked + '16' => 'N', # Postal code doesn't match, address unknown + '17' => 'U', # Postal code doesn't match, address not checked + '18' => 'I' # Neither postal code nor address were checked } def commit(action, post, account = 'ws', password = @options[:password]) @@ -161,20 +163,20 @@ def commit(action, post, account = 'ws', password = @options[:password]) message_from(response), response, test: test?, - avs_result: AVSResult.new(:code => parse_avs_code(response)), + avs_result: AVSResult.new(code: parse_avs_code(response)), authorization: response['recurringDetailReference'] || authorization_from(post, response) ) rescue ResponseError => e case e.response.code when '401' - return Response.new(false, 'Invalid credentials', {}, :test => test?) + return Response.new(false, 'Invalid credentials', {}, test: test?) when '403' - return Response.new(false, 'Not allowed', {}, :test => test?) + return Response.new(false, 'Not allowed', {}, test: test?) when '422', '500' if e.response.body.split(/\W+/).any? { |word| %w(validation configuration security).include?(word) } error_message = e.response.body[/#{Regexp.escape('message=')}(.*?)#{Regexp.escape('&')}/m, 1].tr('+', ' ') error_code = e.response.body[/#{Regexp.escape('errorCode=')}(.*?)#{Regexp.escape('&')}/m, 1] - return Response.new(false, error_code + ': ' + error_message, {}, :test => test?) + return Response.new(false, error_code + ': ' + error_message, {}, test: test?) end end raise @@ -184,6 +186,7 @@ def authorization_from(parameters, response) authorization = [parameters[:originalReference], response['pspReference']].compact return nil if authorization.empty? + return authorization.join('#') end @@ -238,6 +241,7 @@ def message_from(response) return response['resultCode'] if response.has_key?('resultCode') # Payment request return response['response'] if response['response'] # Modification request return response['result'] if response.has_key?('result') # Store/Recurring request + 'Failure' # Negative fallback in case of error end @@ -359,8 +363,15 @@ def add_3ds(post, options) add_browser_info(three_ds_2_options[:browser_info], post) post[:threeDS2RequestData] = { deviceChannel: device_channel, notificationURL: three_ds_2_options[:notification_url] } end + + if options.has_key?(:execute_threed) + post[:additionalData] ||= {} + post[:additionalData][:executeThreeD] = options[:execute_threed] + post[:additionalData][:scaExemption] = options[:sca_exemption] if options[:sca_exemption] + end else return unless options[:execute_threed] || options[:threed_dynamic] + post[:browserInfo] = { userAgent: options[:user_agent], acceptHeader: options[:accept_header] } post[:additionalData] = { executeThreeD: 'true' } if options[:execute_threed] end @@ -368,6 +379,7 @@ def add_3ds(post, options) def add_browser_info(browser_info, post) return unless browser_info + post[:browserInfo] = { acceptHeader: browser_info[:accept_header], colorDepth: browser_info[:depth], diff --git a/lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb b/lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb index 6f020860b2a..b0e42176e5e 100644 --- a/lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb +++ b/lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb @@ -8,7 +8,7 @@ class BarclaysEpdqExtraPlusGateway < OgoneGateway self.homepage_url = 'http://www.barclaycard.co.uk/business/accepting-payments/epdq-ecomm/' self.supported_countries = ['GB'] - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :discover, :jcb, :maestro] + self.supported_cardtypes = %i[visa master american_express diners_club discover jcb maestro] self.default_currency = 'GBP' end end diff --git a/lib/active_merchant/billing/gateways/be2bill.rb b/lib/active_merchant/billing/gateways/be2bill.rb index f309272466f..f00ae7db8a9 100644 --- a/lib/active_merchant/billing/gateways/be2bill.rb +++ b/lib/active_merchant/billing/gateways/be2bill.rb @@ -9,7 +9,7 @@ class Be2billGateway < Gateway self.display_name = 'Be2Bill' self.homepage_url = 'http://www.be2bill.com/' self.supported_countries = ['FR'] - self.supported_cardtypes = [:visa, :master, :american_express] + self.supported_cardtypes = %i[visa master american_express] self.default_currency = 'EUR' self.money_format = :cents @@ -92,8 +92,8 @@ def commit(action, money, parameters) successful?(response), message_from(response), response, - :authorization => response['TRANSACTIONID'], - :test => test? + authorization: response['TRANSACTIONID'], + test: test? ) end @@ -111,8 +111,8 @@ def message_from(response) def post_data(action, parameters = {}) { - :method => action, - :params => parameters.merge(HASH: signature(parameters, action)) + method: action, + params: parameters.merge(HASH: signature(parameters, action)) }.to_query end diff --git a/lib/active_merchant/billing/gateways/beanstream.rb b/lib/active_merchant/billing/gateways/beanstream.rb index 5689f902d4e..68168211868 100644 --- a/lib/active_merchant/billing/gateways/beanstream.rb +++ b/lib/active_merchant/billing/gateways/beanstream.rb @@ -104,7 +104,7 @@ def void(authorization, options = {}) end end - def verify(source, options={}) + def verify(source, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, source, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -175,10 +175,10 @@ def store(payment_method, options = {}) # can't actually delete a secure profile with the supplicated API. This function sets the status of the profile to closed (C). # Closed profiles will have to removed manually. def delete(vault_id) - update(vault_id, false, {:status => 'C'}) + update(vault_id, false, { status: 'C' }) end - alias_method :unstore, :delete + alias unstore delete # Update the values (such as CC expiration) stored at # the gateway. The CC number must be supplied in the diff --git a/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb b/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb index e4d2c77e70a..b794899c579 100644 --- a/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +++ b/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb @@ -9,20 +9,20 @@ module BeanstreamCore SP_SERVICE_VERSION = '1.1' TRANSACTIONS = { - :authorization => 'PA', - :purchase => 'P', - :capture => 'PAC', - :refund => 'R', - :void => 'VP', - :check_purchase => 'D', - :check_refund => 'C', - :void_purchase => 'VP', - :void_refund => 'VR' + authorization: 'PA', + purchase: 'P', + capture: 'PAC', + refund: 'R', + void: 'VP', + check_purchase: 'D', + check_refund: 'C', + void_purchase: 'VP', + void_refund: 'VR' } PROFILE_OPERATIONS = { - :new => 'N', - :modify => 'M' + new: 'N', + modify: 'M' } CVD_CODES = { @@ -41,24 +41,24 @@ module BeanstreamCore } PERIODS = { - :days => 'D', - :weeks => 'W', - :months => 'M', - :years => 'Y' + days: 'D', + weeks: 'W', + months: 'M', + years: 'Y' } PERIODICITIES = { - :daily => [:days, 1], - :weekly => [:weeks, 1], - :biweekly => [:weeks, 2], - :monthly => [:months, 1], - :bimonthly => [:months, 2], - :yearly => [:years, 1] + daily: [:days, 1], + weekly: [:weeks, 1], + biweekly: [:weeks, 2], + monthly: [:months, 1], + bimonthly: [:months, 2], + yearly: [:years, 1] } RECURRING_OPERATION = { - :update => 'M', - :cancel => 'C' + update: 'M', + cancel: 'C' } STATES = { @@ -131,10 +131,10 @@ def self.included(base) base.default_currency = 'CAD' # The countries the gateway supports merchants from as 2 digit ISO country codes - base.supported_countries = ['CA', 'US'] + base.supported_countries = %w[CA US] # The card types supported by the payment gateway - base.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb] + base.supported_cardtypes = %i[visa master american_express discover diners_club jcb] # The homepage URL of the gateway base.homepage_url = 'http://www.beanstream.com/' @@ -155,7 +155,7 @@ def initialize(options = {}) end def capture(money, authorization, options = {}) - reference, _, _ = split_auth(authorization) + reference, = split_auth(authorization) post = {} add_amount(post, money) add_reference(post, reference) @@ -256,9 +256,10 @@ def state_for(address) end def prepare_address_for_non_american_countries(options) - [ options[:billing_address], options[:shipping_address] ].compact.each do |address| + [options[:billing_address], options[:shipping_address]].compact.each do |address| next if empty?(address[:country]) - unless ['US', 'CA'].include?(address[:country]) + + unless %w[US CA].include?(address[:country]) address[:state] = '--' address[:zip] = '000000' unless address[:zip] end @@ -366,6 +367,7 @@ def interval(options) if interval.respond_to? :parts parts = interval.parts raise ArgumentError.new("Cannot recur with mixed interval (#{interval}). Use only one of: days, weeks, months or years") if parts.length > 1 + parts.first elsif interval.kind_of? Hash requires!(interval, :unit) @@ -408,15 +410,14 @@ def recurring_commit(params) recurring_post(post_data(params, false)) end - def post(data, use_profile_api=nil) + def post(data, use_profile_api = nil) response = parse(ssl_post((use_profile_api ? SECURE_PROFILE_URL : self.live_url), data)) response[:customer_vault_id] = response[:customerCode] if response[:customerCode] build_response(success?(response), message_from(response), response, - :test => test? || response[:authCode] == 'TEST', - :authorization => authorization_from(response), - :cvv_result => CVD_CODES[response[:cvdId]], - :avs_result => { :code => AVS_CODES.include?(response[:avsId]) ? AVS_CODES[response[:avsId]] : response[:avsId] } - ) + test: test? || response[:authCode] == 'TEST', + authorization: authorization_from(response), + cvv_result: CVD_CODES[response[:cvdId]], + avs_result: { code: AVS_CODES.include?(response[:avsId]) ? AVS_CODES[response[:avsId]] : response[:avsId] }) end def recurring_post(data) @@ -441,7 +442,7 @@ def recurring_success?(response) end def add_source(post, source) - if source.is_a?(String) or source.is_a?(Integer) + if source.is_a?(String) || source.is_a?(Integer) post[:customerCode] = source else card_brand(source) == 'check' ? add_check(post, source) : add_credit_card(post, source) @@ -466,7 +467,7 @@ def post_data(params, use_profile_api) params[:vbvEnabled] = '0' params[:scEnabled] = '0' - params.reject { |k, v| v.blank? }.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join('&') + params.reject { |_k, v| v.blank? }.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join('&') end end end diff --git a/lib/active_merchant/billing/gateways/beanstream_interac.rb b/lib/active_merchant/billing/gateways/beanstream_interac.rb index 37ca7595a31..5459e0aa8b2 100644 --- a/lib/active_merchant/billing/gateways/beanstream_interac.rb +++ b/lib/active_merchant/billing/gateways/beanstream_interac.rb @@ -18,7 +18,7 @@ class BeanstreamInteracGateway < Gateway # post back is for until the response of the confirmation is # received, which contains the order number. def self.confirm(transaction) - gateway = new(:login => '') + gateway = new(login: '') gateway.confirm(transaction) end diff --git a/lib/active_merchant/billing/gateways/blue_pay.rb b/lib/active_merchant/billing/gateways/blue_pay.rb index 5040d2d15c6..f4f2e54bfff 100644 --- a/lib/active_merchant/billing/gateways/blue_pay.rb +++ b/lib/active_merchant/billing/gateways/blue_pay.rb @@ -10,15 +10,15 @@ class BluePayGateway < Gateway self.ignore_http_status = true - CARD_CODE_ERRORS = %w( N S ) - AVS_ERRORS = %w( A E N R W Z ) + CARD_CODE_ERRORS = %w(N S) + AVS_ERRORS = %w(A E N R W Z) AVS_REASON_CODES = %w(27 45) FIELD_MAP = { 'TRANS_ID' => :transaction_id, 'STATUS' => :response_code, 'AVS' => :avs_result_code, - 'CVV2'=> :card_code, + 'CVV2' => :card_code, 'AUTH_CODE' => :authorization, 'MESSAGE' => :message, 'REBID' => :rebid, @@ -29,7 +29,7 @@ class BluePayGateway < Gateway REBILL_FIELD_MAP = { 'REBILL_ID' => :rebill_id, - 'ACCOUNT_ID'=> :account_id, + 'ACCOUNT_ID' => :account_id, 'USER_ID' => :user_id, 'TEMPLATE_ID' => :template_id, 'STATUS' => :status, @@ -44,8 +44,8 @@ class BluePayGateway < Gateway 'CUST_TOKEN' => :cust_token } - self.supported_countries = ['US', 'CA'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb] + self.supported_countries = %w[US CA] + self.supported_cardtypes = %i[visa master american_express discover diners_club jcb] self.homepage_url = 'http://www.bluepay.com/' self.display_name = 'BluePay' self.money_format = :dollars @@ -84,7 +84,7 @@ def authorize(money, payment_object, options = {}) add_customer_data(post, options) add_rebill(post, options) if options[:rebill] add_duplicate_override(post, options) - post[:TRANS_TYPE] = 'AUTH' + post[:TRANS_TYPE] = 'AUTH' commit('AUTH_ONLY', money, post, options) end @@ -107,7 +107,7 @@ def purchase(money, payment_object, options = {}) add_customer_data(post, options) add_rebill(post, options) if options[:rebill] add_duplicate_override(post, options) - post[:TRANS_TYPE] = 'SALE' + post[:TRANS_TYPE] = 'SALE' commit('AUTH_CAPTURE', money, post, options) end @@ -155,7 +155,7 @@ def void(identification, options = {}) # If the payment_object is either a CreditCard or Check object, then the transaction type will be an unmatched credit placing funds in the specified account. This is referred to a CREDIT transaction in BluePay. # * options -- A hash of parameters. def refund(money, identification, options = {}) - if(identification && !identification.kind_of?(String)) + if identification && !identification.kind_of?(String) ActiveMerchant.deprecated 'refund should only be used to refund a referenced transaction' return credit(money, identification, options) end @@ -317,7 +317,7 @@ def scrub(transcript) private def commit(action, money, fields, options = {}) - fields[:AMOUNT] = amount(money) unless(fields[:TRANS_TYPE] == 'VOID' || action == 'rebill') + fields[:AMOUNT] = amount(money) unless fields[:TRANS_TYPE] == 'VOID' || action == 'rebill' fields[:MODE] = (test? ? 'TEST' : 'LIVE') fields[:ACCOUNT_ID] = @options[:login] fields[:CUSTOMER_IP] = options[:ip] if options[:ip] @@ -332,7 +332,7 @@ def commit(action, money, fields, options = {}) parse(ssl_post(url, post_data(action, fields))) end - def parse_recurring(response_fields, opts={}) # expected status? + def parse_recurring(response_fields, opts = {}) # expected status? parsed = {} response_fields.each do |k, v| mapped_key = REBILL_FIELD_MAP.include?(k) ? REBILL_FIELD_MAP[k] : k @@ -343,17 +343,15 @@ def parse_recurring(response_fields, opts={}) # expected status? message = parsed[:status] Response.new(success, message, parsed, - :test => test?, - :authorization => parsed[:rebill_id]) + test: test?, + authorization: parsed[:rebill_id]) end def parse(body) # The bp20api has max one value per form field. response_fields = Hash[CGI::parse(body).map { |k, v| [k.upcase, v.first] }] - if response_fields.include? 'REBILL_ID' - return parse_recurring(response_fields) - end + return parse_recurring(response_fields) if response_fields.include? 'REBILL_ID' parsed = {} response_fields.each do |k, v| @@ -365,16 +363,15 @@ def parse(body) message = message_from(parsed) success = parsed[:response_code] == '1' Response.new(success, message, parsed, - :test => test?, - :authorization => (parsed[:rebid] && parsed[:rebid] != '' ? parsed[:rebid] : parsed[:transaction_id]), - :avs_result => { :code => parsed[:avs_result_code] }, - :cvv_result => parsed[:card_code] - ) + test: test?, + authorization: (parsed[:rebid] && parsed[:rebid] != '' ? parsed[:rebid] : parsed[:transaction_id]), + avs_result: { code: parsed[:avs_result_code] }, + cvv_result: parsed[:card_code]) end def message_from(parsed) message = parsed[:message] - if(parsed[:response_code].to_i == 2) + if parsed[:response_code].to_i == 2 if CARD_CODE_ERRORS.include?(parsed[:card_code]) message = CVVResult.messages[parsed[:card_code]] elsif AVS_ERRORS.include?(parsed[:avs_result_code]) @@ -384,10 +381,10 @@ def message_from(parsed) end elsif message == 'Missing ACCOUNT_ID' message = 'The merchant login ID or password is invalid' - elsif message =~ /Approved/ + elsif /Approved/.match?(message) message = 'This transaction has been approved' - elsif message =~ /Expired/ - message = 'The credit card has expired' + elsif /Expired/.match?(message) + message = 'The credit card has expired' end message end @@ -514,9 +511,8 @@ def calc_rebill_tps(post) end def handle_response(response) - if ignore_http_status || (200...300).cover?(response.code.to_i) - return response.body - end + return response.body if ignore_http_status || (200...300).cover?(response.code.to_i) + raise ResponseError.new(response) end end diff --git a/lib/active_merchant/billing/gateways/blue_snap.rb b/lib/active_merchant/billing/gateways/blue_snap.rb index b344749b2d4..3dd530e6d7c 100644 --- a/lib/active_merchant/billing/gateways/blue_snap.rb +++ b/lib/active_merchant/billing/gateways/blue_snap.rb @@ -8,7 +8,9 @@ class BlueSnapGateway < Gateway self.supported_countries = %w(US CA GB AT BE BG HR CY CZ DK EE FI FR DE GR HU IE IT LV LT LU MT NL PL PT RO SK SI ES SE AR BO BR BZ CL CO CR DO EC GF GP GT HN HT MF MQ MX NI PA PE PR PY SV UY VE) self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club, :maestro, :naranja, :cabal] + self.supported_cardtypes = %i[visa master american_express discover jcb diners_club maestro naranja cabal] + self.currencies_without_fractions = %w(BYR CLP ILS JPY KRW VND XOF) + self.currencies_with_three_decimal_places = %w(BHD JOD KWD OMR TND) self.homepage_url = 'https://home.bluesnap.com/' self.display_name = 'BlueSnap' @@ -56,7 +58,7 @@ class BlueSnapGateway < Gateway 'line1: N, zip: M, name: N' => 'W', 'line1: N, zip: N, name: U' => 'N', 'line1: N, zip: N, name: M' => 'K', - 'line1: N, zip: N, name: N' => 'N', + 'line1: N, zip: N, name: N' => 'N' } BANK_ACCOUNT_TYPE_MAPPING = { @@ -68,12 +70,12 @@ class BlueSnapGateway < Gateway STATE_CODE_COUNTRIES = %w(US CA) - def initialize(options={}) + def initialize(options = {}) requires!(options, :api_username, :api_password) super end - def purchase(money, payment_method, options={}) + def purchase(money, payment_method, options = {}) payment_method_details = PaymentMethodDetails.new(payment_method) commit(:purchase, :post, payment_method_details) do |doc| @@ -85,13 +87,13 @@ def purchase(money, payment_method, options={}) end end - def authorize(money, payment_method, options={}) + def authorize(money, payment_method, options = {}) commit(:authorize) do |doc| add_auth_purchase(doc, money, payment_method, options) end end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) commit(:capture, :put) do |doc| add_authorization(doc, authorization) add_order(doc, options) @@ -99,7 +101,7 @@ def capture(money, authorization, options={}) end end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) commit(:refund, :put) do |doc| add_authorization(doc, authorization) add_amount(doc, money, options) @@ -107,14 +109,14 @@ def refund(money, authorization, options={}) end end - def void(authorization, options={}) + def void(authorization, options = {}) commit(:void, :put) do |doc| add_authorization(doc, authorization) add_order(doc, options) end end - def verify(payment_method, options={}) + def verify(payment_method, options = {}) authorize(0, payment_method, options) end @@ -175,7 +177,7 @@ def add_auth_purchase(doc, money, payment_method, options) add_order(doc, options) doc.send('store-card', options[:store_card] || false) add_amount(doc, money, options) - add_fraud_info(doc, options) + add_fraud_info(doc, payment_method, options) if payment_method.is_a?(String) doc.send('vaulted-shopper-id', payment_method) @@ -188,8 +190,9 @@ def add_auth_purchase(doc, money, payment_method, options) end def add_amount(doc, money, options) - doc.amount(amount(money)) - doc.currency(options[:currency] || currency(money)) + currency = options[:currency] || currency(money) + doc.amount(localized_amount(money, currency)) + doc.currency(currency) end def add_personal_info(doc, payment_method, options) @@ -197,6 +200,7 @@ def add_personal_info(doc, payment_method, options) doc.send('last-name', payment_method.last_name) doc.send('personal-identification-number', options[:personal_identification_number]) if options[:personal_identification_number] doc.email(options[:email]) if options[:email] + doc.phone(options[:phone_number]) if options[:phone_number] add_address(doc, options) end @@ -209,12 +213,28 @@ def add_credit_card(doc, card) end end - def add_description(doc, description) + def add_metadata(doc, options) + transaction_meta_data = options[:transaction_meta_data] || [] + return if transaction_meta_data.empty? && !options[:description] + doc.send('transaction-meta-data') do - doc.send('meta-data') do - doc.send('meta-key', 'description') - doc.send('meta-value', truncate(description, 500)) - doc.send('meta-description', 'Description') + # ensure backwards compatibility for calls expecting :description + # to become meta-data fields. + if options[:description] + doc.send('meta-data') do + doc.send('meta-key', 'description') + doc.send('meta-value', truncate(options[:description], 500)) + doc.send('meta-description', 'Description') + end + end + + # https://developers.bluesnap.com/v8976-XML/docs/meta-data + transaction_meta_data.each do |entry| + doc.send('meta-data') do + doc.send('meta-key', truncate(entry[:meta_key], 40)) + doc.send('meta-value', truncate(entry[:meta_value], 500)) + doc.send('meta-description', truncate(entry[:meta_description], 40)) + end end end end @@ -222,7 +242,7 @@ def add_description(doc, description) def add_order(doc, options) doc.send('merchant-transaction-id', truncate(options[:order_id], 50)) if options[:order_id] doc.send('soft-descriptor', options[:soft_descriptor]) if options[:soft_descriptor] - add_description(doc, options[:description]) if options[:description] + add_metadata(doc, options) add_3ds(doc, options[:three_d_secure]) if options[:three_d_secure] add_level_3_data(doc, options) end @@ -233,7 +253,8 @@ def add_address(doc, options) doc.country(address[:country]) if address[:country] doc.state(address[:state]) if address[:state] && STATE_CODE_COUNTRIES.include?(address[:country]) - doc.address(address[:address]) if address[:address] + doc.address(address[:address1]) if address[:address1] + doc.address2(address[:address2]) if address[:address2] doc.city(address[:city]) if address[:city] doc.zip(address[:zip]) if address[:zip] end @@ -256,6 +277,7 @@ def add_3ds(doc, three_d_secure_options) def add_level_3_data(doc, options) return unless options[:customer_reference_number] + doc.send('level-3-data') do send_when_present(doc, :customer_reference_number, options) send_when_present(doc, :sales_tax_amount, options) @@ -273,6 +295,7 @@ def add_level_3_data(doc, options) def send_when_present(doc, options_key, options, xml_element_name = nil) return unless options[options_key] + xml_element_name ||= options_key.to_s doc.send(xml_element_name.dasherize, options[options_key]) @@ -293,9 +316,32 @@ def add_authorization(doc, authorization) doc.send('transaction-id', authorization) end - def add_fraud_info(doc, options) + def add_fraud_info(doc, payment_method, options) doc.send('transaction-fraud-info') do doc.send('shopper-ip-address', options[:ip]) if options[:ip] + if fraud_info = options[:transaction_fraud_info] + doc.send('fraud-session-id', fraud_info[:fraud_session_id]) if fraud_info[:fraud_session_id] + end + unless payment_method.is_a? String + doc.send('shipping-contact-info') do + add_shipping_contact_info(doc, payment_method, options) + end + end + end + end + + def add_shipping_contact_info(doc, payment_method, options) + if address = options[:shipping_address] + # https://developers.bluesnap.com/v8976-XML/docs/shipping-contact-info + doc.send('first-name', payment_method.first_name) + doc.send('last-name', payment_method.last_name) + + doc.country(address[:country]) if address[:country] + doc.state(address[:state]) if address[:state] && STATE_CODE_COUNTRIES.include?(address[:country]) + doc.address1(address[:address1]) if address[:address1] + doc.address2(address[:address2]) if address[:address2] + doc.city(address[:city]) if address[:city] + doc.zip(address[:zip]) if address[:zip] end end @@ -307,12 +353,10 @@ def add_alt_transaction_purchase(doc, money, payment_method_details, options) vaulted_shopper_id = payment_method_details.vaulted_shopper_id doc.send('vaulted-shopper-id', vaulted_shopper_id) if vaulted_shopper_id - if payment_method_details.check? - add_echeck_transaction(doc, payment_method_details.payment_method, options, vaulted_shopper_id.present?) - end + add_echeck_transaction(doc, payment_method_details.payment_method, options, vaulted_shopper_id.present?) if payment_method_details.check? - add_fraud_info(doc, options) - add_description(doc, options) + add_fraud_info(doc, payment_method_details.payment_method, options) + add_metadata(doc, options) end def add_echeck_transaction(doc, check, options, vaulted_shopper) @@ -347,12 +391,21 @@ def parse(response) parsed = {} doc = Nokogiri::XML(response.body) doc.root.xpath('*').each do |node| + name = node.name.downcase + if node.elements.empty? - parsed[node.name.downcase] = node.text + parsed[name] = node.text + elsif name == 'transaction-meta-data' + metadata = [] + node.elements.each { |m| + metadata.push parse_metadata_entry(m) + } + + parsed['transaction-meta-data'] = metadata else - node.elements.each do |childnode| + node.elements.each { |childnode| parse_element(parsed, childnode) - end + } end end @@ -360,6 +413,18 @@ def parse(response) parsed end + def parse_metadata_entry(node) + entry = {} + + node.elements.each { |e| + entry = entry.merge({ + e.name => e.text + }) + } + + entry + end + def parse_element(parsed, node) if !node.elements.empty? node.elements.each { |e| parse_element(parsed, e) } @@ -382,7 +447,7 @@ def commit(action, verb = :post, payment_method_details = PaymentMethodDetails.n succeeded = success_from(action, response) Response.new( succeeded, - message_from(succeeded, parsed), + message_from(succeeded, response), parsed, authorization: authorization_from(action, parsed, payment_method_details), avs_result: avs_result(parsed), @@ -414,9 +479,34 @@ def success_from(action, response) (200...300).cover?(response.code.to_i) end - def message_from(succeeded, parsed_response) + def message_from(succeeded, response) return 'Success' if succeeded - parsed_response['description'] + + parsed = parse(response) + if parsed.dig('error-name') == 'FRAUD_DETECTED' + fraud_codes_from(response) + else + parsed['description'] + end + end + + def fraud_codes_from(response) + event_summary = {} + doc = Nokogiri::XML(response.body) + fraud_events = doc.xpath('//xmlns:fraud-events', 'xmlns' => 'http://ws.plimus.com') + fraud_events.children.each do |child| + if child.children.children.any? + event_summary[child.name] = event_summary[child.name] || [] + event = {} + child.children.each do |chi| + event[chi.name] = chi.text + end + event_summary[child.name] << event + else + event_summary[child.name] = child.text + end + end + event_summary.to_json end def authorization_from(action, parsed_response, payment_method_details) @@ -425,6 +515,7 @@ def authorization_from(action, parsed_response, payment_method_details) def vaulted_shopper_id(parsed_response, payment_method_details) return nil unless parsed_response['content-location-header'] + vaulted_shopper_id = parsed_response['content-location-header'].split('/').last vaulted_shopper_id += "|#{payment_method_details.payment_method_type}" if payment_method_details.alt_transaction? vaulted_shopper_id @@ -447,7 +538,7 @@ def root_element(action, payment_method_details) def headers { 'Content-Type' => 'application/xml', - 'Authorization' => ('Basic ' + Base64.strict_encode64("#{@options[:api_username]}:#{@options[:api_password]}").strip), + 'Authorization' => ('Basic ' + Base64.strict_encode64("#{@options[:api_username]}:#{@options[:api_password]}").strip) } end diff --git a/lib/active_merchant/billing/gateways/bogus.rb b/lib/active_merchant/billing/gateways/bogus.rb index 8cafd0eeba5..9aed8028586 100644 --- a/lib/active_merchant/billing/gateways/bogus.rb +++ b/lib/active_merchant/billing/gateways/bogus.rb @@ -47,9 +47,9 @@ def credit(money, paysource, options = {}) money = amount(money) case normalize(paysource) when /1$/ - Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money}, :test => true) + Response.new(true, SUCCESS_MESSAGE, { paid_amount: money }, test: true) when /2$/ - Response.new(false, FAILURE_MESSAGE, {:paid_amount => money, :error => FAILURE_MESSAGE }, :test => true, :error_code => STANDARD_ERROR_CODE[:processing_error]) + Response.new(false, FAILURE_MESSAGE, { paid_amount: money, error: FAILURE_MESSAGE }, test: true, error_code: STANDARD_ERROR_CODE[:processing_error]) else raise Error, error_message(paysource) end @@ -61,9 +61,9 @@ def refund(money, reference, options = {}) when /1$/ raise Error, REFUND_ERROR_MESSAGE when /2$/ - Response.new(false, FAILURE_MESSAGE, {:paid_amount => money, :error => FAILURE_MESSAGE }, :test => true, :error_code => STANDARD_ERROR_CODE[:processing_error]) + Response.new(false, FAILURE_MESSAGE, { paid_amount: money, error: FAILURE_MESSAGE }, test: true, error_code: STANDARD_ERROR_CODE[:processing_error]) else - Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money}, :test => true) + Response.new(true, SUCCESS_MESSAGE, { paid_amount: money }, test: true) end end @@ -73,9 +73,9 @@ def capture(money, reference, options = {}) when /1$/ raise Error, CAPTURE_ERROR_MESSAGE when /2$/ - Response.new(false, FAILURE_MESSAGE, {:paid_amount => money, :error => FAILURE_MESSAGE }, :test => true, :error_code => STANDARD_ERROR_CODE[:processing_error]) + Response.new(false, FAILURE_MESSAGE, { paid_amount: money, error: FAILURE_MESSAGE }, test: true, error_code: STANDARD_ERROR_CODE[:processing_error]) else - Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money}, :test => true) + Response.new(true, SUCCESS_MESSAGE, { paid_amount: money }, test: true) end end @@ -84,18 +84,18 @@ def void(reference, options = {}) when /1$/ raise Error, VOID_ERROR_MESSAGE when /2$/ - Response.new(false, FAILURE_MESSAGE, {:authorization => reference, :error => FAILURE_MESSAGE }, :test => true, :error_code => STANDARD_ERROR_CODE[:processing_error]) + Response.new(false, FAILURE_MESSAGE, { authorization: reference, error: FAILURE_MESSAGE }, test: true, error_code: STANDARD_ERROR_CODE[:processing_error]) else - Response.new(true, SUCCESS_MESSAGE, {:authorization => reference}, :test => true) + Response.new(true, SUCCESS_MESSAGE, { authorization: reference }, test: true) end end def store(paysource, options = {}) case normalize(paysource) when /1$/ - Response.new(true, SUCCESS_MESSAGE, {:billingid => '1'}, :test => true, :authorization => AUTHORIZATION) + Response.new(true, SUCCESS_MESSAGE, { billingid: '1' }, test: true, authorization: AUTHORIZATION) when /2$/ - Response.new(false, FAILURE_MESSAGE, {:billingid => nil, :error => FAILURE_MESSAGE }, :test => true, :error_code => STANDARD_ERROR_CODE[:processing_error]) + Response.new(false, FAILURE_MESSAGE, { billingid: nil, error: FAILURE_MESSAGE }, test: true, error_code: STANDARD_ERROR_CODE[:processing_error]) else raise Error, error_message(paysource) end @@ -104,9 +104,9 @@ def store(paysource, options = {}) def unstore(reference, options = {}) case reference when /1$/ - Response.new(true, SUCCESS_MESSAGE, {}, :test => true) + Response.new(true, SUCCESS_MESSAGE, {}, test: true) when /2$/ - Response.new(false, FAILURE_MESSAGE, {:error => FAILURE_MESSAGE }, :test => true, :error_code => STANDARD_ERROR_CODE[:processing_error]) + Response.new(false, FAILURE_MESSAGE, { error: FAILURE_MESSAGE }, test: true, error_code: STANDARD_ERROR_CODE[:processing_error]) else raise Error, UNSTORE_ERROR_MESSAGE end @@ -118,9 +118,9 @@ def authorize_emv(money, paysource, options = {}) money = amount(money) case money when /00$/ - Response.new(true, SUCCESS_MESSAGE, {:authorized_amount => money}, :test => true, :authorization => AUTHORIZATION, :emv_authorization => AUTHORIZATION_EMV_SUCCESS) + Response.new(true, SUCCESS_MESSAGE, { authorized_amount: money }, test: true, authorization: AUTHORIZATION, emv_authorization: AUTHORIZATION_EMV_SUCCESS) when /05$/ - Response.new(false, FAILURE_MESSAGE, {:authorized_amount => money, :error => FAILURE_MESSAGE }, :test => true, :error_code => STANDARD_ERROR_CODE[:processing_error], :emv_authorization => AUTHORIZATION_EMV_DECLINE) + Response.new(false, FAILURE_MESSAGE, { authorized_amount: money, error: FAILURE_MESSAGE }, test: true, error_code: STANDARD_ERROR_CODE[:processing_error], emv_authorization: AUTHORIZATION_EMV_DECLINE) else raise Error, error_message(paysource) end @@ -130,9 +130,9 @@ def authorize_swipe(money, paysource, options = {}) money = amount(money) case normalize(paysource) when /1$/, AUTHORIZATION - Response.new(true, SUCCESS_MESSAGE, {:authorized_amount => money}, :test => true, :authorization => AUTHORIZATION) + Response.new(true, SUCCESS_MESSAGE, { authorized_amount: money }, test: true, authorization: AUTHORIZATION) when /2$/ - Response.new(false, FAILURE_MESSAGE, {:authorized_amount => money, :error => FAILURE_MESSAGE }, :test => true, :error_code => STANDARD_ERROR_CODE[:processing_error]) + Response.new(false, FAILURE_MESSAGE, { authorized_amount: money, error: FAILURE_MESSAGE }, test: true, error_code: STANDARD_ERROR_CODE[:processing_error]) else raise Error, error_message(paysource) end @@ -142,9 +142,9 @@ def purchase_emv(money, paysource, options = {}) money = amount(money) case money when /00$/ - Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money}, :test => true, :authorization => AUTHORIZATION, :emv_authorization => AUTHORIZATION_EMV_SUCCESS) + Response.new(true, SUCCESS_MESSAGE, { paid_amount: money }, test: true, authorization: AUTHORIZATION, emv_authorization: AUTHORIZATION_EMV_SUCCESS) when /05$/ - Response.new(false, FAILURE_MESSAGE, {:paid_amount => money, :error => FAILURE_MESSAGE }, :test => true, :error_code => STANDARD_ERROR_CODE[:processing_error], :emv_authorization => AUTHORIZATION_EMV_DECLINE) + Response.new(false, FAILURE_MESSAGE, { paid_amount: money, error: FAILURE_MESSAGE }, test: true, error_code: STANDARD_ERROR_CODE[:processing_error], emv_authorization: AUTHORIZATION_EMV_DECLINE) else raise Error, error_message(paysource) end @@ -154,9 +154,9 @@ def purchase_swipe(money, paysource, options = {}) money = amount(money) case normalize(paysource) when /1$/, AUTHORIZATION - Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money}, :test => true, :authorization => AUTHORIZATION) + Response.new(true, SUCCESS_MESSAGE, { paid_amount: money }, test: true, authorization: AUTHORIZATION) when /2$/ - Response.new(false, FAILURE_MESSAGE, {:paid_amount => money, :error => FAILURE_MESSAGE }, :test => true, :error_code => STANDARD_ERROR_CODE[:processing_error]) + Response.new(false, FAILURE_MESSAGE, { paid_amount: money, error: FAILURE_MESSAGE }, test: true, error_code: STANDARD_ERROR_CODE[:processing_error]) else raise Error, error_message(paysource) end diff --git a/lib/active_merchant/billing/gateways/borgun.rb b/lib/active_merchant/billing/gateways/borgun.rb index b949144fcfb..80ac3ca4f57 100644 --- a/lib/active_merchant/billing/gateways/borgun.rb +++ b/lib/active_merchant/billing/gateways/borgun.rb @@ -9,19 +9,19 @@ class BorgunGateway < Gateway self.test_url = 'https://gatewaytest.borgun.is/ws/Heimir.pub.ws:Authorization' self.live_url = 'https://gateway01.borgun.is/ws/Heimir.pub.ws:Authorization' - self.supported_countries = ['IS', 'GB', 'HU', 'CZ', 'DE', 'DK', 'SE' ] + self.supported_countries = %w[IS GB HU CZ DE DK SE] self.default_currency = 'ISK' self.money_format = :cents - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :discover, :jcb] + self.supported_cardtypes = %i[visa master american_express diners_club discover jcb] self.homepage_url = 'https://www.borgun.is/' - def initialize(options={}) + def initialize(options = {}) requires!(options, :processor, :merchant_id, :username, :password) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) post = {} post[:TransType] = '1' add_invoice(post, money, options) @@ -29,15 +29,15 @@ def purchase(money, payment, options={}) commit('sale', post) end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) post = {} post[:TransType] = '5' add_invoice(post, money, options) add_payment_method(post, payment) - commit('authonly', post) + commit('authonly', post, options) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) post = {} post[:TransType] = '1' add_invoice(post, money, options) @@ -45,7 +45,7 @@ def capture(money, authorization, options={}) commit('capture', post) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) post = {} post[:TransType] = '3' add_invoice(post, money, options) @@ -53,7 +53,7 @@ def refund(money, authorization, options={}) commit('refund', post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} # TransType, TrAmount, and currency must match original values from auth or purchase. _, _, _, _, _, transtype, tramount, currency = split_authorization(authorization) @@ -76,7 +76,7 @@ def scrub(transcript) private - CURRENCY_CODES = Hash.new { |h, k| raise ArgumentError.new("Unsupported currency for HDFC: #{k}") } + CURRENCY_CODES = Hash.new { |_h, k| raise ArgumentError.new("Unsupported currency for HDFC: #{k}") } CURRENCY_CODES['ISK'] = '352' CURRENCY_CODES['EUR'] = '978' CURRENCY_CODES['USD'] = '840' @@ -96,7 +96,7 @@ def add_payment_method(post, payment_method) end def add_reference(post, authorization) - dateandtime, _batch, transaction, rrn, authcode, _, _, _ = split_authorization(authorization) + dateandtime, _batch, transaction, rrn, authcode, = split_authorization(authorization) post[:DateAndTime] = dateandtime post[:Transaction] = transaction post[:RRN] = rrn @@ -125,12 +125,12 @@ def parse(xml) response end - def commit(action, post) + def commit(action, post, options = {}) post[:Version] = '1000' post[:Processor] = @options[:processor] post[:MerchantID] = @options[:merchant_id] - request = build_request(action, post) + request = build_request(action, post, options) raw = ssl_post(url(action), request, headers) pairs = parse(raw) success = success_from(pairs) @@ -176,25 +176,36 @@ def split_authorization(authorization) def headers { - 'Authorization' => 'Basic ' + Base64.strict_encode64(@options[:username].to_s + ':' + @options[:password].to_s), + 'Authorization' => 'Basic ' + Base64.strict_encode64(@options[:username].to_s + ':' + @options[:password].to_s) } end - def build_request(action, post) + def build_request(action, post, options = {}) mode = action == 'void' ? 'cancel' : 'get' - xml = Builder::XmlMarkup.new :indent => 18 - xml.instruct!(:xml, :version => '1.0', :encoding => 'utf-8') + xml = Builder::XmlMarkup.new indent: 18 + xml.instruct!(:xml, version: '1.0', encoding: 'utf-8') xml.tag!("#{mode}Authorization") do post.each do |field, value| xml.tag!(field, value) end + build_airline_xml(xml, options[:passenger_itinerary_data]) if options[:passenger_itinerary_data] end inner = CGI.escapeHTML(xml.target!) envelope(mode).sub(/{{ :body }}/, inner) end + def build_airline_xml(xml, airline_data) + xml.tag!('PassengerItineraryData') do + xml.tag!('A1') do + airline_data.each do |field, value| + xml.tag!(field, value) + end + end + end + end + def envelope(mode) - <<-EOS + <<-XML @@ -205,7 +216,7 @@ def envelope(mode) - EOS + XML end def url(action) diff --git a/lib/active_merchant/billing/gateways/bpoint.rb b/lib/active_merchant/billing/gateways/bpoint.rb index 320e024a03b..d8fa40783f9 100644 --- a/lib/active_merchant/billing/gateways/bpoint.rb +++ b/lib/active_merchant/billing/gateways/bpoint.rb @@ -7,17 +7,17 @@ class BpointGateway < Gateway self.supported_countries = ['AU'] self.default_currency = 'AUD' - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club] + self.supported_cardtypes = %i[visa master american_express diners_club] self.homepage_url = 'https://www.bpoint.com.au/bpoint' self.display_name = 'BPoint' - def initialize(options={}) + def initialize(options = {}) requires!(options, :username, :password, :merchant_number) super end - def store(credit_card, options={}) + def store(credit_card, options = {}) options[:crn1] ||= 'DEFAULT' request_body = soap_request do |xml| add_token(xml, credit_card, options) @@ -25,7 +25,7 @@ def store(credit_card, options={}) commit(request_body) end - def purchase(amount, credit_card, options={}) + def purchase(amount, credit_card, options = {}) request_body = soap_request do |xml| process_payment(xml) do |payment_xml| add_purchase(payment_xml, amount, credit_card, options) @@ -34,7 +34,7 @@ def purchase(amount, credit_card, options={}) commit(request_body) end - def authorize(amount, credit_card, options={}) + def authorize(amount, credit_card, options = {}) request_body = soap_request do |xml| process_payment(xml) do |payment_xml| add_authorize(payment_xml, amount, credit_card, options) @@ -43,7 +43,7 @@ def authorize(amount, credit_card, options={}) commit(request_body) end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) request_body = soap_request do |xml| process_payment(xml) do |payment_xml| add_capture(payment_xml, amount, authorization, options) @@ -52,7 +52,7 @@ def capture(amount, authorization, options={}) commit(request_body) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) request_body = soap_request do |xml| process_payment(xml) do |payment_xml| add_refund(payment_xml, amount, authorization, options) @@ -61,19 +61,19 @@ def refund(amount, authorization, options={}) commit(request_body) end - def void(amount, authorization, options={}) + def void(authorization, options = {}) request_body = soap_request do |xml| process_payment(xml) do |payment_xml| - add_void(payment_xml, amount, authorization, options) + add_void(payment_xml, authorization, options) end end commit(request_body) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } - r.process(:ignore_result) { void(100, r.authorization, options) } + r.process(:ignore_result) { void(r.authorization, options.merge(amount: 100)) } end end @@ -91,7 +91,7 @@ def scrub(transcript) private def soap_request - Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml| + Nokogiri::XML::Builder.new(encoding: 'utf-8') do |xml| xml.send('soap12:Envelope', soap_envelope_attributes) { xml.send('soap12:Body') { yield(xml) if block_given? @@ -154,7 +154,9 @@ def add_refund(xml, amount, transaction_number, options) transaction_number_xml(xml, transaction_number) end - def add_void(xml, amount, transaction_number, options) + def add_void(xml, transaction_number, options) + # The amount parameter is required for void requests on BPoint. + amount = options[:amount] payment_xml(xml, 'REVERSAL', amount, options) transaction_number_xml(xml, transaction_number) end @@ -240,7 +242,6 @@ def options end class ProcessPaymentResponse < BPointResponse - private def authorization_key @@ -257,7 +258,6 @@ def message end class AddTokenResponse < BPointResponse - private def authorization_key diff --git a/lib/active_merchant/billing/gateways/braintree.rb b/lib/active_merchant/billing/gateways/braintree.rb index bfe682c31db..c3008feb70a 100644 --- a/lib/active_merchant/billing/gateways/braintree.rb +++ b/lib/active_merchant/billing/gateways/braintree.rb @@ -7,7 +7,7 @@ class BraintreeGateway < Gateway self.abstract_class = true - def self.new(options={}) + def self.new(options = {}) if options.has_key?(:login) BraintreeOrangeGateway.new(options) else diff --git a/lib/active_merchant/billing/gateways/braintree/braintree_common.rb b/lib/active_merchant/billing/gateways/braintree/braintree_common.rb index 7343584f7aa..f6b5560f008 100644 --- a/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +++ b/lib/active_merchant/billing/gateways/braintree/braintree_common.rb @@ -1,7 +1,7 @@ module BraintreeCommon def self.included(base) base.supported_countries = %w(US CA AD AT BE BG HR CY CZ DK EE FI FR GI DE GR GG HU IS IM IE IT JE LV LI LT LU MT MC NL NO PL PT RO SM SK SI ES SE CH TR GB SG HK MY AU NZ) - base.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club, :maestro] + base.supported_cardtypes = %i[visa master american_express discover jcb diners_club maestro] base.homepage_url = 'http://www.braintreepaymentsolutions.com' base.display_name = 'Braintree' base.default_currency = 'USD' @@ -14,6 +14,7 @@ def supports_scrubbing def scrub(transcript) return '' if transcript.blank? + transcript. gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]'). gsub(%r((&?ccnumber=)\d*(&?)), '\1[FILTERED]\2'). diff --git a/lib/active_merchant/billing/gateways/braintree_blue.rb b/lib/active_merchant/billing/gateways/braintree_blue.rb index 463c7ac2b5f..e986962eb30 100644 --- a/lib/active_merchant/billing/gateways/braintree_blue.rb +++ b/lib/active_merchant/billing/gateways/braintree_blue.rb @@ -1,4 +1,5 @@ require 'active_merchant/billing/gateways/braintree/braintree_common' +require 'active_support/core_ext/array/extract_options' begin require 'braintree' @@ -6,9 +7,7 @@ raise 'Could not load the braintree gem. Use `gem install braintree` to install it.' end -unless Braintree::Version::Major == 2 && Braintree::Version::Minor >= 78 - raise "Need braintree gem >= 2.78.0. Run `gem install braintree --version '~>2.78'` to get the correct version." -end +raise "Need braintree gem >= 2.78.0. Run `gem install braintree --version '~>2.78'` to get the correct version." unless Braintree::Version::Major == 2 && Braintree::Version::Minor >= 78 module ActiveMerchant #:nodoc: module Billing #:nodoc: @@ -62,12 +61,12 @@ def initialize(options = {}) end @configuration = Braintree::Configuration.new( - :merchant_id => options[:merchant_id], - :public_key => options[:public_key], - :private_key => options[:private_key], - :environment => (options[:environment] || (test? ? :sandbox : :production)).to_sym, - :custom_user_agent => "ActiveMerchant #{ActiveMerchant::VERSION}", - :logger => options[:logger] || logger + merchant_id: options[:merchant_id], + public_key: options[:public_key], + private_key: options[:private_key], + environment: (options[:environment] || (test? ? :sandbox : :production)).to_sym, + custom_user_agent: "ActiveMerchant #{ActiveMerchant::VERSION}", + logger: options[:logger] || logger ) @braintree_gateway = Braintree::Gateway.new(@configuration) @@ -85,7 +84,7 @@ def capture(money, authorization, options = {}) end def purchase(money, credit_card_or_vault_id, options = {}) - authorize(money, credit_card_or_vault_id, options.merge(:submit_for_settlement => true)) + authorize(money, credit_card_or_vault_id, options.merge(submit_for_settlement: true)) end def credit(money, credit_card_or_vault_id, options = {}) @@ -100,10 +99,13 @@ def refund(*args) commit do response = response_from_result(@braintree_gateway.transaction.refund(transaction_id, money)) - return response if response.success? - return response unless options[:force_full_refund_if_unsettled] - void(transaction_id) if response.message =~ /#{ERROR_CODES[:cannot_refund_if_unsettled]}/ + if !response.success? && options[:force_full_refund_if_unsettled] && + response.message =~ /#{ERROR_CODES[:cannot_refund_if_unsettled]}/ + void(transaction_id) + else + response + end end end @@ -146,33 +148,31 @@ def update(vault_id, creditcard, options = {}) options[:update_existing_token] = braintree_credit_card.token credit_card_params = merge_credit_card_options({ - :credit_card => { - :cardholder_name => creditcard.name, - :number => creditcard.number, - :cvv => creditcard.verification_value, - :expiration_month => creditcard.month.to_s.rjust(2, '0'), - :expiration_year => creditcard.year.to_s + credit_card: { + cardholder_name: creditcard.name, + number: creditcard.number, + cvv: creditcard.verification_value, + expiration_month: creditcard.month.to_s.rjust(2, '0'), + expiration_year: creditcard.year.to_s } }, options)[:credit_card] result = @braintree_gateway.customer.update(vault_id, - :first_name => creditcard.first_name, - :last_name => creditcard.last_name, - :email => scrub_email(options[:email]), - :phone => options[:phone] || (options[:billing_address][:phone] if options[:billing_address] && + first_name: creditcard.first_name, + last_name: creditcard.last_name, + email: scrub_email(options[:email]), + phone: options[:phone] || (options[:billing_address][:phone] if options[:billing_address] && options[:billing_address][:phone]), - :credit_card => credit_card_params - ) + credit_card: credit_card_params) Response.new(result.success?, message_from_result(result), - :braintree_customer => (customer_hash(@braintree_gateway.customer.find(vault_id), :include_credit_cards) if result.success?), - :customer_vault_id => (result.customer.id if result.success?) - ) + braintree_customer: (customer_hash(@braintree_gateway.customer.find(vault_id), :include_credit_cards) if result.success?), + customer_vault_id: (result.customer.id if result.success?)) end end def unstore(customer_vault_id, options = {}) commit do - if(!customer_vault_id && options[:credit_card_token]) + if !customer_vault_id && options[:credit_card_token] @braintree_gateway.credit_card.delete(options[:credit_card_token]) else @braintree_gateway.customer.delete(customer_vault_id) @@ -180,7 +180,7 @@ def unstore(customer_vault_id, options = {}) Response.new(true, 'OK') end end - alias_method :delete, :unstore + alias delete unstore def supports_network_tokenization? true @@ -202,12 +202,10 @@ def verify_credentials def check_customer_exists(customer_vault_id) commit do - begin - @braintree_gateway.customer.find(customer_vault_id) - ActiveMerchant::Billing::Response.new(true, 'Customer found', {exists: true}, authorization: customer_vault_id) - rescue Braintree::NotFoundError - ActiveMerchant::Billing::Response.new(true, 'Customer not found', {exists: false}) - end + @braintree_gateway.customer.find(customer_vault_id) + ActiveMerchant::Billing::Response.new(true, 'Customer found', { exists: true }, authorization: customer_vault_id) + rescue Braintree::NotFoundError + ActiveMerchant::Billing::Response.new(true, 'Customer not found', { exists: false }) end end @@ -217,34 +215,33 @@ def add_customer_with_credit_card(creditcard, options) credit_card_params = { payment_method_nonce: options[:payment_method_nonce] } else credit_card_params = { - :credit_card => { - :cardholder_name => creditcard.name, - :number => creditcard.number, - :cvv => creditcard.verification_value, - :expiration_month => creditcard.month.to_s.rjust(2, '0'), - :expiration_year => creditcard.year.to_s, - :token => options[:credit_card_token] + credit_card: { + cardholder_name: creditcard.name, + number: creditcard.number, + cvv: creditcard.verification_value, + expiration_month: creditcard.month.to_s.rjust(2, '0'), + expiration_year: creditcard.year.to_s, + token: options[:credit_card_token] } } end parameters = { - :first_name => creditcard.first_name, - :last_name => creditcard.last_name, - :email => scrub_email(options[:email]), - :phone => options[:phone] || (options[:billing_address][:phone] if options[:billing_address] && + first_name: creditcard.first_name, + last_name: creditcard.last_name, + email: scrub_email(options[:email]), + phone: options[:phone] || (options[:billing_address][:phone] if options[:billing_address] && options[:billing_address][:phone]), - :id => options[:customer], - :device_data => options[:device_data], + id: options[:customer], + device_data: options[:device_data] }.merge credit_card_params result = @braintree_gateway.customer.create(merge_credit_card_options(parameters, options)) Response.new(result.success?, message_from_result(result), { - :braintree_customer => (customer_hash(result.customer, :include_credit_cards) if result.success?), - :customer_vault_id => (result.customer.id if result.success?), - :credit_card_token => (result.customer.credit_cards[0].token if result.success?) + braintree_customer: (customer_hash(result.customer, :include_credit_cards) if result.success?), + customer_vault_id: (result.customer.id if result.success?), + credit_card_token: (result.customer.credit_cards[0].token if result.success?) }, - :authorization => (result.customer.id if result.success?) - ) + authorization: (result.customer.id if result.success?)) end end @@ -258,11 +255,11 @@ def add_credit_card_to_customer(credit_card, options) cvv: credit_card.verification_value, expiration_month: credit_card.month.to_s.rjust(2, '0'), expiration_year: credit_card.year.to_s, - device_data: options[:device_data], + device_data: options[:device_data] } if options[:billing_address] address = map_address(options[:billing_address]) - parameters[:credit_card][:billing_address] = address unless address.all? { |_k, v| empty?(v) } + parameters[:billing_address] = address unless address.all? { |_k, v| empty?(v) } end result = @braintree_gateway.credit_card.create(parameters) @@ -289,22 +286,20 @@ def scrub_email(email) def scrub_zip(zip) return nil unless zip.present? - return nil if( + return nil if zip.gsub(/[^a-z0-9]/i, '').length > 9 || zip =~ /[^a-z0-9\- ]/i - ) + zip end def merge_credit_card_options(parameters, options) valid_options = {} options.each do |key, value| - valid_options[key] = value if [:update_existing_token, :verify_card, :verification_merchant_account_id].include?(key) + valid_options[key] = value if %i[update_existing_token verify_card verification_merchant_account_id].include?(key) end - if valid_options.include?(:verify_card) && @merchant_account_id - valid_options[:verification_merchant_account_id] ||= @merchant_account_id - end + valid_options[:verification_merchant_account_id] ||= @merchant_account_id if valid_options.include?(:verify_card) && @merchant_account_id parameters[:credit_card] ||= {} parameters[:credit_card][:options] = valid_options @@ -317,20 +312,18 @@ def merge_credit_card_options(parameters, options) def map_address(address) mapped = { - :street_address => address[:address1], - :extended_address => address[:address2], - :company => address[:company], - :locality => address[:city], - :region => address[:state], - :postal_code => scrub_zip(address[:zip]), + street_address: address[:address1], + extended_address: address[:address2], + company: address[:company], + locality: address[:city], + region: address[:state], + postal_code: scrub_zip(address[:zip]) } mapped[:country_code_alpha2] = (address[:country] || address[:country_code_alpha2]) if address[:country] || address[:country_code_alpha2] mapped[:country_name] = address[:country_name] if address[:country_name] mapped[:country_code_alpha3] = address[:country_code_alpha3] if address[:country_code_alpha3] - unless address[:country].blank? - mapped[:country_code_alpha3] ||= Country.find(address[:country]).code(:alpha3).value - end + mapped[:country_code_alpha3] ||= Country.find(address[:country]).code(:alpha3).value unless address[:country].blank? mapped[:country_code_numeric] = address[:country_code_numeric] if address[:country_code_numeric] mapped @@ -468,7 +461,7 @@ def extract_refund_args(args) end end - def customer_hash(customer, include_credit_cards=false) + def customer_hash(customer, include_credit_cards = false) hash = { 'email' => customer.email, 'phone' => customer.phone, @@ -494,9 +487,7 @@ def customer_hash(customer, include_credit_cards=false) end def transaction_hash(result) - unless result.success? - return { 'processor_response_code' => response_code_from_result(result) } - end + return { 'processor_response_code' => response_code_from_result(result) } unless result.success? transaction = result.transaction if transaction.vault_customer @@ -514,7 +505,7 @@ def transaction_hash(result) customer_details = { 'id' => transaction.customer_details.id, 'email' => transaction.customer_details.email, - 'phone' => transaction.customer_details.phone, + 'phone' => transaction.customer_details.phone } billing_details = { @@ -524,7 +515,7 @@ def transaction_hash(result) 'locality' => transaction.billing_details.locality, 'region' => transaction.billing_details.region, 'postal_code' => transaction.billing_details.postal_code, - 'country_name' => transaction.billing_details.country_name, + 'country_name' => transaction.billing_details.country_name } shipping_details = { @@ -534,7 +525,7 @@ def transaction_hash(result) 'locality' => transaction.shipping_details.locality, 'region' => transaction.shipping_details.region, 'postal_code' => transaction.shipping_details.postal_code, - 'country_name' => transaction.shipping_details.country_name, + 'country_name' => transaction.shipping_details.country_name } credit_card_details = { 'masked_number' => transaction.credit_card_details.masked_number, @@ -573,80 +564,136 @@ def transaction_hash(result) def create_transaction_parameters(money, credit_card_or_vault_id, options) parameters = { - :amount => localized_amount(money, options[:currency] || default_currency).to_s, - :order_id => options[:order_id], - :customer => { - :id => options[:store] == true ? '' : options[:store], - :email => scrub_email(options[:email]), - :phone => options[:phone] || (options[:billing_address][:phone] if options[:billing_address] && + amount: localized_amount(money, options[:currency] || default_currency).to_s, + order_id: options[:order_id], + customer: { + id: options[:store] == true ? '' : options[:store], + email: scrub_email(options[:email]), + phone: options[:phone] || (options[:billing_address][:phone] if options[:billing_address] && options[:billing_address][:phone]) }, - :options => { - :store_in_vault => options[:store] ? true : false, - :submit_for_settlement => options[:submit_for_settlement], - :hold_in_escrow => options[:hold_in_escrow], + options: { + store_in_vault: options[:store] ? true : false, + submit_for_settlement: options[:submit_for_settlement], + hold_in_escrow: options[:hold_in_escrow] } } - if options[:skip_advanced_fraud_checking] - parameters[:options][:skip_advanced_fraud_checking] = options[:skip_advanced_fraud_checking] - end - - if options[:skip_avs] - parameters[:options][:skip_avs] = options[:skip_avs] - end - - if options[:skip_cvv] - parameters[:options][:skip_cvv] = options[:skip_cvv] - end - parameters[:custom_fields] = options[:custom_fields] parameters[:device_data] = options[:device_data] if options[:device_data] parameters[:service_fee_amount] = options[:service_fee_amount] if options[:service_fee_amount] - if merchant_account_id = (options[:merchant_account_id] || @merchant_account_id) - parameters[:merchant_account_id] = merchant_account_id - end - if options[:transaction_source] - parameters[:transaction_source] = options[:transaction_source] - elsif options[:recurring] - parameters[:recurring] = true - end + add_account_type(parameters, options) if options[:account_type] + add_skip_options(parameters, options) + add_merchant_account_id(parameters, options) add_payment_method(parameters, credit_card_or_vault_id, options) add_stored_credential_data(parameters, credit_card_or_vault_id, options) + add_addresses(parameters, options) + + add_descriptor(parameters, options) + add_travel_data(parameters, options) if options[:travel_data] + add_lodging_data(parameters, options) if options[:lodging_data] + add_channel(parameters, options) + add_transaction_source(parameters, options) + + add_level_2_data(parameters, options) + add_level_3_data(parameters, options) + + add_3ds_info(parameters, options[:three_d_secure]) + + if options[:payment_method_nonce].is_a?(String) + parameters.delete(:customer) + parameters[:payment_method_nonce] = options[:payment_method_nonce] + end + + parameters + end + + def add_account_type(parameters, options) + parameters[:options][:credit_card] = {} + parameters[:options][:credit_card][:account_type] = options[:account_type] + end + def add_skip_options(parameters, options) + parameters[:options][:skip_advanced_fraud_checking] = options[:skip_advanced_fraud_checking] if options[:skip_advanced_fraud_checking] + parameters[:options][:skip_avs] = options[:skip_avs] if options[:skip_avs] + parameters[:options][:skip_cvv] = options[:skip_cvv] if options[:skip_cvv] + end + + def add_merchant_account_id(parameters, options) + return unless merchant_account_id = (options[:merchant_account_id] || @merchant_account_id) + + parameters[:merchant_account_id] = merchant_account_id + end + + def add_transaction_source(parameters, options) + parameters[:transaction_source] = options[:transaction_source] if options[:transaction_source] + parameters[:transaction_source] = 'recurring' if options[:recurring] + end + + def add_addresses(parameters, options) parameters[:billing] = map_address(options[:billing_address]) if options[:billing_address] parameters[:shipping] = map_address(options[:shipping_address]) if options[:shipping_address] + end + def add_channel(parameters, options) channel = @options[:channel] || application_id parameters[:channel] = channel if channel + end - if options[:descriptor_name] || options[:descriptor_phone] || options[:descriptor_url] - parameters[:descriptor] = { - name: options[:descriptor_name], - phone: options[:descriptor_phone], - url: options[:descriptor_url] - } - end + def add_descriptor(parameters, options) + return unless options[:descriptor_name] || options[:descriptor_phone] || options[:descriptor_url] - add_3ds_info(parameters, options[:three_d_secure]) + parameters[:descriptor] = { + name: options[:descriptor_name], + phone: options[:descriptor_phone], + url: options[:descriptor_url] + } + end + def add_level_2_data(parameters, options) parameters[:tax_amount] = options[:tax_amount] if options[:tax_amount] parameters[:tax_exempt] = options[:tax_exempt] if options[:tax_exempt] parameters[:purchase_order_number] = options[:purchase_order_number] if options[:purchase_order_number] + end + def add_level_3_data(parameters, options) parameters[:shipping_amount] = options[:shipping_amount] if options[:shipping_amount] parameters[:discount_amount] = options[:discount_amount] if options[:discount_amount] parameters[:ships_from_postal_code] = options[:ships_from_postal_code] if options[:ships_from_postal_code] parameters[:line_items] = options[:line_items] if options[:line_items] + end - parameters + def add_travel_data(parameters, options) + parameters[:industry] = { + industry_type: Braintree::Transaction::IndustryType::TravelAndCruise, + data: {} + } + + parameters[:industry][:data][:travel_package] = options[:travel_data][:travel_package] if options[:travel_data][:travel_package] + parameters[:industry][:data][:departure_date] = options[:travel_data][:departure_date] if options[:travel_data][:departure_date] + parameters[:industry][:data][:lodging_check_in_date] = options[:travel_data][:lodging_check_in_date] if options[:travel_data][:lodging_check_in_date] + parameters[:industry][:data][:lodging_check_out_date] = options[:travel_data][:lodging_check_out_date] if options[:travel_data][:lodging_check_out_date] + parameters[:industry][:data][:lodging_name] = options[:travel_data][:lodging_name] if options[:travel_data][:lodging_name] + end + + def add_lodging_data(parameters, options) + parameters[:industry] = { + industry_type: Braintree::Transaction::IndustryType::Lodging, + data: {} + } + + parameters[:industry][:data][:folio_number] = options[:lodging_data][:folio_number] if options[:lodging_data][:folio_number] + parameters[:industry][:data][:check_in_date] = options[:lodging_data][:check_in_date] if options[:lodging_data][:check_in_date] + parameters[:industry][:data][:check_out_date] = options[:lodging_data][:check_out_date] if options[:lodging_data][:check_out_date] + parameters[:industry][:data][:room_rate] = options[:lodging_data][:room_rate] if options[:lodging_data][:room_rate] end def add_3ds_info(parameters, three_d_secure_opts) return if empty?(three_d_secure_opts) + pass_thru = {} pass_thru[:three_d_secure_version] = three_d_secure_opts[:version] if three_d_secure_opts[:version] @@ -669,6 +716,7 @@ def xid_or_ds_trans_id(three_d_secure_opts) def add_stored_credential_data(parameters, credit_card_or_vault_id, options) return unless (stored_credential = options[:stored_credential]) + parameters[:external_vault] = {} if stored_credential[:initial_transaction] parameters[:external_vault][:status] = 'will_vault' @@ -699,38 +747,38 @@ def add_payment_method(parameters, credit_card_or_vault_id, options) end else parameters[:customer].merge!( - :first_name => credit_card_or_vault_id.first_name, - :last_name => credit_card_or_vault_id.last_name + first_name: credit_card_or_vault_id.first_name, + last_name: credit_card_or_vault_id.last_name ) if credit_card_or_vault_id.is_a?(NetworkTokenizationCreditCard) if credit_card_or_vault_id.source == :apple_pay parameters[:apple_pay_card] = { - :number => credit_card_or_vault_id.number, - :expiration_month => credit_card_or_vault_id.month.to_s.rjust(2, '0'), - :expiration_year => credit_card_or_vault_id.year.to_s, - :cardholder_name => credit_card_or_vault_id.name, - :cryptogram => credit_card_or_vault_id.payment_cryptogram, - :eci_indicator => credit_card_or_vault_id.eci + number: credit_card_or_vault_id.number, + expiration_month: credit_card_or_vault_id.month.to_s.rjust(2, '0'), + expiration_year: credit_card_or_vault_id.year.to_s, + cardholder_name: credit_card_or_vault_id.name, + cryptogram: credit_card_or_vault_id.payment_cryptogram, + eci_indicator: credit_card_or_vault_id.eci } elsif credit_card_or_vault_id.source == :android_pay || credit_card_or_vault_id.source == :google_pay parameters[:android_pay_card] = { - :number => credit_card_or_vault_id.number, - :cryptogram => credit_card_or_vault_id.payment_cryptogram, - :expiration_month => credit_card_or_vault_id.month.to_s.rjust(2, '0'), - :expiration_year => credit_card_or_vault_id.year.to_s, - :google_transaction_id => credit_card_or_vault_id.transaction_id, - :source_card_type => credit_card_or_vault_id.brand, - :source_card_last_four => credit_card_or_vault_id.last_digits, - :eci_indicator => credit_card_or_vault_id.eci + number: credit_card_or_vault_id.number, + cryptogram: credit_card_or_vault_id.payment_cryptogram, + expiration_month: credit_card_or_vault_id.month.to_s.rjust(2, '0'), + expiration_year: credit_card_or_vault_id.year.to_s, + google_transaction_id: credit_card_or_vault_id.transaction_id, + source_card_type: credit_card_or_vault_id.brand, + source_card_last_four: credit_card_or_vault_id.last_digits, + eci_indicator: credit_card_or_vault_id.eci } end else parameters[:credit_card] = { - :number => credit_card_or_vault_id.number, - :cvv => credit_card_or_vault_id.verification_value, - :expiration_month => credit_card_or_vault_id.month.to_s.rjust(2, '0'), - :expiration_year => credit_card_or_vault_id.year.to_s, - :cardholder_name => credit_card_or_vault_id.name + number: credit_card_or_vault_id.number, + cvv: credit_card_or_vault_id.verification_value, + expiration_month: credit_card_or_vault_id.month.to_s.rjust(2, '0'), + expiration_year: credit_card_or_vault_id.year.to_s, + cardholder_name: credit_card_or_vault_id.name } end end diff --git a/lib/active_merchant/billing/gateways/bridge_pay.rb b/lib/active_merchant/billing/gateways/bridge_pay.rb index d8cf6218265..7c306842099 100644 --- a/lib/active_merchant/billing/gateways/bridge_pay.rb +++ b/lib/active_merchant/billing/gateways/bridge_pay.rb @@ -9,16 +9,16 @@ class BridgePayGateway < Gateway self.test_url = 'https://gatewaystage.itstgate.com/SmartPayments/transact3.asmx' self.live_url = 'https://gateway.itstgate.com/SmartPayments/transact3.asmx' - self.supported_countries = ['CA', 'US'] + self.supported_countries = %w[CA US] self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb] + self.supported_cardtypes = %i[visa master american_express discover diners_club jcb] - def initialize(options={}) + def initialize(options = {}) requires!(options, :user_name, :password) super end - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) post = initialize_required_fields('Sale') # Allow the same amount in multiple transactions. @@ -30,7 +30,7 @@ def purchase(amount, payment_method, options={}) commit(post) end - def authorize(amount, payment_method, options={}) + def authorize(amount, payment_method, options = {}) post = initialize_required_fields('Auth') add_invoice(post, amount, options) @@ -40,7 +40,7 @@ def authorize(amount, payment_method, options={}) commit(post) end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) post = initialize_required_fields('Force') add_invoice(post, amount, options) @@ -50,7 +50,7 @@ def capture(amount, authorization, options={}) commit(post) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) post = initialize_required_fields('Return') add_invoice(post, amount, options) @@ -59,7 +59,7 @@ def refund(amount, authorization, options={}) commit(post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = initialize_required_fields('Void') add_reference(post, authorization) @@ -74,10 +74,10 @@ def verify(creditcard, options = {}) end end - def store(creditcard, options={}) + def store(creditcard, options = {}) post = initialize_required_fields('') post[:transaction] = 'Create' - post[:CardNumber] = creditcard.number + post[:CardNumber] = creditcard.number post[:CustomerPaymentInfoKey] = '' post[:token] = '' add_payment_method(post, creditcard) @@ -147,7 +147,7 @@ def initialize_required_fields(transaction_type) end def add_customer_data(post, options) - if(billing_address = (options[:billing_address] || options[:address])) + if (billing_address = (options[:billing_address] || options[:address])) post[:Street] = billing_address[:address1] post[:Zip] = billing_address[:zip] end @@ -235,8 +235,8 @@ def add_reference(post, authorization) def post_data(post) { - :UserName => @options[:user_name], - :Password => @options[:password] + UserName: @options[:user_name], + Password: @options[:password] }.merge(post).collect { |k, v| "#{k}=#{CGI.escape(v.to_s)}" }.join('&') end end diff --git a/lib/active_merchant/billing/gateways/cams.rb b/lib/active_merchant/billing/gateways/cams.rb index 4fd30dd0489..75eb07cde8d 100644 --- a/lib/active_merchant/billing/gateways/cams.rb +++ b/lib/active_merchant/billing/gateways/cams.rb @@ -5,7 +5,7 @@ class CamsGateway < Gateway self.supported_countries = ['US'] self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'https://www.centralams.com/' self.display_name = 'CAMS: Central Account Management System' @@ -67,12 +67,12 @@ class CamsGateway < Gateway '894' => STANDARD_ERROR_CODE[:processing_error] } - def initialize(options={}) + def initialize(options = {}) requires!(options, :username, :password) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) post = {} add_invoice(post, money, options) @@ -86,7 +86,7 @@ def purchase(money, payment, options={}) commit('sale', post) end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) post = {} add_invoice(post, money, options) add_payment(post, payment) @@ -95,7 +95,7 @@ def authorize(money, payment, options={}) commit('auth', post) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) post = {} add_reference(post, authorization) add_invoice(post, money, options) @@ -103,20 +103,20 @@ def capture(money, authorization, options={}) commit('capture', post) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) post = {} add_reference(post, authorization) add_invoice(post, money, options) commit('refund', post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} add_reference(post, authorization) commit('void', post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) post = {} add_invoice(post, 0, options) add_payment(post, credit_card) @@ -138,7 +138,7 @@ def scrub(transcript) private - def add_address(post, creditcard, options={}) + def add_address(post, creditcard, options = {}) post[:firstname] = creditcard.first_name post[:lastname] = creditcard.last_name @@ -167,7 +167,7 @@ def add_invoice(post, money, options) def add_payment(post, payment) post[:ccnumber] = payment.number - post[:ccexp] = "#{payment.month.to_s.rjust(2, "0")}#{payment.year.to_s[-2..-1]}" + post[:ccexp] = "#{payment.month.to_s.rjust(2, '0')}#{payment.year.to_s[-2..-1]}" post[:cvv] = payment.verification_value end diff --git a/lib/active_merchant/billing/gateways/card_connect.rb b/lib/active_merchant/billing/gateways/card_connect.rb index 4d953f0a6dd..fe131465e86 100644 --- a/lib/active_merchant/billing/gateways/card_connect.rb +++ b/lib/active_merchant/billing/gateways/card_connect.rb @@ -6,7 +6,7 @@ class CardConnectGateway < Gateway self.supported_countries = ['US'] self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'https://cardconnect.com/' self.display_name = 'Card Connect' @@ -69,7 +69,7 @@ def initialize(options = {}) def require_valid_domain!(options, param) if options[param] - raise ArgumentError.new('not a valid cardconnect domain') unless /\Dcardconnect.com:\d{1,}\D/ =~ options[param] + raise ArgumentError.new('not a valid cardconnect domain') unless /https:\/\/\D*cardconnect.com/ =~ options[param] end end @@ -88,6 +88,7 @@ def purchase(money, payment, options = {}) add_address(post, options) add_customer_data(post, options) add_3DS(post, options) + add_additional_data(post, options) post[:capture] = 'Y' commit('auth', post) end @@ -102,6 +103,7 @@ def authorize(money, payment, options = {}) add_address(post, options) add_customer_data(post, options) add_3DS(post, options) + add_additional_data(post, options) commit('auth', post) end @@ -231,11 +233,12 @@ def add_additional_data(post, options) post[:items] = options[:items].map do |item| updated = {} item.each_pair do |k, v| - updated.merge!(k.to_s.gsub(/_/, '') => v) + updated.merge!(k.to_s.delete('_') => v) end updated end end + post[:userfields] = options[:user_fields] if options[:user_fields] end def add_3DS(post, options) @@ -284,7 +287,8 @@ def commit(action, parameters, verb: :put, path: '') error_code: error_code_from(response) ) rescue ResponseError => e - return Response.new(false, 'Unable to authenticate. Please check your credentials.', {}, :test => test?) if e.response.code == '401' + return Response.new(false, 'Unable to authenticate. Please check your credentials.', {}, test: test?) if e.response.code == '401' + raise end diff --git a/lib/active_merchant/billing/gateways/card_save.rb b/lib/active_merchant/billing/gateways/card_save.rb index 7d5920be05b..096cd4fcb1c 100644 --- a/lib/active_merchant/billing/gateways/card_save.rb +++ b/lib/active_merchant/billing/gateways/card_save.rb @@ -6,17 +6,16 @@ class CardSaveGateway < IridiumGateway self.money_format = :cents self.default_currency = 'GBP' - self.supported_cardtypes = [ :visa, :maestro, :master, :american_express, :jcb ] - self.supported_countries = [ 'GB' ] + self.supported_cardtypes = %i[visa maestro master american_express jcb] + self.supported_countries = ['GB'] self.homepage_url = 'http://www.cardsave.net/' self.display_name = 'CardSave' - def initialize(options={}) + def initialize(options = {}) super @test_url = 'https://gw1.cardsaveonlinepayments.com:4430/' @live_url = 'https://gw1.cardsaveonlinepayments.com:4430/' end - end end end diff --git a/lib/active_merchant/billing/gateways/card_stream.rb b/lib/active_merchant/billing/gateways/card_stream.rb index f5ac54fdb83..5a2ec8b86cb 100644 --- a/lib/active_merchant/billing/gateways/card_stream.rb +++ b/lib/active_merchant/billing/gateways/card_stream.rb @@ -1,14 +1,14 @@ module ActiveMerchant #:nodoc: module Billing #:nodoc: class CardStreamGateway < Gateway - THREEDSECURE_REQUIRED_DEPRECATION_MESSAGE = 'Specifying the :threeDSRequired initialization option is deprecated. Please use the `:threeds_required => true` *transaction* option instead.' self.test_url = self.live_url = 'https://gateway.cardstream.com/direct/' self.money_format = :cents self.default_currency = 'GBP' - self.supported_countries = ['GB', 'US', 'CH', 'SE', 'SG', 'NO', 'JP', 'IS', 'HK', 'NL', 'CZ', 'CA', 'AU'] - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :discover, :jcb, :maestro] + self.currencies_without_fractions = %w(CVE ISK JPY UGX) + self.supported_countries = %w[GB US CH SE SG NO JP IS HK NL CZ CA AU] + self.supported_cardtypes = %i[visa master american_express diners_club discover jcb maestro] self.homepage_url = 'http://www.cardstream.com/' self.display_name = 'CardStream' @@ -173,7 +173,7 @@ def purchase(money, credit_card_or_reference, options = {}) def capture(money, authorization, options = {}) post = {} add_pair(post, :xref, authorization) - add_pair(post, :amount, amount(money), :required => true) + add_pair(post, :amount, localized_amount(money, options[:currency] || currency(money)), required: true) add_remote_address(post, options) commit('CAPTURE', post) @@ -203,7 +203,7 @@ def void(authorization, options = {}) commit('CANCEL', post) end - def verify(creditcard, options={}) + def verify(creditcard, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, creditcard, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -224,8 +224,9 @@ def scrub(transcript) private def add_amount(post, money, options) - add_pair(post, :amount, amount(money), :required => true) - add_pair(post, :currencyCode, currency_code(options[:currency] || currency(money))) + currency = options[:currency] || currency(money) + add_pair(post, :amount, localized_amount(money, currency), required: true) + add_pair(post, :currencyCode, currency_code(currency)) end def add_customer_data(post, options) @@ -241,15 +242,15 @@ def add_customer_data(post, options) end def add_invoice(post, credit_card_or_reference, money, options) - add_pair(post, :transactionUnique, options[:order_id], :required => true) - add_pair(post, :orderRef, options[:description] || options[:order_id], :required => true) + add_pair(post, :transactionUnique, options[:order_id], required: true) + add_pair(post, :orderRef, options[:description] || options[:order_id], required: true) add_pair(post, :statementNarrative1, options[:merchant_name]) if options[:merchant_name] add_pair(post, :statementNarrative2, options[:dynamic_descriptor]) if options[:dynamic_descriptor] if credit_card_or_reference.respond_to?(:number) - if ['american_express', 'diners_club'].include?(card_brand(credit_card_or_reference).to_s) + if %w[american_express diners_club].include?(card_brand(credit_card_or_reference).to_s) add_pair(post, :item1Quantity, 1) add_pair(post, :item1Description, (options[:description] || options[:order_id]).slice(0, 15)) - add_pair(post, :item1GrossValue, amount(money)) + add_pair(post, :item1GrossValue, localized_amount(money, options[:currency] || currency(money))) end end @@ -266,14 +267,14 @@ def add_credit_card_or_reference(post, credit_card_or_reference) end def add_reference(post, reference) - add_pair(post, :xref, reference, :required => true) + add_pair(post, :xref, reference, required: true) end def add_credit_card(post, credit_card) - add_pair(post, :customerName, credit_card.name, :required => true) - add_pair(post, :cardNumber, credit_card.number, :required => true) - add_pair(post, :cardExpiryMonth, format(credit_card.month, :two_digits), :required => true) - add_pair(post, :cardExpiryYear, format(credit_card.year, :two_digits), :required => true) + add_pair(post, :customerName, credit_card.name, required: true) + add_pair(post, :cardNumber, credit_card.number, required: true) + add_pair(post, :cardExpiryMonth, format(credit_card.month, :two_digits), required: true) + add_pair(post, :cardExpiryYear, format(credit_card.year, :two_digits), required: true) add_pair(post, :cardCVV, credit_card.verification_value) end @@ -281,7 +282,7 @@ def add_threeds_required(post, options) add_pair(post, :threeDSRequired, options[:threeds_required] || @threeds_required ? 'Y' : 'N') end - def add_remote_address(post, options={}) + def add_remote_address(post, options = {}) add_pair(post, :remoteAddress, options[:ip] || '1.1.1.1') end @@ -308,10 +309,10 @@ def parse(body) end def commit(action, parameters) - parameters.update(:countryCode => self.supported_countries[0]) unless ['CAPTURE', 'CANCEL'].include?(action) + parameters.update(countryCode: self.supported_countries[0]) unless %w[CAPTURE CANCEL].include?(action) parameters.update( - :merchantID => @options[:login], - :action => action + merchantID: @options[:login], + action: action ) # adds a signature to the post hash/array add_hmac(parameters) @@ -322,10 +323,10 @@ def commit(action, parameters) response[:responseCode] == '0', response[:responseCode] == '0' ? 'APPROVED' : response[:responseMessage], response, - :test => test?, - :authorization => response[:xref], - :cvv_result => CVV_CODE[response[:avscv2ResponseCode].to_s[0, 1]], - :avs_result => avs_from(response) + test: test?, + authorization: response[:xref], + cvv_result: CVV_CODE[response[:avscv2ResponseCode].to_s[0, 1]], + avs_result: avs_from(response) ) end @@ -341,12 +342,12 @@ def avs_from(response) 'A' else 'I' - end + end AVSResult.new({ - :code => code, - :postal_match => postal_match, - :street_match => street_match + code: code, + postal_match: postal_match, + street_match: street_match }) end @@ -361,7 +362,6 @@ def post_data(action, parameters = {}) def add_pair(post, key, value, options = {}) post[key] = value if !value.blank? || options[:required] end - end end end diff --git a/lib/active_merchant/billing/gateways/cardknox.rb b/lib/active_merchant/billing/gateways/cardknox.rb index 938e6ade478..8acabd4d6cd 100644 --- a/lib/active_merchant/billing/gateways/cardknox.rb +++ b/lib/active_merchant/billing/gateways/cardknox.rb @@ -3,9 +3,9 @@ module Billing #:nodoc: class CardknoxGateway < Gateway self.live_url = 'https://x1.cardknox.com/gateway' - self.supported_countries = ['US', 'CA', 'GB'] + self.supported_countries = %w[US CA GB] self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb] + self.supported_cardtypes = %i[visa master american_express discover diners_club jcb] self.homepage_url = 'https://www.cardknox.com/' self.display_name = 'Cardknox' @@ -27,7 +27,7 @@ class CardknoxGateway < Gateway } } - def initialize(options={}) + def initialize(options = {}) requires!(options, :api_key) super end @@ -37,7 +37,7 @@ def initialize(options={}) # - check # - cardknox token, which is returned in the the authorization string "ref_num;token;command" - def purchase(amount, source, options={}) + def purchase(amount, source, options = {}) post = {} add_amount(post, amount, options) add_invoice(post, options) @@ -48,7 +48,7 @@ def purchase(amount, source, options={}) commit(:purchase, source_type(source), post) end - def authorize(amount, source, options={}) + def authorize(amount, source, options = {}) post = {} add_amount(post, amount) add_invoice(post, options) @@ -66,7 +66,7 @@ def capture(amount, authorization, options = {}) commit(:capture, source_type(authorization), post) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) post = {} add_reference(post, authorization) add_amount(post, amount) @@ -79,7 +79,7 @@ def void(authorization, options = {}) commit(:void, source_type(authorization), post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -116,7 +116,7 @@ def split_authorization(authorization) end def add_reference(post, reference) - reference, _, _ = split_authorization(reference) + reference, = split_authorization(reference) post[:Refnum] = reference end @@ -186,7 +186,7 @@ def add_address_for_type(type, post, source, address) post[address_key(prefix, 'FirstName')] = address[:first_name] post[address_key(prefix, 'LastName')] = address[:last_name] end - post[address_key(prefix, 'MiddleName')] = address[:middle_name] + post[address_key(prefix, 'MiddleName')] = address[:middle_name] post[address_key(prefix, 'Company')] = address[:company] post[address_key(prefix, 'Street')] = address[:address1] @@ -247,7 +247,7 @@ def add_check(post, check) end def add_cardknox_token(post, authorization) - _, token, _ = split_authorization(authorization) + _, token, = split_authorization(authorization) post[:Token] = token end @@ -276,7 +276,7 @@ def parse(body) amount: fields['xAuthAmount'], masked_card_num: fields['xMaskedCardNumber'], masked_account_number: fields['MaskedAccountNumber'] - }.delete_if { |k, v| v.nil? } + }.delete_if { |_k, v| v.nil? } end def commit(action, source_type, parameters) @@ -312,7 +312,7 @@ def post_data(command, parameters = {}) Version: '4.5.4', SoftwareName: 'Active Merchant', SoftwareVersion: ActiveMerchant::VERSION.to_s, - Command: command, + Command: command } seed = SecureRandom.hex(32).upcase @@ -320,7 +320,7 @@ def post_data(command, parameters = {}) initial_parameters[:Hash] = "s/#{seed}/#{hash}/n" unless @options[:pin].blank? parameters = initial_parameters.merge(parameters) - parameters.reject { |k, v| v.blank? }.collect { |key, value| "x#{key}=#{CGI.escape(value.to_s)}" }.join('&') + parameters.reject { |_k, v| v.blank? }.collect { |key, value| "x#{key}=#{CGI.escape(value.to_s)}" }.join('&') end end end diff --git a/lib/active_merchant/billing/gateways/cardprocess.rb b/lib/active_merchant/billing/gateways/cardprocess.rb index c91121c0641..78a18105277 100644 --- a/lib/active_merchant/billing/gateways/cardprocess.rb +++ b/lib/active_merchant/billing/gateways/cardprocess.rb @@ -8,7 +8,7 @@ class CardprocessGateway < Gateway MT HU NL AT PL PT RO SI SK FI SE GB IS LI NO CH ME MK AL RS TR BA ] self.default_currency = 'EUR' - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :jcb] + self.supported_cardtypes = %i[visa master american_express diners_club jcb] self.homepage_url = 'https://vr-pay-ecommerce.docs.oppwa.com/' self.display_name = 'CardProcess VR-Pay' @@ -26,7 +26,7 @@ class CardprocessGateway < Gateway # * :user_id -- The CardProcess user ID # * :password -- The CardProcess password # * :entity_id -- The CardProcess channel or entity ID for any transactions - def initialize(options={}) + def initialize(options = {}) requires!(options, :user_id, :password, :entity_id) super # This variable exists purely to allow remote tests to force error codes; @@ -123,6 +123,7 @@ def add_address(post, _card, options) def add_invoice(post, money, options) return if money.nil? + post[:amount] = amount(money) post[:currency] = (options[:currency] || currency(money)) post[:merchantInvoiceId] = options[:merchant_invoice_id] if options[:merchant_invoice_id] @@ -132,6 +133,7 @@ def add_invoice(post, money, options) def add_payment(post, payment) return if payment.is_a?(String) + post[:paymentBrand] = payment.brand.upcase if payment.brand post[:card] ||= {} post[:card][:number] = payment.number diff --git a/lib/active_merchant/billing/gateways/cashnet.rb b/lib/active_merchant/billing/gateways/cashnet.rb index 48a7d1308c5..a90102d12f5 100644 --- a/lib/active_merchant/billing/gateways/cashnet.rb +++ b/lib/active_merchant/billing/gateways/cashnet.rb @@ -7,7 +7,7 @@ class CashnetGateway < Gateway self.test_url = 'https://train.cashnet.com/' self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb] + self.supported_cardtypes = %i[visa master american_express discover diners_club jcb] self.homepage_url = 'http://www.higherone.com/' self.display_name = 'Cashnet' self.money_format = :dollars @@ -49,7 +49,7 @@ def purchase(money, payment_object, options = {}) def refund(money, identification, options = {}) post = {} - post[:origtx] = identification + post[:origtx] = identification add_invoice(post, options) add_customer_data(post, options) commit('REFUND', money, post) @@ -107,8 +107,8 @@ def add_creditcard(post, creditcard) end def add_invoice(post, options) - post[:order_number] = options[:order_id] if options[:order_id].present? - post[:itemcode] = (options[:item_code] || @options[:default_item_code]) + post[:order_number] = options[:order_id] if options[:order_id].present? + post[:itemcode] = (options[:item_code] || @options[:default_item_code]) end def add_address(post, options) @@ -121,8 +121,8 @@ def add_address(post, options) end def add_customer_data(post, options) - post[:email_g] = options[:email] - post[:custcode] = options[:custcode] unless empty?(options[:custcode]) + post[:email_g] = options[:email] + post[:custcode] = options[:custcode] unless empty?(options[:custcode]) end def expdate(creditcard) @@ -145,6 +145,7 @@ def handle_response(response) elsif response.code.to_i == 302 return ssl_get(URI.parse(response['location'])) end + raise ResponseError.new(response) end diff --git a/lib/active_merchant/billing/gateways/cc5.rb b/lib/active_merchant/billing/gateways/cc5.rb index 3d25ec7d3f1..5d248ca7914 100644 --- a/lib/active_merchant/billing/gateways/cc5.rb +++ b/lib/active_merchant/billing/gateways/cc5.rb @@ -48,9 +48,9 @@ def credit(money, creditcard, options = {}) protected def build_sale_request(type, money, creditcard, options = {}) - requires!(options, :order_id) + requires!(options, :order_id) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.tag! 'CC5Request' do add_login_tags(xml) @@ -62,7 +62,7 @@ def build_sale_request(type, money, creditcard, options = {}) add_amount_tags(money, options, xml) xml.tag! 'Email', options[:email] if options[:email] - if(address = (options[:billing_address] || options[:address])) + if (address = (options[:billing_address] || options[:address])) xml.tag! 'BillTo' do add_address(xml, address) end @@ -76,7 +76,7 @@ def build_sale_request(type, money, creditcard, options = {}) end def build_capture_request(money, authorization, options = {}) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.tag! 'CC5Request' do add_login_tags(xml) @@ -87,7 +87,7 @@ def build_capture_request(money, authorization, options = {}) end def build_void_request(authorization, options = {}) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.tag! 'CC5Request' do add_login_tags(xml) @@ -97,7 +97,7 @@ def build_void_request(authorization, options = {}) end def build_authorization_credit_request(money, authorization, options = {}) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.tag! 'CC5Request' do add_login_tags(xml) @@ -108,7 +108,7 @@ def build_authorization_credit_request(money, authorization, options = {}) end def build_creditcard_credit_request(money, creditcard, options = {}) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.tag! 'CC5Request' do add_login_tags(xml) @@ -157,8 +157,8 @@ def commit(request) success, (success ? 'Approved' : "Declined (Reason: #{response[:proc_return_code]} - #{response[:err_msg]})"), response, - :test => test?, - :authorization => response[:order_id] + test: test?, + authorization: response[:order_id] ) end diff --git a/lib/active_merchant/billing/gateways/cecabank.rb b/lib/active_merchant/billing/gateways/cecabank.rb index b09ed92c37a..d85b48f7ed9 100644 --- a/lib/active_merchant/billing/gateways/cecabank.rb +++ b/lib/active_merchant/billing/gateways/cecabank.rb @@ -5,7 +5,7 @@ class CecabankGateway < Gateway self.live_url = 'https://pgw.ceca.es' self.supported_countries = ['ES'] - self.supported_cardtypes = [:visa, :master, :american_express] + self.supported_cardtypes = %i[visa master american_express] self.homepage_url = 'http://www.ceca.es/es/' self.display_name = 'Cecabank' self.default_currency = 'EUR' @@ -21,7 +21,7 @@ class CecabankGateway < Gateway CECA_UI_LESS_REFUND_PAGE = 'anulacion_xml' CECA_ACTION_REFUND = 'anulaciones/anularParcial' # use partial refund's URL to avoid time frame limitations and decision logic on client side CECA_ACTION_PURCHASE = 'tpv/compra' - CECA_CURRENCIES_DICTIONARY = {'EUR' => 978, 'USD' => 840, 'GBP' => 826} + CECA_CURRENCIES_DICTIONARY = { 'EUR' => 978, 'USD' => 840, 'GBP' => 826 } # Creates a new CecabankGateway # @@ -57,14 +57,14 @@ def initialize(options = {}) def purchase(money, creditcard, options = {}) requires!(options, :order_id) - post = {'Descripcion' => options[:description], + post = { 'Descripcion' => options[:description], 'Num_operacion' => options[:order_id], 'Idioma' => CECA_UI_LESS_LANGUAGE, 'Pago_soportado' => CECA_MODE, 'URL_OK' => CECA_NOTIFICATIONS_URL, 'URL_NOK' => CECA_NOTIFICATIONS_URL, 'Importe' => amount(money), - 'TipoMoneda' => CECA_CURRENCIES_DICTIONARY[options[:currency] || currency(money)]} + 'TipoMoneda' => CECA_CURRENCIES_DICTIONARY[options[:currency] || currency(money)] } add_creditcard(post, creditcard) @@ -84,12 +84,12 @@ def purchase(money, creditcard, options = {}) def refund(money, identification, options = {}) reference, order_id = split_authorization(identification) - post = {'Referencia' => reference, + post = { 'Referencia' => reference, 'Num_operacion' => order_id, 'Idioma' => CECA_UI_LESS_LANGUAGE_REFUND, 'Pagina' => CECA_UI_LESS_REFUND_PAGE, 'Importe' => amount(money), - 'TipoMoneda' => CECA_CURRENCIES_DICTIONARY[options[:currency] || currency(money)]} + 'TipoMoneda' => CECA_CURRENCIES_DICTIONARY[options[:currency] || currency(money)] } commit(CECA_ACTION_REFUND, post) end @@ -130,7 +130,7 @@ def parse(body) if root.elements['OPERACION'] response[:operation_type] = root.elements['OPERACION'].attributes['tipo'] - response[:amount] = root.elements['OPERACION/importe'].text.strip + response[:amount] = root.elements['OPERACION/importe'].text.strip end response[:description] = root.elements['OPERACION/descripcion'].text if root.elements['OPERACION/descripcion'] @@ -143,9 +143,7 @@ def parse(body) response[:error_message] = root.elements['ERROR/descripcion'].text else if root.elements['OPERACION'].attributes['numeroOperacion'] == '000' - if(root.elements['OPERACION/numeroAutorizacion']) - response[:authorization] = root.elements['OPERACION/numeroAutorizacion'].text - end + response[:authorization] = root.elements['OPERACION/numeroAutorizacion'].text if root.elements['OPERACION/numeroAutorizacion'] else response[:authorization] = root.attributes['numeroOperacion'] end @@ -175,9 +173,9 @@ def commit(action, parameters) response[:success], message_from(response), response, - :test => test?, - :authorization => build_authorization(response), - :error_code => response[:error_code] + test: test?, + authorization: build_authorization(response), + error_code: response[:error_code] ) end @@ -196,6 +194,7 @@ def post_data(params) params.map do |key, value| next if value.blank? + if value.is_a?(Hash) h = {} value.each do |k, v| @@ -217,31 +216,32 @@ def split_authorization(authorization) end def generate_signature(action, parameters) - signature_fields = case action - when CECA_ACTION_REFUND - options[:key].to_s + - options[:merchant_id].to_s + - options[:acquirer_bin].to_s + - options[:terminal_id].to_s + - parameters['Num_operacion'].to_s + - parameters['Importe'].to_s + - parameters['TipoMoneda'].to_s + - CECA_DECIMALS + - parameters['Referencia'].to_s + - CECA_ENCRIPTION - else - options[:key].to_s + - options[:merchant_id].to_s + - options[:acquirer_bin].to_s + - options[:terminal_id].to_s + - parameters['Num_operacion'].to_s + - parameters['Importe'].to_s + - parameters['TipoMoneda'].to_s + - CECA_DECIMALS + - CECA_ENCRIPTION + - CECA_NOTIFICATIONS_URL + - CECA_NOTIFICATIONS_URL - end + signature_fields = + case action + when CECA_ACTION_REFUND + options[:key].to_s + + options[:merchant_id].to_s + + options[:acquirer_bin].to_s + + options[:terminal_id].to_s + + parameters['Num_operacion'].to_s + + parameters['Importe'].to_s + + parameters['TipoMoneda'].to_s + + CECA_DECIMALS + + parameters['Referencia'].to_s + + CECA_ENCRIPTION + else + options[:key].to_s + + options[:merchant_id].to_s + + options[:acquirer_bin].to_s + + options[:terminal_id].to_s + + parameters['Num_operacion'].to_s + + parameters['Importe'].to_s + + parameters['TipoMoneda'].to_s + + CECA_DECIMALS + + CECA_ENCRIPTION + + CECA_NOTIFICATIONS_URL + + CECA_NOTIFICATIONS_URL + end Digest::SHA2.hexdigest(signature_fields) end end diff --git a/lib/active_merchant/billing/gateways/cenpos.rb b/lib/active_merchant/billing/gateways/cenpos.rb index 9ba37a7c00b..00ae73fafb4 100644 --- a/lib/active_merchant/billing/gateways/cenpos.rb +++ b/lib/active_merchant/billing/gateways/cenpos.rb @@ -11,14 +11,14 @@ class CenposGateway < Gateway self.supported_countries = %w(AD AI AG AR AU AT BS BB BE BZ BM BR BN BG CA HR CY CZ DK DM EE FI FR DE GR GD GY HK HU IS IL IT JP LV LI LT LU MY MT MX MC MS NL PA PL PT KN LC MF VC SM SG SK SI ZA ES SR SE CH TR GB US UY) self.default_currency = 'USD' self.money_format = :dollars - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] - def initialize(options={}) + def initialize(options = {}) requires!(options, :merchant_id, :password, :user_id) super end - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method) @@ -27,7 +27,7 @@ def purchase(amount, payment_method, options={}) commit('Sale', post) end - def authorize(amount, payment_method, options={}) + def authorize(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method) @@ -36,7 +36,7 @@ def authorize(amount, payment_method, options={}) commit('Auth', post) end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) post = {} add_invoice(post, amount, options) add_reference(post, authorization) @@ -45,7 +45,7 @@ def capture(amount, authorization, options={}) commit('SpecialForce', post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} add_void_required_elements(post) add_reference(post, authorization) @@ -56,7 +56,7 @@ def void(authorization, options={}) commit('Void', post) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) post = {} add_invoice(post, amount, options) add_reference(post, authorization) @@ -65,7 +65,7 @@ def refund(amount, authorization, options={}) commit('SpecialReturn', post) end - def credit(amount, payment_method, options={}) + def credit(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method) @@ -73,7 +73,7 @@ def credit(amount, payment_method, options={}) commit('Credit', post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -112,7 +112,7 @@ def add_payment_method(post, payment_method) end def add_customer_data(post, options) - if(billing_address = (options[:billing_address] || options[:address])) + if (billing_address = (options[:billing_address] || options[:address])) post[:CustomerEmailAddress] = billing_address[:email] post[:CustomerPhone] = billing_address[:phone] post[:CustomerBillingAddress] = billing_address[:address1] @@ -156,7 +156,7 @@ def commit(action, post) xml = ssl_post(self.live_url, data, headers) raw = parse(xml) rescue ActiveMerchant::ResponseError => e - if(e.response.code == '500' && e.response.body.start_with?(' 'identity', - 'Content-Type' => 'text/xml;charset=UTF-8', - 'SOAPAction' => 'http://tempuri.org/Transactional/ProcessCreditCard' + 'Content-Type' => 'text/xml;charset=UTF-8', + 'SOAPAction' => 'http://tempuri.org/Transactional/ProcessCreditCard' } end def build_request(post) - xml = Builder::XmlMarkup.new :indent => 8 + xml = Builder::XmlMarkup.new indent: 8 xml.tag!('acr:MerchantId', post.delete(:MerchantId)) xml.tag!('acr:Password', post.delete(:Password)) xml.tag!('acr:UserId', post.delete(:UserId)) @@ -198,18 +198,18 @@ def build_request(post) end def envelope(body) - <<-EOS - - - - - - #{body} - - - - - EOS + <<~XML + + + + + + #{body} + + + + + XML end def parse(xml) @@ -250,11 +250,11 @@ def message_from(succeeded, response) '257' => STANDARD_ERROR_CODE[:invalid_cvc], '333' => STANDARD_ERROR_CODE[:expired_card], '1' => STANDARD_ERROR_CODE[:card_declined], - '99' => STANDARD_ERROR_CODE[:processing_error], + '99' => STANDARD_ERROR_CODE[:processing_error] } def authorization_from(request, response) - [ response[:reference_number], request[:CardLastFourDigits], request[:Amount] ].join('|') + [response[:reference_number], request[:CardLastFourDigits], request[:Amount]].join('|') end def split_authorization(authorization) @@ -277,6 +277,7 @@ def avs_result_from_xml(xml) def cvv_result_code(xml) cvv = validation_result_element(xml, 'CVV') return nil unless cvv + validation_result_matches?(*validation_result_element_text(cvv.parent)) ? 'M' : 'N' end diff --git a/lib/active_merchant/billing/gateways/checkout.rb b/lib/active_merchant/billing/gateways/checkout.rb index bd6149b246d..2773b1b0878 100644 --- a/lib/active_merchant/billing/gateways/checkout.rb +++ b/lib/active_merchant/billing/gateways/checkout.rb @@ -7,8 +7,8 @@ class CheckoutGateway < Gateway self.default_currency = 'USD' self.money_format = :cents - self.supported_countries = ['AD', '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'] - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club] + self.supported_countries = %w[AD 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] + self.supported_cardtypes = %i[visa master american_express diners_club] self.homepage_url = 'https://www.checkout.com/' self.display_name = 'Checkout.com' @@ -83,7 +83,7 @@ def refund(amount, authorization, options = {}) end end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -107,9 +107,7 @@ def add_payment_method(xml, payment_method) xml.bill_cc_ payment_method.number xml.bill_expmonth_ format(payment_method.month, :two_digits) xml.bill_expyear_ format(payment_method.year, :four_digits) - if payment_method.verification_value? - xml.bill_cvv2_ payment_method.verification_value - end + xml.bill_cvv2_ payment_method.verification_value if payment_method.verification_value? end def add_billing_info(xml, options) @@ -152,7 +150,7 @@ def add_other_fields(xml, options) end def add_reference(xml, authorization) - transid, trackid, _, _, _ = split_authorization(authorization) + transid, trackid, = split_authorization(authorization) xml.transid transid add_track_id(xml, trackid) end @@ -161,7 +159,7 @@ def add_track_id(xml, trackid) xml.trackid(trackid) if trackid end - def commit(action, amount=nil, options={}, &builder) + def commit(action, amount = nil, options = {}, &builder) response = parse_xml(ssl_post(live_url, build_xml(action, &builder))) Response.new( (response[:responsecode] == '0'), @@ -200,7 +198,7 @@ def parse_xml(xml) response end - def authorization_from(response, action, amount, options) + def authorization_from(response, action, amount, options) currency = options[:currency] || currency(amount) [response[:tranid], response[:trackid], action, amount, currency].join('|') end diff --git a/lib/active_merchant/billing/gateways/checkout_v2.rb b/lib/active_merchant/billing/gateways/checkout_v2.rb index ea9a4c88393..30ba244e08f 100644 --- a/lib/active_merchant/billing/gateways/checkout_v2.rb +++ b/lib/active_merchant/billing/gateways/checkout_v2.rb @@ -6,10 +6,12 @@ class CheckoutV2Gateway < Gateway self.live_url = 'https://api.checkout.com' self.test_url = 'https://api.sandbox.checkout.com' - self.supported_countries = ['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'] + self.supported_countries = %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] self.default_currency = 'USD' self.money_format = :cents - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :maestro, :discover] + self.supported_cardtypes = %i[visa master american_express diners_club maestro discover jcb] + self.currencies_without_fractions = %w(BIF DJF GNF ISK KMF XAF CLF XPF JPY PYG RWF KRW VUV VND XOF) + self.currencies_with_three_decimal_places = %w(BHD LYD JOD KWD OMR TND) def initialize(options = {}) requires!(options, :secret_key) @@ -17,25 +19,16 @@ def initialize(options = {}) end def purchase(amount, payment_method, options = {}) - multi = MultiResponse.run do |r| - r.process { authorize(amount, payment_method, options) } - r.process { capture(amount, r.authorization, options) } - end - - merged_params = multi.responses.map(&:params).reduce({}, :merge) - succeeded = success_from(merged_params) + post = {} + build_auth_or_purchase(post, amount, payment_method, options) - response(:purchase, succeeded, merged_params) + commit(:purchase, post) end def authorize(amount, payment_method, options = {}) post = {} post[:capture] = false - add_invoice(post, amount, options) - add_payment_method(post, payment_method, options) - add_customer_data(post, options) - add_transaction_data(post, options) - add_3ds(post, options) + build_auth_or_purchase(post, amount, payment_method, options) commit(:authorize, post) end @@ -62,13 +55,10 @@ def refund(amount, authorization, options = {}) end def verify(credit_card, options = {}) - MultiResponse.run(:use_first_response) do |r| - r.process { authorize(100, credit_card, options) } - r.process(:ignore_result) { void(r.authorization, options) } - end + authorize(0, credit_card, options) end - def verify_payment(authorization, option={}) + def verify_payment(authorization, option = {}) commit(:verify_payment, authorization) end @@ -85,6 +75,14 @@ def scrub(transcript) private + def build_auth_or_purchase(post, amount, payment_method, options) + add_invoice(post, amount, options) + add_payment_method(post, payment_method, options) + add_customer_data(post, options) + add_transaction_data(post, options) + add_3ds(post, options) + end + def add_invoice(post, money, options) post[:amount] = localized_amount(money, options[:currency]) post[:reference] = options[:order_id] @@ -100,13 +98,21 @@ def add_invoice(post, money, options) def add_payment_method(post, payment_method, options) post[:source] = {} - post[:source][:type] = 'card' - post[:source][:name] = payment_method.name - post[:source][:number] = payment_method.number - post[:source][:cvv] = payment_method.verification_value + if payment_method.is_a?(NetworkTokenizationCreditCard) && payment_method.source == :network_token + post[:source][:type] = 'network_token' + post[:source][:token] = payment_method.number + post[:source][:token_type] = payment_method.brand == 'visa' ? 'vts' : 'mdes' + post[:source][:cryptogram] = payment_method.payment_cryptogram + post[:source][:eci] = options[:eci] || '05' + else + post[:source][:type] = 'card' + post[:source][:name] = payment_method.name + post[:source][:number] = payment_method.number + post[:source][:cvv] = payment_method.verification_value + post[:source][:stored] = 'true' if options[:card_on_file] == true + end post[:source][:expiry_year] = format(payment_method.year, :four_digits) post[:source][:expiry_month] = format(payment_method.month, :two_digits) - post[:source][:stored] = 'true' if options[:card_on_file] == true end def add_customer_data(post, options) @@ -138,6 +144,7 @@ def add_3ds(post, options) post[:'3ds'][:enabled] = true post[:success_url] = options[:callback_url] if options[:callback_url] post[:failure_url] = options[:callback_url] if options[:callback_url] + post[:'3ds'][:attempt_n3d] = options[:attempt_n3d] if options[:attempt_n3d] end if options[:three_d_secure] @@ -152,12 +159,11 @@ def commit(action, post, authorization = nil) begin raw_response = (action == :verify_payment ? ssl_get("#{base_url}/payments/#{post}", headers) : ssl_post(url(post, action, authorization), post.to_json, headers)) response = parse(raw_response) - if action == :capture && response.key?('_links') - response['id'] = response['_links']['payment']['href'].split('/')[-1] - end + response['id'] = response['_links']['payment']['href'].split('/')[-1] if action == :capture && response.key?('_links') rescue ResponseError => e raise unless e.response.code.to_s =~ /4\d\d/ - response = parse(e.response.body) + + response = parse(e.response.body, error: e.response) end succeeded = success_from(response) @@ -185,12 +191,12 @@ def response(action, succeeded, response) def headers { 'Authorization' => @options[:secret_key], - 'Content-Type' => 'application/json;charset=UTF-8', + 'Content-Type' => 'application/json;charset=UTF-8' } end def url(_post, action, authorization) - if action == :authorize + if %i[authorize purchase].include?(action) "#{base_url}/payments" elsif action == :capture "#{base_url}/payments/#{authorization}/captures" @@ -215,13 +221,16 @@ def cvv_result(response) response['source'] && response['source']['cvv_check'] ? CVVResult.new(response['source']['cvv_check']) : nil end - def parse(body) + def parse(body, error: nil) JSON.parse(body) rescue JSON::ParserError - { + response = { + 'error_type' => error&.code, 'message' => 'Invalid JSON response received from Checkout.com Unified Payments Gateway. Please contact Checkout.com if you continue to receive this message.', 'raw_response' => scrub(body) } + response['error_codes'] = [error&.message] if error&.message + response end def success_from(response) @@ -234,7 +243,7 @@ def message_from(succeeded, response) elsif response['error_type'] response['error_type'] + ': ' + response['error_codes'].first else - response['response_summary'] || response['response_code'] || 'Unable to read error message' + response['response_summary'] || response['response_code'] || response['status'] || response['message'] || 'Unable to read error message' end end @@ -257,6 +266,7 @@ def authorization_from(raw) def error_code_from(succeeded, response) return if succeeded + if response['error_type'] && response['error_codes'] "#{response['error_type']}: #{response['error_codes'].join(', ')}" elsif response['error_type'] diff --git a/lib/active_merchant/billing/gateways/citrus_pay.rb b/lib/active_merchant/billing/gateways/citrus_pay.rb index 00ab762d196..b7f30ac2d89 100644 --- a/lib/active_merchant/billing/gateways/citrus_pay.rb +++ b/lib/active_merchant/billing/gateways/citrus_pay.rb @@ -15,8 +15,7 @@ class CitrusPayGateway < Gateway self.homepage_url = 'http://www.citruspay.com/' self.supported_countries = %w(AR AU BR FR DE HK MX NZ SG GB US) self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb, :maestro] - + self.supported_cardtypes = %i[visa master american_express discover diners_club jcb maestro] end end end diff --git a/lib/active_merchant/billing/gateways/clearhaus.rb b/lib/active_merchant/billing/gateways/clearhaus.rb index b53d792a4f4..08098a1801d 100644 --- a/lib/active_merchant/billing/gateways/clearhaus.rb +++ b/lib/active_merchant/billing/gateways/clearhaus.rb @@ -4,12 +4,12 @@ class ClearhausGateway < Gateway self.test_url = 'https://gateway.test.clearhaus.com' self.live_url = 'https://gateway.clearhaus.com' - self.supported_countries = ['DK', 'NO', 'SE', 'FI', 'DE', 'CH', 'NL', 'AD', 'AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'FO', 'GL', 'EE', 'FR', 'GR', - 'HU', 'IS', 'IE', 'IT', 'LV', 'LI', 'LT', 'LU', 'MT', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'GB'] + self.supported_countries = %w[DK NO SE FI DE CH NL AD AT BE BG HR CY CZ FO GL EE FR GR + HU IS IE IT LV LI LT LU MT PL PT RO SK SI ES GB] self.default_currency = 'EUR' - self.currencies_without_fractions = %w(BIF BYR DJF GNF JPY KMF KRW PYG RWF VND VUV XAF XOF XPF) - self.supported_cardtypes = [:visa, :master] + self.currencies_without_fractions = %w(BIF CLP DJF GNF JPY KMF KRW PYG RWF UGX VND VUV XAF XOF XPF) + self.supported_cardtypes = %i[visa master] self.homepage_url = 'https://www.clearhaus.com' self.display_name = 'Clearhaus' @@ -36,31 +36,32 @@ class ClearhausGateway < Gateway 50000 => 'Clearhaus error' } - def initialize(options={}) + def initialize(options = {}) requires!(options, :api_key) options[:private_key] = options[:private_key].strip if options[:private_key] super end - def purchase(amount, payment, options={}) + def purchase(amount, payment, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(amount, payment, options) } r.process { capture(amount, r.authorization, options) } end end - def authorize(amount, payment, options={}) + def authorize(amount, payment, options = {}) post = {} add_invoice(post, amount, options) - action = if payment.respond_to?(:number) - add_payment(post, payment) - '/authorizations' - elsif payment.kind_of?(String) - "/cards/#{payment}/authorizations" - else - raise ArgumentError.new("Unknown payment type #{payment.inspect}") - end + action = + if payment.respond_to?(:number) + add_payment(post, payment) + '/authorizations' + elsif payment.kind_of?(String) + "/cards/#{payment}/authorizations" + else + raise ArgumentError.new("Unknown payment type #{payment.inspect}") + end post[:recurring] = options[:recurring] if options[:recurring] post[:card][:pares] = options[:pares] if options[:pares] @@ -68,14 +69,14 @@ def authorize(amount, payment, options={}) commit(action, post) end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) post = {} add_invoice(post, amount, options) commit("/authorizations/#{authorization}/captures", post) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) post = {} add_amount(post, amount, options) @@ -86,14 +87,14 @@ def void(authorization, options = {}) commit("/authorizations/#{authorization}/voids", options) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(0, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } end end - def store(credit_card, options={}) + def store(credit_card, options = {}) post = {} add_payment(post, credit_card) @@ -127,12 +128,10 @@ def add_amount(post, amount, options) def add_payment(post, payment) card = {} card[:pan] = payment.number - card[:expire_month] = '%02d'% payment.month + card[:expire_month] = '%02d' % payment.month card[:expire_year] = payment.year - if payment.verification_value? - card[:csc] = payment.verification_value - end + card[:csc] = payment.verification_value if payment.verification_value? post[:card] = card if card.any? end @@ -161,12 +160,14 @@ def commit(action, parameters) end end - response = begin - parse(ssl_post(url, body, headers)) - rescue ResponseError => e - raise unless(e.response.code.to_s =~ /400/) - parse(e.response.body) - end + response = + begin + parse(ssl_post(url, body, headers)) + rescue ResponseError => e + raise unless e.response.code.to_s =~ /400/ + + parse(e.response.body) + end Response.new( success_from(response), @@ -205,15 +206,13 @@ def id_of_auth_for_capture(action) def generate_signature(body) key = OpenSSL::PKey::RSA.new(@options[:private_key]) - hex = key.sign(OpenSSL::Digest.new('sha256'), body).unpack('H*').first + hex = key.sign(OpenSSL::Digest.new('sha256'), body).unpack1('H*') "#{@options[:signing_key]} RS256-hex #{hex}" end def error_code_from(response) - unless success_from(response) - response['status']['code'] - end + response['status']['code'] unless success_from(response) end end end diff --git a/lib/active_merchant/billing/gateways/commercegate.rb b/lib/active_merchant/billing/gateways/commercegate.rb index c1d6d5bc1f4..825ae5fdf0b 100644 --- a/lib/active_merchant/billing/gateways/commercegate.rb +++ b/lib/active_merchant/billing/gateways/commercegate.rb @@ -11,7 +11,7 @@ class CommercegateGateway < Gateway self.money_format = :dollars self.default_currency = 'EUR' - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://www.commercegate.com/' self.display_name = 'CommerceGate' @@ -74,8 +74,8 @@ def add_auth_purchase_options(post, money, options) post[:customerIP] = options[:ip] || '127.0.0.1' post[:amount] = amount(money) post[:email] = options[:email] || 'unknown@example.com' - post[:currencyCode]= options[:currency] || currency(money) - post[:merchAcct] = options[:merchant] + post[:currencyCode] = options[:currency] || currency(money) + post[:merchAcct] = options[:merchant] end def add_creditcard(params, creditcard) @@ -102,7 +102,7 @@ def commit(action, parameters) response, authorization: response['transID'], test: test?, - avs_result: {code: response['avsCode']}, + avs_result: { code: response['avsCode'] }, cvv_result: response['cvvCode'] ) end diff --git a/lib/active_merchant/billing/gateways/conekta.rb b/lib/active_merchant/billing/gateways/conekta.rb index 06aad777b09..c113aa13ebb 100644 --- a/lib/active_merchant/billing/gateways/conekta.rb +++ b/lib/active_merchant/billing/gateways/conekta.rb @@ -4,7 +4,7 @@ class ConektaGateway < Gateway self.live_url = 'https://api.conekta.io/' self.supported_countries = ['MX'] - self.supported_cardtypes = [:visa, :master, :american_express, :carnet] + self.supported_cardtypes = %i[visa master american_express carnet] self.homepage_url = 'https://conekta.io/' self.display_name = 'Conekta Gateway' self.money_format = :cents @@ -105,7 +105,7 @@ def add_shipment(post, options) end def add_shipment_address(post, options) - if(address = options[:shipping_address]) + if (address = options[:shipping_address]) post[:address] = {} post[:address][:street1] = address[:address1] if address[:address1] post[:address][:street2] = address[:address2] if address[:address2] @@ -124,7 +124,7 @@ def add_line_items(post, options) end def add_billing_address(post, options) - if(address = (options[:billing_address] || options[:address])) + if (address = (options[:billing_address] || options[:address])) post[:billing_address] = {} post[:billing_address][:street1] = address[:address1] if address[:address1] post[:billing_address][:street2] = address[:address2] if address[:address2] @@ -142,7 +142,7 @@ def add_billing_address(post, options) end def add_address(post, options) - if(address = (options[:billing_address] || options[:address])) + if (address = (options[:billing_address] || options[:address])) post[:address] = {} post[:address][:street1] = address[:address1] if address[:address1] post[:address][:street2] = address[:address2] if address[:address2] @@ -170,6 +170,7 @@ def add_payment_source(post, payment_source, options) def parse(body) return {} unless body + JSON.parse(body) end @@ -179,7 +180,7 @@ def headers(options) 'Accept-Language' => 'es', 'Authorization' => 'Basic ' + Base64.encode64("#{@options[:key]}:"), 'RaiseHtmlError' => 'false', - 'Conekta-Client-User-Agent' => {'agent'=>"Conekta ActiveMerchantBindings/#{ActiveMerchant::VERSION}"}.to_json, + 'Conekta-Client-User-Agent' => { 'agent' => "Conekta ActiveMerchantBindings/#{ActiveMerchant::VERSION}" }.to_json, 'X-Conekta-Client-User-Agent' => conekta_client_user_agent(options), 'X-Conekta-Client-User-Metadata' => options[:meta].to_json } @@ -187,7 +188,8 @@ def headers(options) def conekta_client_user_agent(options) return user_agent unless options[:application] - JSON.dump(JSON.parse(user_agent).merge!({application: options[:application]})) + + JSON.dump(JSON.parse(user_agent).merge!({ application: options[:application] })) end def commit(method, url, parameters, options = {}) diff --git a/lib/active_merchant/billing/gateways/creditcall.rb b/lib/active_merchant/billing/gateways/creditcall.rb index 45f84569f5d..6f6f0b70d31 100644 --- a/lib/active_merchant/billing/gateways/creditcall.rb +++ b/lib/active_merchant/billing/gateways/creditcall.rb @@ -10,7 +10,7 @@ class CreditcallGateway < Gateway self.supported_countries = ['US'] self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'https://www.creditcall.com' self.display_name = 'Creditcall' @@ -24,29 +24,29 @@ class CreditcallGateway < Gateway AVS_CODE = { 'matched;matched' => 'D', - 'matched;notchecked' =>'B', + 'matched;notchecked' => 'B', 'matched;notmatched' => 'A', 'matched;partialmatch' => 'A', 'notchecked;matched' => 'P', - 'notchecked;notchecked' =>'I', + 'notchecked;notchecked' => 'I', 'notchecked;notmatched' => 'I', 'notchecked;partialmatch' => 'I', 'notmatched;matched' => 'W', - 'notmatched;notchecked' =>'C', + 'notmatched;notchecked' => 'C', 'notmatched;notmatched' => 'C', 'notmatched;partialmatch' => 'C', 'partialmatched;matched' => 'W', - 'partialmatched;notchecked' =>'C', + 'partialmatched;notchecked' => 'C', 'partialmatched;notmatched' => 'C', 'partialmatched;partialmatch' => 'C' } - def initialize(options={}) + def initialize(options = {}) requires!(options, :terminal_id, :transaction_key) super end - def purchase(money, payment_method, options={}) + def purchase(money, payment_method, options = {}) multi_response = MultiResponse.run do |r| r.process { authorize(money, payment_method, options) } r.process { capture(money, r.authorization, options) } @@ -66,7 +66,7 @@ def purchase(money, payment_method, options={}) ) end - def authorize(money, payment_method, options={}) + def authorize(money, payment_method, options = {}) request = build_xml_request do |xml| add_transaction_details(xml, money, nil, 'Auth', options) add_terminal_details(xml, options) @@ -76,7 +76,7 @@ def authorize(money, payment_method, options={}) commit(request) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) request = build_xml_request do |xml| add_transaction_details(xml, money, authorization, 'Conf', options) add_terminal_details(xml, options) @@ -85,7 +85,7 @@ def capture(money, authorization, options={}) commit(request) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) request = build_xml_request do |xml| add_transaction_details(xml, money, authorization, 'Refund', options) add_terminal_details(xml, options) @@ -94,7 +94,7 @@ def refund(money, authorization, options={}) commit(request) end - def void(authorization, options={}) + def void(authorization, options = {}) request = build_xml_request do |xml| add_transaction_details(xml, nil, authorization, 'Void', options) add_terminal_details(xml, options) @@ -103,7 +103,7 @@ def void(authorization, options={}) commit(request) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -144,7 +144,7 @@ def build_xml_request builder.to_xml end - def add_transaction_details(xml, amount, authorization, type, options={}) + def add_transaction_details(xml, amount, authorization, type, options = {}) xml.TransactionDetails do xml.MessageType type xml.Amount(unit: 'Minor') { xml.text(amount) } if amount @@ -153,7 +153,7 @@ def add_transaction_details(xml, amount, authorization, type, options={}) end end - def add_terminal_details(xml, options={}) + def add_terminal_details(xml, options = {}) xml.TerminalDetails do xml.TerminalID @options[:terminal_id] xml.TransactionKey @options[:transaction_key] @@ -161,7 +161,7 @@ def add_terminal_details(xml, options={}) end end - def add_card_details(xml, payment_method, options={}) + def add_card_details(xml, payment_method, options = {}) xml.CardDetails do xml.Manual(type: manual_type(options)) do xml.PAN payment_method.number @@ -175,10 +175,11 @@ def add_card_details(xml, payment_method, options={}) def add_additional_verification(xml, options) return unless (options[:verify_zip].to_s == 'true') || (options[:verify_address].to_s == 'true') + if address = options[:billing_address] xml.AdditionalVerification do - xml.Zip address[:zip] if options[:verify_zip].to_s == 'true' - xml.Address address[:address1] if options[:verify_address].to_s == 'true' + xml.Zip address[:zip] if options[:verify_zip].to_s == 'true' + xml.Address address[:address1] if options[:verify_address].to_s == 'true' end end end diff --git a/lib/active_merchant/billing/gateways/credorax.rb b/lib/active_merchant/billing/gateways/credorax.rb index c835890ac5c..3376bcc86c7 100644 --- a/lib/active_merchant/billing/gateways/credorax.rb +++ b/lib/active_merchant/billing/gateways/credorax.rb @@ -21,11 +21,11 @@ class CredoraxGateway < Gateway self.supported_countries = %w(AD AT BE BG HR CY CZ DK EE FR DE GI GR GG HU IS IE IM IT JE LV LI LT LU MT MC NO PL PT RO SM SK ES SE CH GB) self.default_currency = 'EUR' - self.currencies_without_fractions = %w(CLP JPY KRW PYG VND) - self.currencies_with_three_decimal_places = %w(BHD JOD KWD OMR RSD TND) + self.currencies_without_fractions = %w(BIF CLP DJF GNF JPY KMF KRW PYG RWF VND VUV XAF XOF XPF) + self.currencies_with_three_decimal_places = %w(BHD IQD JOD KWD LYD OMR TND) self.money_format = :cents - self.supported_cardtypes = [:visa, :master, :maestro] + self.supported_cardtypes = %i[visa master maestro american_express] RESPONSE_MESSAGES = { '00' => 'Approved or completed successfully', @@ -117,21 +117,23 @@ class CredoraxGateway < Gateway '96' => 'System malfunction', 'R0' => 'Stop Payment Order', 'R1' => 'Revocation of Authorisation Order', - 'R3' => 'Revocation of all Authorisations Order' + 'R3' => 'Revocation of all Authorisations Order', + '1A' => 'Strong Customer Authentication required' } - def initialize(options={}) + def initialize(options = {}) requires!(options, :merchant_id, :cipher_key) super end - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method) add_customer_data(post, options) add_email(post, options) add_3d_secure(post, options) + add_3ds_2_optional_fields(post, options) add_echo(post, options) add_submerchant_id(post, options) add_stored_credential(post, options) @@ -140,22 +142,24 @@ def purchase(amount, payment_method, options={}) commit(:purchase, post) end - def authorize(amount, payment_method, options={}) + def authorize(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method) add_customer_data(post, options) add_email(post, options) add_3d_secure(post, options) + add_3ds_2_optional_fields(post, options) add_echo(post, options) add_submerchant_id(post, options) add_stored_credential(post, options) add_processor(post, options) + add_authorization_details(post, options) commit(:authorize, post) end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) post = {} add_invoice(post, amount, options) add_reference(post, authorization) @@ -167,7 +171,7 @@ def capture(amount, authorization, options={}) commit(:capture, post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} add_customer_data(post, options) reference_action = add_reference(post, authorization) @@ -179,7 +183,7 @@ def void(authorization, options={}) commit(:void, post, reference_action) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) post = {} add_invoice(post, amount, options) add_reference(post, authorization) @@ -187,11 +191,17 @@ def refund(amount, authorization, options={}) add_echo(post, options) add_submerchant_id(post, options) add_processor(post, options) + add_email(post, options) - commit(:refund, post) + if options[:referral_cft] + add_customer_name(post, options) + commit(:referral_cft, post) + else + commit(:refund, post) + end end - def credit(amount, payment_method, options={}) + def credit(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method) @@ -205,7 +215,7 @@ def credit(amount, payment_method, options={}) commit(:credit, post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -222,6 +232,25 @@ def scrub(transcript) gsub(%r((b5=)\d+), '\1[FILTERED]') end + def add_3ds_2_optional_fields(post, options) + three_ds = options[:three_ds_2] || {} + + if three_ds.has_key?(:optional) + three_ds[:optional].each do |key, value| + normalized_value = normalize(value) + next if normalized_value.nil? + + if key == :'3ds_homephonecountry' + next unless options[:billing_address] && options[:billing_address][:phone] + end + + post[key] = normalized_value unless post[key] + end + end + + post + end + private def add_invoice(post, money, options) @@ -253,6 +282,7 @@ def add_stored_credential(post, options) add_transaction_type(post, options) # if :transaction_type option is not passed, then check for :stored_credential options return unless (stored_credential = options[:stored_credential]) && options.dig(:transaction_type).nil? + if stored_credential[:initiator] == 'merchant' case stored_credential[:reason_type] when 'recurring' @@ -268,12 +298,12 @@ def add_stored_credential(post, options) def add_customer_data(post, options) post[:d1] = options[:ip] || '127.0.0.1' if (billing_address = options[:billing_address]) - post[:c5] = billing_address[:address1] - post[:c7] = billing_address[:city] - post[:c10] = billing_address[:zip] - post[:c8] = billing_address[:state] - post[:c9] = billing_address[:country] - post[:c2] = billing_address[:phone] + post[:c5] = billing_address[:address1] if billing_address[:address1] + post[:c7] = billing_address[:city] if billing_address[:city] + post[:c10] = billing_address[:zip] if billing_address[:zip] + post[:c8] = billing_address[:state] if billing_address[:state] + post[:c9] = billing_address[:country] if billing_address[:country] + post[:c2] = billing_address[:phone] if billing_address[:phone] end end @@ -289,24 +319,29 @@ def add_email(post, options) post[:c3] = options[:email] || 'unspecified@example.com' end + def add_customer_name(post, options) + post[:j5] = options[:first_name] if options[:first_name] + post[:j13] = options[:last_name] if options[:last_name] + end + def add_3d_secure(post, options) - if options[:eci] && options[:xid] + if (options[:eci] && options[:xid]) || (options[:three_d_secure] && options[:three_d_secure][:version]&.start_with?('1')) add_3d_secure_1_data(post, options) elsif options[:execute_threed] && options[:three_ds_2] three_ds_2_options = options[:three_ds_2] browser_info = three_ds_2_options[:browser_info] post[:'3ds_initiate'] = options[:three_ds_initiate] || '01' + post[:f23] = options[:f23] if options[:f23] post[:'3ds_purchasedate'] = Time.now.utc.strftime('%Y%m%d%I%M%S') options.dig(:stored_credential, :initiator) == 'merchant' ? post[:'3ds_channel'] = '03' : post[:'3ds_channel'] = '02' post[:'3ds_redirect_url'] = three_ds_2_options[:notification_url] post[:'3ds_challengewindowsize'] = options[:three_ds_challenge_window_size] || '03' - post[:'3ds_version'] = options[:three_ds_version] if options[:three_ds_version] post[:d5] = browser_info[:user_agent] - post[:'3ds_transtype'] = options[:transaction_type] || '01' + post[:'3ds_transtype'] = options[:three_ds_transtype] || '01' post[:'3ds_browsertz'] = browser_info[:timezone] post[:'3ds_browserscreenwidth'] = browser_info[:width] post[:'3ds_browserscreenheight'] = browser_info[:height] - post[:'3ds_browsercolordepth'] = browser_info[:depth] + post[:'3ds_browsercolordepth'] = browser_info[:depth].to_s == '30' ? '32' : browser_info[:depth] post[:d6] = browser_info[:language] post[:'3ds_browserjavaenabled'] = browser_info[:java] post[:'3ds_browseracceptheader'] = browser_info[:accept_header] @@ -324,7 +359,17 @@ def add_3d_secure(post, options) end def add_3d_secure_1_data(post, options) - post[:i8] = build_i8(options[:eci], options[:cavv], options[:xid]) + if three_d_secure_options = options[:three_d_secure] + post[:i8] = build_i8( + three_d_secure_options[:eci], + three_d_secure_options[:cavv], + three_d_secure_options[:xid] + ) + post[:'3ds_version'] = three_d_secure_options[:version]&.start_with?('1') ? '1.0' : three_d_secure_options[:version] + else + post[:i8] = build_i8(options[:eci], options[:cavv], options[:xid]) + post[:'3ds_version'] = options[:three_ds_version].nil? || options[:three_ds_version]&.start_with?('1') ? '1.0' : options[:three_ds_version] + end end def add_normalized_3d_secure_2_data(post, options) @@ -334,11 +379,11 @@ def add_normalized_3d_secure_2_data(post, options) three_d_secure_options[:eci], three_d_secure_options[:cavv] ) - post[:'3ds_version'] = three_d_secure_options[:version] + post[:'3ds_version'] = three_d_secure_options[:version]&.start_with?('2') ? '2.0' : three_d_secure_options[:version] post[:'3ds_dstrxid'] = three_d_secure_options[:ds_transaction_id] end - def build_i8(eci, cavv=nil, xid=nil) + def build_i8(eci, cavv = nil, xid = nil) "#{eci}:#{cavv || 'none'}:#{xid || 'none'}" end @@ -358,10 +403,15 @@ def add_transaction_type(post, options) end def add_processor(post, options) - post[:r1] = options[:processor] || 'CREDORAX' + post[:r1] = options[:processor] if options[:processor] post[:r2] = options[:processor_merchant_id] if options[:processor_merchant_id] end + def add_authorization_details(post, options) + post[:a10] = options[:authorization_type] if options[:authorization_type] + post[:a11] = options[:multiple_capture_count] if options[:multiple_capture_count] + end + ACTIONS = { purchase: '1', authorize: '2', @@ -372,7 +422,8 @@ def add_processor(post, options) purchase_void: '7', refund_void: '8', capture_void: '9', - threeds_completion: '92' + threeds_completion: '92', + referral_cft: '34' } def commit(action, params, reference_action = nil) @@ -383,7 +434,7 @@ def commit(action, params, reference_action = nil) success_from(response), message_from(response), response, - authorization: "#{response["Z1"]};#{response["Z4"]};#{response["A1"]};#{action}", + authorization: "#{response['Z1']};#{response['Z4']};#{response['A1']};#{action}", avs_result: AVSResult.new(code: response['Z9']), cvv_result: CVVResult.new(response['Z14']), test: test? @@ -392,8 +443,10 @@ def commit(action, params, reference_action = nil) def sign_request(params) params = params.sort - params.each { |param| param[1].gsub!(/[<>()\\]/, ' ') } - values = params.map { |param| param[1].strip } + values = params.map do |param| + value = param[1].gsub(/[<>()\\]/, ' ') + value.strip + end Digest::MD5.hexdigest(values.join + @options[:cipher_key]) end diff --git a/lib/active_merchant/billing/gateways/ct_payment.rb b/lib/active_merchant/billing/gateways/ct_payment.rb index 315f16375d8..6597aeb8be1 100644 --- a/lib/active_merchant/billing/gateways/ct_payment.rb +++ b/lib/active_merchant/billing/gateways/ct_payment.rb @@ -4,9 +4,9 @@ class CtPaymentGateway < Gateway self.test_url = 'https://test.ctpaiement.ca/v1/' self.live_url = 'https://www.ctpaiement.com/v1/' - self.supported_countries = ['US', 'CA'] + self.supported_countries = %w[US CA] self.default_currency = 'CAD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club] + self.supported_cardtypes = %i[visa master american_express discover diners_club] self.homepage_url = 'http://www.ct-payment.com/' self.display_name = 'CT Payment' @@ -26,12 +26,12 @@ class CtPaymentGateway < Gateway 'discover' => 'O' } - def initialize(options={}) + def initialize(options = {}) requires!(options, :api_key, :company_number, :merchant_number) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) requires!(options, :order_id) post = {} add_terminal_number(post, options) @@ -45,7 +45,7 @@ def purchase(money, payment, options={}) payment.is_a?(String) ? commit('purchaseWithToken', post) : commit('purchase', post) end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) requires!(options, :order_id) post = {} add_money(post, money) @@ -59,7 +59,7 @@ def authorize(money, payment, options={}) payment.is_a?(String) ? commit('preAuthorizationWithToken', post) : commit('preAuthorization', post) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) requires!(options, :order_id) post = {} add_invoice(post, money, options) @@ -73,7 +73,7 @@ def capture(money, authorization, options={}) commit('completion', post) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) requires!(options, :order_id) post = {} add_invoice(post, money, options) @@ -86,7 +86,7 @@ def refund(money, authorization, options={}) commit('refundWithoutCard', post) end - def credit(money, payment, options={}) + def credit(money, payment, options = {}) requires!(options, :order_id) post = {} add_terminal_number(post, options) @@ -100,7 +100,7 @@ def credit(money, payment, options={}) payment.is_a?(String) ? commit('refundWithToken', post) : commit('refund', post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} post[:InputType] = 'I' post[:LanguageCode] = 'E' @@ -113,7 +113,7 @@ def void(authorization, options={}) commit('void', post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) requires!(options, :order_id) post = {} add_terminal_number(post, options) @@ -126,7 +126,7 @@ def verify(credit_card, options={}) commit('verifyAccount', post) end - def store(credit_card, options={}) + def store(credit_card, options = {}) requires!(options, :email) post = { LanguageCode: 'E', @@ -177,7 +177,7 @@ def add_address(post, creditcard, options) end end - def add_invoice(post, money, options) + def add_invoice(post, money, options) post[:CurrencyCode] = options[:currency] || (currency(money) if money) post[:InvoiceNumber] = options[:order_id].rjust(12, '0') post[:InputType] = 'I' @@ -227,8 +227,8 @@ def commit(action, parameters) r.process { commit_raw(action, parameters) } r.process { split_auth = split_authorization(r.authorization) - auth = (action.include?('recur')? split_auth[4] : split_auth[0]) - action.include?('recur') ? commit_raw('recur/ack', {ID: auth}) : commit_raw('ack', {TransactionNumber: auth}) + auth = (action.include?('recur') ? split_auth[4] : split_auth[0]) + action.include?('recur') ? commit_raw('recur/ack', { ID: auth }) : commit_raw('ack', { TransactionNumber: auth }) } end end @@ -238,6 +238,7 @@ def success_from(response) return true if response['returnCode'] == ' 00' return true if response['returnCode'] == 'true' return true if response['recurReturnCode'] == ' 00' + return false end diff --git a/lib/active_merchant/billing/gateways/culqi.rb b/lib/active_merchant/billing/gateways/culqi.rb index 80b4d030198..150afe671b1 100644 --- a/lib/active_merchant/billing/gateways/culqi.rb +++ b/lib/active_merchant/billing/gateways/culqi.rb @@ -18,18 +18,18 @@ class CulqiGateway < Gateway self.supported_countries = ['PE'] self.default_currency = 'PEN' self.money_format = :dollars - self.supported_cardtypes = [:visa, :master, :diners_club, :american_express] + self.supported_cardtypes = %i[visa master diners_club american_express] - def initialize(options={}) + def initialize(options = {}) requires!(options, :merchant_id, :terminal_id, :secret_key) super end - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) authorize(amount, payment_method, options) end - def authorize(amount, payment_method, options={}) + def authorize(amount, payment_method, options = {}) if payment_method.is_a?(String) action = :tokenpay else @@ -45,7 +45,7 @@ def authorize(amount, payment_method, options={}) commit(action, post) end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) action = :capture post = {} add_credentials(post) @@ -56,7 +56,7 @@ def capture(amount, authorization, options={}) commit(action, post) end - def void(authorization, options={}) + def void(authorization, options = {}) action = :void post = {} add_credentials(post) @@ -67,7 +67,7 @@ def void(authorization, options={}) commit(action, post) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) action = :refund post = {} add_credentials(post) @@ -78,7 +78,7 @@ def refund(amount, authorization, options={}) commit(action, post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(1000, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -90,7 +90,7 @@ def verify_credentials response.message.include? 'Transaction not found' end - def store(credit_card, options={}) + def store(credit_card, options = {}) action = :tokenize post = {} post[:partnerid] = options[:partner_id] if options[:partner_id] @@ -103,7 +103,7 @@ def store(credit_card, options={}) commit(action, post) end - def invalidate(authorization, options={}) + def invalidate(authorization, options = {}) action = :invalidate post = {} post[:partnerid] = options[:partner_id] if options[:partner_id] @@ -173,22 +173,23 @@ def add_customer_data(post, options) post[:city] = billing_address[:city] post[:state] = billing_address[:state] post[:countrycode] = billing_address[:country] - post[:zip] = billing_address[:zip] + post[:zip] = billing_address[:zip] post[:telno] = billing_address[:phone] post[:telnocc] = options[:telephone_country_code] || '051' end end def add_checksum(action, post) - checksum_elements = case action - when :capture then [post[:toid], post[:trackingid], post[:captureamount], @options[:secret_key]] - when :void then [post[:toid], post[:description], post[:trackingid], @options[:secret_key]] - when :refund then [post[:toid], post[:trackingid], post[:refundamount], @options[:secret_key]] - when :tokenize then [post[:partnerid], post[:cardnumber], post[:cvv], @options[:secret_key]] - when :invalidate then [post[:partnerid], post[:token], @options[:secret_key]] - else [post[:toid], post[:totype], post[:amount], post[:description], post[:redirecturl], - post[:cardnumber] || post[:token], @options[:secret_key]] - end + checksum_elements = + case action + when :capture then [post[:toid], post[:trackingid], post[:captureamount], @options[:secret_key]] + when :void then [post[:toid], post[:description], post[:trackingid], @options[:secret_key]] + when :refund then [post[:toid], post[:trackingid], post[:refundamount], @options[:secret_key]] + when :tokenize then [post[:partnerid], post[:cardnumber], post[:cvv], @options[:secret_key]] + when :invalidate then [post[:partnerid], post[:token], @options[:secret_key]] + else [post[:toid], post[:totype], post[:amount], post[:description], post[:redirecturl], + post[:cardnumber] || post[:token], @options[:secret_key]] + end post[:checksum] = Digest::MD5.hexdigest(checksum_elements.compact.join('|')) end @@ -204,15 +205,16 @@ def add_reference(post, authorization) refund: 'SingleCallGenericReverse', tokenize: 'SingleCallTokenServlet', invalidate: 'SingleCallInvalidateToken', - tokenpay: 'SingleCallTokenTransaction', + tokenpay: 'SingleCallTokenTransaction' } def commit(action, params) - response = begin - parse(ssl_post(url + ACTIONS[action], post_data(action, params), headers)) - rescue ResponseError => e - parse(e.response.body) - end + response = + begin + parse(ssl_post(url + ACTIONS[action], post_data(action, params), headers)) + rescue ResponseError => e + parse(e.response.body) + end success = success_from(response) @@ -229,8 +231,8 @@ def commit(action, params) def headers { - 'Accept' => 'application/json', - 'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8' + 'Accept' => 'application/json', + 'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8' } end diff --git a/lib/active_merchant/billing/gateways/cyber_source.rb b/lib/active_merchant/billing/gateways/cyber_source.rb index 3410af712a7..ea746f10090 100644 --- a/lib/active_merchant/billing/gateways/cyber_source.rb +++ b/lib/active_merchant/billing/gateways/cyber_source.rb @@ -25,11 +25,21 @@ class CyberSourceGateway < Gateway self.live_url = 'https://ics2wsa.ic3.com/commerce/1.x/transactionProcessor' # Schema files can be found here: https://ics2ws.ic3.com/commerce/1.x/transactionProcessor/ - TEST_XSD_VERSION = '1.159' - PRODUCTION_XSD_VERSION = '1.159' - - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb, :dankort, :maestro, :elo] - self.supported_countries = %w(US BR CA CN DK FI FR DE IN JP MX NO SE GB SG LB PK) + TEST_XSD_VERSION = '1.164' + PRODUCTION_XSD_VERSION = '1.164' + ECI_BRAND_MAPPING = { + visa: 'vbv', + master: 'spa', + maestro: 'spa', + american_express: 'aesk', + jcb: 'js', + discover: 'pb', + diners_club: 'pb' + }.freeze + DEFAULT_COLLECTION_INDICATOR = 2 + + self.supported_cardtypes = %i[visa master american_express discover diners_club jcb dankort maestro elo] + self.supported_countries = %w(US AE BR CA CN DK FI FR DE IN JP MX NO SE GB SG LB PK) self.default_currency = 'USD' self.currencies_without_fractions = %w(JPY) @@ -38,56 +48,61 @@ class CyberSourceGateway < Gateway self.display_name = 'CyberSource' @@credit_card_codes = { - :visa => '001', - :master => '002', - :american_express => '003', - :discover => '004', - :diners_club => '005', - :jcb => '007', - :dankort => '034', - :maestro => '042', - :elo => '054' + visa: '001', + master: '002', + american_express: '003', + discover: '004', + diners_club: '005', + jcb: '007', + dankort: '034', + maestro: '042', + elo: '054' + } + + @@decision_codes = { + accept: 'ACCEPT', + review: 'REVIEW' } @@response_codes = { - :r100 => 'Successful transaction', - :r101 => 'Request is missing one or more required fields', - :r102 => 'One or more fields contains invalid data', - :r150 => 'General failure', - :r151 => 'The request was received but a server time-out occurred', - :r152 => 'The request was received, but a service timed out', - :r200 => 'The authorization request was approved by the issuing bank but declined by CyberSource because it did not pass the AVS check', - :r201 => 'The issuing bank has questions about the request', - :r202 => 'Expired card', - :r203 => 'General decline of the card', - :r204 => 'Insufficient funds in the account', - :r205 => 'Stolen or lost card', - :r207 => 'Issuing bank unavailable', - :r208 => 'Inactive card or card not authorized for card-not-present transactions', - :r209 => 'American Express Card Identifiction Digits (CID) did not match', - :r210 => 'The card has reached the credit limit', - :r211 => 'Invalid card verification number', - :r221 => "The customer matched an entry on the processor's negative file", - :r230 => 'The authorization request was approved by the issuing bank but declined by CyberSource because it did not pass the card verification check', - :r231 => 'Invalid account number', - :r232 => 'The card type is not accepted by the payment processor', - :r233 => 'General decline by the processor', - :r234 => 'A problem exists with your CyberSource merchant configuration', - :r235 => 'The requested amount exceeds the originally authorized amount', - :r236 => 'Processor failure', - :r237 => 'The authorization has already been reversed', - :r238 => 'The authorization has already been captured', - :r239 => 'The requested transaction amount must match the previous transaction amount', - :r240 => 'The card type sent is invalid or does not correlate with the credit card number', - :r241 => 'The request ID is invalid', - :r242 => 'You requested a capture, but there is no corresponding, unused authorization record.', - :r243 => 'The transaction has already been settled or reversed', - :r244 => 'The bank account number failed the validation check', - :r246 => 'The capture or credit is not voidable because the capture or credit information has already been submitted to your processor', - :r247 => 'You requested a credit for a capture that was previously voided', - :r250 => 'The request was received, but a time-out occurred with the payment processor', - :r254 => 'Your CyberSource account is prohibited from processing stand-alone refunds', - :r255 => 'Your CyberSource account is not configured to process the service in the country you specified' + r100: 'Successful transaction', + r101: 'Request is missing one or more required fields', + r102: 'One or more fields contains invalid data', + r150: 'General failure', + r151: 'The request was received but a server time-out occurred', + r152: 'The request was received, but a service timed out', + r200: 'The authorization request was approved by the issuing bank but declined by CyberSource because it did not pass the AVS check', + r201: 'The issuing bank has questions about the request', + r202: 'Expired card', + r203: 'General decline of the card', + r204: 'Insufficient funds in the account', + r205: 'Stolen or lost card', + r207: 'Issuing bank unavailable', + r208: 'Inactive card or card not authorized for card-not-present transactions', + r209: 'American Express Card Identifiction Digits (CID) did not match', + r210: 'The card has reached the credit limit', + r211: 'Invalid card verification number', + r221: "The customer matched an entry on the processor's negative file", + r230: 'The authorization request was approved by the issuing bank but declined by CyberSource because it did not pass the card verification check', + r231: 'Invalid account number', + r232: 'The card type is not accepted by the payment processor', + r233: 'General decline by the processor', + r234: 'A problem exists with your CyberSource merchant configuration', + r235: 'The requested amount exceeds the originally authorized amount', + r236: 'Processor failure', + r237: 'The authorization has already been reversed', + r238: 'The authorization has already been captured', + r239: 'The requested transaction amount must match the previous transaction amount', + r240: 'The card type sent is invalid or does not correlate with the credit card number', + r241: 'The request ID is invalid', + r242: 'You requested a capture, but there is no corresponding, unused authorization record.', + r243: 'The transaction has already been settled or reversed', + r244: 'The bank account number failed the validation check', + r246: 'The capture or credit is not voidable because the capture or credit information has already been submitted to your processor', + r247: 'You requested a credit for a capture that was previously voided', + r250: 'The request was received, but a time-out occurred with the payment processor', + r254: 'Your CyberSource account is prohibited from processing stand-alone refunds', + r255: 'Your CyberSource account is not configured to process the service in the country you specified' } # These are the options that can be used when creating a new CyberSource @@ -205,7 +220,7 @@ def retrieve(reference, options = {}) # This functionality is only supported by this particular gateway may # be changed at any time def calculate_tax(creditcard, options) - requires!(options, :line_items) + requires!(options, :line_items) setup_address_hash(options) commit(build_tax_calculation_request(creditcard, options), :calculate_tax, nil, options) end @@ -241,22 +256,35 @@ def verify_credentials private - # Create all address hash key value pairs so that we still function if we - # were only provided with one or two of them or even none + # Create all required address hash key value pairs + # If a value of nil is received, that value will be passed on to the gateway and will not be replaced with a default value + # Billing address fields received without an override value or with an empty string value will be replaced with the default_address values def setup_address_hash(options) default_address = { - :address1 => 'Unspecified', - :city => 'Unspecified', - :state => 'NC', - :zip => '00000', - :country => 'US' + address1: 'Unspecified', + city: 'Unspecified', + state: 'NC', + zip: '00000', + country: 'US' } - options[:billing_address] = options[:billing_address] || options[:address] || default_address + + submitted_address = options[:billing_address] || options[:address] || default_address + options[:billing_address] = default_address.merge(submitted_address.symbolize_keys) { |_k, default, submitted| check_billing_field_value(default, submitted) } options[:shipping_address] = options[:shipping_address] || {} end + def check_billing_field_value(default, submitted) + if submitted.nil? + nil + elsif submitted.blank? + default + else + submitted + end + end + def build_auth_request(money, creditcard_or_reference, options) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 add_payment_method_or_subscription(xml, money, creditcard_or_reference, options) add_threeds_2_ucaf_data(xml, creditcard_or_reference, options) add_decision_manager_fields(xml, options) @@ -265,14 +293,17 @@ def build_auth_request(money, creditcard_or_reference, options) add_threeds_services(xml, options) add_payment_network_token(xml) if network_tokenization?(creditcard_or_reference) add_business_rules_data(xml, creditcard_or_reference, options) - add_stored_credential_options(xml, options) + add_stored_credential_subsequent_auth(xml, options) add_issuer_additional_data(xml, options) + add_partner_solution_id(xml) + add_stored_credential_options(xml, options) + add_merchant_description(xml, options) xml.target! end def build_tax_calculation_request(creditcard, options) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 add_address(xml, creditcard, options[:billing_address], options, false) add_address(xml, creditcard, options[:shipping_address], options, true) add_line_item_data(xml, options) @@ -286,43 +317,62 @@ def build_capture_request(money, authorization, options) order_id, request_id, request_token = authorization.split(';') options[:order_id] = order_id - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 add_purchase_data(xml, money, true, options) + add_other_tax(xml, options) + add_mdd_fields(xml, options) add_capture_service(xml, request_id, request_token) add_business_rules_data(xml, authorization, options) + add_issuer_additional_data(xml, options) + add_merchant_description(xml, options) + add_partner_solution_id(xml) + xml.target! end def build_purchase_request(money, payment_method_or_reference, options) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 add_payment_method_or_subscription(xml, money, payment_method_or_reference, options) add_threeds_2_ucaf_data(xml, payment_method_or_reference, options) add_decision_manager_fields(xml, options) add_mdd_fields(xml, options) if !payment_method_or_reference.is_a?(String) && card_brand(payment_method_or_reference) == 'check' add_check_service(xml) + add_issuer_additional_data(xml, options) + add_partner_solution_id(xml) else add_purchase_service(xml, payment_method_or_reference, options) add_threeds_services(xml, options) add_payment_network_token(xml) if network_tokenization?(payment_method_or_reference) add_business_rules_data(xml, payment_method_or_reference, options) unless options[:pinless_debit_card] + add_stored_credential_subsequent_auth(xml, options) + add_issuer_additional_data(xml, options) + add_partner_solution_id(xml) + add_stored_credential_options(xml, options) end - add_issuer_additional_data(xml, options) + + add_merchant_description(xml, options) xml.target! end def build_void_request(identification, options) - order_id, request_id, request_token, action, money, currency = identification.split(';') + order_id, request_id, request_token, action, money, currency = identification.split(';') options[:order_id] = order_id - xml = Builder::XmlMarkup.new :indent => 2 - if action == 'capture' + xml = Builder::XmlMarkup.new indent: 2 + case action + when 'capture', 'purchase' + add_mdd_fields(xml, options) add_void_service(xml, request_id, request_token) else - add_purchase_data(xml, money, true, options.merge(:currency => currency || default_currency)) + add_purchase_data(xml, money, true, options.merge(currency: currency || default_currency)) + add_mdd_fields(xml, options) add_auth_reversal_service(xml, request_id, request_token) end + add_issuer_additional_data(xml, options) + add_partner_solution_id(xml) + xml.target! end @@ -330,29 +380,33 @@ def build_refund_request(money, identification, options) order_id, request_id, request_token = identification.split(';') options[:order_id] = order_id - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 add_purchase_data(xml, money, true, options) add_credit_service(xml, request_id, request_token) + add_partner_solution_id(xml) xml.target! end def build_credit_request(money, creditcard_or_reference, options) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 add_payment_method_or_subscription(xml, money, creditcard_or_reference, options) + add_mdd_fields(xml, options) add_credit_service(xml) + add_issuer_additional_data(xml, options) + add_merchant_description(xml, options) xml.target! end def build_create_subscription_request(payment_method, options) - default_subscription_params = {:frequency => 'on-demand', :amount => 0, :automatic_renew => false} + default_subscription_params = { frequency: 'on-demand', amount: 0, automatic_renew: false } options[:subscription] = default_subscription_params.update( options[:subscription] || {} ) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 add_address(xml, payment_method, options[:billing_address], options) add_purchase_data(xml, options[:setup_fee] || 0, true, options) if card_brand(payment_method) == 'check' @@ -377,7 +431,7 @@ def build_create_subscription_request(payment_method, options) end def build_update_subscription_request(reference, creditcard, options) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 add_address(xml, creditcard, options[:billing_address], options) unless options[:billing_address].blank? add_purchase_data(xml, options[:setup_fee], true, options) unless options[:setup_fee].blank? add_creditcard(xml, creditcard) if creditcard @@ -389,21 +443,21 @@ def build_update_subscription_request(reference, creditcard, options) end def build_delete_subscription_request(reference, options) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 add_subscription(xml, options, reference) add_subscription_delete_service(xml, options) xml.target! end def build_retrieve_subscription_request(reference, options) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 add_subscription(xml, options, reference) add_subscription_retrieve_service(xml, options) xml.target! end def build_validate_pinless_debit_request(creditcard, options) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 add_creditcard(xml, creditcard) add_validate_pinless_debit_service(xml) xml.target! @@ -429,7 +483,7 @@ def extract_option(prioritized_options, option_name) def add_line_item_data(xml, options) options[:line_items].each_with_index do |value, index| - xml.tag! 'item', {'id' => index} do + xml.tag! 'item', { 'id' => index } do xml.tag! 'unitPrice', localized_amount(value[:declared_value].to_i, options[:currency] || default_currency) xml.tag! 'quantity', value[:quantity] xml.tag! 'productCode', value[:code] || 'shipping_only' @@ -443,23 +497,47 @@ def add_merchant_data(xml, options) xml.tag! 'merchantID', @options[:login] xml.tag! 'merchantReferenceCode', options[:order_id] || generate_unique_id xml.tag! 'clientLibrary', 'Ruby Active Merchant' - xml.tag! 'clientLibraryVersion', VERSION + xml.tag! 'clientLibraryVersion', VERSION xml.tag! 'clientEnvironment', RUBY_PLATFORM + + add_merchant_descriptor(xml, options) end - def add_purchase_data(xml, money = 0, include_grand_total = false, options={}) + def add_merchant_descriptor(xml, options) + return unless options[:merchant_descriptor] + + xml.tag! 'invoiceHeader' do + xml.tag! 'merchantDescriptor', options[:merchant_descriptor] + end + end + + def add_merchant_description(xml, options) + return unless options[:merchant_descriptor_name] || options[:merchant_descriptor_address1] || options[:merchant_descriptor_locality] + + xml.tag! 'merchantInformation' do + xml.tag! 'merchantDescriptor' do + xml.tag! 'name', options[:merchant_descriptor_name] if options[:merchant_descriptor_name] + xml.tag! 'address1', options[:merchant_descriptor_address1] if options[:merchant_descriptor_address1] + xml.tag! 'locality', options[:merchant_descriptor_locality] if options[:merchant_descriptor_locality] + end + end + end + + def add_purchase_data(xml, money = 0, include_grand_total = false, options = {}) xml.tag! 'purchaseTotals' do xml.tag! 'currency', options[:currency] || currency(money) - xml.tag!('grandTotalAmount', localized_amount(money.to_i, options[:currency] || default_currency)) if include_grand_total + xml.tag!('grandTotalAmount', localized_amount(money.to_i, options[:currency] || default_currency)) if include_grand_total end end def add_address(xml, payment_method, address, options, shipTo = false) + first_name, last_name = address_names(address[:name], payment_method) + xml.tag! shipTo ? 'shipTo' : 'billTo' do - xml.tag! 'firstName', payment_method.first_name if payment_method - xml.tag! 'lastName', payment_method.last_name if payment_method + xml.tag! 'firstName', first_name if first_name + xml.tag! 'lastName', last_name if last_name xml.tag! 'street1', address[:address1] - xml.tag! 'street2', address[:address2] unless address[:address2].blank? + xml.tag! 'street2', address[:address2] unless address[:address2].blank? xml.tag! 'city', address[:city] xml.tag! 'state', address[:state] xml.tag! 'postalCode', address[:zip] @@ -467,13 +545,23 @@ def add_address(xml, payment_method, address, options, shipTo = false) xml.tag! 'company', address[:company] unless address[:company].blank? xml.tag! 'companyTaxID', address[:companyTaxID] unless address[:company_tax_id].blank? xml.tag! 'phoneNumber', address[:phone] unless address[:phone].blank? - xml.tag! 'email', options[:email] || 'null@cybersource.com' + xml.tag! 'email', options[:email].presence || 'null@cybersource.com' xml.tag! 'ipAddress', options[:ip] unless options[:ip].blank? || shipTo xml.tag! 'driversLicenseNumber', options[:drivers_license_number] unless options[:drivers_license_number].blank? xml.tag! 'driversLicenseState', options[:drivers_license_state] unless options[:drivers_license_state].blank? end end + def address_names(address_name, payment_method) + names = split_names(address_name) + return names if names.any?(&:present?) + + [ + payment_method&.first_name, + payment_method&.last_name + ] + end + def add_creditcard(xml, creditcard) xml.tag! 'card' do xml.tag! 'accountNumber', creditcard.number @@ -501,8 +589,17 @@ def add_issuer_additional_data(xml, options) end end + def add_other_tax(xml, options) + return unless options[:local_tax_amount] || options[:national_tax_amount] + + xml.tag! 'otherTax' do + xml.tag! 'localTaxAmount', options[:local_tax_amount] if options[:local_tax_amount] + xml.tag! 'nationalTaxAmount', options[:national_tax_amount] if options[:national_tax_amount] + end + end + def add_mdd_fields(xml, options) - return unless options.keys.any? { |key| key.to_s.start_with?('mdd_field') } + return unless options.keys.any? { |key| key.to_s.start_with?('mdd_field') && options[key] } xml.tag! 'merchantDefinedData' do (1..100).each do |each| @@ -521,7 +618,7 @@ def add_check(xml, check) end def add_tax_service(xml) - xml.tag! 'taxService', {'run' => 'true'} do + xml.tag! 'taxService', { 'run' => 'true' } do xml.tag!('nexus', @options[:nexus]) unless @options[:nexus].blank? xml.tag!('sellerRegistration', @options[:vat_reg_number]) unless @options[:vat_reg_number].blank? end @@ -531,43 +628,62 @@ def add_auth_service(xml, payment_method, options) if network_tokenization?(payment_method) add_auth_network_tokenization(xml, payment_method, options) else - xml.tag! 'ccAuthService', {'run' => 'true'} do + xml.tag! 'ccAuthService', { 'run' => 'true' } do if options[:three_d_secure] add_normalized_threeds_2_data(xml, payment_method, options) else indicator = options[:commerce_indicator] || stored_credential_commerce_indicator(options) xml.tag!('commerceIndicator', indicator) if indicator end + xml.tag!('reconciliationID', options[:reconciliation_id]) if options[:reconciliation_id] end end end def add_normalized_threeds_2_data(xml, payment_method, options) threeds_2_options = options[:three_d_secure] + cc_brand = card_brand(payment_method).to_sym + + return if threeds_2_options[:cavv].blank? && infer_commerce_indicator?(options, cc_brand) + + xid = threeds_2_options[:xid] - xml.tag!('cavv', threeds_2_options[:cavv]) if threeds_2_options[:cavv] && card_brand(payment_method).to_sym != :master + xml.tag!('cavv', threeds_2_options[:cavv]) if threeds_2_options[:cavv] && cc_brand != :master xml.tag!('cavvAlgorithm', threeds_2_options[:cavv_algorithm]) if threeds_2_options[:cavv_algorithm] xml.tag!('paSpecificationVersion', threeds_2_options[:version]) if threeds_2_options[:version] xml.tag!('directoryServerTransactionID', threeds_2_options[:ds_transaction_id]) if threeds_2_options[:ds_transaction_id] - xml.tag!('commerceIndicator', options[:commerce_indicator]) if options[:commerce_indicator] + xml.tag!('commerceIndicator', options[:commerce_indicator] || ECI_BRAND_MAPPING[cc_brand]) xml.tag!('eciRaw', threeds_2_options[:eci]) if threeds_2_options[:eci] - xml.tag!('xid', threeds_2_options[:xid]) if threeds_2_options[:xid] + + if xid.present? + xml.tag!('xid', xid) + elsif threeds_2_options[:version]&.start_with?('2') && cc_brand != :master + cavv = threeds_2_options[:cavv] + xml.tag!('xid', cavv) if cavv.present? + end + xml.tag!('veresEnrolled', threeds_2_options[:enrolled]) if threeds_2_options[:enrolled] xml.tag!('paresStatus', threeds_2_options[:authentication_response_status]) if threeds_2_options[:authentication_response_status] end + def infer_commerce_indicator?(options, cc_brand) + options[:commerce_indicator].blank? && ECI_BRAND_MAPPING[cc_brand].present? + end + def add_threeds_2_ucaf_data(xml, payment_method, options) return unless options[:three_d_secure] && card_brand(payment_method).to_sym == :master xml.tag! 'ucaf' do xml.tag!('authenticationData', options[:three_d_secure][:cavv]) - xml.tag!('collectionIndicator', options[:collection_indicator]) if options[:collection_indicator] + xml.tag!('collectionIndicator', options[:collection_indicator] || DEFAULT_COLLECTION_INDICATOR) end end def stored_credential_commerce_indicator(options) return unless options[:stored_credential] + return if options[:stored_credential][:initial_transaction] + case options[:stored_credential][:reason_type] when 'installment' then 'install' when 'recurring' then 'recurring' @@ -581,27 +697,32 @@ def network_tokenization?(payment_method) def add_auth_network_tokenization(xml, payment_method, options) return unless network_tokenization?(payment_method) - case card_brand(payment_method).to_sym + brand = card_brand(payment_method).to_sym + + case brand when :visa - xml.tag! 'ccAuthService', {'run' => 'true'} do + xml.tag! 'ccAuthService', { 'run' => 'true' } do xml.tag!('cavv', payment_method.payment_cryptogram) - xml.tag!('commerceIndicator', 'vbv') + xml.tag!('commerceIndicator', ECI_BRAND_MAPPING[brand]) xml.tag!('xid', payment_method.payment_cryptogram) + xml.tag!('reconciliationID', options[:reconciliation_id]) if options[:reconciliation_id] end when :master xml.tag! 'ucaf' do xml.tag!('authenticationData', payment_method.payment_cryptogram) - xml.tag!('collectionIndicator', '2') + xml.tag!('collectionIndicator', DEFAULT_COLLECTION_INDICATOR) end - xml.tag! 'ccAuthService', {'run' => 'true'} do - xml.tag!('commerceIndicator', 'spa') + xml.tag! 'ccAuthService', { 'run' => 'true' } do + xml.tag!('commerceIndicator', ECI_BRAND_MAPPING[brand]) + xml.tag!('reconciliationID', options[:reconciliation_id]) if options[:reconciliation_id] end when :american_express cryptogram = Base64.decode64(payment_method.payment_cryptogram) - xml.tag! 'ccAuthService', {'run' => 'true'} do + xml.tag! 'ccAuthService', { 'run' => 'true' } do xml.tag!('cavv', Base64.encode64(cryptogram[0...20])) - xml.tag!('commerceIndicator', 'aesk') + xml.tag!('commerceIndicator', ECI_BRAND_MAPPING[brand]) xml.tag!('xid', Base64.encode64(cryptogram[20...40])) + xml.tag!('reconciliationID', options[:reconciliation_id]) if options[:reconciliation_id] end end end @@ -613,60 +734,65 @@ def add_payment_network_token(xml) end def add_capture_service(xml, request_id, request_token) - xml.tag! 'ccCaptureService', {'run' => 'true'} do + xml.tag! 'ccCaptureService', { 'run' => 'true' } do xml.tag! 'authRequestID', request_id xml.tag! 'authRequestToken', request_token + xml.tag! 'reconciliationID', options[:reconciliation_id] if options[:reconciliation_id] end end def add_purchase_service(xml, payment_method, options) if options[:pinless_debit_card] - xml.tag! 'pinlessDebitService', {'run' => 'true'} + xml.tag! 'pinlessDebitService', { 'run' => 'true' } do + xml.tag!('reconciliationID', options[:reconciliation_id]) if options[:reconciliation_id] + end else add_auth_service(xml, payment_method, options) - xml.tag! 'ccCaptureService', {'run' => 'true'} + xml.tag! 'ccCaptureService', { 'run' => 'true' } do + xml.tag!('reconciliationID', options[:reconciliation_id]) if options[:reconciliation_id] + end end end def add_void_service(xml, request_id, request_token) - xml.tag! 'voidService', {'run' => 'true'} do + xml.tag! 'voidService', { 'run' => 'true' } do xml.tag! 'voidRequestID', request_id xml.tag! 'voidRequestToken', request_token end end def add_auth_reversal_service(xml, request_id, request_token) - xml.tag! 'ccAuthReversalService', {'run' => 'true'} do + xml.tag! 'ccAuthReversalService', { 'run' => 'true' } do xml.tag! 'authRequestID', request_id xml.tag! 'authRequestToken', request_token end end def add_credit_service(xml, request_id = nil, request_token = nil) - xml.tag! 'ccCreditService', {'run' => 'true'} do + xml.tag! 'ccCreditService', { 'run' => 'true' } do xml.tag! 'captureRequestID', request_id if request_id xml.tag! 'captureRequestToken', request_token if request_token end end def add_check_service(xml) - xml.tag! 'ecDebitService', {'run' => 'true'} + xml.tag! 'ecDebitService', { 'run' => 'true' } end def add_subscription_create_service(xml, options) - xml.tag! 'paySubscriptionCreateService', {'run' => 'true'} + xml.tag! 'paySubscriptionCreateService', { 'run' => 'true' } end def add_subscription_update_service(xml, options) - xml.tag! 'paySubscriptionUpdateService', {'run' => 'true'} + xml.tag! 'paySubscriptionUpdateService', { 'run' => 'true' } end def add_subscription_delete_service(xml, options) - xml.tag! 'paySubscriptionDeleteService', {'run' => 'true'} + xml.tag! 'paySubscriptionDeleteService', { 'run' => 'true' } end def add_subscription_retrieve_service(xml, options) - xml.tag! 'paySubscriptionRetrieveService', {'run' => 'true'} + xml.tag! 'paySubscriptionRetrieveService', { 'run' => 'true' } end def add_subscription(xml, options, reference = nil) @@ -678,7 +804,7 @@ def add_subscription(xml, options, reference = nil) xml.tag! 'subscriptionID', subscription_id end - xml.tag! 'status', options[:subscription][:status] if options[:subscription][:status] + xml.tag! 'status', options[:subscription][:status] if options[:subscription][:status] xml.tag! 'amount', localized_amount(options[:subscription][:amount].to_i, options[:currency] || default_currency) if options[:subscription][:amount] xml.tag! 'numberOfPayments', options[:subscription][:occurrences] if options[:subscription][:occurrences] xml.tag! 'automaticRenew', options[:subscription][:automatic_renew] if options[:subscription][:automatic_renew] @@ -706,27 +832,38 @@ def add_check_payment_method(xml) def add_payment_method_or_subscription(xml, money, payment_method_or_reference, options) if payment_method_or_reference.is_a?(String) add_purchase_data(xml, money, true, options) + add_installments(xml, options) add_subscription(xml, options, payment_method_or_reference) elsif card_brand(payment_method_or_reference) == 'check' add_address(xml, payment_method_or_reference, options[:billing_address], options) add_purchase_data(xml, money, true, options) + add_installments(xml, options) add_check(xml, payment_method_or_reference) else add_address(xml, payment_method_or_reference, options[:billing_address], options) add_address(xml, payment_method_or_reference, options[:shipping_address], options, true) add_purchase_data(xml, money, true, options) + add_installments(xml, options) add_creditcard(xml, payment_method_or_reference) end end + def add_installments(xml, options) + return unless options[:installment_total_count] + + xml.tag! 'installment' do + xml.tag! 'totalCount', options[:installment_total_count] + end + end + def add_validate_pinless_debit_service(xml) - xml.tag! 'pinlessDebitValidateService', {'run' => 'true'} + xml.tag! 'pinlessDebitValidateService', { 'run' => 'true' } end def add_threeds_services(xml, options) - xml.tag! 'payerAuthEnrollService', {'run' => 'true'} if options[:payer_auth_enroll_service] + xml.tag! 'payerAuthEnrollService', { 'run' => 'true' } if options[:payer_auth_enroll_service] if options[:payer_auth_validate_service] - xml.tag! 'payerAuthValidateService', {'run' => 'true'} do + xml.tag! 'payerAuthValidateService', { 'run' => 'true' } do xml.tag! 'signedPARes', options[:pares] end end @@ -737,35 +874,55 @@ def lookup_country_code(country_field) country_code&.code(:alpha2) end - def add_stored_credential_options(xml, options={}) - return unless options[:stored_credential] - if options[:stored_credential][:initial_transaction] - xml.tag! 'subsequentAuthFirst', 'true' - elsif options[:stored_credential][:reason_type] == 'unscheduled' - xml.tag! 'subsequentAuth', 'true' - xml.tag! 'subsequentAuthTransactionID', options[:stored_credential][:network_transaction_id] - else - xml.tag! 'subsequentAuthTransactionID', options[:stored_credential][:network_transaction_id] - end + def add_stored_credential_subsequent_auth(xml, options = {}) + return unless options[:stored_credential] || options[:stored_credential_overrides] + + stored_credential_subsequent_auth = 'true' if options.dig(:stored_credential, :initiator) == 'merchant' + + override_subsequent_auth = options.dig(:stored_credential_overrides, :subsequent_auth) + + xml.subsequentAuth override_subsequent_auth.nil? ? stored_credential_subsequent_auth : override_subsequent_auth + end + + def add_stored_credential_options(xml, options = {}) + return unless options[:stored_credential] || options[:stored_credential_overrides] + + stored_credential_subsequent_auth_first = 'true' if options.dig(:stored_credential, :initial_transaction) + stored_credential_transaction_id = options.dig(:stored_credential, :network_transaction_id) if options.dig(:stored_credential, :initiator) == 'merchant' + stored_credential_subsequent_auth_stored_cred = 'true' if options.dig(:stored_credential, :initiator) == 'cardholder' && !options.dig(:stored_credential, :initial_transaction) || options.dig(:stored_credential, :initiator) == 'merchant' && options.dig(:stored_credential, :reason_type) == 'unscheduled' + + override_subsequent_auth_first = options.dig(:stored_credential_overrides, :subsequent_auth_first) + override_subsequent_auth_transaction_id = options.dig(:stored_credential_overrides, :subsequent_auth_transaction_id) + override_subsequent_auth_stored_cred = options.dig(:stored_credential_overrides, :subsequent_auth_stored_credential) + + xml.subsequentAuthFirst override_subsequent_auth_first.nil? ? stored_credential_subsequent_auth_first : override_subsequent_auth_first + xml.subsequentAuthTransactionID override_subsequent_auth_transaction_id.nil? ? stored_credential_transaction_id : override_subsequent_auth_transaction_id + xml.subsequentAuthStoredCredential override_subsequent_auth_stored_cred.nil? ? stored_credential_subsequent_auth_stored_cred : override_subsequent_auth_stored_cred + end + + def add_partner_solution_id(xml) + return unless application_id + + xml.tag!('partnerSolutionID', application_id) end # Where we actually build the full SOAP request using builder def build_request(body, options) xsd_version = test? ? TEST_XSD_VERSION : PRODUCTION_XSD_VERSION - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.instruct! - xml.tag! 's:Envelope', {'xmlns:s' => 'http://schemas.xmlsoap.org/soap/envelope/'} do + xml.tag! 's:Envelope', { 'xmlns:s' => 'http://schemas.xmlsoap.org/soap/envelope/' } do xml.tag! 's:Header' do - xml.tag! 'wsse:Security', {'s:mustUnderstand' => '1', 'xmlns:wsse' => 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'} do + xml.tag! 'wsse:Security', { 's:mustUnderstand' => '1', 'xmlns:wsse' => 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' } do xml.tag! 'wsse:UsernameToken' do xml.tag! 'wsse:Username', @options[:login] xml.tag! 'wsse:Password', @options[:password], 'Type' => 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText' end end end - xml.tag! 's:Body', {'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema'} do - xml.tag! 'requestMessage', {'xmlns' => "urn:schemas-cybersource-com:transaction-data-#{xsd_version}"} do + xml.tag! 's:Body', { 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema' } do + xml.tag! 'requestMessage', { 'xmlns' => "urn:schemas-cybersource-com:transaction-data-#{xsd_version}" } do add_merchant_data(xml, options) xml << body end @@ -789,17 +946,16 @@ def commit(request, action, amount, options) response = { message: e.to_s } end - success = response[:decision] == 'ACCEPT' - message = response[:message] - - authorization = success ? authorization_from(response, action, amount, options) : nil + success = success?(response) + message = message_from(response) + authorization = success || in_fraud_review?(response) ? authorization_from(response, action, amount, options) : nil Response.new(success, message, response, - :test => test?, - :authorization => authorization, - :avs_result => { :code => response[:avsCode] }, - :cvv_result => response[:cvCode] - ) + test: test?, + authorization: authorization, + fraud_review: in_fraud_review?(response), + avs_result: { code: response[:avsCode] }, + cvv_result: response[:cvCode]) end # Parse the SOAP response @@ -828,7 +984,7 @@ def parse_element(reply, node) if node.has_elements? node.elements.each { |e| parse_element(reply, e) } else - if node.parent.name =~ /item/ + if /item/.match?(node.parent.name) parent = node.parent.name parent += '_' + node.parent.attributes['id'] if node.parent.attributes['id'] parent += '_' @@ -840,6 +996,7 @@ def parse_element(reply, node) def reason_message(reason_code) return if reason_code.blank? + @@response_codes[:"r#{reason_code}"] end @@ -847,6 +1004,24 @@ def authorization_from(response, action, amount, options) [options[:order_id], response[:requestID], response[:requestToken], action, amount, options[:currency], response[:subscriptionID]].join(';') end + + def in_fraud_review?(response) + response[:decision] == @@decision_codes[:review] + end + + def success?(response) + response[:decision] == @@decision_codes[:accept] + end + + def message_from(response) + if response[:reasonCode] == '101' && response[:missingField] + "#{response[:message]}: #{response[:missingField]}" + elsif response[:reasonCode] == '102' && response[:invalidField] + "#{response[:message]}: #{response[:invalidField]}" + else + response[:message] + end + end end end end diff --git a/lib/active_merchant/billing/gateways/d_local.rb b/lib/active_merchant/billing/gateways/d_local.rb index 19739582f00..7798fb19c32 100644 --- a/lib/active_merchant/billing/gateways/d_local.rb +++ b/lib/active_merchant/billing/gateways/d_local.rb @@ -4,40 +4,40 @@ class DLocalGateway < Gateway self.test_url = 'https://sandbox.dlocal.com' self.live_url = 'https://api.dlocal.com' - self.supported_countries = ['AR', 'BR', 'CL', 'CO', 'MX', 'PE', 'UY', 'TR'] + self.supported_countries = %w[AR BR CL CO MX PE UY TR] self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club, :maestro, :naranja, :cabal] + self.supported_cardtypes = %i[visa master american_express discover jcb diners_club maestro naranja cabal] self.homepage_url = 'https://dlocal.com/' self.display_name = 'dLocal' - def initialize(options={}) + def initialize(options = {}) requires!(options, :login, :trans_key, :secret_key) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) post = {} add_auth_purchase_params(post, money, payment, 'purchase', options) commit('purchase', post, options) end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) post = {} add_auth_purchase_params(post, money, payment, 'authorize', options) commit('authorize', post, options) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) post = {} - post[:payment_id] = authorization + post[:authorization_id] = authorization add_invoice(post, money, options) if money commit('capture', post, options) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) post = {} post[:payment_id] = authorization post[:notification_url] = options[:notification_url] @@ -45,13 +45,13 @@ def refund(money, authorization, options={}) commit('refund', post, options) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} - post[:payment_id] = authorization + post[:authorization_id] = authorization commit('void', post, options) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -89,11 +89,14 @@ def add_invoice(post, money, options) def add_country(post, card, options) return unless address = options[:billing_address] || options[:address] + post[:country] = lookup_country_code(address[:country]) end - def lookup_country_code(country) - Country.find(country).code(:alpha2).value + def lookup_country_code(country_field) + Country.find(country_field).code(:alpha2).value + rescue InvalidCountryCodeError + nil end def add_payer(post, card, options) @@ -111,16 +114,31 @@ def add_payer(post, card, options) def add_address(post, card, options) return unless address = options[:billing_address] || options[:address] + address_object = {} address_object[:state] = address[:state] if address[:state] address_object[:city] = address[:city] if address[:city] - address_object[:zip_code] = address[:zip_code] if address[:zip_code] - address_object[:street] = address[:street] if address[:street] - address_object[:number] = address[:number] if address[:number] + address_object[:zip_code] = address[:zip] if address[:zip] + address_object[:street] = address[:street] || parse_street(address) if parse_street(address) + address_object[:number] = address[:number] || parse_house_number(address) if parse_house_number(address) address_object end - def add_card(post, card, action, options={}) + def parse_street(address) + return unless address[:address1] + + street = address[:address1].split(/\s+/).keep_if { |x| x !~ /\d/ }.join(' ') + street.empty? ? nil : street + end + + def parse_house_number(address) + return unless address[:address1] + + house = address[:address1].split(/\s+/).keep_if { |x| x =~ /\d/ }.join(' ') + house.empty? ? nil : house + end + + def add_card(post, card, action, options = {}) post[:card] = {} post[:card][:holder_name] = card.name post[:card][:expiration_month] = card.month @@ -129,13 +147,15 @@ def add_card(post, card, action, options={}) post[:card][:cvv] = card.verification_value post[:card][:descriptor] = options[:dynamic_descriptor] if options[:dynamic_descriptor] post[:card][:capture] = (action == 'purchase') + post[:card][:installments] = options[:installments] if options[:installments] + post[:card][:installments_id] = options[:installments_id] if options[:installments_id] end def parse(body) JSON.parse(body) end - def commit(action, parameters, options={}) + def commit(action, parameters, options = {}) url = url(action, parameters, options) post = post_data(action, parameters) begin @@ -163,7 +183,8 @@ def commit(action, parameters, options={}) # we count 100 as a success. def success_from(action, response) return false unless response['status_code'] - ['100', '200', '400', '600'].include? response['status_code'].to_s + + %w[100 200 400 600].include? response['status_code'].to_s end def message_from(action, response) @@ -176,11 +197,12 @@ def authorization_from(response) def error_code_from(action, response) return if success_from(action, response) + code = response['status_code'] || response['code'] code&.to_s end - def url(action, parameters, options={}) + def url(action, parameters, options = {}) "#{(test? ? test_url : live_url)}/#{endpoint(action, parameters, options)}/" end @@ -193,13 +215,13 @@ def endpoint(action, parameters, options) when 'refund' 'refunds' when 'capture' - "payments/#{parameters[:payment_id]}/capture" + 'payments' when 'void' - "payments/#{parameters[:payment_id]}/cancel" + "payments/#{parameters[:authorization_id]}/cancel" end end - def headers(post, options={}) + def headers(post, options = {}) timestamp = Time.now.utc.iso8601 headers = { 'Content-Type' => 'application/json', diff --git a/lib/active_merchant/billing/gateways/data_cash.rb b/lib/active_merchant/billing/gateways/data_cash.rb index def3288babf..46058035510 100644 --- a/lib/active_merchant/billing/gateways/data_cash.rb +++ b/lib/active_merchant/billing/gateways/data_cash.rb @@ -6,7 +6,7 @@ class DataCashGateway < Gateway self.default_currency = 'GBP' self.supported_countries = ['GB'] - self.supported_cardtypes = [ :visa, :master, :american_express, :discover, :diners_club, :jcb, :maestro ] + self.supported_cardtypes = %i[visa master american_express discover diners_club jcb maestro] self.homepage_url = 'http://www.datacash.com/' self.display_name = 'DataCash' @@ -92,9 +92,9 @@ def scrub(transcript) def build_void_or_capture_request(type, money, authorization, options) parsed_authorization = parse_authorization_string(authorization) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.instruct! - xml.tag! :Request, :version => '2' do + xml.tag! :Request, version: '2' do add_authentication(xml) xml.tag! :Transaction do @@ -107,7 +107,7 @@ def build_void_or_capture_request(type, money, authorization, options) if money xml.tag! :TxnDetails do xml.tag! :merchantreference, format_reference_number(options[:order_id]) - xml.tag! :amount, amount(money), :currency => options[:currency] || currency(money) + xml.tag! :amount, amount(money), currency: options[:currency] || currency(money) xml.tag! :capturemethod, 'ecomm' end end @@ -117,22 +117,20 @@ def build_void_or_capture_request(type, money, authorization, options) end def build_purchase_or_authorization_request_with_credit_card_request(type, money, credit_card, options) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.instruct! - xml.tag! :Request, :version => '2' do + xml.tag! :Request, version: '2' do add_authentication(xml) xml.tag! :Transaction do - if options[:set_up_continuous_authority] - xml.tag! :ContAuthTxn, :type => 'setup' - end + xml.tag! :ContAuthTxn, type: 'setup' if options[:set_up_continuous_authority] xml.tag! :CardTxn do xml.tag! :method, type add_credit_card(xml, credit_card, options[:billing_address]) end xml.tag! :TxnDetails do xml.tag! :merchantreference, format_reference_number(options[:order_id]) - xml.tag! :amount, amount(money), :currency => options[:currency] || currency(money) + xml.tag! :amount, amount(money), currency: options[:currency] || currency(money) xml.tag! :capturemethod, 'ecomm' end end @@ -144,19 +142,19 @@ def build_purchase_or_authorization_request_with_continuous_authority_reference_ parsed_authorization = parse_authorization_string(authorization) raise ArgumentError, 'The continuous authority reference is required for continuous authority transactions' if parsed_authorization[:ca_reference].blank? - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.instruct! - xml.tag! :Request, :version => '2' do + xml.tag! :Request, version: '2' do add_authentication(xml) xml.tag! :Transaction do - xml.tag! :ContAuthTxn, :type => 'historic' + xml.tag! :ContAuthTxn, type: 'historic' xml.tag! :HistoricTxn do xml.tag! :reference, parsed_authorization[:ca_reference] xml.tag! :method, type end xml.tag! :TxnDetails do xml.tag! :merchantreference, format_reference_number(options[:order_id]) - xml.tag! :amount, amount(money), :currency => options[:currency] || currency(money) + xml.tag! :amount, amount(money), currency: options[:currency] || currency(money) xml.tag! :capturemethod, 'cont_auth' end end @@ -166,9 +164,9 @@ def build_purchase_or_authorization_request_with_continuous_authority_reference_ def build_transaction_refund_request(money, authorization) parsed_authorization = parse_authorization_string(authorization) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.instruct! - xml.tag! :Request, :version => '2' do + xml.tag! :Request, version: '2' do add_authentication(xml) xml.tag! :Transaction do xml.tag! :HistoricTxn do @@ -187,9 +185,9 @@ def build_transaction_refund_request(money, authorization) end def build_credit_request(money, credit_card, options) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.instruct! - xml.tag! :Request, :version => '2' do + xml.tag! :Request, version: '2' do add_authentication(xml) xml.tag! :Transaction do xml.tag! :CardTxn do @@ -237,23 +235,23 @@ def add_credit_card(xml, credit_card, address) # a predefined one xml.tag! :ExtendedPolicy do xml.tag! :cv2_policy, - :notprovided => POLICY_REJECT, - :notchecked => POLICY_REJECT, - :matched => POLICY_ACCEPT, - :notmatched => POLICY_REJECT, - :partialmatch => POLICY_REJECT + notprovided: POLICY_REJECT, + notchecked: POLICY_REJECT, + matched: POLICY_ACCEPT, + notmatched: POLICY_REJECT, + partialmatch: POLICY_REJECT xml.tag! :postcode_policy, - :notprovided => POLICY_ACCEPT, - :notchecked => POLICY_ACCEPT, - :matched => POLICY_ACCEPT, - :notmatched => POLICY_REJECT, - :partialmatch => POLICY_ACCEPT + notprovided: POLICY_ACCEPT, + notchecked: POLICY_ACCEPT, + matched: POLICY_ACCEPT, + notmatched: POLICY_REJECT, + partialmatch: POLICY_ACCEPT xml.tag! :address_policy, - :notprovided => POLICY_ACCEPT, - :notchecked => POLICY_ACCEPT, - :matched => POLICY_ACCEPT, - :notmatched => POLICY_REJECT, - :partialmatch => POLICY_ACCEPT + notprovided: POLICY_ACCEPT, + notchecked: POLICY_ACCEPT, + matched: POLICY_ACCEPT, + notmatched: POLICY_REJECT, + partialmatch: POLICY_ACCEPT end end end @@ -263,9 +261,8 @@ def commit(request) response = parse(ssl_post(test? ? self.test_url : self.live_url, request)) Response.new(response[:status] == '1', response[:reason], response, - :test => test?, - :authorization => "#{response[:datacash_reference]};#{response[:authcode]};#{response[:ca_reference]}" - ) + test: test?, + authorization: "#{response[:datacash_reference]};#{response[:authcode]};#{response[:ca_reference]}") end def format_date(month, year) @@ -298,7 +295,7 @@ def format_reference_number(number) def parse_authorization_string(authorization) reference, auth_code, ca_reference = authorization.to_s.split(';') - {:reference => reference, :auth_code => auth_code, :ca_reference => ca_reference} + { reference: reference, auth_code: auth_code, ca_reference: ca_reference } end end end diff --git a/lib/active_merchant/billing/gateways/decidir.rb b/lib/active_merchant/billing/gateways/decidir.rb index eac328ec7e4..06f9758493a 100644 --- a/lib/active_merchant/billing/gateways/decidir.rb +++ b/lib/active_merchant/billing/gateways/decidir.rb @@ -7,7 +7,7 @@ class DecidirGateway < Gateway self.supported_countries = ['AR'] self.money_format = :cents self.default_currency = 'ARS' - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :naranja, :cabal] + self.supported_cardtypes = %i[visa master american_express diners_club naranja cabal] self.homepage_url = 'http://www.decidir.com' self.display_name = 'Decidir' @@ -37,17 +37,18 @@ class DecidirGateway < Gateway 56 => STANDARD_ERROR_CODE[:card_declined], 57 => STANDARD_ERROR_CODE[:card_declined], 76 => STANDARD_ERROR_CODE[:call_issuer], + 91 => STANDARD_ERROR_CODE[:call_issuer], 96 => STANDARD_ERROR_CODE[:processing_error], - 97 => STANDARD_ERROR_CODE[:processing_error], + 97 => STANDARD_ERROR_CODE[:processing_error] } - def initialize(options={}) + def initialize(options = {}) requires!(options, :api_key) super @options[:preauth_mode] ||= false end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) raise ArgumentError, 'Purchase is not supported on Decidir gateways configured with the preauth_mode option' if @options[:preauth_mode] post = {} @@ -55,7 +56,7 @@ def purchase(money, payment, options={}) commit(:post, 'payments', post) end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) raise ArgumentError, 'Authorize is not supported on Decidir gateways unless the preauth_mode option is enabled' unless @options[:preauth_mode] post = {} @@ -63,7 +64,7 @@ def authorize(money, payment, options={}) commit(:post, 'payments', post) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) raise ArgumentError, 'Capture is not supported on Decidir gateways unless the preauth_mode option is enabled' unless @options[:preauth_mode] post = {} @@ -71,18 +72,18 @@ def capture(money, authorization, options={}) commit(:put, "payments/#{authorization}", post) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) post = {} add_amount(post, money, options) commit(:post, "payments/#{authorization}/refunds", post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} commit(:post, "payments/#{authorization}/refunds", post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) raise ArgumentError, 'Verify is not supported on Decidir gateways unless the preauth_mode option is enabled' unless @options[:preauth_mode] MultiResponse.run(:use_first_response) do |r| @@ -106,22 +107,42 @@ def scrub(transcript) private def add_auth_purchase_params(post, money, credit_card, options) - post[:payment_method_id] = add_payment_method_id(credit_card) + post[:payment_method_id] = add_payment_method_id(credit_card, options) post[:site_transaction_id] = options[:order_id] post[:bin] = credit_card.number[0..5] post[:payment_type] = options[:payment_type] || 'single' post[:installments] = options[:installments] ? options[:installments].to_i : 1 post[:description] = options[:description] if options[:description] post[:email] = options[:email] if options[:email] + post[:establishment_name] = options[:establishment_name] if options[:establishment_name] + post[:fraud_detection] = add_fraud_detection(options[:fraud_detection]) if options[:fraud_detection].present? + post[:site_id] = options[:site_id] if options[:site_id] post[:sub_payments] = [] add_invoice(post, money, options) add_payment(post, credit_card, options) + add_aggregate_data(post, options) if options[:aggregate_data] end - def add_payment_method_id(credit_card) + def add_payment_method_id(credit_card, options) if options[:payment_method_id] options[:payment_method_id].to_i + elsif options[:debit] + if CreditCard.brand?(credit_card.number) == 'visa' + 31 + elsif CreditCard.brand?(credit_card.number) == 'master' + 105 + elsif CreditCard.brand?(credit_card.number) == 'maestro' + 106 + elsif CreditCard.brand?(credit_card.number) == 'cabal' + 108 + end + elsif CreditCard.brand?(credit_card.number) == 'master' + 104 + elsif CreditCard.brand?(credit_card.number) == 'american_express' + 65 + elsif CreditCard.brand?(credit_card.number) == 'diners_club' + 8 elsif CreditCard.brand?(credit_card.number) == 'cabal' 63 elsif CreditCard.brand?(credit_card.number) == 'naranja' @@ -149,6 +170,12 @@ def add_payment(post, credit_card, options) card_data[:security_code] = credit_card.verification_value if credit_card.verification_value? card_data[:card_holder_name] = credit_card.name if credit_card.name + # the device_unique_id has to be sent in via the card data (as device_unique_identifier) no other fraud detection fields require this + if options[:fraud_detection].present? + card_data[:fraud_detection] = {} if (options[:fraud_detection][:device_unique_id]).present? + card_data[:fraud_detection][:device_unique_identifier] = (options[:fraud_detection][:device_unique_id]) if (options[:fraud_detection][:device_unique_id]).present? + end + # additional data used for Visa transactions card_data[:card_holder_door_number] = options[:card_holder_door_number].to_i if options[:card_holder_door_number] card_data[:card_holder_birthday] = options[:card_holder_birthday] if options[:card_holder_birthday] @@ -160,6 +187,51 @@ def add_payment(post, credit_card, options) post[:card_data] = card_data end + def add_aggregate_data(post, options) + aggregate_data = {} + data = options[:aggregate_data] + aggregate_data[:indicator] = data[:indicator] if data[:indicator] + aggregate_data[:identification_number] = data[:identification_number] if data[:identification_number] + aggregate_data[:bill_to_pay] = data[:bill_to_pay] if data[:bill_to_pay] + aggregate_data[:bill_to_refund] = data[:bill_to_refund] if data[:bill_to_refund] + aggregate_data[:merchant_name] = data[:merchant_name] if data[:merchant_name] + aggregate_data[:street] = data[:street] if data[:street] + aggregate_data[:number] = data[:number] if data[:number] + aggregate_data[:postal_code] = data[:postal_code] if data[:postal_code] + aggregate_data[:category] = data[:category] if data[:category] + aggregate_data[:channel] = data[:channel] if data[:channel] + aggregate_data[:geographic_code] = data[:geographic_code] if data[:geographic_code] + aggregate_data[:city] = data[:city] if data[:city] + aggregate_data[:merchant_id] = data[:merchant_id] if data[:merchant_id] + aggregate_data[:province] = data[:province] if data[:province] + aggregate_data[:country] = data[:country] if data[:country] + aggregate_data[:merchant_email] = data[:merchant_email] if data[:merchant_email] + aggregate_data[:merchant_phone] = data[:merchant_phone] if data[:merchant_phone] + post[:aggregate_data] = aggregate_data + end + + def add_fraud_detection(options = {}) + {}.tap do |hsh| + hsh[:send_to_cs] = options[:send_to_cs] if valid_fraud_detection_option?(options[:send_to_cs]) # true/false + hsh[:channel] = options[:channel] if valid_fraud_detection_option?(options[:channel]) + hsh[:dispatch_method] = options[:dispatch_method] if valid_fraud_detection_option?(options[:dispatch_method]) + hsh[:csmdds] = options[:csmdds] if valid_fraud_detection_option?(options[:csmdds]) + hsh[:device_unique_id] = options[:device_unique_id] if valid_fraud_detection_option?(options[:device_unique_id]) + hsh[:bill_to] = options[:bill_to] if valid_fraud_detection_option?(options[:bill_to]) + hsh[:purchase_totals] = options[:purchase_totals] if valid_fraud_detection_option?(options[:purchase_totals]) + hsh[:customer_in_site] = options[:customer_in_site] if valid_fraud_detection_option?(options[:customer_in_site]) + hsh[:retail_transaction_data] = options[:retail_transaction_data] if valid_fraud_detection_option?(options[:retail_transaction_data]) + hsh[:ship_to] = options[:ship_to] if valid_fraud_detection_option?(options[:ship_to]) + hsh[:tax_voucher_required] = options[:tax_voucher_required] if valid_fraud_detection_option?(options[:tax_voucher_required]) + hsh[:copy_paste_card_data] = options[:copy_paste_card_data] if valid_fraud_detection_option?(options[:copy_paste_card_data]) + end + end + + # Avoid sending fields with empty or null when not populated. + def valid_fraud_detection_option?(val) + !val.nil? && val != '' + end + def headers(options = {}) { 'apikey' => @options[:api_key], @@ -168,7 +240,7 @@ def headers(options = {}) } end - def commit(method, endpoint, parameters, options={}) + def commit(method, endpoint, parameters, options = {}) url = "#{(test? ? test_url : live_url)}/#{endpoint}" begin @@ -207,13 +279,10 @@ def message_from(success, response) return response['message'] if response['message'] message = nil - if error = response.dig('status_details', 'error') - message = error.dig('reason', 'description') + message = "#{error.dig('reason', 'description')} | #{error['type']}" elsif response['error_type'] - if response['validation_errors'] - message = response['validation_errors'].map { |errors| "#{errors['code']}: #{errors['param']}" }.join(', ') - end + message = response['validation_errors'].map { |errors| "#{errors['code']}: #{errors['param']}" }.join(', ') if response['validation_errors'] message ||= response['error_type'] end @@ -232,10 +301,21 @@ def error_code_from(response) error_code = nil if error = response.dig('status_details', 'error') code = error.dig('reason', 'id') - error_code = STANDARD_ERROR_CODE_MAPPING[code] + standard_error_code = STANDARD_ERROR_CODE_MAPPING[code] + error_code = "#{code}, #{standard_error_code}" error_code ||= error['type'] elsif response['error_type'] error_code = response['error_type'] if response['validation_errors'] + elsif response.dig('error', 'validation_errors') + error = response.dig('error') + validation_errors = error.dig('validation_errors', 0) + code = validation_errors['code'] if validation_errors && validation_errors['code'] + param = validation_errors['param'] if validation_errors && validation_errors['param'] + error_code = "#{error['error_type']} | #{code} | #{param}" if error['error_type'] + elsif error = response.dig('error') + code = error.dig('reason', 'id') + standard_error_code = STANDARD_ERROR_CODE_MAPPING[code] + error_code = "#{code}, #{standard_error_code}" end error_code || STANDARD_ERROR_CODE[:processing_error] diff --git a/lib/active_merchant/billing/gateways/dibs.rb b/lib/active_merchant/billing/gateways/dibs.rb index e3936bc383f..1e202a206db 100644 --- a/lib/active_merchant/billing/gateways/dibs.rb +++ b/lib/active_merchant/billing/gateways/dibs.rb @@ -6,24 +6,24 @@ class DibsGateway < Gateway self.live_url = 'https://api.dibspayment.com/merchant/v1/JSON/Transaction/' - self.supported_countries = ['US', 'FI', 'NO', 'SE', 'GB'] + self.supported_countries = %w[US FI NO SE GB] self.default_currency = 'USD' self.money_format = :cents - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] - def initialize(options={}) + def initialize(options = {}) requires!(options, :merchant_id, :secret_key) super end - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) MultiResponse.run(false) do |r| r.process { authorize(amount, payment_method, options) } r.process { capture(amount, r.authorization, options) } end end - def authorize(amount, payment_method, options={}) + def authorize(amount, payment_method, options = {}) post = {} add_amount(post, amount) add_invoice(post, amount, options) @@ -36,7 +36,7 @@ def authorize(amount, payment_method, options={}) end end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) post = {} add_amount(post, amount) add_reference(post, authorization) @@ -44,14 +44,14 @@ def capture(amount, authorization, options={}) commit(:capture, post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} add_reference(post, authorization) commit(:void, post) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) post = {} add_amount(post, amount) add_reference(post, authorization) @@ -59,7 +59,7 @@ def refund(amount, authorization, options={}) commit(:refund, post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -87,7 +87,7 @@ def scrub(transcript) private - CURRENCY_CODES = Hash.new { |h, k| raise ArgumentError.new("Unsupported currency: #{k}") } + CURRENCY_CODES = Hash.new { |_h, k| raise ArgumentError.new("Unsupported currency: #{k}") } CURRENCY_CODES['USD'] = '840' CURRENCY_CODES['DKK'] = '208' CURRENCY_CODES['NOK'] = '578' diff --git a/lib/active_merchant/billing/gateways/digitzs.rb b/lib/active_merchant/billing/gateways/digitzs.rb index bbc82d4a2b8..7815b2018e8 100644 --- a/lib/active_merchant/billing/gateways/digitzs.rb +++ b/lib/active_merchant/billing/gateways/digitzs.rb @@ -8,25 +8,25 @@ class DigitzsGateway < Gateway self.supported_countries = ['US'] self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.money_format = :cents self.homepage_url = 'https://digitzs.com' self.display_name = 'Digitzs' - def initialize(options={}) + def initialize(options = {}) requires!(options, :app_key, :api_key) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) MultiResponse.run do |r| r.process { commit('auth/token', app_token_request(options)) } r.process { commit('payments', purchase_request(money, payment, options), options.merge({ app_token: app_token_from(r) })) } end end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) MultiResponse.run do |r| r.process { commit('auth/token', app_token_request(options)) } r.process { commit('payments', refund_request(money, authorization, options), options.merge({ app_token: app_token_from(r) })) } @@ -151,7 +151,7 @@ def refund_request(money, authorization, options) post[:data][:type] = 'payments' post[:data][:attributes][:merchantId] = options[:merchant_id] post[:data][:attributes][:paymentType] = 'cardRefund' - post[:data][:attributes][:originalTransaction] = {id: authorization} + post[:data][:attributes][:originalTransaction] = { id: authorization } add_transaction(post, money, options) post @@ -175,7 +175,7 @@ def create_token_request(payment, options) post[:data][:attributes] = { tokenType: 'card', customerId: options[:customer_id], - label: 'Credit Card', + label: 'Credit Card' } add_payment(post, payment, options) add_address(post, options) @@ -188,6 +188,7 @@ def check_customer_exists(options = {}) response = parse(ssl_get(url + "/customers/#{options[:customer_id]}", headers(options))) return response.try(:[], 'data').try(:[], 'customerId') if success_from(response) + return nil end @@ -205,7 +206,7 @@ def parse(body) JSON.parse(body) end - def commit(action, parameters, options={}) + def commit(action, parameters, options = {}) url = (test? ? test_url : live_url) response = parse(ssl_post(url + "/#{action}", parameters.to_json, headers(options))) @@ -228,12 +229,13 @@ def success_from(response) def message_from(response) return response['message'] if response['message'] return 'Success' if success_from(response) + response['errors'].map { |error_hash| error_hash['detail'] }.join(', ') end def authorization_from(response) if customer_id = response.try(:[], 'data').try(:[], 'attributes').try(:[], 'customerId') - "#{customer_id}|#{response.try(:[], "data").try(:[], "id")}" + "#{customer_id}|#{response.try(:[], 'data').try(:[], 'id')}" else response.try(:[], 'data').try(:[], 'id') end @@ -276,6 +278,7 @@ def determine_payment_type(payment, options) return 'cardSplit' if options[:payment_type] == 'card_split' return 'tokenSplit' if options[:payment_type] == 'token_split' return 'token' if payment.is_a? String + 'card' end diff --git a/lib/active_merchant/billing/gateways/ebanx.rb b/lib/active_merchant/billing/gateways/ebanx.rb index b7d1dc15171..3e312ab6fa8 100644 --- a/lib/active_merchant/billing/gateways/ebanx.rb +++ b/lib/active_merchant/billing/gateways/ebanx.rb @@ -4,9 +4,9 @@ class EbanxGateway < Gateway self.test_url = 'https://sandbox.ebanxpay.com/ws/' self.live_url = 'https://api.ebanxpay.com/ws/' - self.supported_countries = ['BR', 'MX', 'CO', 'CL', 'AR'] + self.supported_countries = %w(BR MX CO CL AR PE) self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club] + self.supported_cardtypes = %i[visa master american_express discover diners_club] self.homepage_url = 'http://www.ebanx.com/' self.display_name = 'EBANX' @@ -37,12 +37,21 @@ class EbanxGateway < Gateway store: :post } - def initialize(options={}) + VERIFY_AMOUNT_PER_COUNTRY = { + 'br' => 100, + 'ar' => 100, + 'co' => 100, + 'pe' => 300, + 'mx' => 300, + 'cl' => 5000 + } + + def initialize(options = {}) requires!(options, :integration_key) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) post = { payment: {} } add_integration_key(post) add_operation(post) @@ -51,11 +60,12 @@ def purchase(money, payment, options={}) add_card_or_token(post, payment) add_address(post, options) add_customer_responsible_person(post, payment, options) + add_additional_data(post, options) commit(:purchase, post) end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) post = { payment: {} } add_integration_key(post) add_operation(post) @@ -64,21 +74,22 @@ def authorize(money, payment, options={}) add_card_or_token(post, payment) add_address(post, options) add_customer_responsible_person(post, payment, options) + add_additional_data(post, options) post[:payment][:creditcard][:auto_capture] = false commit(:authorize, post) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) post = {} add_integration_key(post) post[:hash] = authorization - post[:amount] = amount(money) + post[:amount] = amount(money) if options[:include_capture_amount].to_s == 'true' commit(:capture, post) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) post = {} add_integration_key(post) add_operation(post) @@ -89,7 +100,7 @@ def refund(money, authorization, options={}) commit(:refund, post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} add_integration_key(post) add_authorization(post, authorization) @@ -97,7 +108,7 @@ def void(authorization, options={}) commit(:void, post) end - def store(credit_card, options={}) + def store(credit_card, options = {}) post = {} add_integration_key(post) add_payment_details(post, credit_card) @@ -106,9 +117,9 @@ def store(credit_card, options={}) commit(:store, post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| - r.process { authorize(100, credit_card, options) } + r.process { authorize(VERIFY_AMOUNT_PER_COUNTRY[customer_country(options)], credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } end end @@ -119,7 +130,7 @@ def supports_scrubbing? def scrub(transcript) transcript. - gsub(/(integration_key\\?":\\?")(\d*)/, '\1[FILTERED]'). + gsub(/(integration_key\\?":\\?")(\w*)/, '\1[FILTERED]'). gsub(/(card_number\\?":\\?")(\d*)/, '\1[FILTERED]'). gsub(/(card_cvv\\?":\\?")(\d*)/, '\1[FILTERED]') end @@ -170,14 +181,12 @@ def add_address(post, options) def add_invoice(post, money, options) post[:payment][:amount_total] = amount(money) post[:payment][:currency_code] = (options[:currency] || currency(money)) - post[:payment][:merchant_payment_code] = options[:order_id] + post[:payment][:merchant_payment_code] = Digest::MD5.hexdigest(options[:order_id]) post[:payment][:instalments] = options[:instalments] || 1 end def add_card_or_token(post, payment) - if payment.is_a?(String) - payment, brand = payment.split('|') - end + payment, brand = payment.split('|') if payment.is_a?(String) post[:payment][:payment_type_code] = payment.is_a?(String) ? brand : CARD_BRAND[payment.brand.to_sym] post[:payment][:creditcard] = payment_details(payment) end @@ -200,13 +209,20 @@ def payment_details(payment) end end + def add_additional_data(post, options) + post[:device_id] = options[:device_id] if options[:device_id] + post[:metadata] = options[:metadata] if options[:metadata] + post[:metadata] = {} if post[:metadata].nil? + post[:metadata][:merchant_payment_code] = options[:order_id] if options[:order_id] + end + def parse(body) JSON.parse(body) end def commit(action, parameters) url = url_for((test? ? test_url : live_url), action, parameters) - response = parse(ssl_request(HTTP_METHOD[action], url, post_data(action, parameters), {})) + response = parse(ssl_request(HTTP_METHOD[action], url, post_data(action, parameters), { 'x-ebanx-client-user-agent': "ActiveMerchant/#{ActiveMerchant::VERSION}" })) success = success_from(action, response) @@ -221,7 +237,7 @@ def commit(action, parameters) end def success_from(action, response) - if [:purchase, :capture, :refund].include?(action) + if %i[purchase capture refund].include?(action) response.try(:[], 'payment').try(:[], 'status') == 'CO' elsif action == :authorize response.try(:[], 'payment').try(:[], 'status') == 'PE' @@ -236,12 +252,13 @@ def success_from(action, response) def message_from(response) return response['status_message'] if response['status'] == 'ERROR' + response.try(:[], 'payment').try(:[], 'transaction_status').try(:[], 'description') end def authorization_from(action, parameters, response) if action == :store - "#{response.try(:[], "token")}|#{CARD_BRAND[parameters[:payment_type_code].to_sym]}" + "#{response.try(:[], 'token')}|#{CARD_BRAND[parameters[:payment_type_code].to_sym]}" else response.try(:[], 'payment').try(:[], 'hash') end @@ -250,22 +267,26 @@ def authorization_from(action, parameters, response) def post_data(action, parameters = {}) return nil if requires_http_get(action) return convert_to_url_form_encoded(parameters) if action == :refund + "request_body=#{parameters.to_json}" end def url_for(hostname, action, parameters) return "#{hostname}#{URL_MAP[action]}?#{convert_to_url_form_encoded(parameters)}" if requires_http_get(action) + "#{hostname}#{URL_MAP[action]}" end def requires_http_get(action) - return true if [:capture, :void].include?(action) + return true if %i[capture void].include?(action) + false end def convert_to_url_form_encoded(parameters) parameters.map do |key, value| next if value != false && value.blank? + "#{key}=#{value}" end.compact.join('&') end @@ -273,6 +294,7 @@ def convert_to_url_form_encoded(parameters) def error_code_from(response, success) unless success return response['status_code'] if response['status'] == 'ERROR' + response.try(:[], 'payment').try(:[], 'transaction_status').try(:[], 'code') end end diff --git a/lib/active_merchant/billing/gateways/efsnet.rb b/lib/active_merchant/billing/gateways/efsnet.rb index ad16cfbf349..00a5579c61f 100644 --- a/lib/active_merchant/billing/gateways/efsnet.rb +++ b/lib/active_merchant/billing/gateways/efsnet.rb @@ -4,7 +4,7 @@ module ActiveMerchant #:nodoc: module Billing #:nodoc: class EfsnetGateway < Gateway self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://www.concordefsnet.com/' self.display_name = 'Efsnet' @@ -53,8 +53,8 @@ def refund(money, reference, options = {}) def void(identification, options = {}) requires!(options, :order_id) - original_transaction_id, _ = identification.split(';') - commit(:void_transaction, {:reference_number => format_reference_number(options[:order_id]), :transaction_id => original_transaction_id}) + original_transaction_id, = identification.split(';') + commit(:void_transaction, { reference_number: format_reference_number(options[:order_id]), transaction_id: original_transaction_id }) end def voice_authorize(money, authorization_code, creditcard, options = {}) @@ -81,11 +81,11 @@ def build_refund_or_settle_request(money, identification, options = {}) requires!(options, :order_id) { - :reference_number => format_reference_number(options[:order_id]), - :transaction_amount => amount(money), - :original_transaction_amount => original_transaction_amount, - :original_transaction_id => original_transaction_id, - :client_ip_address => options[:ip] + reference_number: format_reference_number(options[:order_id]), + transaction_amount: amount(money), + original_transaction_amount: original_transaction_amount, + original_transaction_id: original_transaction_id, + client_ip_address: options[:ip] } end @@ -93,10 +93,10 @@ def build_credit_card_request(money, creditcard, options = {}) requires!(options, :order_id) post = { - :reference_number => format_reference_number(options[:order_id]), - :authorization_number => options[:authorization_number], - :transaction_amount => amount(money), - :client_ip_address => options[:ip] + reference_number: format_reference_number(options[:order_id]), + authorization_number: options[:authorization_number], + transaction_amount: amount(money), + client_ip_address: options[:ip] } add_creditcard(post, creditcard) @@ -111,46 +111,45 @@ def format_reference_number(number) def add_address(post, options) if address = options[:billing_address] || options[:address] if address[:address2] - post[:billing_address] = address[:address1].to_s << ' ' << address[:address2].to_s + post[:billing_address] = address[:address1].to_s << ' ' << address[:address2].to_s else post[:billing_address] = address[:address1].to_s end post[:billing_city] = address[:city].to_s - post[:billing_state] = address[:state].blank? ? 'n/a' : address[:state] + post[:billing_state] = address[:state].blank? ? 'n/a' : address[:state] post[:billing_postal_code] = address[:zip].to_s post[:billing_country] = address[:country].to_s end if address = options[:shipping_address] if address[:address2] - post[:shipping_address] = address[:address1].to_s << ' ' << address[:address2].to_s + post[:shipping_address] = address[:address1].to_s << ' ' << address[:address2].to_s else post[:shipping_address] = address[:address1].to_s end post[:shipping_city] = address[:city].to_s - post[:shipping_state] = address[:state].blank? ? 'n/a' : address[:state] + post[:shipping_state] = address[:state].blank? ? 'n/a' : address[:state] post[:shipping_postal_code] = address[:zip].to_s post[:shipping_country] = address[:country].to_s end end def add_creditcard(post, creditcard) - post[:billing_name] = creditcard.name if creditcard.name - post[:account_number] = creditcard.number + post[:billing_name] = creditcard.name if creditcard.name + post[:account_number] = creditcard.number post[:card_verification_value] = creditcard.verification_value if creditcard.verification_value? - post[:expiration_month] = sprintf('%.2i', creditcard.month) - post[:expiration_year] = sprintf('%.4i', creditcard.year)[-2..-1] + post[:expiration_month] = sprintf('%.2i', creditcard.month) + post[:expiration_year] = sprintf('%.4i', creditcard.year)[-2..-1] end def commit(action, parameters) response = parse(ssl_post(test? ? self.test_url : self.live_url, post_data(action, parameters), 'Content-Type' => 'text/xml')) Response.new(success?(response), message_from(response[:result_message]), response, - :test => test?, - :authorization => authorization_from(response, parameters), - :avs_result => { :code => response[:avs_response_code] }, - :cvv_result => response[:cvv_response_code] - ) + test: test?, + authorization: authorization_from(response, parameters), + avs_result: { code: response[:avs_response_code] }, + cvv_result: response[:cvv_response_code]) end def success?(response) @@ -158,7 +157,7 @@ def success?(response) end def authorization_from(response, params) - [ response[:transaction_id], params[:transaction_amount] ].compact.join(';') + [response[:transaction_id], params[:transaction_amount]].compact.join(';') end def parse(xml) @@ -190,6 +189,7 @@ def post_data(action, parameters = {}) def message_from(message) return 'Unspecified error' if message.blank? + message.gsub(/[^\w]/, ' ').split.join(' ').capitalize end @@ -197,18 +197,18 @@ def actions ACTIONS end - CREDIT_CARD_FIELDS = %w(AuthorizationNumber ClientIpAddress BillingAddress BillingCity BillingState BillingPostalCode BillingCountry BillingName CardVerificationValue ExpirationMonth ExpirationYear ReferenceNumber TransactionAmount AccountNumber ) + CREDIT_CARD_FIELDS = %w(AuthorizationNumber ClientIpAddress BillingAddress BillingCity BillingState BillingPostalCode BillingCountry BillingName CardVerificationValue ExpirationMonth ExpirationYear ReferenceNumber TransactionAmount AccountNumber) ACTIONS = { - :credit_card_authorize => CREDIT_CARD_FIELDS, - :credit_card_charge => CREDIT_CARD_FIELDS, - :credit_card_voice_authorize => CREDIT_CARD_FIELDS, - :credit_card_capture => CREDIT_CARD_FIELDS, - :credit_card_credit => CREDIT_CARD_FIELDS + ['OriginalTransactionAmount'], - :credit_card_refund => %w(ReferenceNumber TransactionAmount OriginalTransactionAmount OriginalTransactionID ClientIpAddress), - :void_transaction => %w(ReferenceNumber TransactionID), - :credit_card_settle => %w(ReferenceNumber TransactionAmount OriginalTransactionAmount OriginalTransactionID ClientIpAddress), - :system_check => %w(SystemCheck), + credit_card_authorize: CREDIT_CARD_FIELDS, + credit_card_charge: CREDIT_CARD_FIELDS, + credit_card_voice_authorize: CREDIT_CARD_FIELDS, + credit_card_capture: CREDIT_CARD_FIELDS, + credit_card_credit: CREDIT_CARD_FIELDS + ['OriginalTransactionAmount'], + credit_card_refund: %w(ReferenceNumber TransactionAmount OriginalTransactionAmount OriginalTransactionID ClientIpAddress), + void_transaction: %w(ReferenceNumber TransactionID), + credit_card_settle: %w(ReferenceNumber TransactionAmount OriginalTransactionAmount OriginalTransactionID ClientIpAddress), + system_check: %w(SystemCheck) } end end diff --git a/lib/active_merchant/billing/gateways/elavon.rb b/lib/active_merchant/billing/gateways/elavon.rb index 7abaa0abfd7..0ea84c0542b 100644 --- a/lib/active_merchant/billing/gateways/elavon.rb +++ b/lib/active_merchant/billing/gateways/elavon.rb @@ -1,4 +1,5 @@ require 'active_merchant/billing/gateways/viaklix' +require 'nokogiri' module ActiveMerchant #:nodoc: module Billing #:nodoc: @@ -7,25 +8,28 @@ class ElavonGateway < Gateway class_attribute :test_url, :live_url, :delimiter, :actions - self.test_url = 'https://api.demo.convergepay.com/VirtualMerchantDemo/process.do' - self.live_url = 'https://api.convergepay.com/VirtualMerchant/process.do' + self.test_url = 'https://api.demo.convergepay.com/VirtualMerchantDemo/processxml.do' + self.live_url = 'https://api.convergepay.com/VirtualMerchant/processxml.do' self.display_name = 'Elavon MyVirtualMerchant' self.supported_countries = %w(US CA PR DE IE NO PL LU BE NL MX) - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://www.elavon.com/' + self.money_format = :dollars + self.default_currency = 'USD' self.delimiter = "\n" self.actions = { - :purchase => 'CCSALE', - :credit => 'CCCREDIT', - :refund => 'CCRETURN', - :authorize => 'CCAUTHONLY', - :capture => 'CCFORCE', - :capture_complete => 'CCCOMPLETE', - :void => 'CCDELETE', - :store => 'CCGETTOKEN', - :update => 'CCUPDATETOKEN', + purchase: 'CCSALE', + credit: 'CCCREDIT', + refund: 'CCRETURN', + authorize: 'CCAUTHONLY', + capture: 'CCFORCE', + capture_complete: 'CCCOMPLETE', + void: 'CCDELETE', + store: 'CCGETTOKEN', + update: 'CCUPDATETOKEN', + verify: 'CCVERIFY' } def initialize(options = {}) @@ -34,110 +38,143 @@ def initialize(options = {}) end def purchase(money, payment_method, options = {}) - form = {} - add_salestax(form, options) - add_invoice(form, options) - if payment_method.is_a?(String) - add_token(form, payment_method) - else - add_creditcard(form, payment_method) + request = build_xml_request do |xml| + xml.ssl_transaction_type self.actions[:purchase] + xml.ssl_amount amount(money) + + if payment_method.is_a?(String) + add_token(xml, payment_method) + else + add_creditcard(xml, payment_method) + end + + add_invoice(xml, options) + add_salestax(xml, options) + add_currency(xml, money, options) + add_address(xml, options) + add_customer_email(xml, options) + add_test_mode(xml, options) + add_ip(xml, options) + add_auth_purchase_params(xml, options) + add_level_3_fields(xml, options) if options[:level_3_data] end - add_currency(form, money, options) - add_address(form, options) - add_customer_data(form, options) - add_test_mode(form, options) - add_ip(form, options) - commit(:purchase, money, form, options) + commit(request) end def authorize(money, creditcard, options = {}) - form = {} - add_salestax(form, options) - add_invoice(form, options) - add_creditcard(form, creditcard) - add_currency(form, money, options) - add_address(form, options) - add_customer_data(form, options) - add_test_mode(form, options) - add_ip(form, options) - commit(:authorize, money, form, options) + request = build_xml_request do |xml| + xml.ssl_transaction_type self.actions[:authorize] + xml.ssl_amount amount(money) + + add_salestax(xml, options) + add_invoice(xml, options) + add_creditcard(xml, creditcard) + add_currency(xml, money, options) + add_address(xml, options) + add_customer_email(xml, options) + add_test_mode(xml, options) + add_ip(xml, options) + add_auth_purchase_params(xml, options) + add_level_3_fields(xml, options) if options[:level_3_data] + end + commit(request) end def capture(money, authorization, options = {}) - form = {} - if options[:credit_card] - action = :capture - add_salestax(form, options) - add_approval_code(form, authorization) - add_invoice(form, options) - add_creditcard(form, options[:credit_card]) - add_currency(form, money, options) - add_customer_data(form, options) - add_test_mode(form, options) - else - action = :capture_complete - add_txn_id(form, authorization) - add_partial_shipment_flag(form, options) - add_test_mode(form, options) + request = build_xml_request do |xml| + if options[:credit_card] + xml.ssl_transaction_type self.actions[:capture] + xml.ssl_amount amount(money) + add_salestax(xml, options) + add_approval_code(xml, authorization) + add_invoice(xml, options) + add_creditcard(xml, options[:credit_card]) + add_currency(xml, money, options) + add_address(xml, options) + add_customer_email(xml, options) + add_test_mode(xml, options) + else + xml.ssl_transaction_type self.actions[:capture_complete] + xml.ssl_amount amount(money) + add_currency(xml, money, options) + add_txn_id(xml, authorization) + add_partial_shipment_flag(xml, options) + add_test_mode(xml, options) + end end - commit(action, money, form, options) + commit(request) end def refund(money, identification, options = {}) - form = {} - add_txn_id(form, identification) - add_test_mode(form, options) - commit(:refund, money, form, options) + request = build_xml_request do |xml| + xml.ssl_transaction_type self.actions[:refund] + xml.ssl_amount amount(money) + add_txn_id(xml, identification) + add_test_mode(xml, options) + end + commit(request) end def void(identification, options = {}) - form = {} - add_txn_id(form, identification) - add_test_mode(form, options) - commit(:void, nil, form, options) + request = build_xml_request do |xml| + xml.ssl_transaction_type self.actions[:void] + + add_txn_id(xml, identification) + add_test_mode(xml, options) + end + commit(request) end def credit(money, creditcard, options = {}) - if creditcard.is_a?(String) - raise ArgumentError, 'Reference credits are not supported. Please supply the original credit card or use the #refund method.' + raise ArgumentError, 'Reference credits are not supported. Please supply the original credit card or use the #refund method.' if creditcard.is_a?(String) + + request = build_xml_request do |xml| + xml.ssl_transaction_type self.actions[:credit] + xml.ssl_amount amount(money) + add_invoice(xml, options) + add_creditcard(xml, creditcard) + add_currency(xml, money, options) + add_address(xml, options) + add_customer_email(xml, options) + add_test_mode(xml, options) end - - form = {} - add_invoice(form, options) - add_creditcard(form, creditcard) - add_currency(form, money, options) - add_address(form, options) - add_customer_data(form, options) - add_test_mode(form, options) - commit(:credit, money, form, options) + commit(request) end def verify(credit_card, options = {}) - MultiResponse.run(:use_first_response) do |r| - r.process { authorize(100, credit_card, options) } - r.process(:ignore_result) { void(r.authorization, options) } + request = build_xml_request do |xml| + xml.ssl_transaction_type self.actions[:verify] + add_creditcard(xml, credit_card) + add_address(xml, options) + add_test_mode(xml, options) + add_ip(xml, options) end + commit(request) end def store(creditcard, options = {}) - form = {} - add_creditcard(form, creditcard) - add_address(form, options) - add_customer_data(form, options) - add_test_mode(form, options) - add_verification(form, options) - form[:add_token] = 'Y' - commit(:store, nil, form, options) + request = build_xml_request do |xml| + xml.ssl_transaction_type self.actions[:store] + xml.ssl_add_token 'Y' + add_creditcard(xml, creditcard) + add_address(xml, options) + add_customer_email(xml, options) + add_test_mode(xml, options) + add_verification(xml, options) + end + commit(request) end def update(token, creditcard, options = {}) - form = {} - add_token(form, token) - add_creditcard(form, creditcard) - add_address(form, options) - add_customer_data(form, options) - add_test_mode(form, options) - commit(:update, nil, form, options) + request = build_xml_request do |xml| + xml.ssl_transaction_type self.actions[:update] + add_token(xml, token) + add_creditcard(xml, creditcard) + add_address(xml, options) + add_customer_email(xml, options) + add_test_mode(xml, options) + end + commit(request) end def supports_scrubbing? @@ -146,175 +183,248 @@ def supports_scrubbing? def scrub(transcript) transcript. - gsub(%r((&?ssl_pin=)[^&]*)i, '\1[FILTERED]'). - gsub(%r((&?ssl_card_number=)[^&\\n\r\n]*)i, '\1[FILTERED]'). - gsub(%r((&?ssl_cvv2cvc2=)[^&]*)i, '\1[FILTERED]') + gsub(%r(()(.*)()), '\1[FILTERED]\3'). + gsub(%r(()(.*)()), '\1[FILTERED]\3'). + gsub(%r(()(.*)()), '\1[FILTERED]\3') end private - def add_invoice(form, options) - form[:invoice_number] = truncate((options[:order_id] || options[:invoice]), 10) - form[:description] = truncate(options[:description], 255) - end - - def add_approval_code(form, authorization) - form[:approval_code] = authorization.split(';').first + def add_invoice(xml, options) + xml.ssl_invoice_number truncate((options[:order_id] || options[:invoice]), 25) + xml.ssl_description truncate(options[:description], 255) end - def add_txn_id(form, authorization) - form[:txn_id] = authorization.split(';').last + def add_approval_code(xml, authorization) + xml.ssl_approval_code authorization.split(';').first end - def authorization_from(response) - [response['approval_code'], response['txn_id']].join(';') + def add_txn_id(xml, authorization) + xml.ssl_txn_id authorization.split(';').last end - def add_creditcard(form, creditcard) - form[:card_number] = creditcard.number - form[:exp_date] = expdate(creditcard) + def add_creditcard(xml, creditcard) + xml.ssl_card_number creditcard.number + xml.ssl_exp_date expdate(creditcard) - if creditcard.verification_value? - add_verification_value(form, creditcard) - end + add_verification_value(xml, creditcard) if creditcard.verification_value? - form[:first_name] = truncate(creditcard.first_name, 20) - form[:last_name] = truncate(creditcard.last_name, 30) + xml.ssl_first_name truncate(creditcard.first_name, 20) + xml.ssl_last_name truncate(creditcard.last_name, 30) end - def add_currency(form, money, options) + def add_currency(xml, money, options) currency = options[:currency] || currency(money) - form[:transaction_currency] = currency if currency && (@options[:multi_currency] || options[:multi_currency]) + return unless currency && (@options[:multi_currency] || options[:multi_currency]) + + xml.ssl_transaction_currency currency end - def add_token(form, token) - form[:token] = token + def add_token(xml, token) + xml.ssl_token token end - def add_verification_value(form, creditcard) - form[:cvv2cvc2] = creditcard.verification_value - form[:cvv2cvc2_indicator] = '1' + def add_verification_value(xml, creditcard) + xml.ssl_cvv2cvc2 creditcard.verification_value + xml.ssl_cvv2cvc2_indicator 1 end - def add_customer_data(form, options) - form[:email] = truncate(options[:email], 100) unless empty?(options[:email]) - form[:customer_code] = truncate(options[:customer], 10) unless empty?(options[:customer]) - form[:customer_number] = options[:customer_number] unless empty?(options[:customer_number]) - options[:custom_fields]&.each do |key, value| - form[key.to_s] = value - end + def add_customer_email(xml, options) + xml.ssl_email truncate(options[:email], 100) unless empty?(options[:email]) end - def add_salestax(form, options) - form[:salestax] = options[:tax] if options[:tax].present? + def add_salestax(xml, options) + return unless options[:tax].present? + + xml.ssl_salestax options[:tax] end - def add_address(form, options) + def add_address(xml, options) billing_address = options[:billing_address] || options[:address] if billing_address - form[:avs_address] = truncate(billing_address[:address1], 30) - form[:address2] = truncate(billing_address[:address2], 30) - form[:avs_zip] = truncate(billing_address[:zip].to_s.gsub(/[^a-zA-Z0-9]/, ''), 9) - form[:city] = truncate(billing_address[:city], 30) - form[:state] = truncate(billing_address[:state], 10) - form[:company] = truncate(billing_address[:company], 50) - form[:phone] = truncate(billing_address[:phone], 20) - form[:country] = truncate(billing_address[:country], 50) + xml.ssl_avs_address truncate(billing_address[:address1], 30) + xml.ssl_address2 truncate(billing_address[:address2], 30) + xml.ssl_avs_zip truncate(billing_address[:zip].to_s.gsub(/[^a-zA-Z0-9]/, ''), 9) + xml.ssl_city truncate(billing_address[:city], 30) + xml.ssl_state truncate(billing_address[:state], 10) + xml.ssl_company truncate(billing_address[:company], 50) + xml.ssl_phone truncate(billing_address[:phone], 20) + xml.ssl_country truncate(billing_address[:country], 50) end if shipping_address = options[:shipping_address] - first_name, last_name = split_names(shipping_address[:name]) - form[:ship_to_first_name] = truncate(first_name, 20) - form[:ship_to_last_name] = truncate(last_name, 30) - form[:ship_to_address1] = truncate(shipping_address[:address1], 30) - form[:ship_to_address2] = truncate(shipping_address[:address2], 30) - form[:ship_to_city] = truncate(shipping_address[:city], 30) - form[:ship_to_state] = truncate(shipping_address[:state], 10) - form[:ship_to_company] = truncate(shipping_address[:company], 50) - form[:ship_to_country] = truncate(shipping_address[:country], 50) - form[:ship_to_zip] = truncate(shipping_address[:zip], 10) + xml.ssl_ship_to_address1 truncate(shipping_address[:address1], 30) + xml.ssl_ship_to_address2 truncate(shipping_address[:address2], 30) + xml.ssl_ship_to_city truncate(shipping_address[:city], 30) + xml.ssl_ship_to_company truncate(shipping_address[:company], 50) + xml.ssl_ship_to_country truncate(shipping_address[:country], 50) + xml.ssl_ship_to_first_name truncate(shipping_address[:first_name], 20) + xml.ssl_ship_to_last_name truncate(shipping_address[:last_name], 30) + xml.ssl_ship_to_phone truncate(shipping_address[:phone], 10) + xml.ssl_ship_to_state truncate(shipping_address[:state], 2) + xml.ssl_ship_to_zip truncate(shipping_address[:zip], 10) end end - def add_verification(form, options) - form[:verify] = 'Y' if options[:verify] + def add_verification(xml, options) + xml.ssl_verify 'Y' if options[:verify] end - def add_test_mode(form, options) - form[:test_mode] = 'TRUE' if options[:test_mode] + def add_test_mode(xml, options) + xml.ssl_test_mode 'TRUE' if options[:test_mode] end - def add_partial_shipment_flag(form, options) - form[:partial_shipment_flag] = 'Y' if options[:partial_shipment_flag] + def add_partial_shipment_flag(xml, options) + xml.ssl_partial_shipment_flag 'Y' if options[:partial_shipment_flag] end - def add_ip(form, options) - form[:cardholder_ip] = options[:ip] if options.has_key?(:ip) + def add_ip(xml, options) + xml.ssl_cardholder_ip options[:ip] if options.has_key?(:ip) end - def message_from(response) - success?(response) ? response['result_message'] : response['errorMessage'] + def add_auth_purchase_params(xml, options) + xml.ssl_dynamic_dba options[:dba] if options.has_key?(:dba) + xml.ssl_merchant_initiated_unscheduled merchant_initiated_unscheduled(options) if merchant_initiated_unscheduled(options) + xml.ssl_customer_code options[:customer] if options.has_key?(:customer) + xml.ssl_customer_number options[:customer_number] if options.has_key?(:customer_number) + xml.ssl_entry_mode entry_mode(options) if entry_mode(options) + add_custom_fields(xml, options) if options[:custom_fields] + add_stored_credential(xml, options) if options[:stored_credential] end - def success?(response) - !response.has_key?('errorMessage') + def add_custom_fields(xml, options) + options[:custom_fields]&.each do |key, value| + xml.send(key.to_sym, value) + end end - def commit(action, money, parameters, options) - parameters[:amount] = amount(money) - parameters[:transaction_type] = self.actions[action] + def add_level_3_fields(xml, options) + level_3_data = options[:level_3_data] + xml.ssl_customer_code level_3_data[:customer_code] if level_3_data[:customer_code] + xml.ssl_salestax level_3_data[:salestax] if level_3_data[:salestax] + xml.ssl_salestax_indicator level_3_data[:salestax_indicator] if level_3_data[:salestax_indicator] + xml.ssl_level3_indicator level_3_data[:level3_indicator] if level_3_data[:level3_indicator] + xml.ssl_ship_to_zip level_3_data[:ship_to_zip] if level_3_data[:ship_to_zip] + xml.ssl_ship_to_country level_3_data[:ship_to_country] if level_3_data[:ship_to_country] + xml.ssl_shipping_amount level_3_data[:shipping_amount] if level_3_data[:shipping_amount] + xml.ssl_ship_from_postal_code level_3_data[:ship_from_postal_code] if level_3_data[:ship_from_postal_code] + xml.ssl_discount_amount level_3_data[:discount_amount] if level_3_data[:discount_amount] + xml.ssl_duty_amount level_3_data[:duty_amount] if level_3_data[:duty_amount] + xml.ssl_national_tax_indicator level_3_data[:national_tax_indicator] if level_3_data[:national_tax_indicator] + xml.ssl_national_tax_amount level_3_data[:national_tax_amount] if level_3_data[:national_tax_amount] + xml.ssl_order_date level_3_data[:order_date] if level_3_data[:order_date] + xml.ssl_other_tax level_3_data[:other_tax] if level_3_data[:other_tax] + xml.ssl_summary_commodity_code level_3_data[:summary_commodity_code] if level_3_data[:summary_commodity_code] + xml.ssl_merchant_vat_number level_3_data[:merchant_vat_number] if level_3_data[:merchant_vat_number] + xml.ssl_customer_vat_number level_3_data[:customer_vat_number] if level_3_data[:customer_vat_number] + xml.ssl_freight_tax_amount level_3_data[:freight_tax_amount] if level_3_data[:freight_tax_amount] + xml.ssl_vat_invoice_number level_3_data[:vat_invoice_number] if level_3_data[:vat_invoice_number] + xml.ssl_tracking_number level_3_data[:tracking_number] if level_3_data[:tracking_number] + xml.ssl_shipping_company level_3_data[:shipping_company] if level_3_data[:shipping_company] + xml.ssl_other_fees level_3_data[:other_fees] if level_3_data[:other_fees] + add_line_items(xml, level_3_data) if level_3_data[:line_items] + end + + def add_line_items(xml, level_3_data) + xml.LineItemProducts { + level_3_data[:line_items].each do |line_item| + xml.product { + line_item.each do |key, value| + prefixed_key = "ssl_line_Item_#{key}" + xml.send(prefixed_key, value) + end + } + end + } + end - response = parse(ssl_post(test? ? self.test_url : self.live_url, post_data(parameters, options))) + def add_stored_credential(xml, options) + network_transaction_id = options.dig(:stored_credential, :network_transaction_id) + case + when network_transaction_id.nil? + return + when network_transaction_id.to_s.include?('|') + oar_data, ps2000_data = options[:stored_credential][:network_transaction_id].split('|') + xml.ssl_oar_data oar_data unless oar_data.nil? || oar_data.empty? + xml.ssl_ps2000_data ps2000_data unless ps2000_data.nil? || ps2000_data.empty? + when network_transaction_id.to_s.length > 22 + xml.ssl_oar_data options.dig(:stored_credential, :network_transaction_id) + else + xml.ssl_ps2000_data options.dig(:stored_credential, :network_transaction_id) + end + end - Response.new(response['result'] == '0', message_from(response), response, - :test => @options[:test] || test?, - :authorization => authorization_from(response), - :avs_result => { :code => response['avs_response'] }, - :cvv_result => response['cvv2_response'] - ) + def merchant_initiated_unscheduled(options) + return options[:merchant_initiated_unscheduled] if options[:merchant_initiated_unscheduled] + return 'Y' if options.dig(:stored_credential, :initiator) == 'merchant' && options.dig(:stored_credential, :reason_type) == 'unscheduled' end - def post_data(parameters, options) - result = preamble - result.merge!(parameters) - result.collect { |key, value| post_data_string(key, value, options) }.join('&') + def entry_mode(options) + return options[:entry_mode] if options[:entry_mode] + return 12 if options[:stored_credential] end - def post_data_string(key, value, options) - if custom_field?(key, options) - "#{key}=#{CGI.escape(value.to_s)}" - else - "ssl_#{key}=#{CGI.escape(value.to_s)}" + def build_xml_request + builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml| + xml.txn do + xml.ssl_merchant_id @options[:login] + xml.ssl_user_id @options[:user] + xml.ssl_pin @options[:password] + yield(xml) + end end + + builder.to_xml.gsub("\n", '') end - def custom_field?(field_name, options) - return true if options[:custom_fields]&.include?(field_name.to_sym) - field_name == :customer_number + def commit(request) + request = "xmldata=#{request}".delete('&') + + response = parse(ssl_post(test? ? self.test_url : self.live_url, request, headers)) + + Response.new( + response[:result] == '0', + response[:result_message] || response[:errorMessage], + response, + test: @options[:test] || test?, + authorization: authorization_from(response), + error_code: response[:errorCode], + avs_result: { code: response[:avs_response] }, + cvv_result: response[:cvv2_response], + network_transaction_id: build_network_transaction_id(response) + ) end - def preamble - result = { - 'merchant_id' => @options[:login], - 'pin' => @options[:password], - 'show_form' => 'false', - 'result_format' => 'ASCII' + def build_network_transaction_id(response) + "#{response[:oar_data]}|#{response[:ps2000_data]}" + end + + def headers + { + 'Accept' => 'application/xml', + 'Content-type' => 'application/x-www-form-urlencoded' } + end - result['user_id'] = @options[:user] unless empty?(@options[:user]) - result + def parse(body) + xml = Nokogiri::XML(body) + response = Hash.from_xml(xml.to_s)['txn'] + + response.deep_transform_keys { |key| key.gsub('ssl_', '').to_sym } end - def parse(msg) - resp = {} - msg.split(self.delimiter).collect { |li| - key, value = li.split('=') - resp[key.to_s.strip.gsub(/^ssl_/, '')] = value.to_s.strip - } - resp + def authorization_from(response) + [response[:approval_code], response[:txn_id]].join(';') end + def truncate(value, size) + return nil unless value + + difference = value.force_encoding('iso-8859-1').length - value.length + + return value.delete('&"<>').to_s[0, (size - difference)] + end end end end diff --git a/lib/active_merchant/billing/gateways/element.rb b/lib/active_merchant/billing/gateways/element.rb index a82803884ba..979ad6f32d8 100644 --- a/lib/active_merchant/billing/gateways/element.rb +++ b/lib/active_merchant/billing/gateways/element.rb @@ -9,7 +9,7 @@ class ElementGateway < Gateway self.supported_countries = ['US'] self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb] + self.supported_cardtypes = %i[visa master american_express discover diners_club jcb] self.homepage_url = 'http://www.elementps.com' self.display_name = 'Element' @@ -17,12 +17,12 @@ class ElementGateway < Gateway SERVICE_TEST_URL = 'https://certservices.elementexpress.com/express.asmx' SERVICE_LIVE_URL = 'https://services.elementexpress.com/express.asmx' - def initialize(options={}) + def initialize(options = {}) requires!(options, :account_id, :account_token, :application_id, :acceptor_id, :application_name, :application_version) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) action = payment.is_a?(Check) ? 'CheckSale' : 'CreditCardSale' request = build_soap_request do |xml| @@ -38,7 +38,7 @@ def purchase(money, payment, options={}) commit(action, request, money) end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) request = build_soap_request do |xml| xml.CreditCardAuthorization(xmlns: 'https://transaction.elementexpress.com') do add_credentials(xml) @@ -52,8 +52,8 @@ def authorize(money, payment, options={}) commit('CreditCardAuthorization', request, money) end - def capture(money, authorization, options={}) - trans_id, _ = split_authorization(authorization) + def capture(money, authorization, options = {}) + trans_id, = split_authorization(authorization) options[:trans_id] = trans_id request = build_soap_request do |xml| @@ -67,8 +67,8 @@ def capture(money, authorization, options={}) commit('CreditCardAuthorizationCompletion', request, money) end - def refund(money, authorization, options={}) - trans_id, _ = split_authorization(authorization) + def refund(money, authorization, options = {}) + trans_id, = split_authorization(authorization) options[:trans_id] = trans_id request = build_soap_request do |xml| @@ -82,9 +82,9 @@ def refund(money, authorization, options={}) commit('CreditCardReturn', request, money) end - def void(authorization, options={}) + def void(authorization, options = {}) trans_id, trans_amount = split_authorization(authorization) - options.merge!({trans_id: trans_id, trans_amount: trans_amount, reversal_type: 'Full'}) + options.merge!({ trans_id: trans_id, trans_amount: trans_amount, reversal_type: 'Full' }) request = build_soap_request do |xml| xml.CreditCardReversal(xmlns: 'https://transaction.elementexpress.com') do @@ -110,11 +110,19 @@ def store(payment, options = {}) commit('PaymentAccountCreate', request, nil) end - def verify(credit_card, options={}) - MultiResponse.run(:use_first_response) do |r| - r.process { authorize(100, credit_card, options) } - r.process(:ignore_result) { void(r.authorization, options) } + def verify(credit_card, options = {}) + request = build_soap_request do |xml| + xml.CreditCardAVSOnly(xmlns: 'https://transaction.elementexpress.com') do + add_credentials(xml) + add_payment_method(xml, credit_card) + add_transaction(xml, 0, options) + add_terminal(xml, options) + add_address(xml, options) + end end + + # send request with the transaction amount set to 0 + commit('CreditCardAVSOnly', request, 0) end def supports_scrubbing? @@ -180,13 +188,17 @@ def add_transaction(xml, money, options = {}) xml.TransactionAmount amount(money.to_i) if money xml.MarketCode 'Default' if money xml.ReferenceNumber options[:order_id] || SecureRandom.hex(20) + + xml.PaymentType options[:payment_type] if options[:payment_type] + xml.SubmissionType options[:submission_type] if options[:submission_type] + xml.DuplicateCheckDisableFlag options[:duplicate_check_disable_flag].to_s == 'true' ? 'True' : 'False' unless options[:duplicate_check_disable_flag].nil? end end def add_terminal(xml, options) xml.terminal do - xml.TerminalID '01' - xml.CardPresentCode 'UseDefault' + xml.TerminalID options[:terminal_id] || '01' + xml.CardPresentCode options[:card_present_code] || 'UseDefault' xml.CardholderPresentCode 'UseDefault' xml.CardInputCode 'UseDefault' xml.CVVPresenceCode 'UseDefault' @@ -246,9 +258,7 @@ def parse(xml) doc.remove_namespaces! root = doc.root.xpath('//response/*') - if root.empty? - root = doc.root.xpath('//Response/*') - end + root = doc.root.xpath('//Response/*') if root.empty? root.each do |node| if node.elements.empty? diff --git a/lib/active_merchant/billing/gateways/epay.rb b/lib/active_merchant/billing/gateways/epay.rb index 6b34708e816..d26382cfe3c 100644 --- a/lib/active_merchant/billing/gateways/epay.rb +++ b/lib/active_merchant/billing/gateways/epay.rb @@ -5,48 +5,48 @@ class EpayGateway < Gateway self.default_currency = 'DKK' self.money_format = :cents - self.supported_cardtypes = [:dankort, :forbrugsforeningen, :visa, :master, - :american_express, :diners_club, :jcb, :maestro] - self.supported_countries = ['DK', 'SE', 'NO'] + self.supported_countries = %w[DK SE NO] + self.supported_cardtypes = %i[dankort forbrugsforeningen visa master + american_express diners_club jcb maestro] self.homepage_url = 'http://epay.dk/' self.display_name = 'ePay' CURRENCY_CODES = { - :ADP => '020', :AED => '784', :AFA => '004', :ALL => '008', :AMD => '051', - :ANG => '532', :AOA => '973', :ARS => '032', :AUD => '036', :AWG => '533', - :AZM => '031', :BAM => '977', :BBD => '052', :BDT => '050', :BGL => '100', - :BGN => '975', :BHD => '048', :BIF => '108', :BMD => '060', :BND => '096', - :BOB => '068', :BOV => '984', :BRL => '986', :BSD => '044', :BTN => '064', - :BWP => '072', :BYR => '974', :BZD => '084', :CAD => '124', :CDF => '976', - :CHF => '756', :CLF => '990', :CLP => '152', :CNY => '156', :COP => '170', - :CRC => '188', :CUP => '192', :CVE => '132', :CYP => '196', :CZK => '203', - :DJF => '262', :DKK => '208', :DOP => '214', :DZD => '012', :ECS => '218', - :ECV => '983', :EEK => '233', :EGP => '818', :ERN => '232', :ETB => '230', - :EUR => '978', :FJD => '242', :FKP => '238', :GBP => '826', :GEL => '981', - :GHC => '288', :GIP => '292', :GMD => '270', :GNF => '324', :GTQ => '320', - :GWP => '624', :GYD => '328', :HKD => '344', :HNL => '340', :HRK => '191', - :HTG => '332', :HUF => '348', :IDR => '360', :ILS => '376', :INR => '356', - :IQD => '368', :IRR => '364', :ISK => '352', :JMD => '388', :JOD => '400', - :JPY => '392', :KES => '404', :KGS => '417', :KHR => '116', :KMF => '174', - :KPW => '408', :KRW => '410', :KWD => '414', :KYD => '136', :KZT => '398', - :LAK => '418', :LBP => '422', :LKR => '144', :LRD => '430', :LSL => '426', - :LTL => '440', :LVL => '428', :LYD => '434', :MAD => '504', :MDL => '498', - :MGF => '450', :MKD => '807', :MMK => '104', :MNT => '496', :MOP => '446', - :MRO => '478', :MTL => '470', :MUR => '480', :MVR => '462', :MWK => '454', - :MXN => '484', :MXV => '979', :MYR => '458', :MZM => '508', :NAD => '516', - :NGN => '566', :NIO => '558', :NOK => '578', :NPR => '524', :NZD => '554', - :OMR => '512', :PAB => '590', :PEN => '604', :PGK => '598', :PHP => '608', - :PKR => '586', :PLN => '985', :PYG => '600', :QAR => '634', :ROL => '642', - :RUB => '643', :RUR => '810', :RWF => '646', :SAR => '682', :SBD => '090', - :SCR => '690', :SDD => '736', :SEK => '752', :SGD => '702', :SHP => '654', - :SIT => '705', :SKK => '703', :SLL => '694', :SOS => '706', :SRG => '740', - :STD => '678', :SVC => '222', :SYP => '760', :SZL => '748', :THB => '764', - :TJS => '972', :TMM => '795', :TND => '788', :TOP => '776', :TPE => '626', - :TRL => '792', :TRY => '949', :TTD => '780', :TWD => '901', :TZS => '834', - :UAH => '980', :UGX => '800', :USD => '840', :UYU => '858', :UZS => '860', - :VEB => '862', :VND => '704', :VUV => '548', :XAF => '950', :XCD => '951', - :XOF => '952', :XPF => '953', :YER => '886', :YUM => '891', :ZAR => '710', - :ZMK => '894', :ZWD => '716' + ADP: '020', AED: '784', AFA: '004', ALL: '008', AMD: '051', + ANG: '532', AOA: '973', ARS: '032', AUD: '036', AWG: '533', + AZM: '031', BAM: '977', BBD: '052', BDT: '050', BGL: '100', + BGN: '975', BHD: '048', BIF: '108', BMD: '060', BND: '096', + BOB: '068', BOV: '984', BRL: '986', BSD: '044', BTN: '064', + BWP: '072', BYR: '974', BZD: '084', CAD: '124', CDF: '976', + CHF: '756', CLF: '990', CLP: '152', CNY: '156', COP: '170', + CRC: '188', CUP: '192', CVE: '132', CYP: '196', CZK: '203', + DJF: '262', DKK: '208', DOP: '214', DZD: '012', ECS: '218', + ECV: '983', EEK: '233', EGP: '818', ERN: '232', ETB: '230', + EUR: '978', FJD: '242', FKP: '238', GBP: '826', GEL: '981', + GHC: '288', GIP: '292', GMD: '270', GNF: '324', GTQ: '320', + GWP: '624', GYD: '328', HKD: '344', HNL: '340', HRK: '191', + HTG: '332', HUF: '348', IDR: '360', ILS: '376', INR: '356', + IQD: '368', IRR: '364', ISK: '352', JMD: '388', JOD: '400', + JPY: '392', KES: '404', KGS: '417', KHR: '116', KMF: '174', + KPW: '408', KRW: '410', KWD: '414', KYD: '136', KZT: '398', + LAK: '418', LBP: '422', LKR: '144', LRD: '430', LSL: '426', + LTL: '440', LVL: '428', LYD: '434', MAD: '504', MDL: '498', + MGF: '450', MKD: '807', MMK: '104', MNT: '496', MOP: '446', + MRO: '478', MTL: '470', MUR: '480', MVR: '462', MWK: '454', + MXN: '484', MXV: '979', MYR: '458', MZM: '508', NAD: '516', + NGN: '566', NIO: '558', NOK: '578', NPR: '524', NZD: '554', + OMR: '512', PAB: '590', PEN: '604', PGK: '598', PHP: '608', + PKR: '586', PLN: '985', PYG: '600', QAR: '634', ROL: '642', + RUB: '643', RUR: '810', RWF: '646', SAR: '682', SBD: '090', + SCR: '690', SDD: '736', SEK: '752', SGD: '702', SHP: '654', + SIT: '705', SKK: '703', SLL: '694', SOS: '706', SRG: '740', + STD: '678', SVC: '222', SYP: '760', SZL: '748', THB: '764', + TJS: '972', TMM: '795', TND: '788', TOP: '776', TPE: '626', + TRL: '792', TRY: '949', TTD: '780', TWD: '901', TZS: '834', + UAH: '980', UGX: '800', USD: '840', UYU: '858', UZS: '860', + VEB: '862', VND: '704', VUV: '548', XAF: '950', XCD: '951', + XOF: '952', XPF: '953', YER: '886', YUM: '891', ZAR: '710', + ZMK: '894', ZWD: '716' } # login: merchant number @@ -177,14 +177,14 @@ def commit(action, params) Response.new response['accept'].to_i == 1, response['errortext'], response, - :test => test?, - :authorization => response['tid'] + test: test?, + authorization: response['tid'] else Response.new response['result'] == 'true', messages(response['epay'], response['pbs']), response, - :test => test?, - :authorization => params[:transaction] + test: test?, + authorization: params[:transaction] end end @@ -261,7 +261,7 @@ def make_headers(data, soap_call) end def xml_builder(params, soap_call) - xml = Builder::XmlMarkup.new(:indent => 2) + xml = Builder::XmlMarkup.new(indent: 2) xml.instruct! xml.tag! 'soap:Envelope', { 'xmlns:xsi' => 'http://schemas.xmlsoap.org/soap/envelope/', 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema', diff --git a/lib/active_merchant/billing/gateways/evo_ca.rb b/lib/active_merchant/billing/gateways/evo_ca.rb index b5f976b7cee..8aeabf72977 100644 --- a/lib/active_merchant/billing/gateways/evo_ca.rb +++ b/lib/active_merchant/billing/gateways/evo_ca.rb @@ -36,7 +36,7 @@ class EvoCaGateway < Gateway self.live_url = 'https://secure.evoepay.com/api/transact.php' self.supported_countries = ['CA'] - self.supported_cardtypes = [:visa, :master, :american_express, :jcb, :discover] + self.supported_cardtypes = %i[visa master american_express jcb discover] self.money_format = :dollars self.homepage_url = 'http://www.evocanada.com/' self.display_name = 'EVO Canada' @@ -139,8 +139,8 @@ def authorize(money, credit_card, options = {}) # options. def capture(money, authorization, options = {}) post = { - :amount => amount(money), - :transactionid => authorization + amount: amount(money), + transactionid: authorization } add_order(post, options) commit('capture', money, post) @@ -153,7 +153,7 @@ def capture(money, authorization, options = {}) # The identification parameter is the transaction ID, retrieved # from {Response#authorization}. def refund(money, identification) - post = {:transactionid => identification} + post = { transactionid: identification } commit('refund', money, post) end @@ -181,7 +181,7 @@ def credit(money, credit_card, options = {}) # The identification parameter is the transaction ID, retrieved # from {Response#authorization}. def void(identification) - post = {:transactionid => identification} + post = { transactionid: identification } commit('void', nil, post) end @@ -192,7 +192,7 @@ def void(identification) # The identification parameter is the transaction ID, retrieved # from {Response#authorization}. def update(identification, options) - post = {:transactionid => identification} + post = { transactionid: identification } add_order(post, options) commit('update', nil, post) end @@ -245,7 +245,7 @@ def add_invoice(post, options) end def add_paymentmethod(post, payment) - if card_brand(payment)=='check' + if card_brand(payment) == 'check' post[:payment] = 'check' post[:checkname] = payment.name post[:checkaba] = payment.routing_number @@ -280,11 +280,10 @@ def commit(action, money, parameters) message = message_from(response) Response.new(success?(response), message, response, - :test => test?, - :authorization => response['transactionid'], - :avs_result => { :code => response['avsresponse'] }, - :cvv_result => response['cvvresponse'] - ) + test: test?, + authorization: response['transactionid'], + avs_result: { code: response['avsresponse'] }, + cvv_result: response['cvvresponse']) end def message_from(response) @@ -292,7 +291,7 @@ def message_from(response) end def post_data(action, parameters = {}) - post = {:type => action} + post = { type: action } if test? post[:username] = 'demo' diff --git a/lib/active_merchant/billing/gateways/eway.rb b/lib/active_merchant/billing/gateways/eway.rb index 04874aac7ba..3032bb2d4fe 100644 --- a/lib/active_merchant/billing/gateways/eway.rb +++ b/lib/active_merchant/billing/gateways/eway.rb @@ -9,7 +9,7 @@ class EwayGateway < Gateway self.money_format = :cents self.supported_countries = ['AU'] - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club] + self.supported_cardtypes = %i[visa master american_express diners_club] self.homepage_url = 'http://www.eway.com.au/' self.display_name = 'eWAY' @@ -38,7 +38,7 @@ def purchase(money, creditcard, options = {}) commit(purchase_url(post[:CVN]), money, post) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) post = {} add_customer_id(post) @@ -66,12 +66,12 @@ def scrub(transcript) private def requires_address!(options) - raise ArgumentError.new('Missing eWay required parameters: address or billing_address') unless options.has_key?(:address) or options.has_key?(:billing_address) + raise ArgumentError.new('Missing eWay required parameters: address or billing_address') unless options.has_key?(:address) || options.has_key?(:billing_address) end def add_creditcard(post, creditcard) - post[:CardNumber] = creditcard.number - post[:CardExpiryMonth] = sprintf('%.2i', creditcard.month) + post[:CardNumber] = creditcard.number + post[:CardExpiryMonth] = sprintf('%.2i', creditcard.month) post[:CardExpiryYear] = sprintf('%.4i', creditcard.year)[-2..-1] post[:CustomerFirstName] = creditcard.first_name post[:CustomerLastName] = creditcard.last_name @@ -82,7 +82,7 @@ def add_creditcard(post, creditcard) def add_address(post, options) if address = options[:billing_address] || options[:address] - post[:CustomerAddress] = [ address[:address1], address[:address2], address[:city], address[:state], address[:country] ].compact.join(', ') + post[:CustomerAddress] = [address[:address1], address[:address2], address[:city], address[:state], address[:country]].compact.join(', ') post[:CustomerPostcode] = address[:zip] end end @@ -114,9 +114,8 @@ def commit(url, money, parameters) Response.new(success?(response), message_from(response[:ewaytrxnerror]), response, - :authorization => response[:ewaytrxnnumber], - :test => test? - ) + authorization: response[:ewaytrxnnumber], + test: test?) end def success?(response) @@ -145,6 +144,7 @@ def post_data(parameters = {}) def message_from(message) return '' if message.blank? + MESSAGES[message[0, 2]] || message end diff --git a/lib/active_merchant/billing/gateways/eway_managed.rb b/lib/active_merchant/billing/gateways/eway_managed.rb index fcdd34afbd4..02cd5b5cf6f 100644 --- a/lib/active_merchant/billing/gateways/eway_managed.rb +++ b/lib/active_merchant/billing/gateways/eway_managed.rb @@ -8,7 +8,7 @@ class EwayManagedGateway < Gateway self.supported_countries = ['AU'] # The card types supported by the payment gateway - self.supported_cardtypes = [:visa, :master] + self.supported_cardtypes = %i[visa master] self.default_currency = 'AUD' @@ -49,7 +49,7 @@ def store(creditcard, options = {}) commit('CreateCustomer', post) end - def update(billing_id, creditcard, options={}) + def update(billing_id, creditcard, options = {}) post = {} # Handle our required fields @@ -59,7 +59,7 @@ def update(billing_id, creditcard, options={}) billing_address = options[:billing_address] eway_requires!(billing_address) - post[:managedCustomerID]=billing_id + post[:managedCustomerID] = billing_id add_creditcard(post, creditcard) add_address(post, billing_address) add_misc_fields(post, options) @@ -80,10 +80,10 @@ def update(billing_id, creditcard, options={}) # * :order_id -- The order number, passed to eWay as the "Invoice Reference" # * :invoice -- The invoice number, passed to eWay as the "Invoice Reference" unless :order_id is also given # * :description -- A description of the payment, passed to eWay as the "Invoice Description" - def purchase(money, billing_id, options={}) + def purchase(money, billing_id, options = {}) post = {} post[:managedCustomerID] = billing_id.to_s - post[:amount]=money + post[:amount] = money add_invoice(post, options) commit('ProcessPayment', post) @@ -122,13 +122,13 @@ def add_address(post, address) end def add_misc_fields(post, options) - post[:CustomerRef]=options[:billing_address][:customer_ref] || options[:customer] - post[:Title]=options[:billing_address][:title] - post[:Company]=options[:billing_address][:company] - post[:JobDesc]=options[:billing_address][:job_desc] - post[:Email]=options[:billing_address][:email] || options[:email] - post[:URL]=options[:billing_address][:url] - post[:Comments]=options[:description] + post[:CustomerRef] = options[:billing_address][:customer_ref] || options[:customer] + post[:Title] = options[:billing_address][:title] + post[:Company] = options[:billing_address][:company] + post[:JobDesc] = options[:billing_address][:job_desc] + post[:Email] = options[:billing_address][:email] || options[:email] + post[:URL] = options[:billing_address][:url] + post[:Comments] = options[:description] end def add_invoice(post, options) @@ -138,8 +138,8 @@ def add_invoice(post, options) # add credit card details to be stored by eway. NOTE eway requires "title" field def add_creditcard(post, creditcard) - post[:CCNumber] = creditcard.number - post[:CCExpiryMonth] = sprintf('%.2i', creditcard.month) + post[:CCNumber] = creditcard.number + post[:CCExpiryMonth] = sprintf('%.2i', creditcard.month) post[:CCExpiryYear] = sprintf('%.4i', creditcard.year)[-2..-1] post[:CCNameOnCard] = creditcard.name post[:FirstName] = creditcard.first_name @@ -150,24 +150,24 @@ def parse(body) reply = {} xml = REXML::Document.new(body) if root = REXML::XPath.first(xml, '//soap:Fault') then - reply=parse_fault(root) + reply = parse_fault(root) else if root = REXML::XPath.first(xml, '//ProcessPaymentResponse/ewayResponse') then # Successful payment - reply=parse_purchase(root) + reply = parse_purchase(root) else if root = REXML::XPath.first(xml, '//QueryCustomerResult') then - reply=parse_query_customer(root) + reply = parse_query_customer(root) else if root = REXML::XPath.first(xml, '//CreateCustomerResult') then - reply[:message]='OK' - reply[:CreateCustomerResult]=root.text - reply[:success]=true + reply[:message] = 'OK' + reply[:CreateCustomerResult] = root.text + reply[:success] = true else if root = REXML::XPath.first(xml, '//UpdateCustomerResult') then if root.text.casecmp('true').zero? then - reply[:message]='OK' - reply[:success]=true + reply[:message] = 'OK' + reply[:success] = true else # ERROR: This state should never occur. If there is a problem, # a soap:Fault will be returned. The presence of this @@ -187,44 +187,44 @@ def parse(body) end def parse_fault(node) - reply={} - reply[:message]=REXML::XPath.first(node, '//soap:Reason/soap:Text').text - reply[:success]=false + reply = {} + reply[:message] = REXML::XPath.first(node, '//soap:Reason/soap:Text').text + reply[:success] = false reply end def parse_purchase(node) - reply={} - reply[:message]=REXML::XPath.first(node, '//ewayTrxnError').text - reply[:success]=(REXML::XPath.first(node, '//ewayTrxnStatus').text == 'True') - reply[:auth_code]=REXML::XPath.first(node, '//ewayAuthCode').text - reply[:transaction_number]=REXML::XPath.first(node, '//ewayTrxnNumber').text + reply = {} + reply[:message] = REXML::XPath.first(node, '//ewayTrxnError').text + reply[:success] = (REXML::XPath.first(node, '//ewayTrxnStatus').text == 'True') + reply[:auth_code] = REXML::XPath.first(node, '//ewayAuthCode').text + reply[:transaction_number] = REXML::XPath.first(node, '//ewayTrxnNumber').text reply end def parse_query_customer(node) - reply={} - reply[:message]='OK' - reply[:success]=true - reply[:CCNumber]=REXML::XPath.first(node, '//CCNumber').text - reply[:CCName]=REXML::XPath.first(node, '//CCName').text - reply[:CCExpiryMonth]=REXML::XPath.first(node, '//CCExpiryMonth').text - reply[:CCExpiryYear]=REXML::XPath.first(node, '//CCExpiryYear').text + reply = {} + reply[:message] = 'OK' + reply[:success] = true + reply[:CCNumber] = REXML::XPath.first(node, '//CCNumber').text + reply[:CCName] = REXML::XPath.first(node, '//CCName').text + reply[:CCExpiryMonth] = REXML::XPath.first(node, '//CCExpiryMonth').text + reply[:CCExpiryYear] = REXML::XPath.first(node, '//CCExpiryYear').text reply end def commit(action, post) - raw = begin - ssl_post(test? ? self.test_url : self.live_url, soap_request(post, action), 'Content-Type' => 'application/soap+xml; charset=utf-8') - rescue ResponseError => e - e.response.body - end + raw = + begin + ssl_post(test? ? self.test_url : self.live_url, soap_request(post, action), 'Content-Type' => 'application/soap+xml; charset=utf-8') + rescue ResponseError => e + e.response.body + end response = parse(raw) EwayResponse.new(response[:success], response[:message], response, - :test => test?, - :authorization => response[:auth_code] - ) + test: test?, + authorization: response[:auth_code]) end # Where we build the full SOAP 1.2 request using builder @@ -241,18 +241,18 @@ def soap_request(arguments, action) default_customer_fields.merge(arguments) end - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.instruct! - xml.tag! 'soap12:Envelope', {'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema', 'xmlns:soap12' => 'http://www.w3.org/2003/05/soap-envelope'} do + xml.tag! 'soap12:Envelope', { 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema', 'xmlns:soap12' => 'http://www.w3.org/2003/05/soap-envelope' } do xml.tag! 'soap12:Header' do - xml.tag! 'eWAYHeader', {'xmlns' => 'https://www.eway.com.au/gateway/managedpayment'} do + xml.tag! 'eWAYHeader', { 'xmlns' => 'https://www.eway.com.au/gateway/managedpayment' } do xml.tag! 'eWAYCustomerID', @options[:login] xml.tag! 'Username', @options[:username] xml.tag! 'Password', @options[:password] end end xml.tag! 'soap12:Body' do |x| - x.tag! action, {'xmlns' => 'https://www.eway.com.au/gateway/managedpayment'} do |y| + x.tag! action, { 'xmlns' => 'https://www.eway.com.au/gateway/managedpayment' } do |y| post.each do |key, value| y.tag! key, value end @@ -263,17 +263,17 @@ def soap_request(arguments, action) end def default_customer_fields - hash={} - %w( CustomerRef Title FirstName LastName Company JobDesc Email Address Suburb State PostCode Country Phone Mobile Fax URL Comments CCNumber CCNameOnCard CCExpiryMonth CCExpiryYear ).each do |field| - hash[field.to_sym]='' + hash = {} + %w(CustomerRef Title FirstName LastName Company JobDesc Email Address Suburb State PostCode Country Phone Mobile Fax URL Comments CCNumber CCNameOnCard CCExpiryMonth CCExpiryYear).each do |field| + hash[field.to_sym] = '' end return hash end def default_payment_fields - hash={} - %w( managedCustomerID amount invoiceReference invoiceDescription ).each do |field| - hash[field.to_sym]='' + hash = {} + %w(managedCustomerID amount invoiceReference invoiceDescription).each do |field| + hash[field.to_sym] = '' end return hash end @@ -284,7 +284,6 @@ def token @params['CreateCustomerResult'] end end - end end end diff --git a/lib/active_merchant/billing/gateways/eway_rapid.rb b/lib/active_merchant/billing/gateways/eway_rapid.rb index 34470c07183..a49e7dd8c1a 100644 --- a/lib/active_merchant/billing/gateways/eway_rapid.rb +++ b/lib/active_merchant/billing/gateways/eway_rapid.rb @@ -7,8 +7,8 @@ class EwayRapidGateway < Gateway self.live_url = 'https://api.ewaypayments.com/' self.money_format = :cents - self.supported_countries = ['AU', 'NZ', 'GB', 'SG', 'MY', 'HK'] - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :jcb] + self.supported_countries = %w[AU NZ GB SG MY HK] + self.supported_cardtypes = %i[visa master american_express diners_club jcb] self.homepage_url = 'http://www.eway.com.au/' self.display_name = 'eWAY Rapid 3.1' self.default_currency = 'AUD' @@ -47,17 +47,18 @@ def initialize(options = {}) # (default: "https://github.com/activemerchant/active_merchant") # # Returns an ActiveMerchant::Billing::Response object where authorization is the Transaction ID on success - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) params = {} add_metadata(params, options) add_invoice(params, amount, options) add_customer_data(params, options, payment_method) add_credit_card(params, payment_method, options) + add_3ds_authenticated_data(params, options) if options[:three_d_secure] params['Method'] = payment_method.respond_to?(:number) ? 'ProcessPayment' : 'TokenPayment' commit(url_for('Transaction'), params) end - def authorize(amount, payment_method, options={}) + def authorize(amount, payment_method, options = {}) params = {} add_metadata(params, options) add_invoice(params, amount, options) @@ -197,6 +198,18 @@ def add_metadata(params, options) params end + def add_3ds_authenticated_data(params, options) + three_d_secure_options = options[:three_d_secure] + params['PaymentInstrument'] ||= {} if params['PaymentInstrument'].nil? + threed_secure_auth = params['PaymentInstrument']['ThreeDSecureAuth'] = {} + threed_secure_auth['Cryptogram'] = three_d_secure_options[:cavv] + threed_secure_auth['ECI'] = three_d_secure_options[:eci] + threed_secure_auth['XID'] = three_d_secure_options[:xid] + threed_secure_auth['AuthStatus'] = three_d_secure_options[:authentication_response_status] + threed_secure_auth['dsTransactionId'] = three_d_secure_options[:ds_transaction_id] + threed_secure_auth['Version'] = three_d_secure_options[:version] + end + def add_invoice(params, money, options, key = 'Payment') currency_code = options[:currency] || currency(money) params[key] = { @@ -204,7 +217,7 @@ def add_invoice(params, money, options, key = 'Payment') 'InvoiceReference' => truncate(options[:order_id], 50), 'InvoiceNumber' => truncate(options[:invoice] || options[:order_id], 12), 'InvoiceDescription' => truncate(options[:description], 64), - 'CurrencyCode' => currency_code, + 'CurrencyCode' => currency_code } end @@ -232,7 +245,7 @@ def add_shipping_fields(params, options) params[key] = {} add_name_and_email(params[key], options[:shipping_address], options[:email]) - add_address(params[key], options[:shipping_address], {:skip_company => true}) + add_address(params[key], options[:shipping_address], { skip_company: true }) end def add_name_and_email(params, address, email, payment_method = nil) @@ -251,7 +264,7 @@ def payment_method_name_available?(payment_method) payment_method.first_name.present? && payment_method.last_name.present? end - def add_address(params, address, options={}) + def add_address(params, address, options = {}) return unless address params['Title'] = address[:title] @@ -268,6 +281,7 @@ def add_address(params, address, options={}) def add_credit_card(params, credit_card, options) return unless credit_card + params['Customer'] ||= {} if credit_card.respond_to? :number card_details = params['Customer']['CardDetails'] = {} @@ -303,13 +317,13 @@ def commit(url, params) succeeded, message_from(succeeded, raw), raw, - :authorization => authorization_from(raw), - :test => test?, - :avs_result => avs_result_from(raw), - :cvv_result => cvv_result_from(raw) + authorization: authorization_from(raw), + test: test?, + avs_result: avs_result_from(raw), + cvv_result: cvv_result_from(raw) ) rescue ActiveMerchant::ResponseError => e - return ActiveMerchant::Billing::Response.new(false, e.response.message, {:status_code => e.response.code}, :test => test?) + return ActiveMerchant::Billing::Response.new(false, e.response.message, { status_code: e.response.code }, test: test?) end def parse(data) @@ -355,15 +369,16 @@ def authorization_from(response) def avs_result_from(response) verification = response['Verification'] || {} - code = case verification['Address'] - when 'Valid' - 'M' - when 'Invalid' - 'N' - else - 'I' - end - {:code => code} + code = + case verification['Address'] + when 'Valid' + 'M' + when 'Invalid' + 'N' + else + 'I' + end + { code: code } end def cvv_result_from(response) @@ -556,7 +571,7 @@ def cvv_result_from(response) 'V6150' => 'Invalid Refund Amount', 'V6151' => 'Refund amount greater than original transaction', 'V6152' => 'Original transaction already refunded for total amount', - 'V6153' => 'Card type not support by merchant', + 'V6153' => 'Card type not support by merchant' } end end diff --git a/lib/active_merchant/billing/gateways/exact.rb b/lib/active_merchant/billing/gateways/exact.rb index d9649b84e21..144e3dc1359 100644 --- a/lib/active_merchant/billing/gateways/exact.rb +++ b/lib/active_merchant/billing/gateways/exact.rb @@ -5,37 +5,33 @@ class ExactGateway < Gateway API_VERSION = '8.5' - TEST_LOGINS = [ {:login => 'A00049-01', :password => 'test1'}, - {:login => 'A00427-01', :password => 'testus'} ] + TEST_LOGINS = [{ login: 'A00049-01', password: 'test1' }, + { login: 'A00427-01', password: 'testus' }] - TRANSACTIONS = { :sale => '00', - :authorization => '01', - :capture => '32', - :credit => '34' } + TRANSACTIONS = { sale: '00', + authorization: '01', + capture: '32', + credit: '34' } ENVELOPE_NAMESPACES = { 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema', 'xmlns:env' => 'http://schemas.xmlsoap.org/soap/envelope/', - 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance' - } + 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance' } SEND_AND_COMMIT_ATTRIBUTES = { 'xmlns:n1' => 'http://secure2.e-xact.com/vplug-in/transaction/rpc-enc/Request', - 'env:encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/' - } + 'env:encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/' } SEND_AND_COMMIT_SOURCE_ATTRIBUTES = { 'xmlns:n2' => 'http://secure2.e-xact.com/vplug-in/transaction/rpc-enc/encodedTypes', - 'xsi:type' => 'n2:Transaction' - } + 'xsi:type' => 'n2:Transaction' } POST_HEADERS = { 'soapAction' => 'http://secure2.e-xact.com/vplug-in/transaction/rpc-enc/SendAndCommit', - 'Content-Type' => 'text/xml' - } + 'Content-Type' => 'text/xml' } SUCCESS = 'true' - SENSITIVE_FIELDS = [ :verification_str2, :expiry_date, :card_number ] + SENSITIVE_FIELDS = %i[verification_str2 expiry_date card_number] - self.supported_cardtypes = [:visa, :master, :american_express, :jcb, :discover] - self.supported_countries = ['CA', 'US'] + self.supported_countries = %w[CA US] + self.supported_cardtypes = %i[visa master american_express jcb discover] self.homepage_url = 'http://www.e-xact.com' self.display_name = 'E-xact' @@ -163,15 +159,14 @@ def commit(action, request) response = parse(ssl_post(self.live_url, build_request(action, request), POST_HEADERS)) Response.new(successful?(response), message_from(response), response, - :test => test?, - :authorization => authorization_from(response), - :avs_result => { :code => response[:avs] }, - :cvv_result => response[:cvv2] - ) + test: test?, + authorization: authorization_from(response), + avs_result: { code: response[:avs] }, + cvv_result: response[:cvv2]) rescue ResponseError => e case e.response.code when '401' - return Response.new(false, "Invalid Login: #{e.response.body}", {}, :test => test?) + return Response.new(false, "Invalid Login: #{e.response.body}", {}, test: test?) else raise end @@ -211,7 +206,7 @@ def parse(xml) parse_elements(response, root) end - response.delete_if { |k, v| SENSITIVE_FIELDS.include?(k) } + response.delete_if { |k, _v| SENSITIVE_FIELDS.include?(k) } end def parse_elements(response, root) diff --git a/lib/active_merchant/billing/gateways/ezic.rb b/lib/active_merchant/billing/gateways/ezic.rb index 3bfe469c857..480c3313cd8 100644 --- a/lib/active_merchant/billing/gateways/ezic.rb +++ b/lib/active_merchant/billing/gateways/ezic.rb @@ -5,17 +5,17 @@ class EzicGateway < Gateway self.supported_countries = %w(AU CA CN FR DE GI IL MT MU MX NL NZ PA PH RU SG KR ES KN GB US) self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club] + self.supported_cardtypes = %i[visa master american_express discover jcb diners_club] self.homepage_url = 'http://www.ezic.com/' self.display_name = 'Ezic' - def initialize(options={}) + def initialize(options = {}) requires!(options, :account_id) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) post = {} add_account_id(post) @@ -26,7 +26,7 @@ def purchase(money, payment, options={}) commit('S', post) end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) post = {} add_account_id(post) @@ -37,7 +37,7 @@ def authorize(money, payment, options={}) commit('A', post) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) post = {} add_account_id(post) @@ -48,7 +48,7 @@ def capture(money, authorization, options={}) commit('D', post) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) post = {} add_account_id(post) @@ -59,7 +59,7 @@ def refund(money, authorization, options={}) commit('R', post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} add_account_id(post) @@ -69,7 +69,7 @@ def void(authorization, options={}) commit('U', post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -187,7 +187,7 @@ def post_data(parameters = {}) def headers { - 'User-Agent' => "ActiveMerchantBindings/#{ActiveMerchant::VERSION}", + 'User-Agent' => "ActiveMerchantBindings/#{ActiveMerchant::VERSION}" } end end diff --git a/lib/active_merchant/billing/gateways/fat_zebra.rb b/lib/active_merchant/billing/gateways/fat_zebra.rb index 9903e010a99..91b4e23bb68 100644 --- a/lib/active_merchant/billing/gateways/fat_zebra.rb +++ b/lib/active_merchant/billing/gateways/fat_zebra.rb @@ -9,7 +9,7 @@ class FatZebraGateway < Gateway self.supported_countries = ['AU'] self.default_currency = 'AUD' self.money_format = :cents - self.supported_cardtypes = [:visa, :master, :american_express, :jcb] + self.supported_cardtypes = %i[visa master american_express jcb] self.homepage_url = 'https://www.fatzebra.com.au/' self.display_name = 'Fat Zebra' @@ -48,7 +48,7 @@ def authorize(money, creditcard, options = {}) end def capture(money, authorization, options = {}) - txn_id, _ = authorization.to_s.split('|') + txn_id, = authorization.to_s.split('|') post = {} add_amount(post, money, options) @@ -57,8 +57,8 @@ def capture(money, authorization, options = {}) commit(:post, "purchases/#{CGI.escape(txn_id)}/capture", post) end - def refund(money, authorization, options={}) - txn_id, _ = authorization.to_s.split('|') + def refund(money, authorization, options = {}) + txn_id, = authorization.to_s.split('|') post = {} add_extra_options(post, options) @@ -69,16 +69,17 @@ def refund(money, authorization, options={}) commit(:post, 'refunds', post) end - def void(authorization, options={}) + def void(authorization, options = {}) txn_id, endpoint = authorization.to_s.split('|') commit(:post, "#{endpoint}/void?id=#{txn_id}", {}) end - def store(creditcard, options={}) + def store(creditcard, options = {}) post = {} add_creditcard(post, creditcard) + post[:is_billing] = true if options[:recurring] commit(:post, 'credit_cards', post) end @@ -109,7 +110,7 @@ def add_creditcard(post, creditcard, options = {}) post[:cvv] = creditcard.verification_value if creditcard.verification_value? post[:card_holder] = creditcard.name if creditcard.name elsif creditcard.is_a?(String) - id, _ = creditcard.to_s.split('|') + id, = creditcard.to_s.split('|') post[:card_token] = id post[:cvv] = options[:cvv] elsif creditcard.is_a?(Hash) @@ -124,11 +125,13 @@ def add_creditcard(post, creditcard, options = {}) def add_extra_options(post, options) extra = {} extra[:ecm] = '32' if options[:recurring] - extra[:cavv] = options[:cavv] if options[:cavv] - extra[:xid] = options[:xid] if options[:xid] - extra[:sli] = options[:sli] if options[:sli] + extra[:cavv] = options[:cavv] || options.dig(:three_d_secure, :cavv) if options[:cavv] || options.dig(:three_d_secure, :cavv) + extra[:xid] = options[:xid] || options.dig(:three_d_secure, :xid) if options[:xid] || options.dig(:three_d_secure, :xid) + extra[:sli] = options[:sli] || options.dig(:three_d_secure, :eci) if options[:sli] || options.dig(:three_d_secure, :eci) extra[:name] = options[:merchant] if options[:merchant] extra[:location] = options[:merchant_location] if options[:merchant_location] + extra[:card_on_file] = options.dig(:extra, :card_on_file) if options.dig(:extra, :card_on_file) + extra[:auth_reason] = options.dig(:extra, :auth_reason) if options.dig(:extra, :auth_reason) post[:extra] = extra if extra.any? end @@ -144,21 +147,23 @@ def add_metadata(post, options) post[:metadata] = options.fetch(:metadata, {}) end - def commit(method, uri, parameters=nil) - response = begin - parse(ssl_request(method, get_url(uri), parameters.to_json, headers)) - rescue ResponseError => e - return Response.new(false, 'Invalid Login') if(e.response.code == '401') - parse(e.response.body) - end + def commit(method, uri, parameters = nil) + response = + begin + parse(ssl_request(method, get_url(uri), parameters.to_json, headers)) + rescue ResponseError => e + return Response.new(false, 'Invalid Login') if e.response.code == '401' + + parse(e.response.body) + end success = success_from(response) Response.new( success, message_from(response), response, - :test => response['test'], - :authorization => authorization_from(response, success, uri) + test: response['test'], + authorization: authorization_from(response, success, uri) ) end diff --git a/lib/active_merchant/billing/gateways/federated_canada.rb b/lib/active_merchant/billing/gateways/federated_canada.rb index b6666a9fa44..9399db829f5 100644 --- a/lib/active_merchant/billing/gateways/federated_canada.rb +++ b/lib/active_merchant/billing/gateways/federated_canada.rb @@ -12,7 +12,7 @@ class FederatedCanadaGateway < Gateway self.default_currency = 'CAD' # The card types supported by the payment gateway - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] # The homepage URL of the gateway self.homepage_url = 'http://www.federatedcanada.com/' @@ -54,7 +54,7 @@ def void(authorization, options = {}) end def refund(money, authorization, options = {}) - commit('refund', money, options.merge(:transactionid => authorization)) + commit('refund', money, options.merge(transactionid: authorization)) end def credit(money, authorization, options = {}) @@ -122,11 +122,10 @@ def commit(action, money, parameters) message = message_from(response) Response.new(success?(response), message, response, - :test => test?, - :authorization => response['transactionid'], - :avs_result => {:code => response['avsresponse']}, - :cvv_result => response['cvvresponse'] - ) + test: test?, + authorization: response['transactionid'], + avs_result: { code: response['avsresponse'] }, + cvv_result: response['cvvresponse']) end def success?(response) diff --git a/lib/active_merchant/billing/gateways/finansbank.rb b/lib/active_merchant/billing/gateways/finansbank.rb index 5f496570853..8d14bc40b95 100644 --- a/lib/active_merchant/billing/gateways/finansbank.rb +++ b/lib/active_merchant/billing/gateways/finansbank.rb @@ -3,14 +3,14 @@ module ActiveMerchant #:nodoc: module Billing #:nodoc: class FinansbankGateway < CC5Gateway - self.live_url = 'https://www.fbwebpos.com/servlet/cc5ApiServer' + self.live_url = 'https://www.fbwebpos.com/servlet/cc5ApiServer' self.test_url = 'https://entegrasyon.asseco-see.com.tr/fim/api' # The countries the gateway supports merchants from as 2 digit ISO country codes - self.supported_countries = ['US', 'TR'] + self.supported_countries = %w[US TR] # The card types supported by the payment gateway - self.supported_cardtypes = [:visa, :master] + self.supported_cardtypes = %i[visa master] # The homepage URL of the gateway self.homepage_url = 'https://www.fbwebpos.com/' diff --git a/lib/active_merchant/billing/gateways/first_giving.rb b/lib/active_merchant/billing/gateways/first_giving.rb index 09dea7f8e5a..3059943d457 100644 --- a/lib/active_merchant/billing/gateways/first_giving.rb +++ b/lib/active_merchant/billing/gateways/first_giving.rb @@ -7,7 +7,7 @@ class FirstGivingGateway < Gateway self.live_url = 'https://api.firstgiving.com' self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://www.firstgiving.com/' self.default_currency = 'USD' self.display_name = 'FirstGiving' @@ -30,7 +30,7 @@ def purchase(money, creditcard, options = {}) def refund(money, identifier, options = {}) get = {} get[:transactionId] = identifier - get[:tranType] = 'REFUNDREQUEST' + get[:tranType] = 'REFUNDREQUEST' commit('/transaction/refundrequest?' + encode(get)) end @@ -49,7 +49,7 @@ def add_customer_data(post, options) end def add_address(post, options) - if(billing_address = (options[:billing_address] || options[:address])) + if (billing_address = (options[:billing_address] || options[:address])) post[:billToAddressLine1] = billing_address[:address1] post[:billToCity] = billing_address[:city] post[:billToState] = billing_address[:state] @@ -83,13 +83,14 @@ def parse(body) end element.children.each do |child| next if child.text? + response[child.name] = child.text end response end - def commit(action, post=nil) + def commit(action, post = nil) url = (test? ? self.test_url : self.live_url) + action begin diff --git a/lib/active_merchant/billing/gateways/first_pay.rb b/lib/active_merchant/billing/gateways/first_pay.rb index 3c197f0d79e..e6f92b3cdd8 100644 --- a/lib/active_merchant/billing/gateways/first_pay.rb +++ b/lib/active_merchant/billing/gateways/first_pay.rb @@ -8,17 +8,17 @@ class FirstPayGateway < Gateway self.supported_countries = ['US'] self.default_currency = 'USD' self.money_format = :dollars - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://1stpaygateway.net/' self.display_name = '1stPayGateway.Net' - def initialize(options={}) + def initialize(options = {}) requires!(options, :transaction_center_id, :gateway_id) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) post = {} add_invoice(post, money, options) add_payment(post, payment, options) @@ -28,7 +28,7 @@ def purchase(money, payment, options={}) commit('sale', post) end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) post = {} add_invoice(post, money, options) add_payment(post, payment, options) @@ -38,19 +38,19 @@ def authorize(money, payment, options={}) commit('auth', post) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) post = {} add_reference(post, 'settle', money, authorization) commit('settle', post) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) post = {} add_reference(post, 'credit', money, authorization) commit('credit', post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} add_reference(post, 'void', nil, authorization) commit('void', post) diff --git a/lib/active_merchant/billing/gateways/firstdata_e4.rb b/lib/active_merchant/billing/gateways/firstdata_e4.rb index 12290ad51c6..aa2cb1e39c8 100755 --- a/lib/active_merchant/billing/gateways/firstdata_e4.rb +++ b/lib/active_merchant/billing/gateways/firstdata_e4.rb @@ -22,22 +22,22 @@ class FirstdataE4Gateway < Gateway SUCCESS = 'true' - SENSITIVE_FIELDS = [:verification_str2, :expiry_date, :card_number] + SENSITIVE_FIELDS = %i[verification_str2 expiry_date card_number] BRANDS = { - :visa => 'Visa', - :master => 'Mastercard', - :american_express => 'American Express', - :jcb => 'JCB', - :discover => 'Discover' + visa: 'Visa', + master: 'Mastercard', + american_express: 'American Express', + jcb: 'JCB', + discover: 'Discover' } - E4_BRANDS = BRANDS.merge({:mastercard => 'Mastercard'}) + E4_BRANDS = BRANDS.merge({ mastercard: 'Mastercard' }) DEFAULT_ECI = '07' self.supported_cardtypes = BRANDS.keys - self.supported_countries = ['CA', 'US'] + self.supported_countries = %w[CA US] self.default_currency = 'USD' self.homepage_url = 'http://www.firstdata.com' self.display_name = 'FirstData Global Gateway e4' @@ -217,7 +217,7 @@ def add_transaction_type(xml, action) end def add_identification(xml, identification) - authorization_num, transaction_tag, _ = identification.split(';') + authorization_num, transaction_tag, = identification.split(';') xml.tag! 'Authorization_Num', authorization_num xml.tag! 'Transaction_Tag', transaction_tag @@ -245,23 +245,24 @@ def add_credit_card(xml, credit_card, options) end def add_credit_card_eci(xml, credit_card, options) - eci = if credit_card.is_a?(NetworkTokenizationCreditCard) && credit_card.source == :apple_pay && card_brand(credit_card) == 'discover' - # Discover requires any Apple Pay transaction, regardless of in-app - # or web, and regardless of the ECI contained in the PKPaymentToken, - # to have an ECI value explicitly of 04. - '04' - else - (credit_card.respond_to?(:eci) ? credit_card.eci : nil) || options[:eci] || DEFAULT_ECI - end + eci = + if credit_card.is_a?(NetworkTokenizationCreditCard) && credit_card.source == :apple_pay && card_brand(credit_card) == 'discover' + # Discover requires any Apple Pay transaction, regardless of in-app + # or web, and regardless of the ECI contained in the PKPaymentToken, + # to have an ECI value explicitly of 04. + '04' + else + (credit_card.respond_to?(:eci) ? credit_card.eci : nil) || options[:eci] || DEFAULT_ECI + end - xml.tag! 'Ecommerce_Flag', eci.to_s =~ /^[0-9]+$/ ? eci.to_s.rjust(2, '0') : eci + xml.tag! 'Ecommerce_Flag', /^[0-9]+$/.match?(eci.to_s) ? eci.to_s.rjust(2, '0') : eci end def add_credit_card_verification_strings(xml, credit_card, options) address = options[:billing_address] || options[:address] if address address_values = [] - [:address1, :zip, :city, :state, :country].each { |part| address_values << address[part].to_s } + %i[address1 zip city state country].each { |part| address_values << address[part].to_s.tr("\r\n", ' ').strip } xml.tag! 'VerificationStr1', address_values.join('|') end @@ -297,11 +298,12 @@ def add_card_authentication_data(xml, options) def add_credit_card_token(xml, store_authorization, options) params = store_authorization.split(';') credit_card = CreditCard.new( - :brand => params[1], - :first_name => params[2], - :last_name => params[3], - :month => params[4], - :year => params[5]) + brand: params[1], + first_name: params[2], + last_name: params[3], + month: params[4], + year: params[5] + ) xml.tag! 'TransarmorToken', params[0] xml.tag! 'Expiry_Date', expdate(credit_card) @@ -353,12 +355,11 @@ def commit(action, request, credit_card = nil) end Response.new(successful?(response), message_from(response), response, - :test => test?, - :authorization => successful?(response) ? response_authorization(action, response, credit_card) : '', - :avs_result => {:code => response[:avs]}, - :cvv_result => response[:cvv2], - :error_code => standard_error_code(response) - ) + test: test?, + authorization: successful?(response) ? response_authorization(action, response, credit_card) : '', + avs_result: { code: response[:avs] }, + cvv_result: response[:cvv2], + error_code: standard_error_code(response)) end def successful?(response) @@ -394,7 +395,7 @@ def store_authorization_from(response, credit_card) credit_card.last_name, credit_card.month, credit_card.year - ].map { |value| value.to_s.gsub(/;/, '') }.join(';') + ].map { |value| value.to_s.delete(';') }.join(';') else raise StandardError, "TransArmor support is not enabled on your #{display_name} account" end @@ -406,9 +407,9 @@ def money_from_authorization(auth) end def message_from(response) - if(response[:faultcode] && response[:faultstring]) + if response[:faultcode] && response[:faultstring] response[:faultstring] - elsif(response[:error_number] && response[:error_number] != '0') + elsif response[:error_number] && response[:error_number] != '0' response[:error_description] else result = (response[:exact_message] || '') @@ -419,10 +420,10 @@ def message_from(response) def parse_error(error) { - :transaction_approved => 'false', - :error_number => error.code, - :error_description => error.body, - :ecommerce_error_code => error.body.gsub(/[^\d]/, '') + transaction_approved: 'false', + error_number: error.code, + error_description: error.body, + ecommerce_error_code: error.body.gsub(/[^\d]/, '') } end @@ -438,7 +439,7 @@ def parse(xml) parse_elements(response, root) end - response.delete_if { |k, v| SENSITIVE_FIELDS.include?(k) } + response.delete_if { |k, _v| SENSITIVE_FIELDS.include?(k) } end def parse_elements(response, root) diff --git a/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb b/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb index 4124139a7ca..e6c438916d5 100644 --- a/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb +++ b/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb @@ -16,20 +16,20 @@ class FirstdataE4V27Gateway < Gateway SUCCESS = 'true' - SENSITIVE_FIELDS = [:cvdcode, :expiry_date, :card_number] + SENSITIVE_FIELDS = %i[cvdcode expiry_date card_number] BRANDS = { - :visa => 'Visa', - :master => 'Mastercard', - :american_express => 'American Express', - :jcb => 'JCB', - :discover => 'Discover' + visa: 'Visa', + master: 'Mastercard', + american_express: 'American Express', + jcb: 'JCB', + discover: 'Discover' } DEFAULT_ECI = '07' self.supported_cardtypes = BRANDS.keys - self.supported_countries = ['CA', 'US'] + self.supported_countries = %w[CA US] self.default_currency = 'USD' self.homepage_url = 'http://www.firstdata.com' self.display_name = 'FirstData Global Gateway e4 v27' @@ -191,7 +191,7 @@ def add_transaction_type(xml, action) end def add_identification(xml, identification) - authorization_num, transaction_tag, _ = identification.split(';') + authorization_num, transaction_tag, = identification.split(';') xml.tag! 'Authorization_Num', authorization_num xml.tag! 'Transaction_Tag', transaction_tag @@ -212,8 +212,8 @@ def add_credit_card(xml, credit_card, options) xml.tag! 'Expiry_Date', expdate(credit_card) xml.tag! 'CardHoldersName', credit_card.name xml.tag! 'CardType', card_type(credit_card.brand) - xml.tag! 'WalletProviderID', options[:wallet_provider_id] if options[:wallet_provider_id] + add_wallet_provider_id(xml, credit_card, options) add_credit_card_eci(xml, credit_card, options) add_credit_card_verification_strings(xml, credit_card, options) end @@ -221,15 +221,14 @@ def add_credit_card(xml, credit_card, options) def add_credit_card_eci(xml, credit_card, options) eci = if credit_card.is_a?(NetworkTokenizationCreditCard) && credit_card.source == :apple_pay && card_brand(credit_card) == 'discover' - # Discover requires any Apple Pay transaction, regardless of in-app - # or web, and regardless of the ECI contained in the PKPaymentToken, - # to have an ECI value explicitly of 04. - '04' + # Payeezy requires an ECI of 5 for apple pay transactions + # See: https://support.payeezy.com/hc/en-us/articles/203730589-Ecommerce-Flag-Values + '05' else (credit_card.respond_to?(:eci) ? credit_card.eci : nil) || options[:eci] || DEFAULT_ECI end - xml.tag! 'Ecommerce_Flag', eci.to_s =~ /^[0-9]+$/ ? eci.to_s.rjust(2, '0') : eci + xml.tag! 'Ecommerce_Flag', /^[0-9]+$/.match?(eci.to_s) ? eci.to_s.rjust(2, '0') : eci end def add_credit_card_verification_strings(xml, credit_card, options) @@ -265,20 +264,33 @@ def add_card_authentication_data(xml, options) def add_credit_card_token(xml, store_authorization, options) params = store_authorization.split(';') credit_card = CreditCard.new( - :brand => params[1], - :first_name => params[2], - :last_name => params[3], - :month => params[4], - :year => params[5]) + brand: params[1], + first_name: params[2], + last_name: params[3], + month: params[4], + year: params[5] + ) xml.tag! 'TransarmorToken', params[0] xml.tag! 'Expiry_Date', expdate(credit_card) xml.tag! 'CardHoldersName', credit_card.name xml.tag! 'CardType', card_type(credit_card.brand) - xml.tag! 'WalletProviderID', options[:wallet_provider_id] if options[:wallet_provider_id] + + add_wallet_provider_id(xml, credit_card, options) add_card_authentication_data(xml, options) end + def add_wallet_provider_id(xml, credit_card, options) + provider_id = if options[:wallet_provider_id] + options[:wallet_provider_id] + elsif credit_card.is_a?(NetworkTokenizationCreditCard) && credit_card.source == :apple_pay + # See: https://support.payeezy.com/hc/en-us/articles/206601408-First-Data-Payeezy-Gateway-Web-Service-API-Reference-Guide#3.9 + 4 + end + + xml.tag! 'WalletProviderID', provider_id if provider_id + end + def add_customer_data(xml, options) xml.tag! 'Customer_Ref', options[:customer] if options[:customer] xml.tag! 'Client_IP', options[:ip] if options[:ip] @@ -287,6 +299,8 @@ def add_customer_data(xml, options) def add_address(xml, options) if (address = options[:billing_address] || options[:address]) + address = strip_line_breaks(address) + xml.tag! 'Address' do xml.tag! 'Address1', address[:address1] xml.tag! 'Address2', address[:address2] if address[:address2] @@ -299,6 +313,12 @@ def add_address(xml, options) end end + def strip_line_breaks(address) + return unless address.is_a?(Hash) + + Hash[address.map { |k, s| [k, s&.tr("\r\n", ' ')&.strip] }] + end + def add_invoice(xml, options) xml.tag! 'Reference_No', options[:order_id] xml.tag! 'Reference_3', options[:description] if options[:description] @@ -315,10 +335,11 @@ def add_level_3(xml, options) def add_stored_credentials(xml, card, options) return unless options[:stored_credential] + xml.tag! 'StoredCredentials' do xml.tag! 'Indicator', stored_credential_indicator(xml, card, options) if initiator = options.dig(:stored_credential, :initiator) - xml.tag! initiator == 'merchant' ? 'M' : 'C' + xml.tag! 'Initiation', initiator == 'merchant' ? 'M' : 'C' end if reason_type = options.dig(:stored_credential, :reason_type) xml.tag! 'Schedule', reason_type == 'unscheduled' ? 'U' : 'S' @@ -360,12 +381,11 @@ def commit(action, data, credit_card = nil) end Response.new(successful?(response), message_from(response), response, - :test => test?, - :authorization => successful?(response) ? response_authorization(action, response, credit_card) : '', - :avs_result => {:code => response[:avs]}, - :cvv_result => response[:cvv2], - :error_code => standard_error_code(response) - ) + test: test?, + authorization: successful?(response) ? response_authorization(action, response, credit_card) : '', + avs_result: { code: response[:avs] }, + cvv_result: response[:cvv2], + error_code: standard_error_code(response)) end def headers(method, url, request) @@ -443,10 +463,10 @@ def message_from(response) def parse_error(error) { - :transaction_approved => 'false', - :error_number => error.code, - :error_description => error.body, - :ecommerce_error_code => error.body.gsub(/[^\d]/, '') + transaction_approved: 'false', + error_number: error.code, + error_description: error.body, + ecommerce_error_code: error.body.gsub(/[^\d]/, '') } end diff --git a/lib/active_merchant/billing/gateways/flo2cash.rb b/lib/active_merchant/billing/gateways/flo2cash.rb index 1f5c9d8076b..698f0ee74fd 100644 --- a/lib/active_merchant/billing/gateways/flo2cash.rb +++ b/lib/active_merchant/billing/gateways/flo2cash.rb @@ -10,7 +10,7 @@ class Flo2cashGateway < Gateway self.supported_countries = ['NZ'] self.default_currency = 'NZD' self.money_format = :dollars - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club] + self.supported_cardtypes = %i[visa master american_express diners_club] BRAND_MAP = { 'visa' => 'VISA', @@ -19,19 +19,19 @@ class Flo2cashGateway < Gateway 'diners_club' => 'DINERS' } - def initialize(options={}) + def initialize(options = {}) requires!(options, :username, :password, :account_id) super end - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) MultiResponse.run do |r| r.process { authorize(amount, payment_method, options) } r.process { capture(amount, r.authorization, options) } end end - def authorize(amount, payment_method, options={}) + def authorize(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method) @@ -40,7 +40,7 @@ def authorize(amount, payment_method, options={}) commit('ProcessAuthorise', post) end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) post = {} add_invoice(post, amount, options) add_reference(post, authorization) @@ -49,7 +49,7 @@ def capture(amount, authorization, options={}) commit('ProcessCapture', post) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) post = {} add_invoice(post, amount, options) add_reference(post, authorization) @@ -71,7 +71,7 @@ def scrub(transcript) private - CURRENCY_CODES = Hash.new { |h, k| raise ArgumentError.new("Unsupported currency: #{k}") } + CURRENCY_CODES = Hash.new { |_h, k| raise ArgumentError.new("Unsupported currency: #{k}") } CURRENCY_CODES['NZD'] = '554' def add_invoice(post, money, options) @@ -89,7 +89,7 @@ def add_payment_method(post, payment_method) end def add_customer_data(post, options) - if(billing_address = (options[:billing_address] || options[:address])) + if (billing_address = (options[:billing_address] || options[:address])) post[:Email] = billing_address[:email] end end @@ -107,7 +107,7 @@ def commit(action, post) begin raw = parse(ssl_post(url, data, headers(action)), action) rescue ActiveMerchant::ResponseError => e - if(e.response.code == '500' && e.response.body.start_with?(' authorization_from(action, raw[:transaction_id], post[:OriginalTransactionId]), - :error_code => error_code_from(succeeded, raw), - :test => test? + authorization: authorization_from(action, raw[:transaction_id], post[:OriginalTransactionId]), + error_code: error_code_from(succeeded, raw), + test: test? ) end @@ -133,7 +133,7 @@ def headers(action) end def build_request(action, post) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 post.each do |field, value| xml.tag!(field, value) end @@ -142,16 +142,16 @@ def build_request(action, post) end def envelope_wrap(action, body) - <<-EOS - - - - <#{action} xmlns="http://www.flo2cash.co.nz/webservices/paymentwebservice"> - #{body} - - - - EOS + <<~XML + + + + <#{action} xmlns="http://www.flo2cash.co.nz/webservices/paymentwebservice"> + #{body} + + + + XML end def url @@ -204,7 +204,7 @@ def authorization_from(action, current, original) 'Bank Declined Transaction' => STANDARD_ERROR_CODE[:card_declined], 'Insufficient Funds' => STANDARD_ERROR_CODE[:card_declined], 'Transaction Declined - Bank Error' => STANDARD_ERROR_CODE[:processing_error], - 'No Reply from Bank' => STANDARD_ERROR_CODE[:processing_error], + 'No Reply from Bank' => STANDARD_ERROR_CODE[:processing_error] } def error_code_from(succeeded, response) diff --git a/lib/active_merchant/billing/gateways/flo2cash_simple.rb b/lib/active_merchant/billing/gateways/flo2cash_simple.rb index f0662ff463c..bafe9fa6d21 100644 --- a/lib/active_merchant/billing/gateways/flo2cash_simple.rb +++ b/lib/active_merchant/billing/gateways/flo2cash_simple.rb @@ -3,7 +3,7 @@ module Billing #:nodoc: class Flo2cashSimpleGateway < Flo2cashGateway self.display_name = 'Flo2Cash Simple' - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method) diff --git a/lib/active_merchant/billing/gateways/forte.rb b/lib/active_merchant/billing/gateways/forte.rb index bdc06c7a3f5..7163434c3fe 100644 --- a/lib/active_merchant/billing/gateways/forte.rb +++ b/lib/active_merchant/billing/gateways/forte.rb @@ -10,41 +10,45 @@ class ForteGateway < Gateway self.supported_countries = ['US'] self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'https://www.forte.net' self.display_name = 'Forte' - def initialize(options={}) + def initialize(options = {}) requires!(options, :api_key, :secret, :location_id, :account_id) super end - def purchase(money, payment_method, options={}) + def purchase(money, payment_method, options = {}) post = {} add_amount(post, money, options) + add_service_fee(post, options) add_invoice(post, options) - add_payment_method(post, payment_method) + add_payment_method(post, payment_method, options) add_billing_address(post, payment_method, options) add_shipping_address(post, options) + add_xdata(post, options) post[:action] = 'sale' commit(:post, post) end - def authorize(money, payment_method, options={}) + def authorize(money, payment_method, options = {}) post = {} add_amount(post, money, options) + add_service_fee(post, options) add_invoice(post, options) - add_payment_method(post, payment_method) + add_payment_method(post, payment_method, options) add_billing_address(post, payment_method, options) add_shipping_address(post, options) + add_xdata(post, options) post[:action] = 'authorize' commit(:post, post) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) post = {} post[:transaction_id] = transaction_id_from(authorization) post[:authorization_code] = authorization_code_from(authorization) || '' @@ -53,18 +57,18 @@ def capture(money, authorization, options={}) commit(:put, post) end - def credit(money, payment_method, options={}) + def credit(money, payment_method, options = {}) post = {} add_amount(post, money, options) add_invoice(post, options) - add_payment_method(post, payment_method) + add_payment_method(post, payment_method, options) add_billing_address(post, payment_method, options) post[:action] = 'disburse' commit(:post, post) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) post = {} add_amount(post, money, options) post[:original_transaction_id] = transaction_id_from(authorization) @@ -74,7 +78,7 @@ def refund(money, authorization, options={}) commit(:post, post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} post[:transaction_id] = transaction_id_from(authorization) post[:authorization_code] = authorization_code_from(authorization) @@ -83,7 +87,7 @@ def void(authorization, options={}) commit(:put, post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -116,6 +120,20 @@ def add_amount(post, money, options) post[:authorization_amount] = amount(money) end + def add_service_fee(post, options) + post[:service_fee_amount] = options[:service_fee_amount] if options[:service_fee_amount] + end + + def add_xdata(post, options) + post[:xdata] = {} + if xdata = options[:xdata] + (1..9).each do |n| + field = "xdata_#{n}".to_sym + post[:xdata][field] = xdata[field] if xdata[field] + end + end + end + def add_billing_address(post, payment, options) post[:billing_address] = {} if address = options[:billing_address] || options[:address] @@ -130,17 +148,14 @@ def add_billing_address(post, payment, options) post[:billing_address][:physical_address][:locality] = address[:city] if address[:city] end - if empty?(post[:billing_address][:first_name]) && payment.first_name - post[:billing_address][:first_name] = payment.first_name - end + post[:billing_address][:first_name] = payment.first_name if empty?(post[:billing_address][:first_name]) && payment.first_name - if empty?(post[:billing_address][:last_name]) && payment.last_name - post[:billing_address][:last_name] = payment.last_name - end + post[:billing_address][:last_name] = payment.last_name if empty?(post[:billing_address][:last_name]) && payment.last_name end def add_shipping_address(post, options) return unless options[:shipping_address] + address = options[:shipping_address] post[:shipping_address] = {} @@ -154,21 +169,22 @@ def add_shipping_address(post, options) post[:shipping_address][:physical_address][:locality] = address[:city] if address[:city] end - def add_payment_method(post, payment_method) + def add_payment_method(post, payment_method, options) if payment_method.respond_to?(:brand) add_credit_card(post, payment_method) else - add_echeck(post, payment_method) + add_echeck(post, payment_method, options) end end - def add_echeck(post, payment) + def add_echeck(post, payment, options) post[:echeck] = {} post[:echeck][:account_holder] = payment.name post[:echeck][:account_number] = payment.account_number post[:echeck][:routing_number] = payment.routing_number post[:echeck][:account_type] = payment.account_type post[:echeck][:check_number] = payment.number + post[:echeck][:sec_code] = options[:sec_code] || 'PPD' end def add_credit_card(post, payment) @@ -262,7 +278,7 @@ def authorization_code_from(authorization) end def transaction_id_from(authorization) - transaction_id, _, original_auth_transaction_id, _= split_authorization(authorization) + transaction_id, _, original_auth_transaction_id, = split_authorization(authorization) original_auth_transaction_id.present? ? original_auth_transaction_id : transaction_id end end diff --git a/lib/active_merchant/billing/gateways/garanti.rb b/lib/active_merchant/billing/gateways/garanti.rb index 3c7f19efc5d..2bdd1071981 100644 --- a/lib/active_merchant/billing/gateways/garanti.rb +++ b/lib/active_merchant/billing/gateways/garanti.rb @@ -5,10 +5,10 @@ class GarantiGateway < Gateway self.test_url = 'https://sanalposprovtest.garanti.com.tr/VPServlet' # The countries the gateway supports merchants from as 2 digit ISO country codes - self.supported_countries = ['US', 'TR'] + self.supported_countries = %w[US TR] # The card types supported by the payment gateway - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] # The homepage URL of the gateway self.homepage_url = 'https://sanalposweb.garanti.com.tr' @@ -36,17 +36,17 @@ def initialize(options = {}) end def purchase(money, credit_card, options = {}) - options = options.merge(:gvp_order_type => 'sales') + options = options.merge(gvp_order_type: 'sales') commit(money, build_sale_request(money, credit_card, options)) end def authorize(money, credit_card, options = {}) - options = options.merge(:gvp_order_type => 'preauth') + options = options.merge(gvp_order_type: 'preauth') commit(money, build_authorize_request(money, credit_card, options)) end def capture(money, ref_id, options = {}) - options = options.merge(:gvp_order_type => 'postauth') + options = options.merge(gvp_order_type: 'postauth') commit(money, build_capture_request(money, ref_id, options)) end @@ -66,8 +66,8 @@ def build_xml_request(money, credit_card, options, &block) card_number = credit_card.respond_to?(:number) ? credit_card.number : '' hash_data = generate_hash_data(format_order_id(options[:order_id]), @options[:terminal_id], card_number, amount(money), security_data) - xml = Builder::XmlMarkup.new(:indent => 2) - xml.instruct! :xml, :version => '1.0', :encoding => 'UTF-8' + xml = Builder::XmlMarkup.new(indent: 2) + xml.instruct! :xml, version: '1.0', encoding: 'UTF-8' xml.tag! 'GVPSRequest' do xml.tag! 'Mode', test? ? 'TEST' : 'PROD' @@ -104,7 +104,7 @@ def build_sale_request(money, credit_card, options) def build_authorize_request(money, credit_card, options) build_xml_request(money, credit_card, options) do |xml| add_customer_data(xml, options) - add_order_data(xml, options) do + add_order_data(xml, options) do add_addresses(xml, options) end add_credit_card(xml, credit_card) @@ -115,7 +115,7 @@ def build_authorize_request(money, credit_card, options) end def build_capture_request(money, ref_id, options) - options = options.merge(:order_id => ref_id) + options = options.merge(order_id: ref_id) build_xml_request(money, ref_id, options) do |xml| add_customer_data(xml, options) add_order_data(xml, options) @@ -137,9 +137,7 @@ def add_order_data(xml, options, &block) xml.tag! 'OrderID', format_order_id(options[:order_id]) xml.tag! 'GroupID' - if block_given? - yield xml - end + yield xml if block_given? end end @@ -224,8 +222,8 @@ def commit(money, request) Response.new(success, success ? 'Approved' : "Declined (Reason: #{response[:reason_code]} - #{response[:error_msg]} - #{response[:sys_err_msg]})", response, - :test => test?, - :authorization => response[:order_id]) + test: test?, + authorization: response[:order_id]) end def parse(body) @@ -253,7 +251,6 @@ def success?(response) def strip_invalid_xml_chars(xml) xml.gsub(/&(?!(?:[a-z]+|#[0-9]+|x[a-zA-Z0-9]+);)/, '&') end - end end end diff --git a/lib/active_merchant/billing/gateways/global_collect.rb b/lib/active_merchant/billing/gateways/global_collect.rb index dd5c86c6db6..94f5ee07294 100644 --- a/lib/active_merchant/billing/gateways/global_collect.rb +++ b/lib/active_merchant/billing/gateways/global_collect.rb @@ -7,24 +7,24 @@ class GlobalCollectGateway < Gateway self.test_url = 'https://eu.sandbox.api-ingenico.com' self.live_url = 'https://api.globalcollect.com' - self.supported_countries = ['AD', 'AE', 'AG', 'AI', 'AL', 'AM', 'AO', 'AR', 'AS', 'AT', 'AU', 'AW', 'AX', 'AZ', 'BA', 'BB', 'BD', 'BE', 'BF', 'BG', 'BH', 'BI', 'BJ', 'BL', 'BM', 'BN', 'BO', 'BQ', 'BR', 'BS', 'BT', 'BW', 'BY', 'BZ', 'CA', 'CC', 'CD', 'CF', 'CH', 'CI', 'CK', 'CL', 'CM', 'CN', 'CO', 'CR', 'CU', 'CV', 'CW', 'CX', 'CY', 'CZ', 'DE', 'DJ', 'DK', 'DM', 'DO', 'DZ', 'EC', 'EE', 'EG', 'ER', 'ES', 'ET', 'FI', 'FJ', 'FK', 'FM', 'FO', 'FR', 'GA', 'GB', 'GD', 'GE', 'GF', 'GH', 'GI', 'GL', 'GM', 'GN', 'GP', 'GQ', 'GR', 'GS', 'GT', 'GU', 'GW', 'GY', 'HK', 'HN', 'HR', 'HT', 'HU', 'ID', 'IE', 'IL', 'IM', 'IN', 'IS', 'IT', 'JM', 'JO', 'JP', 'KE', 'KG', 'KH', 'KI', 'KM', 'KN', 'KR', 'KW', 'KY', 'KZ', 'LA', 'LB', 'LC', 'LI', 'LK', 'LR', 'LS', 'LT', 'LU', 'LV', 'MA', 'MC', 'MD', 'ME', 'MF', 'MG', 'MH', 'MK', 'MM', 'MN', 'MO', 'MP', 'MQ', 'MR', 'MS', 'MT', 'MU', 'MV', 'MW', 'MX', 'MY', 'MZ', 'NA', 'NC', 'NE', 'NG', 'NI', 'NL', 'NO', 'NP', 'NR', 'NU', 'NZ', 'OM', 'PA', 'PE', 'PF', 'PG', 'PH', 'PL', 'PN', 'PS', 'PT', 'PW', 'QA', 'RE', 'RO', 'RS', 'RU', 'RW', 'SA', 'SB', 'SC', 'SE', 'SG', 'SH', 'SI', 'SJ', 'SK', 'SL', 'SM', 'SN', 'SR', 'ST', 'SV', 'SZ', 'TC', 'TD', 'TG', 'TH', 'TJ', 'TL', 'TM', 'TN', 'TO', 'TR', 'TT', 'TV', 'TW', 'TZ', 'UA', 'UG', 'US', 'UY', 'UZ', 'VC', 'VE', 'VG', 'VI', 'VN', 'WF', 'WS', 'ZA', 'ZM', 'ZW'] + self.supported_countries = %w[AD AE AG AI AL AM AO AR AS AT AU AW AX AZ BA BB BD BE BF BG BH BI BJ BL BM BN BO BQ BR BS BT BW BY BZ CA CC CD CF CH CI CK CL CM CN CO CR CU CV CW CX CY CZ DE DJ DK DM DO DZ EC EE EG ER ES ET FI FJ FK FM FO FR GA GB GD GE GF GH GI GL GM GN GP GQ GR GS GT GU GW GY HK HN HR HT HU ID IE IL IM IN IS IT JM JO JP KE KG KH KI KM KN KR KW KY KZ LA LB LC LI LK LR LS LT LU LV MA MC MD ME MF MG MH MK MM MN MO MP MQ MR MS MT MU MV MW MX MY MZ NA NC NE NG NI NL NO NP NR NU NZ OM PA PE PF PG PH PL PN PS PT PW QA RE RO RS RU RW SA SB SC SE SG SH SI SJ SK SL SM SN SR ST SV SZ TC TD TG TH TJ TL TM TN TO TR TT TV TW TZ UA UG US UY UZ VC VE VG VI VN WF WS ZA ZM ZW] self.default_currency = 'USD' self.money_format = :cents - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :naranja, :cabal] + self.supported_cardtypes = %i[visa master american_express discover naranja cabal] - def initialize(options={}) + def initialize(options = {}) requires!(options, :merchant_id, :api_key_id, :secret_api_key) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) MultiResponse.run do |r| r.process { authorize(money, payment, options) } - r.process { capture(money, r.authorization, options) } unless capture_requested?(r) + r.process { capture(money, r.authorization, options) } if should_request_capture?(r, options[:requires_approval]) end end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) post = nestable_hash add_order(post, money, options) add_payment(post, payment, options) @@ -32,11 +32,11 @@ def authorize(money, payment, options={}) add_address(post, payment, options) add_creator_info(post, options) add_fraud_fields(post, options) - + add_external_cardholder_authentication_data(post, options) commit(:authorize, post) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) post = nestable_hash add_order(post, money, options, capture: true) add_customer_data(post, options) @@ -44,7 +44,7 @@ def capture(money, authorization, options={}) commit(:capture, post, authorization) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) post = nestable_hash add_amount(post, money, options) add_refund_customer_data(post, options) @@ -52,13 +52,13 @@ def refund(money, authorization, options={}) commit(:refund, post, authorization) end - def void(authorization, options={}) + def void(authorization, options = {}) post = nestable_hash add_creator_info(post, options) commit(:void, post, authorization) end - def verify(payment, options={}) + def verify(payment, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, payment, options) } r.process { void(r.authorization, options) } @@ -100,6 +100,36 @@ def add_order(post, money, options, capture: false) post['order']['references']['invoiceData'] = { 'invoiceNumber' => options[:invoice] } + add_airline_data(post, options) if options[:airline_data] + add_number_of_installments(post, options) if options[:number_of_installments] + end + + def add_airline_data(post, options) + airline_data = {} + + flight_date = options[:airline_data][:flight_date] + passenger_name = options[:airline_data][:passenger_name] + code = options[:airline_data][:code] + name = options[:airline_data][:name] + + airline_data['flightDate'] = flight_date if flight_date + airline_data['passengerName'] = passenger_name if passenger_name + airline_data['code'] = code if code + airline_data['name'] = name if name + + flight_legs = [] + options[:airline_data][:flight_legs]&.each do |fl| + leg = {} + leg['arrivalAirport'] = fl[:arrival_airport] if fl[:arrival_airport] + leg['originAirport'] = fl[:origin_airport] if fl[:origin_airport] + leg['date'] = fl[:date] if fl[:date] + leg['number'] = fl[:number] if fl[:number] + leg['carrierCode'] = fl[:carrier_code] if fl[:carrier_code] + leg['airlineClass'] = fl[:carrier_code] if fl[:airline_class] + flight_legs << leg + end + airline_data['flightLegs'] = flight_legs + post['order']['additionalInput']['airlineData'] = airline_data end def add_creator_info(post, options) @@ -113,7 +143,7 @@ def add_creator_info(post, options) post['shoppingCartExtension']['extensionID'] = options[:extension_ID] if options[:extension_ID] end - def add_amount(post, money, options={}) + def add_amount(post, money, options = {}) post['amountOfMoney'] = { 'amount' => amount(money), 'currencyCode' => options[:currency] || currency(money) @@ -123,20 +153,22 @@ def add_amount(post, money, options={}) def add_payment(post, payment, options) year = format(payment.year, :two_digits) month = format(payment.month, :two_digits) - expirydate = "#{month}#{year}" + expirydate = "#{month}#{year}" pre_authorization = options[:pre_authorization] ? 'PRE_AUTHORIZATION' : 'FINAL_AUTHORIZATION' post['cardPaymentMethodSpecificInput'] = { - 'paymentProductId' => BRAND_MAP[payment.brand], - 'skipAuthentication' => 'true', # refers to 3DSecure - 'skipFraudService' => 'true', - 'authorizationMode' => pre_authorization + 'paymentProductId' => BRAND_MAP[payment.brand], + 'skipAuthentication' => 'true', # refers to 3DSecure + 'skipFraudService' => 'true', + 'authorizationMode' => pre_authorization } + post['cardPaymentMethodSpecificInput']['requiresApproval'] = options[:requires_approval] unless options[:requires_approval].nil? + post['cardPaymentMethodSpecificInput']['card'] = { - 'cvv' => payment.verification_value, - 'cardNumber' => payment.number, - 'expiryDate' => expirydate, - 'cardholderName' => payment.name + 'cvv' => payment.verification_value, + 'cardNumber' => payment.number, + 'expiryDate' => expirydate, + 'cardholderName' => payment.name } end @@ -169,21 +201,21 @@ def add_address(post, creditcard, options) shipping_address = options[:shipping_address] if billing_address = options[:billing_address] || options[:address] post['order']['customer']['billingAddress'] = { - 'street' => billing_address[:address1], - 'additionalInfo' => billing_address[:address2], + 'street' => truncate(billing_address[:address1], 50), + 'additionalInfo' => truncate(billing_address[:address2], 50), 'zip' => billing_address[:zip], 'city' => billing_address[:city], - 'state' => billing_address[:state], + 'state' => truncate(billing_address[:state], 35), 'countryCode' => billing_address[:country] } end if shipping_address post['order']['customer']['shippingAddress'] = { - 'street' => shipping_address[:address1], - 'additionalInfo' => shipping_address[:address2], + 'street' => truncate(shipping_address[:address1], 50), + 'additionalInfo' => truncate(shipping_address[:address2], 50), 'zip' => shipping_address[:zip], 'city' => shipping_address[:city], - 'state' => shipping_address[:state], + 'state' => truncate(shipping_address[:state], 35), 'countryCode' => shipping_address[:country] } post['order']['customer']['shippingAddress']['name'] = { @@ -201,6 +233,28 @@ def add_fraud_fields(post, options) post['fraudFields'] = fraud_fields unless fraud_fields.empty? end + def add_external_cardholder_authentication_data(post, options) + return unless threeds_2_options = options[:three_d_secure] + + authentication_data = {} + authentication_data[:acsTransactionId] = threeds_2_options[:acs_transaction_id] if threeds_2_options[:acs_transaction_id] + authentication_data[:cavv] = threeds_2_options[:cavv] if threeds_2_options[:cavv] + authentication_data[:cavvAlgorithm] = threeds_2_options[:cavv_algorithm] if threeds_2_options[:cavv_algorithm] + authentication_data[:directoryServerTransactionId] = threeds_2_options[:ds_transaction_id] if threeds_2_options[:ds_transaction_id] + authentication_data[:eci] = threeds_2_options[:eci] if threeds_2_options[:eci] + authentication_data[:threeDSecureVersion] = threeds_2_options[:version] if threeds_2_options[:version] + authentication_data[:validationResult] = threeds_2_options[:authentication_response_status] if threeds_2_options[:authentication_response_status] + authentication_data[:xid] = threeds_2_options[:xid] if threeds_2_options[:xid] + + post['cardPaymentMethodSpecificInput'] ||= {} + post['cardPaymentMethodSpecificInput']['threeDSecure'] ||= {} + post['cardPaymentMethodSpecificInput']['threeDSecure']['externalCardholderAuthenticationData'] = authentication_data unless authentication_data.empty? + end + + def add_number_of_installments(post, options) + post['order']['additionalInput']['numberOfInstallments'] = options[:number_of_installments] if options[:number_of_installments] + end + def parse(body) JSON.parse(body) end @@ -228,9 +282,7 @@ def commit(action, post, authorization = nil) raw_response = ssl_post(url(action, authorization), post.to_json, headers(action, post, authorization)) response = parse(raw_response) rescue ResponseError => e - if e.response.code.to_i >= 400 - response = parse(e.response.body) - end + response = parse(e.response.body) if e.response.code.to_i >= 400 rescue JSON::ParserError response = json_error(raw_response) end @@ -256,19 +308,19 @@ def json_error(raw_response) def headers(action, post, authorization = nil) { - 'Content-Type' => content_type, + 'Content-Type' => content_type, 'Authorization' => auth_digest(action, post, authorization), 'Date' => date } end def auth_digest(action, post, authorization = nil) - data = <<-EOS -POST -#{content_type} -#{date} -#{uri(action, authorization)} - EOS + data = <<~REQUEST + POST + #{content_type} + #{date} + #{uri(action, authorization)} + REQUEST digest = OpenSSL::Digest.new('sha256') key = @options[:secret_api_key] "GCS v1HMAC:#{@options[:api_key_id]}:#{Base64.strict_encode64(OpenSSL::HMAC.digest(digest, key, data))}" @@ -287,18 +339,16 @@ def success_from(response) end def message_from(succeeded, response) - if succeeded - 'Succeeded' + return 'Succeeded' if succeeded + + if errors = response['errors'] + errors.first.try(:[], 'message') + elsif response['error_message'] + response['error_message'] + elsif response['status'] + 'Status: ' + response['status'] else - if errors = response['errors'] - errors.first.try(:[], 'message') - elsif response['error_message'] - response['error_message'] - elsif response['status'] - 'Status: ' + response['status'] - else - 'No message available' - end + 'No message available' end end @@ -313,14 +363,14 @@ def authorization_from(succeeded, response) end def error_code_from(succeeded, response) - unless succeeded - if errors = response['errors'] - errors.first.try(:[], 'code') - elsif status = response.try(:[], 'statusOutput').try(:[], 'statusCode') - status.to_s - else - 'No error code available' - end + return if succeeded + + if errors = response['errors'] + errors.first.try(:[], 'code') + elsif status = response.try(:[], 'statusOutput').try(:[], 'statusCode') + status.to_s + else + 'No error code available' end end @@ -328,6 +378,13 @@ def nestable_hash Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) } end + # Capture hasn't already been requested, + # and + # `requires_approval` is not false + def should_request_capture?(response, requires_approval) + !capture_requested?(response) && requires_approval != false + end + def capture_requested?(response) response.params.try(:[], 'payment').try(:[], 'status') == 'CAPTURE_REQUESTED' end diff --git a/lib/active_merchant/billing/gateways/global_transport.rb b/lib/active_merchant/billing/gateways/global_transport.rb index 94087b23e17..ca3732a8bd8 100644 --- a/lib/active_merchant/billing/gateways/global_transport.rb +++ b/lib/active_merchant/billing/gateways/global_transport.rb @@ -8,7 +8,7 @@ class GlobalTransportGateway < Gateway self.supported_countries = %w(CA PR US) self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb] + self.supported_cardtypes = %i[visa master american_express discover diners_club jcb] self.homepage_url = 'https://www.globalpaymentsinc.com' self.display_name = 'Global Transport' @@ -20,12 +20,12 @@ class GlobalTransportGateway < Gateway # :global_password - Your Global password # :term_type - 3 character field assigned by Global Transport after # - your application is certified. - def initialize(options={}) + def initialize(options = {}) requires!(options, :global_user_name, :global_password, :term_type) super end - def purchase(money, payment_method, options={}) + def purchase(money, payment_method, options = {}) post = {} add_invoice(post, money, options) add_payment_method(post, payment_method) @@ -34,7 +34,7 @@ def purchase(money, payment_method, options={}) commit('Sale', post, options) end - def authorize(money, payment_method, options={}) + def authorize(money, payment_method, options = {}) post = {} add_invoice(post, money, options) add_payment_method(post, payment_method) @@ -43,7 +43,7 @@ def authorize(money, payment_method, options={}) commit('Auth', post, options) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) post = {} add_invoice(post, money, options) add_auth(post, authorization) @@ -51,7 +51,7 @@ def capture(money, authorization, options={}) commit('Force', post, options) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) post = {} add_invoice(post, money, options) add_auth(post, authorization) @@ -59,14 +59,14 @@ def refund(money, authorization, options={}) commit('Return', post, options) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} add_auth(post, authorization) commit('Void', post, options) end - def verify(payment_method, options={}) + def verify(payment_method, options = {}) post = {} add_payment_method(post, payment_method) add_address(post, options) @@ -188,7 +188,6 @@ def default_params ExtData: '' } end - end end end diff --git a/lib/active_merchant/billing/gateways/hdfc.rb b/lib/active_merchant/billing/gateways/hdfc.rb index 142d7c83b82..8941ab19151 100644 --- a/lib/active_merchant/billing/gateways/hdfc.rb +++ b/lib/active_merchant/billing/gateways/hdfc.rb @@ -12,14 +12,14 @@ class HdfcGateway < Gateway self.supported_countries = ['IN'] self.default_currency = 'INR' self.money_format = :dollars - self.supported_cardtypes = [:visa, :master, :discover, :diners_club] + self.supported_cardtypes = %i[visa master discover diners_club] - def initialize(options={}) + def initialize(options = {}) requires!(options, :login, :password) super end - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method) @@ -28,7 +28,7 @@ def purchase(amount, payment_method, options={}) commit('purchase', post) end - def authorize(amount, payment_method, options={}) + def authorize(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method) @@ -37,7 +37,7 @@ def authorize(amount, payment_method, options={}) commit('authorize', post) end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) post = {} add_invoice(post, amount, options) add_reference(post, authorization) @@ -46,7 +46,7 @@ def capture(amount, authorization, options={}) commit('capture', post) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) post = {} add_invoice(post, amount, options) add_reference(post, authorization) @@ -57,7 +57,7 @@ def refund(amount, authorization, options={}) private - CURRENCY_CODES = Hash.new { |h, k| raise ArgumentError.new("Unsupported currency for HDFC: #{k}") } + CURRENCY_CODES = Hash.new { |_h, k| raise ArgumentError.new("Unsupported currency for HDFC: #{k}") } CURRENCY_CODES['AED'] = '784' CURRENCY_CODES['AUD'] = '036' CURRENCY_CODES['CAD'] = '124' @@ -81,14 +81,14 @@ def add_customer_data(post, options) post[:udf2] = escape(options[:email]) if options[:email] if address = (options[:billing_address] || options[:address]) post[:udf3] = escape(address[:phone]) if address[:phone] - post[:udf4] = escape(< '1', 'refund' => '2', 'authorize' => '4', - 'capture' => '5', + 'capture' => '5' } def commit(action, post) @@ -149,13 +149,13 @@ def commit(action, post) succeeded, message_from(succeeded, raw), raw, - :authorization => authorization_from(post, raw), - :test => test? + authorization: authorization_from(post, raw), + test: test? ) end def build_request(post) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.instruct! post.each do |field, value| xml.tag!(field, value) @@ -194,11 +194,10 @@ def split_authorization(authorization) [tranid, member] end - def escape(string, max_length=250) + def escape(string, max_length = 250) return '' unless string - if max_length - string = string[0...max_length] - end + + string = string[0...max_length] if max_length string.gsub(/[^A-Za-z0-9 \-_@\.\n]/, '') end end diff --git a/lib/active_merchant/billing/gateways/hps.rb b/lib/active_merchant/billing/gateways/hps.rb index 6069040003c..05ff49c237f 100644 --- a/lib/active_merchant/billing/gateways/hps.rb +++ b/lib/active_merchant/billing/gateways/hps.rb @@ -8,7 +8,7 @@ class HpsGateway < Gateway self.supported_countries = ['US'] self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jbc, :diners_club] + self.supported_cardtypes = %i[visa master american_express discover jbc diners_club] self.homepage_url = 'http://developer.heartlandpaymentsystems.com/SecureSubmit/' self.display_name = 'Heartland Payment Systems' @@ -21,65 +21,81 @@ class HpsGateway < Gateway visa: 'Visa 3DSecure', american_express: 'AMEX 3DSecure', discover: 'Discover 3DSecure', + android_pay: 'GooglePayApp', + google_pay: 'GooglePayApp' } - def initialize(options={}) + def initialize(options = {}) requires!(options, :secret_api_key) super end - def authorize(money, card_or_token, options={}) + def authorize(money, card_or_token, options = {}) commit('CreditAuth') do |xml| add_amount(xml, money) add_allow_dup(xml) - add_customer_data(xml, card_or_token, options) + add_card_or_token_customer_data(xml, card_or_token, options) add_details(xml, options) add_descriptor_name(xml, options) - add_payment(xml, card_or_token, options) + add_card_or_token_payment(xml, card_or_token, options) add_three_d_secure(xml, card_or_token, options) + add_stored_credentials(xml, options) end end - def capture(money, transaction_id, options={}) - commit('CreditAddToBatch') do |xml| + def capture(money, transaction_id, options = {}) + commit('CreditAddToBatch', transaction_id) do |xml| add_amount(xml, money) add_reference(xml, transaction_id) end end - def purchase(money, card_or_token, options={}) - commit('CreditSale') do |xml| + def purchase(money, payment_method, options = {}) + if payment_method.is_a?(Check) + commit_check_sale(money, payment_method, options) + elsif options.dig(:stored_credential, :reason_type) == 'recurring' + commit_recurring_billing_sale(money, payment_method, options) + else + commit_credit_sale(money, payment_method, options) + end + end + + def refund(money, transaction_id, options = {}) + commit('CreditReturn') do |xml| add_amount(xml, money) add_allow_dup(xml) - add_customer_data(xml, card_or_token, options) + add_reference(xml, transaction_id) + add_card_or_token_customer_data(xml, transaction_id, options) add_details(xml, options) - add_descriptor_name(xml, options) - add_payment(xml, card_or_token, options) - add_three_d_secure(xml, card_or_token, options) end end - def refund(money, transaction_id, options={}) + def credit(money, payment_method, options = {}) commit('CreditReturn') do |xml| add_amount(xml, money) add_allow_dup(xml) - add_reference(xml, transaction_id) - add_customer_data(xml, transaction_id, options) + add_card_or_token_payment(xml, payment_method, options) add_details(xml, options) end end - def verify(card_or_token, options={}) + def verify(card_or_token, options = {}) commit('CreditAccountVerify') do |xml| - add_customer_data(xml, card_or_token, options) + add_card_or_token_customer_data(xml, card_or_token, options) add_descriptor_name(xml, options) - add_payment(xml, card_or_token, options) + add_card_or_token_payment(xml, card_or_token, options) end end - def void(transaction_id, options={}) - commit('CreditVoid') do |xml| - add_reference(xml, transaction_id) + def void(transaction_id, options = {}) + if options[:check_void] + commit('CheckVoid') do |xml| + add_reference(xml, transaction_id) + end + else + commit('CreditVoid') do |xml| + add_reference(xml, transaction_id) + end end end @@ -92,20 +108,60 @@ def scrub(transcript) gsub(%r(()[^<]*(<\/hps:CardNbr>))i, '\1[FILTERED]\2'). gsub(%r(()[^<]*(<\/hps:CVV2>))i, '\1[FILTERED]\2'). gsub(%r(()[^<]*(<\/hps:SecretAPIKey>))i, '\1[FILTERED]\2'). - gsub(%r(()[^<]*(<\/hps:PaymentData>))i, '\1[FILTERED]\2') + gsub(%r(()[^<]*(<\/hps:PaymentData>))i, '\1[FILTERED]\2'). + gsub(%r(()[^<]*(<\/hps:RoutingNumber>))i, '\1[FILTERED]\2'). + gsub(%r(()[^<]*(<\/hps:AccountNumber>))i, '\1[FILTERED]\2') end private + def commit_check_sale(money, check, options) + commit('CheckSale') do |xml| + add_check_payment(xml, check, options) + add_amount(xml, money) + add_sec_code(xml, options) + add_check_customer_data(xml, check, options) + add_details(xml, options) + end + end + + def commit_credit_sale(money, card_or_token, options) + commit('CreditSale') do |xml| + add_amount(xml, money) + add_allow_dup(xml) + add_card_or_token_customer_data(xml, card_or_token, options) + add_details(xml, options) + add_descriptor_name(xml, options) + add_card_or_token_payment(xml, card_or_token, options) + add_three_d_secure(xml, card_or_token, options) + add_stored_credentials(xml, options) + end + end + + def commit_recurring_billing_sale(money, card_or_token, options) + commit('RecurringBilling') do |xml| + add_amount(xml, money) + add_allow_dup(xml) + add_card_or_token_customer_data(xml, card_or_token, options) + add_details(xml, options) + add_descriptor_name(xml, options) + add_card_or_token_payment(xml, card_or_token, options) + add_three_d_secure(xml, card_or_token, options) + add_stored_credentials(xml, options) + add_stored_credentials_for_recurring_billing(xml, options) + end + end + def add_reference(xml, transaction_id) - xml.hps :GatewayTxnId, transaction_id + reference = transaction_id.to_s.include?('|') ? transaction_id.split('|').first : transaction_id + xml.hps :GatewayTxnId, reference end def add_amount(xml, money) xml.hps :Amt, amount(money) if money end - def add_customer_data(xml, credit_card, options) + def add_card_or_token_customer_data(xml, credit_card, options) xml.hps :CardHolderData do if credit_card.respond_to?(:number) xml.hps :CardHolderFirstName, credit_card.first_name if credit_card.first_name @@ -115,7 +171,7 @@ def add_customer_data(xml, credit_card, options) xml.hps :CardHolderEmail, options[:email] if options[:email] xml.hps :CardHolderPhone, options[:phone] if options[:phone] - if(billing_address = (options[:billing_address] || options[:address])) + if (billing_address = (options[:billing_address] || options[:address])) xml.hps :CardHolderAddr, billing_address[:address1] if billing_address[:address1] xml.hps :CardHolderCity, billing_address[:city] if billing_address[:city] xml.hps :CardHolderState, billing_address[:state] if billing_address[:state] @@ -124,11 +180,19 @@ def add_customer_data(xml, credit_card, options) end end - def add_payment(xml, card_or_token, options) + def add_check_customer_data(xml, check, options) + xml.hps :ConsumerInfo do + xml.hps :FirstName, check.first_name + xml.hps :LastName, check.last_name + xml.hps :CheckName, options[:company_name] if options[:company_name] + end + end + + def add_card_or_token_payment(xml, card_or_token, options) xml.hps :CardData do if card_or_token.respond_to?(:number) if card_or_token.track_data - xml.tag!('hps:TrackData', 'method'=>'swipe') do + xml.tag!('hps:TrackData', 'method' => 'swipe') do xml.text! card_or_token.track_data end if options[:encryption_type] @@ -159,14 +223,29 @@ def add_payment(xml, card_or_token, options) end end + def add_check_payment(xml, check, options) + xml.hps :CheckAction, 'SALE' + xml.hps :AccountInfo do + xml.hps :RoutingNumber, check.routing_number + xml.hps :AccountNumber, check.account_number + xml.hps :CheckNumber, check.number + xml.hps :AccountType, check.account_type&.upcase + end + xml.hps :CheckType, check.account_holder_type&.upcase + end + def add_details(xml, options) xml.hps :AdditionalTxnFields do xml.hps :Description, options[:description] if options[:description] - xml.hps :InvoiceNbr, options[:order_id] if options[:order_id] + xml.hps :InvoiceNbr, options[:order_id][0..59] if options[:order_id] xml.hps :CustomerID, options[:customer_id] if options[:customer_id] end end + def add_sec_code(xml, options) + xml.hps :SECCode, options[:sec_code] || 'WEB' + end + def add_allow_dup(xml) xml.hps :AllowDup, 'Y' end @@ -181,7 +260,7 @@ def add_three_d_secure(xml, card_or_token, options) source: card_or_token.source, cavv: card_or_token.payment_cryptogram, eci: card_or_token.eci, - xid: card_or_token.transaction_id, + xid: card_or_token.transaction_id }) elsif options[:three_d_secure] options[:three_d_secure][:source] ||= card_brand(card_or_token) @@ -204,8 +283,41 @@ def build_three_d_secure(xml, three_d_secure) end end + # We do not currently support installments on this gateway. + # The HPS gateway treats recurring transactions as a seperate transaction type + def add_stored_credentials(xml, options) + return unless options[:stored_credential] + + xml.hps :CardOnFileData do + if options[:stored_credential][:initiator] == 'customer' + xml.hps :CardOnFile, 'C' + elsif options[:stored_credential][:initiator] == 'merchant' + xml.hps :CardOnFile, 'M' + else + return + end + + if options[:stored_credential][:network_transaction_id] + xml.hps :CardBrandTxnId, options[:stored_credential][:network_transaction_id] + else + return + end + end + end + + def add_stored_credentials_for_recurring_billing(xml, options) + xml.hps :RecurringData do + if options[:stored_credential][:reason_type] = 'recurring' + xml.hps :OneTime, 'N' + else + xml.hps :OneTime, 'Y' + end + end + end + def strip_leading_zero(value) return value unless value[0] == '0' + value[1, 1] end @@ -213,8 +325,9 @@ def build_request(action) xml = Builder::XmlMarkup.new(encoding: 'UTF-8') xml.instruct!(:xml, encoding: 'UTF-8') xml.SOAP :Envelope, { - 'xmlns:SOAP' => 'http://schemas.xmlsoap.org/soap/envelope/', - 'xmlns:hps' => 'http://Hps.Exchange.PosGateway' } do + 'xmlns:SOAP' => 'http://schemas.xmlsoap.org/soap/envelope/', + 'xmlns:hps' => 'http://Hps.Exchange.PosGateway' + } do xml.SOAP :Body do xml.hps :PosRequest do xml.hps 'Ver1.0'.to_sym do @@ -247,7 +360,7 @@ def parse(raw) doc = Nokogiri::XML(raw) doc.remove_namespaces! - if(header = doc.xpath('//Header').first) + if (header = doc.xpath('//Header').first) header.elements.each do |node| if node.elements.size == 0 response[node.name] = node.text @@ -258,33 +371,34 @@ def parse(raw) end end end - if(transaction = doc.xpath('//Transaction/*[1]').first) + if (transaction = doc.xpath('//Transaction/*[1]').first) transaction.elements.each do |node| response[node.name] = node.text end end - if(fault = doc.xpath('//Fault/Reason/Text').first) + if (fault = doc.xpath('//Fault/Reason/Text').first) response['Fault'] = fault.text end response end - def commit(action, &request) + def commit(action, reference = nil, &request) data = build_request(action, &request) - response = begin - parse(ssl_post((test? ? test_url : live_url), data, 'Content-Type' => 'text/xml')) - rescue ResponseError => e - parse(e.response.body) - end + response = + begin + parse(ssl_post((test? ? test_url : live_url), data, 'Content-Type' => 'text/xml')) + rescue ResponseError => e + parse(e.response.body) + end ActiveMerchant::Billing::Response.new( successful?(response), message_from(response), response, test: test?, - authorization: authorization_from(response), + authorization: authorization_from(response, reference), avs_result: { code: response['AVSRsltCode'], message: response['AVSRsltText'] @@ -293,28 +407,31 @@ def commit(action, &request) ) end + SUCCESSFUL_RESPONSE_CODES = %w(0 00 85) def successful?(response) ( (response['GatewayRspCode'] == '0') && - ((response['RspCode'] || '00') == '00' || response['RspCode'] == '85') + ((SUCCESSFUL_RESPONSE_CODES.include? response['RspCode']) || !response['RspCode']) ) end def message_from(response) - if(response['Fault']) + if response['Fault'] response['Fault'] - elsif(response['GatewayRspCode'] == '0') - if(response['RspCode'] != '00' && response['RspCode'] != '85') - issuer_message(response['RspCode']) - else + elsif response['GatewayRspCode'] == '0' + if SUCCESSFUL_RESPONSE_CODES.include? response['RspCode'] response['GatewayRspMsg'] + else + issuer_message(response['RspCode']) end else (GATEWAY_MESSAGES[response['GatewayRspCode']] || response['GatewayRspMsg']) end end - def authorization_from(response) + def authorization_from(response, reference) + return [reference, response['GatewayTxnId']].join('|') if reference + response['GatewayTxnId'] end @@ -335,6 +452,7 @@ def issuer_message(code) return 'The card was declined.' if %w(02 03 04 05 41 43 44 51 56 61 62 63 65 78).include?(code) return 'An error occurred while processing the card.' if %w(06 07 12 15 19 12 52 53 57 58 76 77 91 96 EC).include?(code) return "The card's security code is incorrect." if %w(EB N7).include?(code) + ISSUER_MESSAGES[code] end diff --git a/lib/active_merchant/billing/gateways/iats_payments.rb b/lib/active_merchant/billing/gateways/iats_payments.rb index c2d4505dfb9..b8e6303f57d 100644 --- a/lib/active_merchant/billing/gateways/iats_payments.rb +++ b/lib/active_merchant/billing/gateways/iats_payments.rb @@ -8,22 +8,23 @@ class IatsPaymentsGateway < Gateway self.supported_countries = %w(AU BR CA CH DE DK ES FI FR GR HK IE IT NL NO PT SE SG TR GB US TH ID PH BE) self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://home.iatspayments.com/' self.display_name = 'iATS Payments' ACTIONS = { - purchase: 'ProcessCreditCardV1', - purchase_check: 'ProcessACHEFTV1', - refund: 'ProcessCreditCardRefundWithTransactionIdV1', - refund_check: 'ProcessACHEFTRefundWithTransactionIdV1', - store: 'CreateCreditCardCustomerCodeV1', - unstore: 'DeleteCustomerCodeV1' + purchase: 'ProcessCreditCard', + purchase_check: 'ProcessACHEFT', + purchase_customer_code: 'ProcessCreditCardWithCustomerCode', + refund: 'ProcessCreditCardRefundWithTransactionId', + refund_check: 'ProcessACHEFTRefundWithTransactionId', + store: 'CreateCreditCardCustomerCode', + unstore: 'DeleteCustomerCode' } - def initialize(options={}) - if(options[:login]) + def initialize(options = {}) + if options[:login] ActiveMerchant.deprecated("The 'login' option is deprecated in favor of 'agent_code' and will be removed in a future version.") options[:agent_code] = options[:login] end @@ -34,18 +35,19 @@ def initialize(options={}) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) post = {} add_invoice(post, money, options) add_payment(post, payment) add_address(post, options) add_ip(post, options) add_description(post, options) + add_customer_details(post, options) - commit((payment.is_a?(Check) ? :purchase_check : :purchase), post) + commit(determine_purchase_type(payment), post) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) post = {} transaction_id, payment_type = split_authorization(authorization) post[:transaction_id] = transaction_id @@ -90,17 +92,30 @@ def scrub(transcript) private + def determine_purchase_type(payment) + if payment.is_a?(String) + :purchase_customer_code + elsif payment.is_a?(Check) + :purchase_check + else + :purchase + end + end + def add_ip(post, options) post[:customer_ip_address] = options[:ip] if options.has_key?(:ip) end def add_address(post, options) billing_address = options[:billing_address] || options[:address] - if(billing_address) + if billing_address post[:address] = billing_address[:address1] post[:city] = billing_address[:city] post[:state] = billing_address[:state] post[:zip_code] = billing_address[:zip] + post[:phone] = billing_address[:phone] if billing_address[:phone] + post[:email] = billing_address[:email] if billing_address[:email] + post[:country] = billing_address[:country] if billing_address[:country] end end @@ -114,7 +129,9 @@ def add_description(post, options) end def add_payment(post, payment) - if payment.is_a?(Check) + if payment.is_a?(String) + post[:customer_code] = payment + elsif payment.is_a?(Check) add_check(post, payment) else add_credit_card(post, payment) @@ -144,6 +161,10 @@ def add_store_defaults(post) post[:amount] = 0 end + def add_customer_details(post, options) + post[:email] = options[:email] if options[:email] + end + def expdate(creditcard) year = sprintf('%.4i', creditcard.year) month = sprintf('%.2i', creditcard.month) @@ -165,7 +186,7 @@ def creditcard_brand(brand) def commit(action, parameters) response = parse(ssl_post(url(action), post_data(action, parameters), - { 'Content-Type' => 'application/soap+xml; charset=utf-8'})) + { 'Content-Type' => 'application/soap+xml; charset=utf-8' })) Response.new( success_from(response), @@ -178,12 +199,13 @@ def commit(action, parameters) def endpoints { - purchase: 'ProcessLink.asmx', - purchase_check: 'ProcessLink.asmx', - refund: 'ProcessLink.asmx', - refund_check: 'ProcessLink.asmx', - store: 'CustomerLink.asmx', - unstore: 'CustomerLink.asmx' + purchase: 'ProcessLinkv3.asmx', + purchase_check: 'ProcessLinkv3.asmx', + purchase_customer_code: 'ProcessLinkv3.asmx', + refund: 'ProcessLinkv3.asmx', + refund_check: 'ProcessLinkv3.asmx', + store: 'CustomerLinkv3.asmx', + unstore: 'CustomerLinkv3.asmx' } end @@ -217,7 +239,7 @@ def hashify_xml!(xml, response) end def recursively_parse_element(node, response) - if(node.has_elements?) + if node.has_elements? node.elements.each { |n| recursively_parse_element(n, response) } else response[dexmlize_param_name(node.name)] = (node.text ? node.text.strip : nil) @@ -235,7 +257,7 @@ def success_from(response) def message_from(response) if !successful_result_message?(response) && response[:authorization_result] return response[:authorization_result].strip - elsif(response[:status] == 'Failure') + elsif response[:status] == 'Failure' return response[:errors] else response[:status] @@ -243,7 +265,7 @@ def message_from(response) end def authorization_from(action, response) - if [:store, :unstore].include?(action) + if %i[store unstore].include?(action) response[:customercode] elsif [:purchase_check].include?(action) response[:transaction_id] ? "#{response[:transaction_id]}|check" : nil @@ -266,7 +288,7 @@ def envelope_namespaces def post_data(action, parameters = {}) xml = Builder::XmlMarkup.new - xml.instruct!(:xml, :version => '1.0', :encoding => 'utf-8') + xml.instruct!(:xml, version: '1.0', encoding: 'utf-8') xml.tag! 'soap12:Envelope', envelope_namespaces do xml.tag! 'soap12:Body' do xml.tag! ACTIONS[action], { 'xmlns' => 'https://www.iatspayments.com/NetGate/' } do diff --git a/lib/active_merchant/billing/gateways/in_context_paypal_express.rb b/lib/active_merchant/billing/gateways/in_context_paypal_express.rb index e746d978ca0..6f892d122ca 100644 --- a/lib/active_merchant/billing/gateways/in_context_paypal_express.rb +++ b/lib/active_merchant/billing/gateways/in_context_paypal_express.rb @@ -5,7 +5,7 @@ class InContextPaypalExpressGateway < PaypalExpressGateway self.live_redirect_url = 'https://www.paypal.com/checkoutnow' def redirect_url_for(token, options = {}) - options = {review: true}.update(options) + options = { review: true }.update(options) url = "#{redirect_url}?token=#{token}" url += '&useraction=commit' unless options[:review] url diff --git a/lib/active_merchant/billing/gateways/inspire.rb b/lib/active_merchant/billing/gateways/inspire.rb index e7771e9ec81..61f6f8c4b85 100644 --- a/lib/active_merchant/billing/gateways/inspire.rb +++ b/lib/active_merchant/billing/gateways/inspire.rb @@ -5,7 +5,7 @@ class InspireGateway < Gateway self.live_url = self.test_url = 'https://secure.inspiregateway.net/api/transact.php' self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express] + self.supported_cardtypes = %i[visa master american_express] self.homepage_url = 'http://www.inspiregateway.com' self.display_name = 'Inspire Commerce' @@ -51,13 +51,13 @@ def purchase(money, payment_source, options = {}) end def capture(money, authorization, options = {}) - post ={} + post = {} post[:transactionid] = authorization commit('capture', money, post) end def void(authorization, options = {}) - post ={} + post = {} post[:transactionid] = authorization commit('void', nil, post) end @@ -93,33 +93,29 @@ def delete(vault_id) # store and unstore need to be defined def store(creditcard, options = {}) billing_id = options.delete(:billing_id).to_s || true - authorize(100, creditcard, options.merge(:store => billing_id)) + authorize(100, creditcard, options.merge(store: billing_id)) end - alias_method :unstore, :delete + alias unstore delete private def add_customer_data(post, options) - if options.has_key? :email - post[:email] = options[:email] - end + post[:email] = options[:email] if options.has_key? :email - if options.has_key? :ip - post[:ipaddress] = options[:ip] - end + post[:ipaddress] = options[:ip] if options.has_key? :ip end def add_address(post, creditcard, options) if address = options[:billing_address] || options[:address] post[:address1] = address[:address1].to_s post[:address2] = address[:address2].to_s unless address[:address2].blank? - post[:company] = address[:company].to_s - post[:phone] = address[:phone].to_s - post[:zip] = address[:zip].to_s - post[:city] = address[:city].to_s - post[:country] = address[:country].to_s - post[:state] = address[:state].blank? ? 'n/a' : address[:state] + post[:company] = address[:company].to_s + post[:phone] = address[:phone].to_s + post[:zip] = address[:zip].to_s + post[:city] = address[:city].to_s + post[:country] = address[:country].to_s + post[:state] = address[:state].blank? ? 'n/a' : address[:state] end end @@ -128,7 +124,7 @@ def add_invoice(post, options) post[:orderdescription] = options[:description] end - def add_payment_source(params, source, options={}) + def add_payment_source(params, source, options = {}) case determine_funding_source(source) when :vault then add_customer_vault_id(params, source) when :credit_card then add_creditcard(params, source, options) @@ -145,9 +141,9 @@ def add_creditcard(post, creditcard, options) post[:customer_vault] = 'add_customer' post[:customer_vault_id] = options[:store] unless options[:store] == true end - post[:ccnumber] = creditcard.number + post[:ccnumber] = creditcard.number post[:cvv] = creditcard.verification_value if creditcard.verification_value? - post[:ccexp] = expdate(creditcard) + post[:ccexp] = expdate(creditcard) post[:firstname] = creditcard.first_name post[:lastname] = creditcard.last_name end @@ -172,16 +168,15 @@ def parse(body) end def commit(action, money, parameters) - parameters[:amount] = amount(money) if money + parameters[:amount] = amount(money) if money response = parse(ssl_post(self.live_url, post_data(action, parameters))) Response.new(response['response'] == '1', message_from(response), response, - :authorization => response['transactionid'], - :test => test?, - :cvv_result => response['cvvresponse'], - :avs_result => { :code => response['avsresponse'] } - ) + authorization: response['transactionid'], + test: test?, + cvv_result: response['cvvresponse'], + avs_result: { code: response['avsresponse'] }) end def message_from(response) @@ -197,7 +192,7 @@ def message_from(response) def post_data(action, parameters = {}) post = {} - post[:username] = @options[:login] + post[:username] = @options[:login] post[:password] = @options[:password] post[:type] = action if action diff --git a/lib/active_merchant/billing/gateways/instapay.rb b/lib/active_merchant/billing/gateways/instapay.rb index 7d18c8da05b..4ca11852dd8 100644 --- a/lib/active_merchant/billing/gateways/instapay.rb +++ b/lib/active_merchant/billing/gateways/instapay.rb @@ -8,7 +8,7 @@ class InstapayGateway < Gateway self.money_format = :dollars self.default_currency = 'USD' # The card types supported by the payment gateway - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] # The homepage URL of the gateway self.homepage_url = 'http://www.instapayllc.com' @@ -141,18 +141,15 @@ def commit(action, parameters) response = parse(data) Response.new(response[:success], response[:message], response, - :authorization => response[:transaction_id], - :avs_result => { :code => response[:avs_result] }, - :cvv_result => response[:cvv_result] - ) + authorization: response[:transaction_id], + avs_result: { code: response[:avs_result] }, + cvv_result: response[:cvv_result]) end def post_data(action, parameters = {}) post = {} post[:acctid] = @options[:login] - if(@options[:password]) - post[:merchantpin] = @options[:password] - end + post[:merchantpin] = @options[:password] if @options[:password] post[:action] = action request = post.merge(parameters).collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join('&') request diff --git a/lib/active_merchant/billing/gateways/ipp.rb b/lib/active_merchant/billing/gateways/ipp.rb index fa672636787..4fd0c5c6293 100644 --- a/lib/active_merchant/billing/gateways/ipp.rb +++ b/lib/active_merchant/billing/gateways/ipp.rb @@ -7,7 +7,7 @@ class IppGateway < Gateway self.test_url = 'https://demo.ippayments.com.au/interface/api/dts.asmx' self.supported_countries = ['AU'] - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :jcb] + self.supported_cardtypes = %i[visa master american_express diners_club jcb] self.homepage_url = 'http://www.ippayments.com.au/' self.display_name = 'IPP' @@ -18,16 +18,16 @@ class IppGateway < Gateway '05' => STANDARD_ERROR_CODE[:card_declined], '06' => STANDARD_ERROR_CODE[:processing_error], '14' => STANDARD_ERROR_CODE[:invalid_number], - '54' => STANDARD_ERROR_CODE[:expired_card], + '54' => STANDARD_ERROR_CODE[:expired_card] } - def initialize(options={}) + def initialize(options = {}) ActiveMerchant.deprecated('IPP gateway is now named Bambora Asia-Pacific') requires!(options, :username, :password) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) commit('SubmitSinglePayment') do |xml| xml.Transaction do xml.CustRef options[:order_id] @@ -40,7 +40,7 @@ def purchase(money, payment, options={}) end end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) commit('SubmitSinglePayment') do |xml| xml.Transaction do xml.CustRef options[:order_id] @@ -53,7 +53,7 @@ def authorize(money, payment, options={}) end end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) commit('SubmitSingleCapture') do |xml| xml.Capture do xml.Receipt authorization @@ -63,7 +63,7 @@ def capture(money, authorization, options={}) end end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) commit('SubmitSingleRefund') do |xml| xml.Refund do xml.Receipt authorization @@ -98,7 +98,7 @@ def add_amount(xml, money) end def add_credit_card(xml, payment) - xml.CreditCard :Registered => 'False' do + xml.CreditCard Registered: 'False' do xml.CardNumber payment.number xml.ExpM format(payment.month, :two_digits) xml.ExpY format(payment.year, :four_digits) @@ -121,7 +121,7 @@ def parse(body) def commit(action, &block) headers = { 'Content-Type' => 'text/xml; charset=utf-8', - 'SOAPAction' => "http://www.ippayments.com.au/interface/api/dts/#{action}", + 'SOAPAction' => "http://www.ippayments.com.au/interface/api/dts/#{action}" } response = parse(ssl_post(commit_url, new_submit_xml(action, &block), headers)) diff --git a/lib/active_merchant/billing/gateways/iridium.rb b/lib/active_merchant/billing/gateways/iridium.rb index 6b6eda3805b..d2f3beff909 100644 --- a/lib/active_merchant/billing/gateways/iridium.rb +++ b/lib/active_merchant/billing/gateways/iridium.rb @@ -10,12 +10,12 @@ class IridiumGateway < Gateway self.live_url = self.test_url = 'https://gw1.iridiumcorp.net/' # The countries the gateway supports merchants from as 2 digit ISO country codes - self.supported_countries = ['GB', 'ES'] + self.supported_countries = %w[GB ES] self.default_currency = 'EUR' self.money_format = :cents # The card types supported by the payment gateway - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :maestro, :jcb, :diners_club] + self.supported_cardtypes = %i[visa master american_express discover maestro jcb diners_club] # The homepage URL of the gateway self.homepage_url = 'http://www.iridiumcorp.co.uk/' @@ -203,7 +203,7 @@ class IridiumGateway < Gateway 'YER' => '886', 'ZAR' => '710', 'ZMK' => '894', - 'ZWD' => '716', + 'ZWD' => '716' } AVS_CODE = { @@ -251,16 +251,16 @@ def capture(money, authorization, options = {}) commit(build_reference_request('COLLECTION', money, authorization, options), options) end - def credit(money, authorization, options={}) + def credit(money, authorization, options = {}) ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE refund(money, authorization, options) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) commit(build_reference_request('REFUND', money, authorization, options), options) end - def void(authorization, options={}) + def void(authorization, options = {}) commit(build_reference_request('VOID', nil, authorization, options), options) end @@ -288,15 +288,16 @@ def build_purchase_request(type, money, creditcard, options) def build_reference_request(type, money, authorization, options) options[:action] = 'CrossReferenceTransaction' - order_id, cross_reference, _ = authorization.split(';') + order_id, cross_reference, = authorization.split(';') build_request(options) do |xml| if money - details = {'CurrencyCode' => currency_code(options[:currency] || default_currency), 'Amount' => amount(money)} + currency = options[:currency] || currency(money) + details = { 'CurrencyCode' => currency_code(currency), 'Amount' => localized_amount(money, currency) } else - details = {'CurrencyCode' => currency_code(default_currency), 'Amount' => '0'} + details = { 'CurrencyCode' => currency_code(default_currency), 'Amount' => '0' } end xml.tag! 'TransactionDetails', details do - xml.tag! 'MessageDetails', {'TransactionType' => type, 'CrossReference' => cross_reference} + xml.tag! 'MessageDetails', { 'TransactionType' => type, 'CrossReference' => cross_reference } xml.tag! 'OrderID', (options[:order_id] || order_id) end end @@ -304,13 +305,13 @@ def build_reference_request(type, money, authorization, options) def build_request(options) requires!(options, :action) - xml = Builder::XmlMarkup.new :indent => 2 - xml.instruct!(:xml, :version => '1.0', :encoding => 'utf-8') + xml = Builder::XmlMarkup.new indent: 2 + xml.instruct!(:xml, version: '1.0', encoding: 'utf-8') xml.tag! 'soap:Envelope', { 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', - 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema'} do + 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema' } do xml.tag! 'soap:Body' do - xml.tag! options[:action], {'xmlns' => 'https://www.thepaymentgateway.net/'} do + xml.tag! options[:action], { 'xmlns' => 'https://www.thepaymentgateway.net/' } do xml.tag! 'PaymentMessage' do add_merchant_data(xml, options) yield(xml) @@ -327,9 +328,10 @@ def setup_address_hash(options) end def add_purchase_data(xml, type, money, options) + currency = options[:currency] || currency(money) requires!(options, :order_id) - xml.tag! 'TransactionDetails', {'Amount' => amount(money), 'CurrencyCode' => currency_code(options[:currency] || currency(money))} do - xml.tag! 'MessageDetails', {'TransactionType' => type} + xml.tag! 'TransactionDetails', { 'Amount' => localized_amount(money, currency), 'CurrencyCode' => currency_code(currency) } do + xml.tag! 'MessageDetails', { 'TransactionType' => type } xml.tag! 'OrderID', options[:order_id] xml.tag! 'TransactionControl' do xml.tag! 'ThreeDSecureOverridePolicy', 'FALSE' @@ -342,9 +344,7 @@ def add_purchase_data(xml, type, money, options) def add_customerdetails(xml, creditcard, address, options, shipTo = false) xml.tag! 'CustomerDetails' do if address - unless address[:country].blank? - country_code = Country.find(address[:country]).code(:numeric) - end + country_code = Country.find(address[:country]).code(:numeric) unless address[:country].blank? xml.tag! 'BillingAddress' do xml.tag! 'Address1', address[:address1] xml.tag! 'Address2', address[:address2] @@ -371,35 +371,34 @@ def add_creditcard(xml, creditcard) end def add_merchant_data(xml, options) - xml.tag! 'MerchantAuthentication', {'MerchantID' => @options[:login], 'Password' => @options[:password]} + xml.tag! 'MerchantAuthentication', { 'MerchantID' => @options[:login], 'Password' => @options[:password] } end def commit(request, options) requires!(options, :action) response = parse(ssl_post(test? ? self.test_url : self.live_url, request, - {'SOAPAction' => 'https://www.thepaymentgateway.net/' + options[:action], + { 'SOAPAction' => 'https://www.thepaymentgateway.net/' + options[:action], 'Content-Type' => 'text/xml; charset=utf-8' })) success = response[:transaction_result][:status_code] == '0' message = response[:transaction_result][:message] - authorization = success ? [ options[:order_id], response[:transaction_output_data][:cross_reference], response[:transaction_output_data][:auth_code] ].compact.join(';') : nil + authorization = success ? [options[:order_id], response[:transaction_output_data][:cross_reference], response[:transaction_output_data][:auth_code]].compact.join(';') : nil Response.new(success, message, response, - :test => test?, - :authorization => authorization, - :avs_result => { - :street_match => AVS_CODE[ response[:transaction_output_data][:address_numeric_check_result] ], - :postal_match => AVS_CODE[ response[:transaction_output_data][:post_code_check_result] ], + test: test?, + authorization: authorization, + avs_result: { + street_match: AVS_CODE[ response[:transaction_output_data][:address_numeric_check_result] ], + postal_match: AVS_CODE[ response[:transaction_output_data][:post_code_check_result] ] }, - :cvv_result => CVV_CODE[ response[:transaction_output_data][:cv2_check_result] ] - ) + cvv_result: CVV_CODE[ response[:transaction_output_data][:cv2_check_result] ]) end def parse(xml) reply = {} xml = REXML::Document.new(xml) - if (root = REXML::XPath.first(xml, '//CardDetailsTransactionResponse')) or - (root = REXML::XPath.first(xml, '//CrossReferenceTransactionResponse')) + if (root = REXML::XPath.first(xml, '//CardDetailsTransactionResponse')) || + (root = REXML::XPath.first(xml, '//CrossReferenceTransactionResponse')) root.elements.to_a.each do |node| case node.name when 'Message' diff --git a/lib/active_merchant/billing/gateways/itransact.rb b/lib/active_merchant/billing/gateways/itransact.rb index 8bac0734e0a..2a881e1939b 100644 --- a/lib/active_merchant/billing/gateways/itransact.rb +++ b/lib/active_merchant/billing/gateways/itransact.rb @@ -38,7 +38,7 @@ class ItransactGateway < Gateway self.supported_countries = ['US'] # The card types supported by the payment gateway - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] # The homepage URL of the gateway self.homepage_url = 'http://www.itransact.com/' @@ -301,8 +301,8 @@ def add_customer_data(xml, payment_source, options) def add_invoice(xml, money, options) xml.AuthCode options[:force] if options[:force] if options[:order_items].blank? - xml.Total(amount(money)) unless(money.nil? || money < 0.01) - xml.Description(options[:description]) unless(options[:description].blank?) + xml.Total(amount(money)) unless money.nil? || money < 0.01 + xml.Description(options[:description]) unless options[:description].blank? else xml.OrderItems { options[:order_items].each do |item| @@ -371,6 +371,7 @@ def add_transaction_control(xml, options) def add_vendor_data(xml, options) return if options[:vendor_data].blank? + xml.VendorData { options[:vendor_data].each do |k, v| xml.Element { @@ -387,14 +388,14 @@ def commit(payload) response = parse(ssl_post(self.live_url, post_data(payload), 'Content-Type' => 'text/xml')) Response.new(successful?(response), response[:error_message], response, - :test => test?, - :authorization => response[:xid], - :avs_result => { :code => response[:avs_response] }, - :cvv_result => response[:cvv_response]) + test: test?, + authorization: response[:xid], + avs_result: { code: response[:avs_response] }, + cvv_result: response[:cvv_response]) end def post_data(payload) - payload_xml = payload.root.to_xml(:indent => 0) + payload_xml = payload.root.to_xml(indent: 0) payload_signature = sign_payload(payload_xml) @@ -409,7 +410,7 @@ def post_data(payload) end.doc request.root.children.first.after payload.root - request.to_xml(:indent => 0) + request.to_xml(indent: 0) end def parse(raw_xml) @@ -438,7 +439,7 @@ def message_from(response) def sign_payload(payload) key = @options[:password].to_s - digest=OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new(key), key, payload) + digest = OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new(key), key, payload) signature = Base64.encode64(digest) signature.chomp! end diff --git a/lib/active_merchant/billing/gateways/iveri.rb b/lib/active_merchant/billing/gateways/iveri.rb index 4a8d96e4752..26e03b45461 100644 --- a/lib/active_merchant/billing/gateways/iveri.rb +++ b/lib/active_merchant/billing/gateways/iveri.rb @@ -5,20 +5,20 @@ module Billing #:nodoc: class IveriGateway < Gateway self.live_url = self.test_url = 'https://portal.nedsecure.co.za/iVeriWebService/Service.asmx' - self.supported_countries = ['US', 'ZA', 'GB'] + self.supported_countries = %w[US ZA GB] self.default_currency = 'ZAR' self.money_format = :cents - self.supported_cardtypes = [:visa, :master, :american_express] + self.supported_cardtypes = %i[visa master american_express] self.homepage_url = 'http://www.iveri.com' self.display_name = 'iVeri' - def initialize(options={}) + def initialize(options = {}) requires!(options, :app_id, :cert_id) super end - def purchase(money, payment_method, options={}) + def purchase(money, payment_method, options = {}) post = build_vxml_request('Debit', options) do |xml| add_auth_purchase_params(xml, money, payment_method, options) end @@ -26,7 +26,7 @@ def purchase(money, payment_method, options={}) commit(post) end - def authorize(money, payment_method, options={}) + def authorize(money, payment_method, options = {}) post = build_vxml_request('Authorisation', options) do |xml| add_auth_purchase_params(xml, money, payment_method, options) end @@ -34,7 +34,7 @@ def authorize(money, payment_method, options={}) commit(post) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) post = build_vxml_request('Debit', options) do |xml| add_authorization(xml, authorization, options) end @@ -42,7 +42,7 @@ def capture(money, authorization, options={}) commit(post) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) post = build_vxml_request('Credit', options) do |xml| add_amount(xml, money, options) add_authorization(xml, authorization, options) @@ -51,7 +51,7 @@ def refund(money, authorization, options={}) commit(post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = build_vxml_request('Void', options) do |xml| add_authorization(xml, authorization, options) end @@ -59,13 +59,17 @@ def void(authorization, options={}) commit(post) end - def verify(credit_card, options={}) - authorize(0, credit_card, options) + def verify(credit_card, options = {}) + MultiResponse.run(:use_first_response) do |r| + r.process { authorize(100, credit_card, options) } + r.process(:ignore_result) { void(r.authorization, options) } + end end def verify_credentials void = void('', options) - return true if void.message == 'Missing OriginalMerchantTrace' + return true if void.message == 'Missing OriginalMerchantTrace' + false end @@ -83,7 +87,7 @@ def scrub(transcript) private def build_xml_envelope(vxml) - builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml| + builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml| xml[:soap].Envelope 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema', 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/' do xml[:soap].Body do xml.Execute 'xmlns' => 'http://iveri.com/' do @@ -150,11 +154,12 @@ def add_card_holder_authentication(post, options) end def commit(post) - raw_response = begin - ssl_post(live_url, build_xml_envelope(post), headers(post)) - rescue ActiveMerchant::ResponseError => e - e.response.body - end + raw_response = + begin + ssl_post(live_url, build_xml_envelope(post), headers(post)) + rescue ActiveMerchant::ResponseError => e + e.response.body + end parsed = parse(raw_response) succeeded = success_from(parsed) @@ -201,7 +206,7 @@ def parse(body) def parse_element(parsed, node) if !node.attributes.empty? node.attributes.each do |a| - parsed[underscore(node.name)+ '_' + underscore(a[1].name)] = a[1].value + parsed[underscore(node.name) + '_' + underscore(a[1].name)] = a[1].value end end @@ -234,9 +239,7 @@ def split_auth(authorization) end def error_code_from(response, succeeded) - unless succeeded - response['result_code'] - end + response['result_code'] unless succeeded end def underscore(camel_cased_word) diff --git a/lib/active_merchant/billing/gateways/ixopay.rb b/lib/active_merchant/billing/gateways/ixopay.rb new file mode 100644 index 00000000000..db928d445c9 --- /dev/null +++ b/lib/active_merchant/billing/gateways/ixopay.rb @@ -0,0 +1,320 @@ +require 'nokogiri' + +module ActiveMerchant #:nodoc: + module Billing #:nodoc: + class IxopayGateway < Gateway + self.test_url = 'https://secure.ixopay.com/transaction' + self.live_url = 'https://secure.ixopay.com/transaction' + + self.supported_countries = %w(AO AQ AR AS AT AU AW AX AZ BA BB BD BE BF BG BH BI BJ BL BM BN BO BQ BQ BR BS BT BV BW BY BZ CA CC CD CF CG CH CI CK CL CM CN CO CR CU CV CW CX CY CZ DE DJ DK DM DO DZ EC EE EG EH ER ES ET FI FJ FK FM FO FR GA GB GD GE GF GG GH GI GL GM GN GP GQ GR GS GT GU GW GY HK HM HN HR HT HU ID IE IL IM IN IO IQ IR IS IT JE JM JO JP KE KG KH KI KM KN KP KR KW KY KZ LA LB LC LI LK LR LS LT LU LV LY MA MC MD ME MF MG MH MK ML MM MN MO MP MQ MR MS MT MU MV MW MX MY MZ NA NC NE NF NG NI NL NO NP NR NU NZ OM PA PE PF PG PH PK PL PM PN PR PS PT PW PY QA RE RO RS RU RW SA SB SC SD SE SG SH SI SJ SK SL SM SN SO SR SS ST SV SX SY SZ TC TD TF TG TH TJ TK TL TM TN TO TR TT TV TW TZ UA UG UM US UY UZ VA VC VE VG VI VN VU WF WS YE YT ZA ZM ZW) + self.default_currency = 'EUR' + self.currencies_with_three_decimal_places = %w(BHD IQD JOD KWD LWD OMR TND) + self.supported_cardtypes = %i[visa master american_express discover diners_club jcb maestro] + + self.homepage_url = 'https://www.ixopay.com' + self.display_name = 'Ixopay' + + def initialize(options = {}) + requires!(options, :username, :password, :secret, :api_key) + @secret = options[:secret] + super + end + + def purchase(money, payment_method, options = {}) + request = build_xml_request do |xml| + add_card_data(xml, payment_method) + add_debit(xml, money, options) + end + + commit(request) + end + + def authorize(money, payment_method, options = {}) + request = build_xml_request do |xml| + add_card_data(xml, payment_method) + add_preauth(xml, money, options) + end + + commit(request) + end + + def capture(money, authorization, options = {}) + request = build_xml_request do |xml| + add_capture(xml, money, authorization, options) + end + + commit(request) + end + + def refund(money, authorization, options = {}) + request = build_xml_request do |xml| + add_refund(xml, money, authorization, options) + end + + commit(request) + end + + def void(authorization, options = {}) + request = build_xml_request do |xml| + add_void(xml, authorization) + end + + commit(request) + end + + def verify(credit_card, options = {}) + MultiResponse.run(:use_first_response) do |r| + r.process { authorize(100, credit_card, options) } + r.process(:ignore_result) { void(r.authorization, options) } + end + end + + def supports_scrubbing? + true + end + + def scrub(transcript) + clean_transcript = remove_invalid_utf_8_byte_sequences(transcript) + + clean_transcript. + gsub(%r((Authorization: Gateway )(.*)(:)), '\1[FILTERED]\3'). + gsub(%r(()(.*)()), '\1[FILTERED]\3'). + gsub(%r(()(.*)()), '\1[FILTERED]\3'). + gsub(%r(()\d+()), '\1[FILTERED]\2') + end + + private + + def remove_invalid_utf_8_byte_sequences(text) + text.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '') + end + + def headers(xml) + timestamp = Time.now.httpdate + signature = generate_signature('POST', xml, timestamp) + + { + 'Authorization' => "Gateway #{options[:api_key]}:#{signature}", + 'Date' => timestamp, + 'Content-Type' => 'text/xml; charset=utf-8' + } + end + + def generate_signature(http_method, xml, timestamp) + content_type = 'text/xml; charset=utf-8' + message = "#{http_method}\n#{Digest::MD5.hexdigest(xml)}\n#{content_type}\n#{timestamp}\n\n/transaction" + digest = OpenSSL::Digest.new('sha512') + hmac = OpenSSL::HMAC.digest(digest, @secret, message) + + Base64.encode64(hmac).delete("\n") + end + + def parse(body) + xml = Nokogiri::XML(body) + response = Hash.from_xml(xml.to_s)['result'] + + response.deep_transform_keys(&:underscore).transform_keys(&:to_sym) + end + + def build_xml_request + builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml| + xml.transactionWithCard 'xmlns' => 'http://secure.ixopay.com/Schema/V2/TransactionWithCard' do + xml.username @options[:username] + xml.password Digest::SHA1.hexdigest(@options[:password]) + yield(xml) + end + end + + builder.to_xml + end + + def add_card_data(xml, payment_method) + xml.cardData do + xml.cardHolder payment_method.name + xml.pan payment_method.number + xml.cvv payment_method.verification_value + xml.expirationMonth format(payment_method.month, :two_digits) + xml.expirationYear format(payment_method.year, :four_digits) + end + end + + def add_debit(xml, money, options) + currency = options[:currency] || currency(money) + description = options[:description].blank? ? 'Purchase' : options[:description] + + xml.debit do + xml.transactionId new_transaction_id + + add_customer_data(xml, options) + add_extra_data(xml, options[:extra_data]) if options[:extra_data] + + xml.amount localized_amount(money, currency) + xml.currency currency + xml.description description + xml.callbackUrl(options[:callback_url]) + add_stored_credentials(xml, options) + end + end + + def add_preauth(xml, money, options) + description = options[:description].blank? ? 'Preauthorize' : options[:description] + currency = options[:currency] || currency(money) + callback_url = options[:callback_url] + + xml.preauthorize do + xml.transactionId new_transaction_id + + add_customer_data(xml, options) + add_extra_data(xml, options[:extra_data]) if options[:extra_data] + + xml.amount localized_amount(money, currency) + xml.currency currency + xml.description description + xml.callbackUrl callback_url + add_stored_credentials(xml, options) + end + end + + def add_refund(xml, money, authorization, options) + currency = options[:currency] || currency(money) + + xml.refund do + xml.transactionId new_transaction_id + add_extra_data(xml, options[:extra_data]) if options[:extra_data] + xml.referenceTransactionId authorization&.split('|')&.first + xml.amount localized_amount(money, currency) + xml.currency currency + end + end + + def add_void(xml, authorization) + xml.void do + xml.transactionId new_transaction_id + add_extra_data(xml, options[:extra_data]) if options[:extra_data] + xml.referenceTransactionId authorization&.split('|')&.first + end + end + + def add_capture(xml, money, authorization, options) + currency = options[:currency] || currency(money) + + xml.capture_ do + xml.transactionId new_transaction_id + add_extra_data(xml, options[:extra_data]) if options[:extra_data] + xml.referenceTransactionId authorization&.split('|')&.first + xml.amount localized_amount(money, currency) + xml.currency currency + end + end + + def add_customer_data(xml, options) + # Ixopay returns an error if the elements are not added in the order used here. + xml.customer do + add_billing_address(xml, options[:billing_address]) if options[:billing_address] + add_shipping_address(xml, options[:shipping_address]) if options[:shipping_address] + + xml.company options[:billing_address][:company] if options.dig(:billing_address, :company) + xml.email options[:email] + xml.ipAddress(options[:ip] || '127.0.0.1') + end + end + + def add_billing_address(xml, address) + if address[:name] + xml.firstName split_names(address[:name])[0] + xml.lastName split_names(address[:name])[1] + end + + xml.billingAddress1 address[:address1] + xml.billingAddress2 address[:address2] + xml.billingCity address[:city] + xml.billingPostcode address[:zip] + xml.billingState address[:state] + xml.billingCountry address[:country] + xml.billingPhone address[:phone] + end + + def add_shipping_address(xml, address) + if address[:name] + xml.shippingFirstName split_names(address[:name])[0] + xml.shippingLastName split_names(address[:name])[1] + end + + xml.shippingCompany address[:company] + xml.shippingAddress1 address[:address1] + xml.shippingAddress2 address[:address2] + xml.shippingCity address[:city] + xml.shippingPostcode address[:zip] + xml.shippingState address[:state] + xml.shippingCountry address[:country] + xml.shippingPhone address[:phone] + end + + def new_transaction_id + SecureRandom.uuid + end + + # Ixopay does not pass any parameters for cardholder/merchant initiated. + # Ixopay also doesn't support installment transactions, only recurring + # ("RECURRING") and unscheduled ("CARDONFILE"). + # + # Furthermore, Ixopay is slightly unusual in its application of stored + # credentials in that the gateway does not return a true + # network_transaction_id that can be sent on subsequent transactions. + def add_stored_credentials(xml, options) + return unless stored_credential = options[:stored_credential] + + if stored_credential[:initial_transaction] + xml.transactionIndicator 'INITIAL' + elsif stored_credential[:reason_type] == 'recurring' + xml.transactionIndicator 'RECURRING' + elsif stored_credential[:reason_type] == 'unscheduled' + xml.transactionIndicator 'CARDONFILE' + end + end + + def add_extra_data(xml, extra_data) + extra_data.each do |k, v| + xml.extraData(v, key: k) + end + end + + def commit(request) + url = (test? ? test_url : live_url) + + # ssl_post raises an exception for any non-2xx HTTP status from the gateway + response = + begin + parse(ssl_post(url, request, headers(request))) + rescue StandardError => error + parse(error.response.body) + end + + Response.new( + success_from(response), + message_from(response), + response, + authorization: authorization_from(response), + test: test?, + error_code: error_code_from(response) + ) + end + + def success_from(response) + response[:success] == 'true' + end + + def message_from(response) + response.dig(:errors, 'error', 'message') || response[:return_type] + end + + def authorization_from(response) + response[:reference_id] ? "#{response[:reference_id]}|#{response[:purchase_id]}" : nil + end + + def error_code_from(response) + response.dig(:errors, 'error', 'code') unless success_from(response) + end + end + end +end diff --git a/lib/active_merchant/billing/gateways/jetpay.rb b/lib/active_merchant/billing/gateways/jetpay.rb index aaa955dd24a..94b6d0bb224 100644 --- a/lib/active_merchant/billing/gateways/jetpay.rb +++ b/lib/active_merchant/billing/gateways/jetpay.rb @@ -8,10 +8,10 @@ class JetpayGateway < Gateway self.live_ca_url = 'https://gateway17.jetpay.com/canada-bb' # The countries the gateway supports merchants from as 2 digit ISO country codes - self.supported_countries = ['US', 'CA'] + self.supported_countries = %w[US CA] # The card types supported by the payment gateway - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] # The homepage URL of the gateway self.homepage_url = 'http://www.jetpay.com/' @@ -213,9 +213,7 @@ def build_xml_request(transaction_type, options = {}, transaction_id = nil, &blo xml.tag! 'TerminalID', @options[:login] xml.tag! 'TransactionType', transaction_type xml.tag! 'TransactionID', transaction_id.nil? ? generate_unique_id.slice(0, 18) : transaction_id - if options && options[:origin] - xml.tag! 'Origin', options[:origin] - end + xml.tag! 'Origin', options[:origin] if options && options[:origin] if block_given? yield xml @@ -289,11 +287,10 @@ def commit(money, request, token = nil) Response.new(success, success ? 'APPROVED' : message_from(response), response, - :test => test?, - :authorization => authorization_from(response, money, token), - :avs_result => { :code => response[:avs] }, - :cvv_result => response[:cvv2] - ) + test: test?, + authorization: authorization_from(response, money, token), + avs_result: { code: response[:avs] }, + cvv_result: response[:cvv2]) end def url @@ -335,7 +332,7 @@ def message_from(response) def authorization_from(response, money, previous_token) original_amount = amount(money) if money - [ response[:transaction_id], response[:approval], original_amount, (response[:token] || previous_token)].join(';') + [response[:transaction_id], response[:approval], original_amount, (response[:token] || previous_token)].join(';') end def add_credit_card(xml, credit_card) @@ -343,13 +340,9 @@ def add_credit_card(xml, credit_card) xml.tag! 'CardExpMonth', format_exp(credit_card.month) xml.tag! 'CardExpYear', format_exp(credit_card.year) - if credit_card.first_name || credit_card.last_name - xml.tag! 'CardName', [credit_card.first_name, credit_card.last_name].compact.join(' ') - end + xml.tag! 'CardName', [credit_card.first_name, credit_card.last_name].compact.join(' ') if credit_card.first_name || credit_card.last_name - unless credit_card.verification_value.nil? || (credit_card.verification_value.length == 0) - xml.tag! 'CVV2', credit_card.verification_value - end + xml.tag! 'CVV2', credit_card.verification_value unless credit_card.verification_value.nil? || (credit_card.verification_value.length == 0) end def add_addresses(xml, options) diff --git a/lib/active_merchant/billing/gateways/jetpay_v2.rb b/lib/active_merchant/billing/gateways/jetpay_v2.rb index 515bba8fc84..19ff95a7e99 100644 --- a/lib/active_merchant/billing/gateways/jetpay_v2.rb +++ b/lib/active_merchant/billing/gateways/jetpay_v2.rb @@ -6,8 +6,8 @@ class JetpayV2Gateway < Gateway self.money_format = :cents self.default_currency = 'USD' - self.supported_countries = ['US', 'CA'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_countries = %w[US CA] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://www.jetpay.com' self.display_name = 'JetPay' @@ -210,8 +210,8 @@ def build_xml_request(transaction_type, options = {}, transaction_id = nil, &blo xml.tag! 'TransactionID', transaction_id.nil? ? generate_unique_id.slice(0, 18) : transaction_id xml.tag! 'Origin', options[:origin] || 'INTERNET' xml.tag! 'IndustryInfo', 'Type' => options[:industry_info] || 'ECOMMERCE' - xml.tag! 'Application', (options[:application] || 'n/a'), {'Version' => options[:application_version] || '1.0'} - xml.tag! 'Device', (options[:device] || 'n/a'), {'Version' => options[:device_version] || '1.0'} + xml.tag! 'Application', (options[:application] || 'n/a'), { 'Version' => options[:application_version] || '1.0' } + xml.tag! 'Device', (options[:device] || 'n/a'), { 'Version' => options[:device_version] || '1.0' } xml.tag! 'Library', 'VirtPOS SDK', 'Version' => '1.5' xml.tag! 'Gateway', 'JetPay' xml.tag! 'DeveloperID', options[:developer_id] || 'n/a' @@ -298,12 +298,11 @@ def commit(money, request, token = nil) Response.new(success, success ? 'APPROVED' : message_from(response), response, - :test => test?, - :authorization => authorization_from(response, money, token), - :avs_result => AVSResult.new(:code => response[:avs]), - :cvv_result => CVVResult.new(response[:cvv2]), - :error_code => success ? nil : error_code_from(response) - ) + test: test?, + authorization: authorization_from(response, money, token), + avs_result: AVSResult.new(code: response[:avs]), + cvv_result: CVVResult.new(response[:cvv2]), + error_code: success ? nil : error_code_from(response)) end def url @@ -344,7 +343,7 @@ def message_from(response) def authorization_from(response, money, previous_token) original_amount = amount(money) if money - [ response[:transaction_id], response[:approval], original_amount, (response[:token] || previous_token)].join(';') + [response[:transaction_id], response[:approval], original_amount, (response[:token] || previous_token)].join(';') end def error_code_from(response) @@ -368,13 +367,9 @@ def add_credit_card(xml, credit_card) xml.tag! 'CardExpMonth', format_exp(credit_card.month) xml.tag! 'CardExpYear', format_exp(credit_card.year) - if credit_card.first_name || credit_card.last_name - xml.tag! 'CardName', [credit_card.first_name, credit_card.last_name].compact.join(' ') - end + xml.tag! 'CardName', [credit_card.first_name, credit_card.last_name].compact.join(' ') if credit_card.first_name || credit_card.last_name - unless credit_card.verification_value.nil? || (credit_card.verification_value.length == 0) - xml.tag! 'CVV2', credit_card.verification_value - end + xml.tag! 'CVV2', credit_card.verification_value unless credit_card.verification_value.nil? || (credit_card.verification_value.length == 0) end def add_addresses(xml, options) @@ -410,7 +405,7 @@ def add_customer_data(xml, options) def add_invoice_data(xml, options) xml.tag! 'OrderNumber', options[:order_id] if options[:order_id] if tax_amount = options[:tax_amount] - xml.tag! 'TaxAmount', tax_amount, {'ExemptInd' => options[:tax_exempt] || 'false'} + xml.tag! 'TaxAmount', tax_amount, { 'ExemptInd' => options[:tax_exempt] || 'false' } end end diff --git a/lib/active_merchant/billing/gateways/komoju.rb b/lib/active_merchant/billing/gateways/komoju.rb index d53ab5f5165..1d882c00c00 100644 --- a/lib/active_merchant/billing/gateways/komoju.rb +++ b/lib/active_merchant/billing/gateways/komoju.rb @@ -10,7 +10,7 @@ class KomojuGateway < Gateway self.money_format = :cents self.homepage_url = 'https://www.komoju.com/' self.display_name = 'Komoju' - self.supported_cardtypes = [:visa, :master, :american_express, :jcb] + self.supported_cardtypes = %i[visa master american_express jcb] STANDARD_ERROR_CODE_MAPPING = { 'bad_verification_value' => 'incorrect_cvc', diff --git a/lib/active_merchant/billing/gateways/kushki.rb b/lib/active_merchant/billing/gateways/kushki.rb index 646df52166a..38cf2656787 100644 --- a/lib/active_merchant/billing/gateways/kushki.rb +++ b/lib/active_merchant/billing/gateways/kushki.rb @@ -4,27 +4,44 @@ class KushkiGateway < Gateway self.display_name = 'Kushki' self.homepage_url = 'https://www.kushkipagos.com' - self.test_url = 'https://api-uat.kushkipagos.com/v1/' - self.live_url = 'https://api.kushkipagos.com/v1/' + self.test_url = 'https://api-uat.kushkipagos.com/' + self.live_url = 'https://api.kushkipagos.com/' - self.supported_countries = ['CL', 'CO', 'EC', 'MX', 'PE'] + self.supported_countries = %w[CL CO EC MX PE] self.default_currency = 'USD' self.money_format = :dollars - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club] + self.supported_cardtypes = %i[visa master american_express discover diners_club alia] - def initialize(options={}) + def initialize(options = {}) requires!(options, :public_merchant_id, :private_merchant_id) super end - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) MultiResponse.run() do |r| r.process { tokenize(amount, payment_method, options) } r.process { charge(amount, r.authorization, options) } end end - def refund(amount, authorization, options={}) + def authorize(amount, payment_method, options = {}) + MultiResponse.run() do |r| + r.process { tokenize(amount, payment_method, options) } + r.process { preauthorize(amount, r.authorization, options) } + end + end + + def capture(amount, authorization, options = {}) + action = 'capture' + + post = {} + post[:ticketNumber] = authorization + add_invoice(action, post, amount, options) + + commit(action, post) + end + + def refund(amount, authorization, options = {}) action = 'refund' post = {} @@ -33,7 +50,7 @@ def refund(amount, authorization, options={}) commit(action, post) end - def void(authorization, options={}) + def void(authorization, options = {}) action = 'void' post = {} @@ -75,6 +92,16 @@ def charge(amount, authorization, options) commit(action, post) end + def preauthorize(amount, authorization, options) + action = 'preAuthorization' + + post = {} + add_reference(post, authorization, options) + add_invoice(action, post, amount, options) + + commit(action, post) + end + def add_invoice(action, post, money, options) if action == 'tokenize' post[:totalAmount] = amount(money).to_f @@ -94,9 +121,7 @@ def add_amount_defaults(sum, money, options) sum[:iva] = 0 sum[:subtotalIva0] = 0 - if sum[:currency] != 'COP' - sum[:ice] = 0 - end + sum[:ice] = 0 if sum[:currency] != 'COP' end def add_amount_by_country(sum, options) @@ -133,15 +158,18 @@ def add_reference(post, authorization, options) 'tokenize' => 'tokens', 'charge' => 'charges', 'void' => 'charges', - 'refund' => 'refund' + 'refund' => 'refund', + 'preAuthorization' => 'preAuthorization', + 'capture' => 'capture' } def commit(action, params) - response = begin - parse(ssl_invoke(action, params)) - rescue ResponseError => e - parse(e.response.body) - end + response = + begin + parse(ssl_invoke(action, params)) + rescue ResponseError => e + parse(e.response.body) + end success = success_from(response) @@ -156,7 +184,7 @@ def commit(action, params) end def ssl_invoke(action, params) - if ['void', 'refund'].include?(action) + if %w[void refund].include?(action) ssl_request(:delete, url(action, params), nil, headers(action)) else ssl_post(url(action, params), post_data(params), headers(action)) @@ -178,10 +206,10 @@ def post_data(params) def url(action, params) base_url = test? ? test_url : live_url - if ['void', 'refund'].include?(action) - base_url + ENDPOINT[action] + '/' + params[:ticketNumber].to_s + if %w[void refund].include?(action) + base_url + 'v1/' + ENDPOINT[action] + '/' + params[:ticketNumber].to_s else - base_url + ENDPOINT[action] + base_url + 'card/v1/' + ENDPOINT[action] end end diff --git a/lib/active_merchant/billing/gateways/latitude19.rb b/lib/active_merchant/billing/gateways/latitude19.rb index d30b5e14a22..526ec32210e 100644 --- a/lib/active_merchant/billing/gateways/latitude19.rb +++ b/lib/active_merchant/billing/gateways/latitude19.rb @@ -7,10 +7,10 @@ class Latitude19Gateway < Gateway self.live_url = 'https://gateway.l19tech.com/payments/' self.test_url = 'https://gateway-sb.l19tech.com/payments/' - self.supported_countries = ['US', 'CA'] + self.supported_countries = %w[US CA] self.default_currency = 'USD' - self.money_format = :cents - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb] + self.money_format = :dollars + self.supported_cardtypes = %i[visa master american_express discover diners_club jcb] RESPONSE_CODE_MAPPING = { '100' => 'Approved', @@ -51,12 +51,12 @@ class Latitude19Gateway < Gateway 'jcb' => 'JC' } - def initialize(options={}) + def initialize(options = {}) requires!(options, :account_number, :configuration_id, :secret) super end - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) if payment_method.is_a?(String) auth_or_sale('sale', payment_method, amount, nil, options) else @@ -68,7 +68,7 @@ def purchase(amount, payment_method, options={}) end end - def authorize(amount, payment_method, options={}) + def authorize(amount, payment_method, options = {}) if payment_method.is_a?(String) auth_or_sale('auth', payment_method, amount, nil, options) else @@ -80,7 +80,7 @@ def authorize(amount, payment_method, options={}) end end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) post = {} post[:method] = 'deposit' add_request_id(post) @@ -96,7 +96,7 @@ def capture(amount, authorization, options={}) commit('v1/', post) end - def void(authorization, options={}) + def void(authorization, options = {}) method, pgwTID = split_authorization(authorization) case method when 'auth' @@ -109,7 +109,7 @@ def void(authorization, options={}) end end - def credit(amount, payment_method, options={}) + def credit(amount, payment_method, options = {}) if payment_method.is_a?(String) refundWithCard(payment_method, amount, nil, options) else @@ -121,7 +121,7 @@ def credit(amount, payment_method, options={}) end end - def verify(payment_method, options={}, action=nil) + def verify(payment_method, options = {}, action = nil) if payment_method.is_a?(String) verifyOnly(action, payment_method, nil, options) else @@ -133,7 +133,7 @@ def verify(payment_method, options={}, action=nil) end end - def store(payment_method, options={}) + def store(payment_method, options = {}) verify(payment_method, options, 'store') end @@ -201,7 +201,7 @@ def add_customer_data(params, options) end end - def get_session(options={}) + def get_session(options = {}) post = {} post[:method] = 'getSession' add_request_id(post) @@ -213,7 +213,7 @@ def get_session(options={}) commit('session', post) end - def get_token(authorization, payment_method, options={}) + def get_token(authorization, payment_method, options = {}) post = {} post[:method] = 'tokenize' add_request_id(post) @@ -226,7 +226,7 @@ def get_token(authorization, payment_method, options={}) commit('token', post) end - def auth_or_sale(method, authorization, amount, credit_card, options={}) + def auth_or_sale(method, authorization, amount, credit_card, options = {}) post = {} post[:method] = method add_request_id(post) @@ -246,7 +246,7 @@ def auth_or_sale(method, authorization, amount, credit_card, options={}) commit('v1/', post) end - def verifyOnly(action, authorization, credit_card, options={}) + def verifyOnly(action, authorization, credit_card, options = {}) post = {} post[:method] = 'verifyOnly' add_request_id(post) @@ -267,7 +267,7 @@ def verifyOnly(action, authorization, credit_card, options={}) commit('v1/', post) end - def refundWithCard(authorization, amount, credit_card, options={}) + def refundWithCard(authorization, amount, credit_card, options = {}) post = {} post[:method] = 'refundWithCard' add_request_id(post) @@ -286,7 +286,7 @@ def refundWithCard(authorization, amount, credit_card, options={}) commit('v1/', post) end - def reverse_or_void(method, pgwTID, options={}) + def reverse_or_void(method, pgwTID, options = {}) post = {} post[:method] = method add_request_id(post) @@ -324,7 +324,7 @@ def commit(endpoint, post) def headers { - 'Content-Type' => 'application/json' + 'Content-Type' => 'application/json' } end @@ -364,6 +364,7 @@ def message_from(response) def error_from(response) return response['error'] if response['error'] return 'Failed' unless response.key?('result') + return response['result']['pgwResponseCode'] || response['result']['processor']['responseCode'] || 'Failed' end @@ -397,7 +398,7 @@ def response_error(raw_response) false, message_from(response), response, - :test => test? + test: test? ) end diff --git a/lib/active_merchant/billing/gateways/linkpoint.rb b/lib/active_merchant/billing/gateways/linkpoint.rb index 4dd09c89800..dc5bf64e56f 100644 --- a/lib/active_merchant/billing/gateways/linkpoint.rb +++ b/lib/active_merchant/billing/gateways/linkpoint.rb @@ -130,7 +130,7 @@ class LinkpointGateway < Gateway self.live_url = 'https://secure.linkpt.net:1129/' self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club] + self.supported_cardtypes = %i[visa master american_express discover jcb diners_club] self.homepage_url = 'http://www.linkpoint.com/' self.display_name = 'LinkPoint' @@ -138,8 +138,8 @@ def initialize(options = {}) requires!(options, :login) @options = { - :result => 'LIVE', - :pem => LinkpointGateway.pem_file + result: 'LIVE', + pem: LinkpointGateway.pem_file }.update(options) raise ArgumentError, "You need to pass in your pem file using the :pem parameter or set it globally using ActiveMerchant::Billing::LinkpointGateway.pem_file = File.read( File.dirname(__FILE__) + '/../mycert.pem' ) or similar" if @options[:pem].blank? @@ -166,28 +166,28 @@ def initialize(options = {}) # :threshold Tells how many times to retry the transaction (if it fails) before contacting the merchant. # :comments Uh... comments # - def recurring(money, creditcard, options={}) + def recurring(money, creditcard, options = {}) ActiveMerchant.deprecated RECURRING_DEPRECATION_MESSAGE - requires!(options, [:periodicity, :bimonthly, :monthly, :biweekly, :weekly, :yearly, :daily], :installments, :order_id) + requires!(options, %i[periodicity bimonthly monthly biweekly weekly yearly daily], :installments, :order_id) options.update( - :ordertype => 'SALE', - :action => options[:action] || 'SUBMIT', - :installments => options[:installments] || 12, - :startdate => options[:startdate] || 'immediate', - :periodicity => options[:periodicity].to_s || 'monthly', - :comments => options[:comments] || nil, - :threshold => options[:threshold] || 3 + ordertype: 'SALE', + action: options[:action] || 'SUBMIT', + installments: options[:installments] || 12, + startdate: options[:startdate] || 'immediate', + periodicity: options[:periodicity].to_s || 'monthly', + comments: options[:comments] || nil, + threshold: options[:threshold] || 3 ) commit(money, creditcard, options) end # Buy the thing - def purchase(money, creditcard, options={}) + def purchase(money, creditcard, options = {}) requires!(options, :order_id) options.update( - :ordertype => 'SALE' + ordertype: 'SALE' ) commit(money, creditcard, options) end @@ -200,7 +200,7 @@ def purchase(money, creditcard, options={}) def authorize(money, creditcard, options = {}) requires!(options, :order_id) options.update( - :ordertype => 'PREAUTH' + ordertype: 'PREAUTH' ) commit(money, creditcard, options) end @@ -213,8 +213,8 @@ def authorize(money, creditcard, options = {}) # def capture(money, authorization, options = {}) options.update( - :order_id => authorization, - :ordertype => 'POSTAUTH' + order_id: authorization, + ordertype: 'POSTAUTH' ) commit(money, nil, options) end @@ -222,8 +222,8 @@ def capture(money, authorization, options = {}) # Void a previous transaction def void(identification, options = {}) options.update( - :order_id => identification, - :ordertype => 'VOID' + order_id: identification, + ordertype: 'VOID' ) commit(nil, nil, options) end @@ -235,8 +235,8 @@ def void(identification, options = {}) # def refund(money, identification, options = {}) options.update( - :ordertype => 'CREDIT', - :order_id => identification + ordertype: 'CREDIT', + order_id: identification ) commit(money, nil, options) end @@ -264,11 +264,10 @@ def commit(money, creditcard, options = {}) response = parse(ssl_post(test? ? self.test_url : self.live_url, post_data(money, creditcard, options))) Response.new(successful?(response), response[:message], response, - :test => test?, - :authorization => response[:ordernum], - :avs_result => { :code => response[:avs].to_s[2, 1] }, - :cvv_result => response[:avs].to_s[3, 1] - ) + test: test?, + authorization: response[:ordernum], + avs_result: { code: response[:avs].to_s[2, 1] }, + cvv_result: response[:avs].to_s[3, 1]) end def successful?(response) @@ -311,11 +310,11 @@ def build_items(element, items) options_element = item_element.add_element('options') for option in value opt_element = options_element.add_element('option') - opt_element.add_element('name').text = option[:name] unless option[:name].blank? - opt_element.add_element('value').text = option[:value] unless option[:value].blank? + opt_element.add_element('name').text = option[:name] unless option[:name].blank? + opt_element.add_element('value').text = option[:value] unless option[:value].blank? end else - item_element.add_element(key.to_s).text = item[key].to_s unless item[key].blank? + item_element.add_element(key.to_s).text = item[key].to_s unless item[key].blank? end end end @@ -325,55 +324,55 @@ def build_items(element, items) # for every action. def parameters(money, creditcard, options = {}) params = { - :payment => { - :subtotal => amount(options[:subtotal]), - :tax => amount(options[:tax]), - :vattax => amount(options[:vattax]), - :shipping => amount(options[:shipping]), - :chargetotal => amount(money) + payment: { + subtotal: amount(options[:subtotal]), + tax: amount(options[:tax]), + vattax: amount(options[:vattax]), + shipping: amount(options[:shipping]), + chargetotal: amount(money) }, - :transactiondetails => { - :transactionorigin => options[:transactionorigin] || 'ECI', - :oid => options[:order_id], - :ponumber => options[:ponumber], - :taxexempt => options[:taxexempt], - :terminaltype => options[:terminaltype], - :ip => options[:ip], - :reference_number => options[:reference_number], - :recurring => options[:recurring] || 'NO', # DO NOT USE if you are using the periodic billing option. - :tdate => options[:tdate] + transactiondetails: { + transactionorigin: options[:transactionorigin] || 'ECI', + oid: options[:order_id], + ponumber: options[:ponumber], + taxexempt: options[:taxexempt], + terminaltype: options[:terminaltype], + ip: options[:ip], + reference_number: options[:reference_number], + recurring: options[:recurring] || 'NO', # DO NOT USE if you are using the periodic billing option. + tdate: options[:tdate] }, - :orderoptions => { - :ordertype => options[:ordertype], - :result => @options[:result] + orderoptions: { + ordertype: options[:ordertype], + result: @options[:result] }, - :periodic => { - :action => options[:action], - :installments => options[:installments], - :threshold => options[:threshold], - :startdate => options[:startdate], - :periodicity => options[:periodicity], - :comments => options[:comments] + periodic: { + action: options[:action], + installments: options[:installments], + threshold: options[:threshold], + startdate: options[:startdate], + periodicity: options[:periodicity], + comments: options[:comments] }, - :telecheck => { - :routing => options[:telecheck_routing], - :account => options[:telecheck_account], - :checknumber => options[:telecheck_checknumber], - :bankname => options[:telecheck_bankname], - :dl => options[:telecheck_dl], - :dlstate => options[:telecheck_dlstate], - :void => options[:telecheck_void], - :accounttype => options[:telecheck_accounttype], - :ssn => options[:telecheck_ssn], + telecheck: { + routing: options[:telecheck_routing], + account: options[:telecheck_account], + checknumber: options[:telecheck_checknumber], + bankname: options[:telecheck_bankname], + dl: options[:telecheck_dl], + dlstate: options[:telecheck_dlstate], + void: options[:telecheck_void], + accounttype: options[:telecheck_accounttype], + ssn: options[:telecheck_ssn] } } if creditcard params[:creditcard] = { - :cardnumber => creditcard.number, - :cardexpmonth => creditcard.month, - :cardexpyear => format_creditcard_expiry_year(creditcard.year), - :track => nil + cardnumber: creditcard.number, + cardexpmonth: creditcard.month, + cardexpyear: format_creditcard_expiry_year(creditcard.year), + track: nil } if creditcard.verification_value? @@ -395,8 +394,8 @@ def parameters(money, creditcard, options = {}) params[:billing][:zip] = billing_address[:zip] unless billing_address[:zip].blank? params[:billing][:country] = billing_address[:country] unless billing_address[:country].blank? params[:billing][:company] = billing_address[:company] unless billing_address[:company].blank? - params[:billing][:phone] = billing_address[:phone] unless billing_address[:phone].blank? - params[:billing][:email] = options[:email] unless options[:email].blank? + params[:billing][:phone] = billing_address[:phone] unless billing_address[:phone].blank? + params[:billing][:email] = options[:email] unless options[:email].blank? end if shipping_address = options[:shipping_address] @@ -431,7 +430,7 @@ def parse(xml) # APPROVED # - response = {:message => 'Global Error Receipt', :complete => false} + response = { message: 'Global Error Receipt', complete: false } xml = REXML::Document.new("#{xml}") xml.root&.elements&.each do |node| diff --git a/lib/active_merchant/billing/gateways/litle.rb b/lib/active_merchant/billing/gateways/litle.rb index 2a871d892d0..467d84e0e61 100644 --- a/lib/active_merchant/billing/gateways/litle.rb +++ b/lib/active_merchant/billing/gateways/litle.rb @@ -5,22 +5,25 @@ module Billing #:nodoc: class LitleGateway < Gateway SCHEMA_VERSION = '9.14' + class_attribute :postlive_url + self.test_url = 'https://www.testvantivcnp.com/sandbox/communicator/online' + self.postlive_url = 'https://payments.vantivpostlive.com/vap/communicator/online' self.live_url = 'https://payments.vantivcnp.com/vap/communicator/online' self.supported_countries = ['US'] self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb] + self.supported_cardtypes = %i[visa master american_express discover diners_club jcb] self.homepage_url = 'http://www.vantiv.com/' self.display_name = 'Vantiv eCommerce' - def initialize(options={}) + def initialize(options = {}) requires!(options, :login, :password, :merchant_id) super end - def purchase(money, payment_method, options={}) + def purchase(money, payment_method, options = {}) request = build_xml_request do |doc| add_authentication(doc) if check?(payment_method) @@ -36,7 +39,7 @@ def purchase(money, payment_method, options={}) check?(payment_method) ? commit(:echeckSales, request, money) : commit(:sale, request, money) end - def authorize(money, payment_method, options={}) + def authorize(money, payment_method, options = {}) request = build_xml_request do |doc| add_authentication(doc) if check?(payment_method) @@ -52,8 +55,8 @@ def authorize(money, payment_method, options={}) check?(payment_method) ? commit(:echeckVerification, request, money) : commit(:authorization, request, money) end - def capture(money, authorization, options={}) - transaction_id, _, _ = split_authorization(authorization) + def capture(money, authorization, options = {}) + transaction_id, = split_authorization(authorization) request = build_xml_request do |doc| add_authentication(doc) @@ -72,19 +75,19 @@ def credit(money, authorization, options = {}) refund(money, authorization, options) end - def refund(money, payment, options={}) + def refund(money, payment, options = {}) request = build_xml_request do |doc| add_authentication(doc) add_descriptor(doc, options) doc.send(refund_type(payment), transaction_attributes(options)) do if payment.is_a?(String) - transaction_id, _, _ = split_authorization(payment) + transaction_id, = split_authorization(payment) doc.litleTxnId(transaction_id) doc.amount(money) if money elsif check?(payment) add_echeck_purchase_params(doc, money, payment, options) else - add_auth_purchase_params(doc, money, payment, options) + add_credit_params(doc, money, payment, options) end end end @@ -99,7 +102,7 @@ def verify(creditcard, options = {}) end end - def void(authorization, options={}) + def void(authorization, options = {}) transaction_id, kind, money = split_authorization(authorization) request = build_xml_request do |doc| @@ -164,21 +167,21 @@ def scrub(transcript) } AVS_RESPONSE_CODE = { - '00' => 'Y', - '01' => 'X', - '02' => 'D', - '10' => 'Z', - '11' => 'W', - '12' => 'A', - '13' => 'A', - '14' => 'P', - '20' => 'N', - '30' => 'S', - '31' => 'R', - '32' => 'U', - '33' => 'R', - '34' => 'I', - '40' => 'E' + '00' => 'Y', + '01' => 'X', + '02' => 'D', + '10' => 'Z', + '11' => 'W', + '12' => 'A', + '13' => 'A', + '14' => 'P', + '20' => 'N', + '30' => 'S', + '31' => 'R', + '32' => 'U', + '33' => 'R', + '34' => 'I', + '40' => 'E' } def void_type(kind) @@ -192,8 +195,8 @@ def void_type(kind) end def refund_type(payment) - _, kind, _ = split_authorization(payment) - if check?(payment) || kind == 'echeckSales' + _, kind, = split_authorization(payment) + if check?(payment) || kind == 'echeckSales' :echeckCredit else :credit @@ -202,6 +205,7 @@ def refund_type(payment) def check?(payment_method) return false if payment_method.is_a?(String) + card_brand(payment_method) == 'check' end @@ -226,7 +230,18 @@ def add_auth_purchase_params(doc, money, payment_method, options) add_stored_credential_params(doc, options) end - def add_merchant_data(doc, options={}) + def add_credit_params(doc, money, payment_method, options) + doc.orderId(truncate(options[:order_id], 24)) + doc.amount(money) + add_order_source(doc, payment_method, options) + add_billing_address(doc, payment_method, options) + add_payment_method(doc, payment_method, options) + add_pos(doc, payment_method) + add_descriptor(doc, options) + add_merchant_data(doc, options) + end + + def add_merchant_data(doc, options = {}) if options[:affiliate] || options[:campaign] || options[:merchant_grouping_id] doc.merchantData do doc.affiliate(options[:affiliate]) if options[:affiliate] @@ -262,6 +277,7 @@ def add_payment_method(doc, payment_method, options) if payment_method.is_a?(String) doc.token do doc.litleToken(payment_method) + doc.expDate(format_exp_date(options[:basis_expiration_month], options[:basis_expiration_year])) if options[:basis_expiration_month] && options[:basis_expiration_year] end elsif payment_method.respond_to?(:track_data) && payment_method.track_data.present? doc.card do @@ -272,7 +288,7 @@ def add_payment_method(doc, payment_method, options) doc.accType(payment_method.account_type.capitalize) doc.accNum(payment_method.account_number) doc.routingNum(payment_method.routing_number) - doc.checkNum(payment_method.number) + doc.checkNum(payment_method.number) if payment_method.number end else doc.card do @@ -294,7 +310,7 @@ def add_payment_method(doc, payment_method, options) end end - def add_stored_credential_params(doc, options={}) + def add_stored_credential_params(doc, options = {}) return unless options[:stored_credential] if options[:stored_credential][:initial_transaction] @@ -355,9 +371,9 @@ def add_address(doc, address) return unless address doc.companyName(address[:company]) unless address[:company].blank? - doc.addressLine1(address[:address1]) unless address[:address1].blank? - doc.addressLine2(address[:address2]) unless address[:address2].blank? - doc.city(address[:city]) unless address[:city].blank? + doc.addressLine1(truncate(address[:address1], 35)) unless address[:address1].blank? + doc.addressLine2(truncate(address[:address2], 35)) unless address[:address2].blank? + doc.city(truncate(address[:city], 35)) unless address[:city].blank? doc.state(address[:state]) unless address[:state].blank? doc.zip(address[:zip]) unless address[:zip].blank? doc.country(address[:country]) unless address[:country].blank? @@ -379,8 +395,9 @@ def add_order_source(doc, payment_method, options) end end - def order_source(options={}) + def order_source(options = {}) return options[:order_source] unless options[:stored_credential] + order_source = nil case options[:stored_credential][:reason_type] @@ -414,7 +431,11 @@ def add_pos(doc, payment_method) end def exp_date(payment_method) - "#{format(payment_method.month, :two_digits)}#{format(payment_method.year, :two_digits)}" + format_exp_date(payment_method.month, payment_method.year) + end + + def format_exp_date(month, year) + "#{format(month, :two_digits)}#{format(year, :two_digits)}" end def parse(kind, xml) @@ -441,14 +462,14 @@ def parse(kind, xml) parsed end - def commit(kind, request, money=nil) + def commit(kind, request, money = nil) parsed = parse(kind, ssl_post(url, request, headers)) options = { authorization: authorization_from(kind, parsed, money), test: test?, - :avs_result => { :code => AVS_RESPONSE_CODE[parsed[:fraudResult_avsResult]] }, - :cvv_result => parsed[:fraudResult_cardValidationResult] + avs_result: { code: AVS_RESPONSE_CODE[parsed[:fraudResult_avsResult]] }, + cvv_result: parsed[:fraudResult_cardValidationResult] } Response.new(success_from(kind, parsed), parsed[:message], parsed, options) @@ -456,6 +477,7 @@ def commit(kind, request, money=nil) def success_from(kind, parsed) return (parsed[:response] == '000') unless kind == :registerToken + %w(000 801 802).include?(parsed[:response]) end @@ -472,8 +494,8 @@ def transaction_attributes(options) attributes = {} attributes[:id] = truncate(options[:id] || options[:order_id], 24) attributes[:reportGroup] = options[:merchant] || 'Default Report Group' - attributes[:customerId] = options[:customer] - attributes.delete_if { |key, value| value == nil } + attributes[:customerId] = options[:customer_id] + attributes.delete_if { |_key, value| value == nil } attributes end @@ -494,6 +516,8 @@ def build_xml_request end def url + return postlive_url if @options[:url_override].to_s == 'postlive' + test? ? test_url : live_url end diff --git a/lib/active_merchant/billing/gateways/mastercard.rb b/lib/active_merchant/billing/gateways/mastercard.rb index e2f31193ea9..be18bda516f 100644 --- a/lib/active_merchant/billing/gateways/mastercard.rb +++ b/lib/active_merchant/billing/gateways/mastercard.rb @@ -1,12 +1,12 @@ module ActiveMerchant module Billing module MastercardGateway - def initialize(options={}) + def initialize(options = {}) requires!(options, :userid, :password) super end - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) if options[:pay_mode] post = new_post add_invoice(post, amount, options) @@ -24,7 +24,7 @@ def purchase(amount, payment_method, options={}) end end - def authorize(amount, payment_method, options={}) + def authorize(amount, payment_method, options = {}) post = new_post add_invoice(post, amount, options) add_reference(post, *new_authorization) @@ -35,7 +35,7 @@ def authorize(amount, payment_method, options={}) commit('authorize', post) end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) post = new_post add_invoice(post, amount, options, :transaction) add_reference(post, *next_authorization(authorization)) @@ -45,7 +45,7 @@ def capture(amount, authorization, options={}) commit('capture', post) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) post = new_post add_invoice(post, amount, options, :transaction) add_reference(post, *next_authorization(authorization)) @@ -54,14 +54,14 @@ def refund(amount, authorization, options={}) commit('refund', post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = new_post add_reference(post, *next_authorization(authorization), :targetTransactionId) commit('void', post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -105,16 +105,16 @@ def new_post billing: {}, device: {}, shipping: {}, - transaction: {}, + transaction: {} } end - def add_invoice(post, amount, options, node=:order) + def add_invoice(post, amount, options, node = :order) post[node][:amount] = amount(amount) post[node][:currency] = (options[:currency] || currency(amount)) end - def add_reference(post, orderid, transactionid, transaction_reference, reference_key=:reference) + def add_reference(post, orderid, transactionid, transaction_reference, reference_key = :reference) post[:orderid] = orderid post[:transactionid] = transactionid post[:transaction][reference_key] = transaction_reference if transaction_reference @@ -175,7 +175,8 @@ def add_customer_data(post, payment_method, options) def add_3dsecure_id(post, options) return unless options[:threed_secure_id] - post.merge!({'3DSecureId' => options[:threed_secure_id]}) + + post.merge!({ '3DSecureId' => options[:threed_secure_id] }) end def country_code(country) @@ -189,7 +190,7 @@ def country_code(country) def headers { 'Authorization' => 'Basic ' + Base64.encode64("merchant.#{@options[:userid]}:#{@options[:password]}").strip.delete("\r\n"), - 'Content-Type' => 'application/json', + 'Content-Type' => 'application/json' } end @@ -206,8 +207,8 @@ def commit(action, post) succeeded, message_from(succeeded, raw), raw, - :authorization => authorization_from(post, raw), - :test => test? + authorization: authorization_from(post, raw), + test: test? ) end diff --git a/lib/active_merchant/billing/gateways/maxipago.rb b/lib/active_merchant/billing/gateways/maxipago.rb index b4ca346327b..c22ceaeaf01 100644 --- a/lib/active_merchant/billing/gateways/maxipago.rb +++ b/lib/active_merchant/billing/gateways/maxipago.rb @@ -11,7 +11,7 @@ class MaxipagoGateway < Gateway self.supported_countries = ['BR'] self.default_currency = 'BRL' self.money_format = :dollars - self.supported_cardtypes = [:visa, :master, :discover, :american_express, :diners_club] + self.supported_cardtypes = %i[visa master discover american_express diners_club] self.homepage_url = 'http://www.maxipago.com/' self.display_name = 'maxiPago!' @@ -212,7 +212,7 @@ def add_billing_address(xml, creditcard, options) end def add_order_id(xml, authorization) - order_id, _ = split_authorization(authorization) + order_id, = split_authorization(authorization) xml.orderID order_id end end diff --git a/lib/active_merchant/billing/gateways/mercado_pago.rb b/lib/active_merchant/billing/gateways/mercado_pago.rb index 98cc40bb374..ca687732449 100644 --- a/lib/active_merchant/billing/gateways/mercado_pago.rb +++ b/lib/active_merchant/billing/gateways/mercado_pago.rb @@ -3,19 +3,19 @@ module Billing #:nodoc: class MercadoPagoGateway < Gateway self.live_url = self.test_url = 'https://api.mercadopago.com/v1' - self.supported_countries = ['AR', 'BR', 'CL', 'CO', 'MX', 'PE', 'UY'] - self.supported_cardtypes = [:visa, :master, :american_express, :elo, :cabal, :naranja] + self.supported_countries = %w[AR BR CL CO MX PE UY] + self.supported_cardtypes = %i[visa master american_express elo cabal naranja creditel] self.homepage_url = 'https://www.mercadopago.com/' self.display_name = 'Mercado Pago' self.money_format = :dollars - def initialize(options={}) + def initialize(options = {}) requires!(options, :access_token) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) MultiResponse.run do |r| r.process { commit('tokenize', 'card_tokens', card_token_request(money, payment, options)) } options[:card_token] = r.authorization.split('|').first @@ -23,7 +23,7 @@ def purchase(money, payment, options={}) end end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) MultiResponse.run do |r| r.process { commit('tokenize', 'card_tokens', card_token_request(money, payment, options)) } options[:card_token] = r.authorization.split('|').first @@ -31,28 +31,28 @@ def authorize(money, payment, options={}) end end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) post = {} - authorization, _ = authorization.split('|') + authorization, = authorization.split('|') post[:capture] = true post[:transaction_amount] = amount(money).to_f commit('capture', "payments/#{authorization}", post) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) post = {} authorization, original_amount = authorization.split('|') post[:amount] = amount(money).to_f if original_amount && original_amount.to_f > amount(money).to_f commit('refund', "payments/#{authorization}/refunds", post) end - def void(authorization, options={}) - authorization, _ = authorization.split('|') + def void(authorization, options = {}) + authorization, = authorization.split('|') post = { status: 'cancelled' } commit('void', "payments/#{authorization}", post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -96,25 +96,31 @@ def purchase_request(money, payment, options = {}) add_customer_data(post, payment, options) add_address(post, options) add_processing_mode(post, options) + add_net_amount(post, options) + add_taxes(post, options) + add_notification_url(post, options) post[:binary_mode] = (options[:binary_mode].nil? ? true : options[:binary_mode]) post end def authorize_request(money, payment, options = {}) post = purchase_request(money, payment, options) - post[:capture] = false + post[:capture] = options[:capture] || false post end def add_processing_mode(post, options) return unless options[:processing_mode] + post[:processing_mode] = options[:processing_mode] post[:merchant_account_id] = options[:merchant_account_id] if options[:merchant_account_id] + post[:payment_method_option_id] = options[:payment_method_option_id] if options[:payment_method_option_id] add_merchant_services(post, options) end def add_merchant_services(post, options) return unless options[:fraud_scoring] || options[:fraud_manual_review] + merchant_services = {} merchant_services[:fraud_scoring] = options[:fraud_scoring] if options[:fraud_scoring] merchant_services[:fraud_manual_review] = options[:fraud_manual_review] if options[:fraud_manual_review] @@ -194,6 +200,51 @@ def add_payment(post, options) post[:payment_method_id] = options[:payment_method_id] if options[:payment_method_id] end + def add_net_amount(post, options) + post[:net_amount] = Float(options[:net_amount]) if options[:net_amount] + end + + def add_notification_url(post, options) + post[:notification_url] = options[:notification_url] if options[:notification_url] + end + + def add_taxes(post, options) + return unless (tax_object = options[:taxes]) + + if tax_object.is_a?(Array) + post[:taxes] = process_taxes_array(tax_object) + elsif tax_object.is_a?(Hash) + post[:taxes] = process_taxes_hash(tax_object) + else + raise taxes_error + end + end + + def process_taxes_hash(tax_object) + [sanitize_taxes_hash(tax_object)] + end + + def process_taxes_array(taxes_array) + taxes_array.map do |tax_object| + raise taxes_error unless tax_object.is_a?(Hash) + + sanitize_taxes_hash(tax_object) + end + end + + def sanitize_taxes_hash(tax_object) + tax_value = tax_object['value'] || tax_object[:value] + tax_type = tax_object['type'] || tax_object[:type] + + raise taxes_error if tax_value.nil? || tax_type.nil? + + { value: Float(tax_value), type: tax_type } + end + + def taxes_error + ArgumentError.new("Taxes should be a single object or array of objects with the shape: { value: 500, type: 'IVA' }") + end + def parse(body) JSON.parse(body) rescue JSON::ParserError @@ -205,7 +256,7 @@ def parse(body) end def commit(action, path, parameters) - if ['capture', 'void'].include?(action) + if %w[capture void].include?(action) response = parse(ssl_request(:put, url(path), post_data(parameters), headers)) else response = parse(ssl_post(url(path), post_data(parameters), headers(parameters))) @@ -225,7 +276,7 @@ def success_from(action, response) if action == 'refund' response['status'] != 404 && response['error'].nil? else - ['active', 'approved', 'authorized', 'cancelled', 'in_process'].include?(response['status']) + %w[active approved authorized cancelled in_process].include?(response['status']) end end @@ -260,7 +311,7 @@ def headers(options = {}) headers = { 'Content-Type' => 'application/json' } - headers['X-Device-Session-ID'] = options[:device_id] if options[:device_id] + headers['X-meli-session-id'] = options[:device_id] if options[:device_id] headers end diff --git a/lib/active_merchant/billing/gateways/merchant_e_solutions.rb b/lib/active_merchant/billing/gateways/merchant_e_solutions.rb index bad8070e2d1..d268e590187 100644 --- a/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +++ b/lib/active_merchant/billing/gateways/merchant_e_solutions.rb @@ -10,7 +10,7 @@ class MerchantESolutionsGateway < Gateway self.supported_countries = ['US'] # The card types supported by the payment gateway - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb] + self.supported_cardtypes = %i[visa master american_express discover jcb] # The homepage URL of the gateway self.homepage_url = 'http://www.merchante-solutions.com/' @@ -46,7 +46,7 @@ def purchase(money, creditcard_or_card_id, options = {}) end def capture(money, transaction_id, options = {}) - post ={} + post = {} post[:transaction_id] = transaction_id post[:client_reference_number] = options[:customer] if options.has_key?(:customer) add_invoice(post, options) @@ -133,9 +133,9 @@ def add_payment_source(post, creditcard_or_card_id, options) end def add_creditcard(post, creditcard, options) - post[:card_number] = creditcard.number + post[:card_number] = creditcard.number post[:cvv2] = creditcard.verification_value if creditcard.verification_value? - post[:card_exp_date] = expdate(creditcard) + post[:card_exp_date] = expdate(creditcard) end def add_3dsecure_params(post, options) @@ -156,20 +156,20 @@ def parse(body) def commit(action, money, parameters) url = test? ? self.test_url : self.live_url - parameters[:transaction_amount] = amount(money) if money unless action == 'V' + parameters[:transaction_amount] = amount(money) if money unless action == 'V' - response = begin - parse(ssl_post(url, post_data(action, parameters))) - rescue ActiveMerchant::ResponseError => e - { 'error_code' => '404', 'auth_response_text' => e.to_s } - end + response = + begin + parse(ssl_post(url, post_data(action, parameters))) + rescue ActiveMerchant::ResponseError => e + { 'error_code' => '404', 'auth_response_text' => e.to_s } + end Response.new(response['error_code'] == '000', message_from(response), response, - :authorization => response['transaction_id'], - :test => test?, - :cvv_result => response['cvv2_result'], - :avs_result => { :code => response['avs_result'] } - ) + authorization: response['transaction_id'], + test: test?, + cvv_result: response['cvv2_result'], + avs_result: { code: response['avs_result'] }) end def message_from(response) diff --git a/lib/active_merchant/billing/gateways/merchant_one.rb b/lib/active_merchant/billing/gateways/merchant_one.rb index 20f60dd0cd2..373b9243f8b 100644 --- a/lib/active_merchant/billing/gateways/merchant_one.rb +++ b/lib/active_merchant/billing/gateways/merchant_one.rb @@ -3,7 +3,6 @@ module ActiveMerchant #:nodoc: module Billing #:nodoc: class MerchantOneGateway < Gateway - class MerchantOneSslConnection < ActiveMerchant::Connection def configure_ssl(http) super(http) @@ -14,7 +13,7 @@ def configure_ssl(http) BASE_URL = 'https://secure.merchantonegateway.com/api/transact.php' self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://merchantone.com/' self.display_name = 'Merchant One Gateway' self.money_format = :dollars @@ -77,10 +76,10 @@ def add_address(post, creditcard, options) def add_creditcard(post, creditcard) post['cvv'] = creditcard.verification_value post['ccnumber'] = creditcard.number - post['ccexp'] = "#{sprintf("%02d", creditcard.month)}#{creditcard.year.to_s[-2, 2]}" + post['ccexp'] = "#{sprintf('%02d', creditcard.month)}#{creditcard.year.to_s[-2, 2]}" end - def commit(action, money, parameters={}) + def commit(action, money, parameters = {}) parameters['username'] = @options[:username] parameters['password'] = @options[:password] parse(ssl_post(BASE_URL, post_data(action, parameters))) @@ -91,21 +90,19 @@ def post_data(action, parameters = {}) ret = '' for key in parameters.keys ret += "#{key}=#{CGI.escape(parameters[key].to_s)}" - if key != parameters.keys.last - ret += '&' - end + ret += '&' if key != parameters.keys.last end ret.to_s end def parse(data) - responses = CGI.parse(data).inject({}) { |h, (k, v)| h[k] = v.first; h } + responses = CGI.parse(data).inject({}) { |h, (k, v)| h[k] = v.first; h } Response.new( (responses['response'].to_i == 1), responses['responsetext'], responses, - :test => test?, - :authorization => responses['transactionid'] + test: test?, + authorization: responses['transactionid'] ) end end diff --git a/lib/active_merchant/billing/gateways/merchant_partners.rb b/lib/active_merchant/billing/gateways/merchant_partners.rb index e4630211a5d..e32dff8b9b2 100644 --- a/lib/active_merchant/billing/gateways/merchant_partners.rb +++ b/lib/active_merchant/billing/gateways/merchant_partners.rb @@ -11,14 +11,14 @@ class MerchantPartnersGateway < Gateway self.supported_countries = ['US'] self.default_currency = 'USD' self.money_format = :dollars - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb] + self.supported_cardtypes = %i[visa master american_express discover diners_club jcb] - def initialize(options={}) + def initialize(options = {}) requires!(options, :account_id, :merchant_pin) super end - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method) @@ -27,7 +27,7 @@ def purchase(amount, payment_method, options={}) commit(payment_method.is_a?(String) ? :stored_purchase : :purchase, post) end - def authorize(amount, payment_method, options={}) + def authorize(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method) @@ -36,7 +36,7 @@ def authorize(amount, payment_method, options={}) commit(:authorize, post) end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) post = {} add_invoice(post, amount, options) add_reference(post, authorization) @@ -45,14 +45,14 @@ def capture(amount, authorization, options={}) commit(:capture, post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} add_reference(post, authorization) commit(:void, post) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) post = {} add_invoice(post, amount, options) add_reference(post, authorization) @@ -61,7 +61,7 @@ def refund(amount, authorization, options={}) commit(:refund, post) end - def credit(amount, payment_method, options={}) + def credit(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method) @@ -69,7 +69,7 @@ def credit(amount, payment_method, options={}) commit(payment_method.is_a?(String) ? :stored_credit : :credit, post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -110,10 +110,10 @@ def add_invoice(post, money, options) end def add_payment_method(post, payment_method) - if(payment_method.is_a?(String)) - user_profile_id, last_4 = split_authorization(payment_method) + if payment_method.is_a?(String) + user_profile_id, last4 = split_authorization(payment_method) post[:userprofileid] = user_profile_id - post[:last4digits] = last_4 + post[:last4digits] = last4 else post[:ccname] = payment_method.name post[:ccnum] = payment_method.number @@ -127,13 +127,13 @@ def add_payment_method(post, payment_method) def add_customer_data(post, options) post[:email] = options[:email] if options[:email] post[:ipaddress] = options[:ip] if options[:ip] - if(billing_address = options[:billing_address]) + if (billing_address = options[:billing_address]) post[:billaddr1] = billing_address[:address1] post[:billaddr2] = billing_address[:address2] post[:billcity] = billing_address[:city] post[:billstate] = billing_address[:state] post[:billcountry] = billing_address[:country] - post[:bilzip] = billing_address[:zip] + post[:bilzip] = billing_address[:zip] post[:phone] = billing_address[:phone] end end @@ -172,20 +172,20 @@ def commit(action, post) message_from(succeeded, response_data), response_data, authorization: authorization_from(post, response_data), - :avs_result => AVSResult.new(code: response_data['avs_response']), - :cvv_result => CVVResult.new(response_data['cvv2_response']), + avs_result: AVSResult.new(code: response_data['avs_response']), + cvv_result: CVVResult.new(response_data['cvv2_response']), test: test? ) end def headers { - 'Content-Type' => 'application/xml' + 'Content-Type' => 'application/xml' } end def build_request(post) - Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml| + Nokogiri::XML::Builder.new(encoding: 'utf-8') do |xml| xml.interface_driver { xml.trans_catalog { xml.transaction(name: 'creditcard') { @@ -235,7 +235,7 @@ def split_authorization(authorization) end def error_message_from(response) - if(response[:status] == 'Declined') + if response[:status] == 'Declined' match = response[:result].match(/DECLINED:\d{10}:(.+):/) match[1] if match end diff --git a/lib/active_merchant/billing/gateways/merchant_ware.rb b/lib/active_merchant/billing/gateways/merchant_ware.rb index d028024ccb0..1781a301968 100644 --- a/lib/active_merchant/billing/gateways/merchant_ware.rb +++ b/lib/active_merchant/billing/gateways/merchant_ware.rb @@ -7,29 +7,27 @@ class MerchantWareGateway < Gateway self.v4_live_url = 'https://ps1.merchantware.net/Merchantware/ws/RetailTransaction/v4/Credit.asmx' self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://merchantwarehouse.com/merchantware' self.display_name = 'MerchantWARE' ENV_NAMESPACES = { 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema', - 'xmlns:env' => 'http://schemas.xmlsoap.org/soap/envelope/' - } + 'xmlns:env' => 'http://schemas.xmlsoap.org/soap/envelope/' } ENV_NAMESPACES_V4 = { 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema', - 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/' - } + 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/' } TX_NAMESPACE = 'http://merchantwarehouse.com/MerchantWARE/Client/TransactionRetail' TX_NAMESPACE_V4 = 'http://schemas.merchantwarehouse.com/merchantware/40/Credit/' ACTIONS = { - :purchase => 'IssueKeyedSale', - :authorize => 'IssueKeyedPreAuth', - :capture => 'IssuePostAuth', - :void => 'VoidPreAuthorization', - :credit => 'IssueKeyedRefund', - :reference_credit => 'IssueRefundByReference' + purchase: 'IssueKeyedSale', + authorize: 'IssueKeyedPreAuth', + capture: 'IssuePostAuth', + void: 'VoidPreAuthorization', + credit: 'IssueKeyedRefund', + reference_credit: 'IssueRefundByReference' } # Creates a new MerchantWareGateway @@ -119,7 +117,7 @@ def refund(money, reference, options = {}) private def soap_request(action) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.instruct! xml.tag! 'env:Envelope', ENV_NAMESPACES do xml.tag! 'env:Body' do @@ -133,7 +131,7 @@ def soap_request(action) end def v4_soap_request(action) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.instruct! xml.tag! 'soap:Envelope', ENV_NAMESPACES_V4 do xml.tag! 'soap:Body' do @@ -274,7 +272,7 @@ def parse_error(http_response) response[element.name] = element.text end - response[:message] = response['faultstring'].to_s.gsub("\n", ' ') + response[:message] = response['faultstring'].to_s.tr("\n", ' ') response rescue REXML::ParseException response[:http_body] = http_response.body @@ -294,25 +292,21 @@ def commit(action, request, v4 = false) begin data = ssl_post(url(v4), request, 'Content-Type' => 'text/xml; charset=utf-8', - 'SOAPAction' => soap_action(action, v4) - ) + 'SOAPAction' => soap_action(action, v4)) response = parse(action, data) rescue ActiveMerchant::ResponseError => e response = parse_error(e.response) end Response.new(response[:success], response[:message], response, - :test => test?, - :authorization => authorization_from(response), - :avs_result => { :code => response['AVSResponse'] }, - :cvv_result => response['CVResponse'] - ) + test: test?, + authorization: authorization_from(response), + avs_result: { code: response['AVSResponse'] }, + cvv_result: response['CVResponse']) end def authorization_from(response) - if response[:success] - [ response['ReferenceID'], response['OrderNumber'] ].join(';') - end + [response['ReferenceID'], response['OrderNumber']].join(';') if response[:success] end end end diff --git a/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb b/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb index 4b1667334a4..36635dd0f2a 100644 --- a/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +++ b/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb @@ -5,7 +5,7 @@ class MerchantWareVersionFourGateway < Gateway self.test_url = 'https://ps1.merchantware.net/Merchantware/ws/RetailTransaction/v4/Credit.asmx' self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://merchantwarehouse.com/merchantware' self.display_name = 'MerchantWARE' @@ -16,12 +16,12 @@ class MerchantWareVersionFourGateway < Gateway TX_NAMESPACE = 'http://schemas.merchantwarehouse.com/merchantware/40/Credit/' ACTIONS = { - :purchase => 'SaleKeyed', - :reference_purchase => 'RepeatSale', - :authorize => 'PreAuthorizationKeyed', - :capture => 'PostAuthorization', - :void => 'Void', - :refund => 'Refund' + purchase: 'SaleKeyed', + reference_purchase: 'RepeatSale', + authorize: 'PreAuthorizationKeyed', + capture: 'PostAuthorization', + void: 'Void', + refund: 'Refund' } # Creates a new MerchantWareVersionFourGateway @@ -108,7 +108,7 @@ def refund(money, identification, options = {}) commit(:refund, request) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -129,7 +129,7 @@ def scrub(transcript) private def soap_request(action) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.instruct! xml.tag! 'soap:Envelope', ENV_NAMESPACES do xml.tag! 'soap:Body' do @@ -243,7 +243,7 @@ def parse_error(http_response, action) response[element.name] = element.text end - response[:message] = response['ErrorMessage'].to_s.gsub("\n", ' ') + response[:message] = response['ErrorMessage'].to_s.tr("\n", ' ') response rescue REXML::ParseException response[:http_body] = http_response.body @@ -263,19 +263,17 @@ def commit(action, request) begin data = ssl_post(url, request, 'Content-Type' => 'text/xml; charset=utf-8', - 'SOAPAction' => soap_action(action) - ) + 'SOAPAction' => soap_action(action)) response = parse(action, data) rescue ActiveMerchant::ResponseError => e response = parse_error(e.response, action) end Response.new(response[:success], response[:message], response, - :test => test?, - :authorization => authorization_from(response), - :avs_result => { :code => response['AvsResponse'] }, - :cvv_result => response['CvResponse'] - ) + test: test?, + authorization: authorization_from(response), + avs_result: { code: response['AvsResponse'] }, + cvv_result: response['CvResponse']) end def authorization_from(response) diff --git a/lib/active_merchant/billing/gateways/merchant_warrior.rb b/lib/active_merchant/billing/gateways/merchant_warrior.rb index 8e92e21811e..1fc4d2ff5e4 100644 --- a/lib/active_merchant/billing/gateways/merchant_warrior.rb +++ b/lib/active_merchant/billing/gateways/merchant_warrior.rb @@ -11,8 +11,8 @@ class MerchantWarriorGateway < Gateway POST_LIVE_URL = 'https://api.merchantwarrior.com/post/' self.supported_countries = ['AU'] - self.supported_cardtypes = [:visa, :master, :american_express, - :diners_club, :discover, :jcb] + self.supported_cardtypes = %i[visa master american_express + diners_club discover jcb] self.homepage_url = 'https://www.merchantwarrior.com/' self.display_name = 'Merchant Warrior' @@ -30,6 +30,8 @@ def authorize(money, payment_method, options = {}) add_order_id(post, options) add_address(post, options) add_payment_method(post, payment_method) + add_recurring_flag(post, options) + add_soft_descriptors(post, options) commit('processAuth', post) end @@ -39,6 +41,8 @@ def purchase(money, payment_method, options = {}) add_order_id(post, options) add_address(post, options) add_payment_method(post, payment_method) + add_recurring_flag(post, options) + add_soft_descriptors(post, options) commit('processCard', post) end @@ -46,6 +50,7 @@ def capture(money, identification, options = {}) post = {} add_amount(post, money, options) add_transaction(post, identification) + add_soft_descriptors(post, options) post['captureAmount'] = amount(money) commit('processCapture', post) end @@ -54,10 +59,21 @@ def refund(money, identification, options = {}) post = {} add_amount(post, money, options) add_transaction(post, identification) + add_soft_descriptors(post, options) post['refundAmount'] = amount(money) commit('refundCard', post) end + def void(identification, options = {}) + post = {} + # The amount parameter is required for void transactions + # on the Merchant Warrior gateway. + post['transactionAmount'] = options[:amount] + post['hash'] = void_verification_hash(identification) + add_transaction(post, identification) + commit('processVoid', post) + end + def store(creditcard, options = {}) post = { 'cardName' => scrub_name(creditcard.name), @@ -87,7 +103,7 @@ def add_transaction(post, identification) end def add_address(post, options) - return unless(address = (options[:billing_address] || options[:address])) + return unless (address = (options[:billing_address] || options[:address])) post['customerName'] = scrub_name(address[:name]) post['customerCountry'] = address[:country] @@ -135,6 +151,18 @@ def add_amount(post, money, options) post['hash'] = verification_hash(amount(money), currency) end + def add_recurring_flag(post, options) + return if options[:recurring_flag].nil? + + post['recurringFlag'] = options[:recurring_flag] + end + + def add_soft_descriptors(post, options) + post['descriptorName'] = options[:descriptor_name] if options[:descriptor_name] + post['descriptorCity'] = options[:descriptor_city] if options[:descriptor_city] + post['descriptorState'] = options[:descriptor_state] if options[:descriptor_state] + end + def verification_hash(money, currency) Digest::MD5.hexdigest( ( @@ -146,6 +174,16 @@ def verification_hash(money, currency) ) end + def void_verification_hash(transaction_id) + Digest::MD5.hexdigest( + ( + @options[:api_passphrase].to_s + + @options[:merchant_uuid].to_s + + transaction_id + ).downcase + ) + end + def parse(body) xml = REXML::Document.new(body) @@ -173,17 +211,15 @@ def commit(action, post) success?(response), response[:response_message], response, - :test => test?, - :authorization => (response[:card_id] || response[:transaction_id]) + test: test?, + authorization: (response[:card_id] || response[:transaction_id]) ) end def add_auth(action, post) post['merchantUUID'] = @options[:merchant_uuid] post['apiKey'] = @options[:api_key] - unless token?(post) - post['method'] = action - end + post['method'] = action unless token?(post) end def url_for(action, post) diff --git a/lib/active_merchant/billing/gateways/mercury.rb b/lib/active_merchant/billing/gateways/mercury.rb index 6fea6dd9197..fcbca035e0c 100644 --- a/lib/active_merchant/billing/gateways/mercury.rb +++ b/lib/active_merchant/billing/gateways/mercury.rb @@ -12,14 +12,14 @@ module Billing #:nodoc: # and +refund+ will become mandatory. class MercuryGateway < Gateway URLS = { - :test => 'https://w1.mercurycert.net/ws/ws.asmx', - :live => 'https://w1.mercurypay.com/ws/ws.asmx' + test: 'https://w1.mercurycert.net/ws/ws.asmx', + live: 'https://w1.mercurypay.com/ws/ws.asmx' } self.homepage_url = 'http://www.mercurypay.com' self.display_name = 'Mercury' - self.supported_countries = ['US', 'CA'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb] + self.supported_countries = %w[US CA] + self.supported_cardtypes = %i[visa master american_express discover diners_club jcb] self.default_currency = 'USD' STANDARD_ERROR_CODE_MAPPING = { @@ -51,14 +51,14 @@ def credit(money, credit_card, options = {}) def authorize(money, credit_card, options = {}) requires!(options, :order_id) - request = build_non_authorized_request('PreAuth', money, credit_card, options.merge(:authorized => money)) + request = build_non_authorized_request('PreAuth', money, credit_card, options.merge(authorized: money)) commit('PreAuth', request) end def capture(money, authorization, options = {}) requires!(options, :credit_card) unless @use_tokenization - request = build_authorized_request('PreAuthCapture', money, authorization, options[:credit_card], options.merge(:authorized => money)) + request = build_authorized_request('PreAuthCapture', money, authorization, options[:credit_card], options.merge(authorized: money)) commit('PreAuthCapture', request) end @@ -69,14 +69,14 @@ def refund(money, authorization, options = {}) commit('Return', request) end - def void(authorization, options={}) + def void(authorization, options = {}) requires!(options, :credit_card) unless @use_tokenization request = build_authorized_request('VoidSale', nil, authorization, options[:credit_card], options) commit('VoidSale', request) end - def store(credit_card, options={}) + def store(credit_card, options = {}) request = build_card_lookup_request(credit_card, options) commit('CardLookup', request) end @@ -103,9 +103,7 @@ def build_non_authorized_request(action, money, credit_card, options) xml.tag! 'Transaction' do xml.tag! 'TranType', 'Credit' xml.tag! 'TranCode', action - if options[:allow_partial_auth] && ['PreAuth', 'Sale'].include?(action) - xml.tag! 'PartialAuth', 'Allow' - end + xml.tag! 'PartialAuth', 'Allow' if options[:allow_partial_auth] && %w[PreAuth Sale].include?(action) add_invoice(xml, options[:order_id], nil, options) add_reference(xml, 'RecordNumberRequested') add_customer_data(xml, options) @@ -126,9 +124,7 @@ def build_authorized_request(action, money, authorization, credit_card, options) xml.tag! 'TStream' do xml.tag! 'Transaction' do xml.tag! 'TranType', 'Credit' - if options[:allow_partial_auth] && (action == 'PreAuthCapture') - xml.tag! 'PartialAuth', 'Allow' - end + xml.tag! 'PartialAuth', 'Allow' if options[:allow_partial_auth] && (action == 'PreAuthCapture') xml.tag! 'TranCode', (@use_tokenization ? (action + 'ByRecordNo') : action) add_invoice(xml, invoice_no, ref_no, options) add_reference(xml, record_no) @@ -215,11 +211,11 @@ def add_credit_card(xml, credit_card, action) # handle with the validation error as it sees fit. # Track 2 requires having the STX and ETX stripped. Track 1 does not. # Max-length track 1s require having the STX and ETX stripped. Max is 79 bytes including LRC. - is_track_2 = credit_card.track_data[0] == ';' + is_track2 = credit_card.track_data[0] == ';' etx_index = credit_card.track_data.rindex('?') || credit_card.track_data.length is_max_track1 = etx_index >= 77 - if is_track_2 + if is_track2 xml.tag! 'Track2', credit_card.track_data[1...etx_index] elsif is_max_track1 xml.tag! 'Track1', credit_card.track_data[1...etx_index] @@ -234,7 +230,7 @@ def add_credit_card(xml, credit_card, action) xml.tag! 'CardType', CARD_CODES[credit_card.brand] if credit_card.brand include_cvv = !%w(Return PreAuthCapture).include?(action) && !credit_card.track_data.present? - xml.tag! 'CVVData', credit_card.verification_value if(include_cvv && credit_card.verification_value) + xml.tag! 'CVVData', credit_card.verification_value if include_cvv && credit_card.verification_value end def add_address(xml, options) @@ -298,7 +294,7 @@ def build_header } end - SUCCESS_CODES = [ 'Approved', 'Success' ] + SUCCESS_CODES = %w[Approved Success] def commit(action, request) response = parse(action, ssl_post(endpoint_url, build_soap_request(request), build_header)) @@ -307,11 +303,11 @@ def commit(action, request) message = success ? 'Success' : message_from(response) Response.new(success, message, response, - :test => test?, - :authorization => authorization_from(response), - :avs_result => { :code => response[:avs_result] }, - :cvv_result => response[:cvv_result], - :error_code => success ? nil : STANDARD_ERROR_CODE_MAPPING[response[:dsix_return_code]]) + test: test?, + authorization: authorization_from(response), + avs_result: { code: response[:avs_result] }, + cvv_result: response[:cvv_result], + error_code: success ? nil : STANDARD_ERROR_CODE_MAPPING[response[:dsix_return_code]]) end def message_from(response) diff --git a/lib/active_merchant/billing/gateways/metrics_global.rb b/lib/active_merchant/billing/gateways/metrics_global.rb index 314f403c83c..5aac5401d4b 100644 --- a/lib/active_merchant/billing/gateways/metrics_global.rb +++ b/lib/active_merchant/billing/gateways/metrics_global.rb @@ -31,12 +31,12 @@ class MetricsGlobalGateway < Gateway AVS_RESULT_CODE, TRANSACTION_ID, CARD_CODE_RESPONSE_CODE = 5, 6, 38 self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb] + self.supported_cardtypes = %i[visa master american_express discover diners_club jcb] self.homepage_url = 'http://www.metricsglobal.com' self.display_name = 'Metrics Global' - CARD_CODE_ERRORS = %w( N S ) - AVS_ERRORS = %w( A E N R W Z ) + CARD_CODE_ERRORS = %w(N S) + AVS_ERRORS = %w(A E N R W Z) AVS_REASON_CODES = %w(27 45) # Creates a new MetricsGlobalGateway @@ -99,7 +99,7 @@ def purchase(money, creditcard, options = {}) # * money -- The amount to be captured as an Integer value in cents. # * authorization -- The authorization returned from the previous authorize request. def capture(money, authorization, options = {}) - post = {:trans_id => authorization} + post = { trans_id: authorization } add_customer_data(post, options) commit('PRIOR_AUTH_CAPTURE', money, post) end @@ -110,7 +110,7 @@ def capture(money, authorization, options = {}) # # * authorization - The authorization returned from the previous authorize request. def void(authorization, options = {}) - post = {:trans_id => authorization} + post = { trans_id: authorization } add_duplicate_window(post) commit('VOID', nil, post) end @@ -135,9 +135,8 @@ def void(authorization, options = {}) def refund(money, identification, options = {}) requires!(options, :card_number) - post = { :trans_id => identification, - :card_num => options[:card_number] - } + post = { trans_id: identification, + card_num: options[:card_number] } post[:first_name] = options[:first_name] if options[:first_name] post[:last_name] = options[:last_name] if options[:last_name] @@ -177,12 +176,11 @@ def commit(action, money, parameters) test_mode = test? || message =~ /TESTMODE/ Response.new(success?(response), message, response, - :test => test_mode, - :authorization => response[:transaction_id], - :fraud_review => fraud_review?(response), - :avs_result => { :code => response[:avs_result_code] }, - :cvv_result => response[:card_code] - ) + test: test_mode, + authorization: response[:transaction_id], + fraud_review: fraud_review?(response), + avs_result: { code: response[:avs_result_code] }, + cvv_result: response[:card_code]) end def success?(response) @@ -197,12 +195,12 @@ def parse(body) fields = split(body) results = { - :response_code => fields[RESPONSE_CODE].to_i, - :response_reason_code => fields[RESPONSE_REASON_CODE], - :response_reason_text => fields[RESPONSE_REASON_TEXT], - :avs_result_code => fields[AVS_RESULT_CODE], - :transaction_id => fields[TRANSACTION_ID], - :card_code => fields[CARD_CODE_RESPONSE_CODE] + response_code: fields[RESPONSE_CODE].to_i, + response_reason_code: fields[RESPONSE_REASON_CODE], + response_reason_text: fields[RESPONSE_REASON_TEXT], + avs_result_code: fields[AVS_RESULT_CODE], + transaction_id: fields[TRANSACTION_ID], + card_code: fields[CARD_CODE_RESPONSE_CODE] } results end @@ -243,21 +241,15 @@ def add_customer_data(post, options) post[:email_customer] = false end - if options.has_key? :customer - post[:cust_id] = options[:customer] - end + post[:cust_id] = options[:customer] if options.has_key? :customer - if options.has_key? :ip - post[:customer_ip] = options[:ip] - end + post[:customer_ip] = options[:ip] if options.has_key? :ip end # x_duplicate_window won't be sent by default, because sending it changes the response. # "If this field is present in the request with or without a value, an enhanced duplicate transaction response will be sent." def add_duplicate_window(post) - unless duplicate_window.nil? - post[:duplicate_window] = duplicate_window - end + post[:duplicate_window] = duplicate_window unless duplicate_window.nil? end def add_address(post, options) @@ -268,7 +260,7 @@ def add_address(post, options) post[:zip] = address[:zip].to_s post[:city] = address[:city].to_s post[:country] = address[:country].to_s - post[:state] = address[:state].blank? ? 'n/a' : address[:state] + post[:state] = address[:state].blank? ? 'n/a' : address[:state] end if address = options[:shipping_address] @@ -280,16 +272,14 @@ def add_address(post, options) post[:ship_to_zip] = address[:zip].to_s post[:ship_to_city] = address[:city].to_s post[:ship_to_country] = address[:country].to_s - post[:ship_to_state] = address[:state].blank? ? 'n/a' : address[:state] + post[:ship_to_state] = address[:state].blank? ? 'n/a' : address[:state] end end def message_from(results) if results[:response_code] == DECLINED return CVVResult.messages[results[:card_code]] if CARD_CODE_ERRORS.include?(results[:card_code]) - if AVS_REASON_CODES.include?(results[:response_reason_code]) && AVS_ERRORS.include?(results[:avs_result_code]) - return AVSResult.messages[results[:avs_result_code]] - end + return AVSResult.messages[results[:avs_result_code]] if AVS_REASON_CODES.include?(results[:response_reason_code]) && AVS_ERRORS.include?(results[:avs_result_code]) end (results[:response_reason_text] ? results[:response_reason_text].chomp('.') : '') diff --git a/lib/active_merchant/billing/gateways/micropayment.rb b/lib/active_merchant/billing/gateways/micropayment.rb index fc416311865..e6cf5f97df4 100644 --- a/lib/active_merchant/billing/gateways/micropayment.rb +++ b/lib/active_merchant/billing/gateways/micropayment.rb @@ -1,7 +1,6 @@ module ActiveMerchant #:nodoc: module Billing #:nodoc: class MicropaymentGateway < Gateway - self.display_name = 'micropayment' self.homepage_url = 'https://www.micropayment.de/' @@ -10,14 +9,14 @@ class MicropaymentGateway < Gateway self.supported_countries = %w(DE) self.default_currency = 'EUR' self.money_format = :cents - self.supported_cardtypes = [:visa, :master, :american_express] + self.supported_cardtypes = %i[visa master american_express] - def initialize(options={}) + def initialize(options = {}) requires!(options, :access_key) super end - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method, options) @@ -26,7 +25,7 @@ def purchase(amount, payment_method, options={}) commit('purchase', post) end - def authorize(amount, payment_method, options={}) + def authorize(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method, options) @@ -35,27 +34,27 @@ def authorize(amount, payment_method, options={}) commit('authorize', post) end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) post = {} add_reference(post, authorization) add_invoice(post, amount, options) commit('capture', post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} add_reference(post, authorization) commit('void', post) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) post = {} add_reference(post, authorization) add_invoice(post, amount, options) commit('refund', post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(250, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -84,7 +83,7 @@ def add_invoice(post, money, options) post['params[title]'] = options[:description] if options[:description] end - def add_payment_method(post, payment_method, options={}) + def add_payment_method(post, payment_method, options = {}) post[:number] = payment_method.number post[:recurring] = 1 if options[:recurring] == true post[:cvc2] = payment_method.verification_value @@ -136,7 +135,7 @@ def commit(action, params) end def headers - { 'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8' } + { 'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8' } end def post_data(action, params) @@ -176,7 +175,7 @@ def split_authorization(authorization) def authorization_from(response, request_params) session_id = response['sessionId'] || request_params[:sessionId] - "#{session_id}|#{response["transactionId"]}" + "#{session_id}|#{response['transactionId']}" end end end diff --git a/lib/active_merchant/billing/gateways/migs.rb b/lib/active_merchant/billing/gateways/migs.rb index e1ae2922682..50a254e49a3 100644 --- a/lib/active_merchant/billing/gateways/migs.rb +++ b/lib/active_merchant/billing/gateways/migs.rb @@ -20,7 +20,7 @@ class MigsGateway < Gateway self.supported_countries = %w(AU AE BD BN EG HK ID JO KW LB LK MU MV MY NZ OM PH QA SA SG TT VN) # The card types supported by the payment gateway - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :jcb] + self.supported_cardtypes = %i[visa master american_express diners_club jcb] self.money_format = :cents self.currencies_without_fractions = %w(IDR) @@ -70,7 +70,7 @@ def purchase(money, creditcard, options = {}) # MiGS works by merchants being either purchase only or authorize/capture # So authorize is the same as purchase when in authorize mode - alias_method :authorize, :purchase + alias authorize purchase # ==== Options # @@ -79,7 +79,7 @@ def purchase(money, creditcard, options = {}) def capture(money, authorization, options = {}) requires!(@options, :advanced_login, :advanced_password) - post = options.merge(:TransNo => authorization) + post = options.merge(TransNo: authorization) add_amount(post, money, options) add_advanced_user(post) @@ -96,7 +96,7 @@ def capture(money, authorization, options = {}) def refund(money, authorization, options = {}) requires!(@options, :advanced_login, :advanced_password) - post = options.merge(:TransNo => authorization) + post = options.merge(TransNo: authorization) add_amount(post, money, options) add_advanced_user(post) @@ -109,7 +109,7 @@ def refund(money, authorization, options = {}) def void(authorization, options = {}) requires!(@options, :advanced_login, :advanced_password) - post = options.merge(:TransNo => authorization) + post = options.merge(TransNo: authorization) add_advanced_user(post) add_standard_parameters('voidAuthorisation', post, options[:unique_id]) @@ -123,7 +123,7 @@ def credit(money, authorization, options = {}) refund(money, authorization, options) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -195,9 +195,7 @@ def purchase_offsite_response(data) response_hash = parse(data) expected_secure_hash = calculate_secure_hash(response_hash, @options[:secure_hash]) - unless response_hash[:SecureHash] == expected_secure_hash - raise SecurityError, 'Secure Hash mismatch, response may be tampered with' - end + raise SecurityError, 'Secure Hash mismatch, response may be tampered with' unless response_hash[:SecureHash] == expected_secure_hash response_object(response_hash) end @@ -256,7 +254,7 @@ def add_creditcard(post, creditcard) end def add_creditcard_type(post, card_type) - post[:Gateway] = 'ssl' + post[:Gateway] = 'ssl' post[:card] = CARD_TYPES.detect { |ct| ct.am_code == card_type }.migs_long_code end @@ -284,12 +282,11 @@ def response_object(response) cvv_result_code = 'P' if cvv_result_code == 'Unsupported' Response.new(success?(response), response[:Message], response, - :test => test?, - :authorization => response[:TransactionNo], - :fraud_review => fraud_review?(response), - :avs_result => { :code => avs_response_code }, - :cvv_result => cvv_result_code - ) + test: test?, + authorization: response[:TransactionNo], + fraud_review: fraud_review?(response), + avs_result: { code: avs_response_code }, + cvv_result: cvv_result_code) end def success?(response) @@ -302,11 +299,11 @@ def fraud_review?(response) def add_standard_parameters(action, post, unique_id = nil) post.merge!( - :Version => API_VERSION, - :Merchant => @options[:login], - :AccessCode => @options[:password], - :Command => action, - :MerchTxnRef => unique_id || generate_unique_id.slice(0, 40) + Version: API_VERSION, + Merchant: @options[:login], + AccessCode: @options[:password], + Command: action, + MerchTxnRef: unique_id || generate_unique_id.slice(0, 40) ) end diff --git a/lib/active_merchant/billing/gateways/migs/migs_codes.rb b/lib/active_merchant/billing/gateways/migs/migs_codes.rb index 9eae5f4bdfc..32929ed8abe 100644 --- a/lib/active_merchant/billing/gateways/migs/migs_codes.rb +++ b/lib/active_merchant/billing/gateways/migs/migs_codes.rb @@ -85,13 +85,13 @@ def initialize(am_code, migs_code, migs_long_code, name) # migs_code: Used in response for purchase/authorize/status # migs_long_code: Used to pre-select card for server_purchase_url # name: The nice display name - %w(american_express AE Amex American\ Express), - %w(diners_club DC Dinersclub Diners\ Club), - %w(jcb JC JCB JCB\ Card), - %w(maestro MS Maestro Maestro\ Card), - %w(master MC Mastercard MasterCard), - %w(na PL PrivateLabelCard Private\ Label\ Card), - %w(visa VC Visa Visa\ Card') + %w(american_express AE Amex American\ Express), + %w(diners_club DC Dinersclub Diners\ Club), + %w(jcb JC JCB JCB\ Card), + %w(maestro MS Maestro Maestro\ Card), + %w(master MC Mastercard MasterCard), + %w(na PL PrivateLabelCard Private\ Label\ Card), + %w(visa VC Visa Visa\ Card) ].map do |am_code, migs_code, migs_long_code, name| CreditCardType.new(am_code, migs_code, migs_long_code, name) end diff --git a/lib/active_merchant/billing/gateways/modern_payments_cim.rb b/lib/active_merchant/billing/gateways/modern_payments_cim.rb index b1626434d38..d5d6f9b2a27 100644 --- a/lib/active_merchant/billing/gateways/modern_payments_cim.rb +++ b/lib/active_merchant/billing/gateways/modern_payments_cim.rb @@ -8,7 +8,7 @@ class ModernPaymentsCimGateway < Gateway #:nodoc: TEST_XMLNS = 'https://secure.modpay.com/netservices/test/' self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://www.modpay.com' self.display_name = 'Modern Payments' @@ -17,8 +17,8 @@ class ModernPaymentsCimGateway < Gateway #:nodoc: ERROR_MESSAGE = 'Transaction error' PAYMENT_METHOD = { - :check => 1, - :credit_card => 2 + check: 1, + credit_card: 2 } def initialize(options = {}) @@ -81,7 +81,7 @@ def add_customer_id(post, customer_id) end def add_customer_data(post, options) - post[:acctNum] = options[:customer] + post[:acctNum] = options[:customer] end def add_address(post, options) @@ -111,7 +111,7 @@ def add_credit_card(post, credit_card) end def build_request(action, params) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.instruct! xml.tag! 'env:Envelope', { 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema', @@ -147,16 +147,14 @@ def url(action) def commit(action, params) data = ssl_post(url(action), build_request(action, params), - { 'Content-Type' =>'text/xml; charset=utf-8', - 'SOAPAction' => "#{xmlns(action)}#{action}" } - ) + { 'Content-Type' => 'text/xml; charset=utf-8', + 'SOAPAction' => "#{xmlns(action)}#{action}" }) response = parse(action, data) Response.new(successful?(action, response), message_from(action, response), response, - :test => test?, - :authorization => authorization_from(action, response), - :avs_result => { :code => response[:avs_code] } - ) + test: test?, + authorization: authorization_from(action, response), + avs_result: { code: response[:avs_code] }) end def authorization_from(action, response) diff --git a/lib/active_merchant/billing/gateways/monei.rb b/lib/active_merchant/billing/gateways/monei.rb index 37247721a6a..948ce4af32c 100755 --- a/lib/active_merchant/billing/gateways/monei.rb +++ b/lib/active_merchant/billing/gateways/monei.rb @@ -14,9 +14,9 @@ class MoneiGateway < Gateway self.test_url = 'https://test.monei-api.net/payment/ctpe' self.live_url = 'https://monei-api.net/payment/ctpe' - self.supported_countries = ['AD', 'AT', 'BE', 'BG', 'CA', 'CH', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FO', 'FR', 'GB', 'GI', 'GR', 'HU', 'IE', 'IL', 'IS', 'IT', 'LI', 'LT', 'LU', 'LV', 'MT', 'NL', 'NO', 'PL', 'PT', 'RO', 'SE', 'SI', 'SK', 'TR', 'US', 'VA'] + self.supported_countries = %w[AD AT BE BG CA CH CY CZ DE DK EE ES FI FO FR GB GI GR HU IE IL IS IT LI LT LU LV MT NL NO PL PT RO SE SI SK TR US VA] self.default_currency = 'EUR' - self.supported_cardtypes = [:visa, :master, :maestro, :jcb, :american_express] + self.supported_cardtypes = %i[visa master maestro jcb american_express] self.homepage_url = 'http://www.monei.net/' self.display_name = 'Monei' @@ -29,7 +29,7 @@ class MoneiGateway < Gateway # :login User login # :pwd User password # - def initialize(options={}) + def initialize(options = {}) requires!(options, :sender_id, :channel_id, :login, :pwd) super end @@ -45,7 +45,7 @@ def initialize(options={}) # :currency Sale currency to override money object or default (optional) # # Returns Active Merchant response object - def purchase(money, credit_card, options={}) + def purchase(money, credit_card, options = {}) execute_new_order(:purchase, money, credit_card, options) end @@ -60,7 +60,7 @@ def purchase(money, credit_card, options={}) # :currency Sale currency to override money object or default (optional) # # Returns Active Merchant response object - def authorize(money, credit_card, options={}) + def authorize(money, credit_card, options = {}) execute_new_order(:authorize, money, credit_card, options) end @@ -76,7 +76,7 @@ def authorize(money, credit_card, options={}) # Note: you should pass either order_id or description # # Returns Active Merchant response object - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) execute_dependant(:capture, money, authorization, options) end @@ -92,7 +92,7 @@ def capture(money, authorization, options={}) # Note: you should pass either order_id or description # # Returns Active Merchant response object - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) execute_dependant(:refund, money, authorization, options) end @@ -103,7 +103,7 @@ def refund(money, authorization, options={}) # :order_id Merchant created id for the authorization (optional) # # Returns Active Merchant response object - def void(authorization, options={}) + def void(authorization, options = {}) execute_dependant(:void, nil, authorization, options) end @@ -117,7 +117,7 @@ def void(authorization, options={}) # :currency Sale currency to override money object or default (optional) # # Returns Active Merchant response object of Authorization operation - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -151,11 +151,11 @@ def execute_dependant(action, money, authorization, options) # Private: Build XML wrapping code yielding to code to fill the transaction information def build_request - builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml| - xml.Request(:version => '1.0') do - xml.Header { xml.Security(:sender => @options[:sender_id]) } - xml.Transaction(:mode => test? ? 'CONNECTOR_TEST' : 'LIVE', :response => 'SYNC', :channel => @options[:channel_id]) do - xml.User(:login => @options[:login], :pwd => @options[:pwd]) + builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml| + xml.Request(version: '1.0') do + xml.Header { xml.Security(sender: @options[:sender_id]) } + xml.Transaction(mode: test? ? 'CONNECTOR_TEST' : 'LIVE', response: 'SYNC', channel: @options[:channel_id]) do + xml.User(login: @options[:login], pwd: @options[:pwd]) yield xml end end @@ -183,7 +183,7 @@ def add_identification_authorization(xml, authorization, options) def add_payment(xml, action, money, options) code = tanslate_payment_code(action) - xml.Payment(:code => code) do + xml.Payment(code: code) do xml.Presentation do xml.Amount amount(money) xml.Currency options[:currency] || currency(money) @@ -198,7 +198,7 @@ def add_account(xml, credit_card) xml.Holder credit_card.name xml.Number credit_card.number xml.Brand credit_card.brand.upcase - xml.Expiry(:month => credit_card.month, :year => credit_card.year) + xml.Expiry(month: credit_card.month, year: credit_card.year) xml.Verification credit_card.verification_value end end @@ -248,10 +248,10 @@ def eci_to_result_indicator(eci) # Private : Add the 3DSecure infos to XML def add_three_d_secure(xml, options) if options[:three_d_secure] - xml.Authentication(:type => '3DSecure') do + xml.Authentication(type: '3DSecure') do xml.ResultIndicator eci_to_result_indicator options[:three_d_secure][:eci] - xml.Parameter(:name => 'VERIFICATION_ID') { xml.text options[:three_d_secure][:cavv] } - xml.Parameter(:name => 'XID') { xml.text options[:three_d_secure][:xid] } + xml.Parameter(name: 'VERIFICATION_ID') { xml.text options[:three_d_secure][:cavv] } + xml.Parameter(name: 'XID') { xml.text options[:three_d_secure][:xid] } end end end @@ -260,10 +260,10 @@ def add_three_d_secure(xml, options) def parse(body) xml = Nokogiri::XML(body) { - :unique_id => xml.xpath('//Response/Transaction/Identification/UniqueID').text, - :status => translate_status_code(xml.xpath('//Response/Transaction/Processing/Status/@code').text), - :reason => translate_status_code(xml.xpath('//Response/Transaction/Processing/Reason/@code').text), - :message => xml.xpath('//Response/Transaction/Processing/Return').text + unique_id: xml.xpath('//Response/Transaction/Identification/UniqueID').text, + status: translate_status_code(xml.xpath('//Response/Transaction/Processing/Status/@code').text), + reason: translate_status_code(xml.xpath('//Response/Transaction/Processing/Reason/@code').text), + message: xml.xpath('//Response/Transaction/Processing/Return').text } end @@ -311,26 +311,26 @@ def post_data(xml) # Private: Translate Monei status code to native ruby symbols def translate_status_code(code) { - '00' => :success, - '40' => :neutral, - '59' => :waiting_bank, - '60' => :rejected_bank, - '64' => :waiting_risk, - '65' => :rejected_risk, - '70' => :rejected_validation, - '80' => :waiting, - '90' => :new + '00' => :success, + '40' => :neutral, + '59' => :waiting_bank, + '60' => :rejected_bank, + '64' => :waiting_risk, + '65' => :rejected_risk, + '70' => :rejected_validation, + '80' => :waiting, + '90' => :new }[code] end # Private: Translate AM operations to Monei operations codes def tanslate_payment_code(action) { - :purchase => 'CC.DB', - :authorize => 'CC.PA', - :capture => 'CC.CP', - :refund => 'CC.RF', - :void => 'CC.RV' + purchase: 'CC.DB', + authorize: 'CC.PA', + capture: 'CC.CP', + refund: 'CC.RF', + void: 'CC.RV' }[action] end end diff --git a/lib/active_merchant/billing/gateways/moneris.rb b/lib/active_merchant/billing/gateways/moneris.rb index 29b5d9b0928..68ccd4559fd 100644 --- a/lib/active_merchant/billing/gateways/moneris.rb +++ b/lib/active_merchant/billing/gateways/moneris.rb @@ -13,7 +13,7 @@ class MonerisGateway < Gateway self.live_url = 'https://www3.moneris.com/gateway2/servlet/MpgRequest' self.supported_countries = ['CA'] - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :discover] + self.supported_cardtypes = %i[visa master american_express diners_club discover] self.homepage_url = 'http://www.moneris.com/' self.display_name = 'Moneris' @@ -92,7 +92,7 @@ def purchase(money, creditcard_or_datakey, options = {}) # gateways the two numbers are concatenated together with a ; separator as # the authorization number returned by authorization def capture(money, authorization, options = {}) - commit 'completion', crediting_params(authorization, :comp_amount => amount(money)) + commit 'completion', crediting_params(authorization, comp_amount: amount(money)) end # Voiding requires the original transaction ID and order ID of some open @@ -130,22 +130,43 @@ def credit(money, authorization, options = {}) end def refund(money, authorization, options = {}) - commit 'refund', crediting_params(authorization, :amount => amount(money)) + commit 'refund', crediting_params(authorization, amount: amount(money)) end - def verify(credit_card, options={}) - MultiResponse.run(:use_first_response) do |r| - r.process { authorize(100, credit_card, options) } - r.process(:ignore_result) { void(r.authorization, options) } - end + def verify(credit_card, options = {}) + requires!(options, :order_id) + post = {} + add_payment_source(post, credit_card, options) + post[:order_id] = options[:order_id] + post[:address] = options[:billing_address] || options[:address] + post[:crypt_type] = options[:crypt_type] || @options[:crypt_type] + add_stored_credential(post, options) + action = if post[:data_key].blank? + 'card_verification' + else + 'res_card_verification_cc' + end + commit(action, post) end + # When passing a :duration option (time in seconds) you can create a + # temporary vault record to avoid incurring Moneris vault storage fees + # + # https://developer.moneris.com/Documentation/NA/E-Commerce%20Solutions/API/Vault#vaulttokenadd def store(credit_card, options = {}) post = {} post[:pan] = credit_card.number post[:expdate] = expdate(credit_card) + post[:address] = options[:billing_address] || options[:address] post[:crypt_type] = options[:crypt_type] || @options[:crypt_type] - commit('res_add_cc', post) + add_stored_credential(post, options) + + if options[:duration] + post[:duration] = options[:duration] + commit('res_temp_add', post) + else + commit('res_add_cc', post) + end end def unstore(data_key, options = {}) @@ -213,6 +234,7 @@ def add_stored_credential(post, options) # if any of :issuer_id, :payment_information, or :payment_indicator is not passed, # then check for :stored credential options return unless (stored_credential = options[:stored_credential]) && !cof_details_present?(options) + if stored_credential[:initial_transaction] add_stored_credential_initial(post, options) else @@ -253,9 +275,9 @@ def add_stored_credential_used(post, options) # Common params used amongst the +credit+, +void+ and +capture+ methods def crediting_params(authorization, options = {}) { - :txn_number => split_authorization(authorization).first, - :order_id => split_authorization(authorization).last, - :crypt_type => options[:crypt_type] || @options[:crypt_type] + txn_number: split_authorization(authorization).first, + order_id: split_authorization(authorization).last, + crypt_type: options[:crypt_type] || @options[:crypt_type] }.merge(options) end @@ -279,28 +301,27 @@ def commit(action, parameters = {}) successful?(response), message_from(response[:message]), response, - :test => test?, - :avs_result => {:code => response[:avs_result_code]}, - :cvv_result => response[:cvd_result_code] && response[:cvd_result_code][-1, 1], - :authorization => authorization_from(response)) + test: test?, + avs_result: { code: response[:avs_result_code] }, + cvv_result: response[:cvd_result_code] && response[:cvd_result_code][-1, 1], + authorization: authorization_from(response) + ) end # Generates a Moneris authorization string of the form 'trans_id;receipt_id'. def authorization_from(response = {}) - if response[:trans_id] && response[:receipt_id] - "#{response[:trans_id]};#{response[:receipt_id]}" - end + "#{response[:trans_id]};#{response[:receipt_id]}" if response[:trans_id] && response[:receipt_id] end # Tests for a successful response from Moneris' servers def successful?(response) response[:response_code] && - response[:complete] && - (0..49).cover?(response[:response_code].to_i) + response[:complete] && + (0..49).cover?(response[:response_code].to_i) end def parse(xml) - response = { :message => 'Global Error Receipt', :complete => false } + response = { message: 'Global Error Receipt', complete: false } hashify_xml!(xml, response) response end @@ -308,6 +329,7 @@ def parse(xml) def hashify_xml!(xml, response) xml = REXML::Document.new(xml) return if xml.root.nil? + xml.elements.each('//receipt/*') do |node| response[node.name.underscore.to_sym] = normalize(node.text) end @@ -384,34 +406,39 @@ def credential_on_file(parameters) def wallet_indicator(token_source) return 'APP' if token_source == 'apple_pay' return 'ANP' if token_source == 'android_pay' + nil end def message_from(message) return 'Unspecified error' if message.blank? + message.gsub(/[^\w]/, ' ').split.join(' ').capitalize end def actions { - 'purchase' => [:order_id, :cust_id, :amount, :pan, :expdate, :crypt_type, :avs_info, :cvd_info, :track2, :pos_code, :cof_info], - 'preauth' => [:order_id, :cust_id, :amount, :pan, :expdate, :crypt_type, :avs_info, :cvd_info, :track2, :pos_code, :cof_info], - 'command' => [:order_id], - 'refund' => [:order_id, :amount, :txn_number, :crypt_type], - 'indrefund' => [:order_id, :cust_id, :amount, :pan, :expdate, :crypt_type], - 'completion' => [:order_id, :comp_amount, :txn_number, :crypt_type], - 'purchasecorrection' => [:order_id, :txn_number, :crypt_type], - 'cavv_preauth' => [:order_id, :cust_id, :amount, :pan, :expdate, :cavv, :crypt_type, :wallet_indicator], - 'cavv_purchase' => [:order_id, :cust_id, :amount, :pan, :expdate, :cavv, :crypt_type, :wallet_indicator], - 'transact' => [:order_id, :cust_id, :amount, :pan, :expdate, :crypt_type], - 'Batchcloseall' => [], - 'opentotals' => [:ecr_number], - 'batchclose' => [:ecr_number], - 'res_add_cc' => [:pan, :expdate, :crypt_type, :cof_info], - 'res_delete' => [:data_key], - 'res_update_cc' => [:data_key, :pan, :expdate, :crypt_type], - 'res_purchase_cc' => [:data_key, :order_id, :cust_id, :amount, :crypt_type, :cof_info], - 'res_preauth_cc' => [:data_key, :order_id, :cust_id, :amount, :crypt_type, :cof_info] + 'purchase' => %i[order_id cust_id amount pan expdate crypt_type avs_info cvd_info track2 pos_code cof_info], + 'preauth' => %i[order_id cust_id amount pan expdate crypt_type avs_info cvd_info track2 pos_code cof_info], + 'command' => [:order_id], + 'refund' => %i[order_id amount txn_number crypt_type], + 'indrefund' => %i[order_id cust_id amount pan expdate crypt_type], + 'completion' => %i[order_id comp_amount txn_number crypt_type], + 'purchasecorrection' => %i[order_id txn_number crypt_type], + 'cavv_preauth' => %i[order_id cust_id amount pan expdate cavv crypt_type wallet_indicator], + 'cavv_purchase' => %i[order_id cust_id amount pan expdate cavv crypt_type wallet_indicator], + 'card_verification' => %i[order_id cust_id pan expdate crypt_type avs_info cvd_info cof_info], + 'transact' => %i[order_id cust_id amount pan expdate crypt_type], + 'Batchcloseall' => [], + 'opentotals' => [:ecr_number], + 'batchclose' => [:ecr_number], + 'res_add_cc' => %i[pan expdate crypt_type avs_info cof_info], + 'res_temp_add' => %i[pan expdate crypt_type duration], + 'res_delete' => [:data_key], + 'res_update_cc' => %i[data_key pan expdate crypt_type avs_info cof_info], + 'res_purchase_cc' => %i[data_key order_id cust_id amount crypt_type cof_info], + 'res_preauth_cc' => %i[data_key order_id cust_id amount crypt_type cof_info], + 'res_card_verification_cc' => %i[order_id data_key expdate crypt_type cof_info] } end end diff --git a/lib/active_merchant/billing/gateways/moneris_us.rb b/lib/active_merchant/billing/gateways/moneris_us.rb deleted file mode 100644 index 28c06ea91d0..00000000000 --- a/lib/active_merchant/billing/gateways/moneris_us.rb +++ /dev/null @@ -1,352 +0,0 @@ -require 'rexml/document' - -module ActiveMerchant #:nodoc: - module Billing #:nodoc: - # To learn more about the Moneris (US) gateway, please contact - # ussales@moneris.com for a copy of their integration guide. For - # information on remote testing, please see "Test Environment Penny Value - # Response Table", and "Test Environment eFraud (AVS and CVD) Penny - # Response Values", available at Moneris' {eSelect Plus Documentation - # Centre}[https://www3.moneris.com/connect/en/documents/index.html]. - class MonerisUsGateway < Gateway - self.test_url = 'https://esplusqa.moneris.com/gateway_us/servlet/MpgRequest' - self.live_url = 'https://esplus.moneris.com/gateway_us/servlet/MpgRequest' - - self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :discover] - self.homepage_url = 'http://www.monerisusa.com/' - self.display_name = 'Moneris (US)' - - # Initialize the Gateway - # - # The gateway requires that a valid login and password be passed - # in the +options+ hash. - # - # ==== Options - # - # * :login -- Your Store ID - # * :password -- Your API Token - # * :cvv_enabled -- Specify that you would like the CVV passed to the gateway. - # Only particular account types at Moneris will allow this. - # Defaults to false. (optional) - def initialize(options = {}) - requires!(options, :login, :password) - @cvv_enabled = options[:cvv_enabled] - @avs_enabled = options[:avs_enabled] - options = { :crypt_type => 7 }.merge(options) - super - end - - def verify(creditcard_or_datakey, options = {}) - MultiResponse.run(:use_first_response) do |r| - r.process { authorize(100, creditcard_or_datakey, options) } - r.process(:ignore_result) { capture(0, r.authorization) } - end - end - - # Referred to as "PreAuth" in the Moneris integration guide, this action - # verifies and locks funds on a customer's card, which then must be - # captured at a later date. - # - # Pass in +order_id+ and optionally a +customer+ parameter. - def authorize(money, creditcard_or_datakey, options = {}) - requires!(options, :order_id) - post = {} - add_payment_source(post, creditcard_or_datakey, options) - post[:amount] = amount(money) - post[:order_id] = options[:order_id] - post[:address] = options[:billing_address] || options[:address] - post[:crypt_type] = options[:crypt_type] || @options[:crypt_type] - action = post[:data_key].blank? ? 'us_preauth' : 'us_res_preauth_cc' - commit(action, post) - end - - # This action verifies funding on a customer's card and readies them for - # deposit in a merchant's account. - # - # Pass in order_id and optionally a customer parameter - def purchase(money, creditcard_or_datakey, options = {}) - requires!(options, :order_id) - post = {} - add_payment_source(post, creditcard_or_datakey, options) - post[:amount] = amount(money) - post[:order_id] = options[:order_id] - add_address(post, creditcard_or_datakey, options) - post[:crypt_type] = options[:crypt_type] || @options[:crypt_type] - action = if creditcard_or_datakey.is_a?(String) - 'us_res_purchase_cc' - elsif card_brand(creditcard_or_datakey) == 'check' - 'us_ach_debit' - elsif post[:data_key].blank? - 'us_purchase' - end - commit(action, post) - end - - # This method retrieves locked funds from a customer's account (from a - # PreAuth) and prepares them for deposit in a merchant's account. - # - # Note: Moneris requires both the order_id and the transaction number of - # the original authorization. To maintain the same interface as the other - # gateways the two numbers are concatenated together with a ; separator as - # the authorization number returned by authorization - def capture(money, authorization, options = {}) - commit 'us_completion', crediting_params(authorization, :comp_amount => amount(money)) - end - - # Voiding requires the original transaction ID and order ID of some open - # transaction. Closed transactions must be refunded. Note that the only - # methods which may be voided are +capture+ and +purchase+. - # - # Concatenate your transaction number and order_id by using a semicolon - # (';'). This is to keep the Moneris interface consistent with other - # gateways. (See +capture+ for details.) - def void(authorization, options = {}) - commit 'us_purchasecorrection', crediting_params(authorization) - end - - # Performs a refund. This method requires that the original transaction - # number and order number be included. Concatenate your transaction - # number and order_id by using a semicolon (';'). This is to keep the - # Moneris interface consistent with other gateways. (See +capture+ for - # details.) - def credit(money, authorization, options = {}) - ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE - refund(money, authorization, options) - end - - def refund(money, authorization, options = {}) - commit 'us_refund', crediting_params(authorization, :amount => amount(money)) - end - - def store(payment_source, options = {}) - post = {} - add_payment_source(post, payment_source, options) - post[:crypt_type] = options[:crypt_type] || @options[:crypt_type] - card_brand(payment_source) == 'check' ? commit('us_res_add_ach', post) : commit('us_res_add_cc', post) - end - - def unstore(data_key, options = {}) - post = {} - post[:data_key] = data_key - commit('us_res_delete', post) - end - - def update(data_key, payment_source, options = {}) - post = {} - add_payment_source(post, payment_source, options) - post[:data_key] = data_key - card_brand(payment_source) == 'check' ? commit('us_res_update_ach', post) : commit('us_res_update_cc', post) - end - - def supports_scrubbing? - true - end - - def scrub(transcript) - transcript. - gsub(%r(()[^<]*())i, '\1[FILTERED]\2'). - gsub(%r(()[^<]*())i, '\1[FILTERED]\2'). - gsub(%r(()[^<]*())i, '\1[FILTERED]\2') - end - - private # :nodoc: all - - def expdate(creditcard) - sprintf('%.4i', creditcard.year)[-2..-1] + sprintf('%.2i', creditcard.month) - end - - def add_address(post, payment_method, options) - if !payment_method.is_a?(String) && card_brand(payment_method) == 'check' - post[:ach_info][:cust_first_name] = payment_method.first_name if payment_method.first_name - post[:ach_info][:cust_last_name] = payment_method.last_name if payment_method.last_name - if address = options[:billing_address] || options[:address] - post[:ach_info][:cust_address1] = address[:address1] if address[:address1] - post[:ach_info][:cust_address2] = address[:address2] if address[:address2] - post[:ach_info][:city] = address[:city] if address[:city] - post[:ach_info][:state] = address[:state] if address[:state] - post[:ach_info][:zip] = address[:zip] if address[:zip] - end - else - post[:address] = options[:billing_address] || options[:address] - end - end - - def add_payment_source(post, source, options) - if source.is_a?(String) - post[:data_key] = source - post[:cust_id] = options[:customer] - elsif card_brand(source) == 'check' - ach_info = {} - ach_info[:sec] = 'web' - ach_info[:routing_num] = source.routing_number - ach_info[:account_num] = source.account_number - ach_info[:account_type] = source.account_type - ach_info[:check_num] = source.number if source.number - post[:ach_info] = ach_info - else - post[:pan] = source.number - post[:expdate] = expdate(source) - post[:cvd_value] = source.verification_value if source.verification_value? - if crypt_type = options[:crypt_type] || @options[:crypt_type] - post[:crypt_type] = crypt_type - end - post[:cust_id] = options[:customer] || source.name - end - end - - # Common params used amongst the +credit+, +void+ and +capture+ methods - def crediting_params(authorization, options = {}) - { - :txn_number => split_authorization(authorization).first, - :order_id => split_authorization(authorization).last, - :crypt_type => options[:crypt_type] || @options[:crypt_type] - }.merge(options) - end - - # Splits an +authorization+ param and retrieves the order id and - # transaction number in that order. - def split_authorization(authorization) - if authorization.nil? || authorization.empty? || authorization !~ /;/ - raise ArgumentError, 'You must include a valid authorization code (e.g. "1234;567")' - else - authorization.split(';') - end - end - - def commit(action, parameters = {}) - data = post_data(action, parameters) - url = test? ? self.test_url : self.live_url - raw = ssl_post(url, data) - response = parse(raw) - - Response.new(successful?(response), message_from(response[:message]), response, - :test => test?, - :avs_result => { :code => response[:avs_result_code] }, - :cvv_result => response[:cvd_result_code] && response[:cvd_result_code][-1, 1], - :authorization => authorization_from(response) - ) - end - - # Generates a Moneris authorization string of the form 'trans_id;receipt_id'. - def authorization_from(response = {}) - if response[:trans_id] && response[:receipt_id] - "#{response[:trans_id]};#{response[:receipt_id]}" - end - end - - # Tests for a successful response from Moneris' servers - def successful?(response) - response[:response_code] && - response[:complete] && - (0..49).cover?(response[:response_code].to_i) - end - - def parse(xml) - response = { :message => 'Global Error Receipt', :complete => false } - hashify_xml!(xml, response) - response - end - - def hashify_xml!(xml, response) - xml = REXML::Document.new(xml) - return if xml.root.nil? - xml.elements.each('//receipt/*') do |node| - response[node.name.underscore.to_sym] = normalize(node.text) - end - end - - def post_data(action, parameters = {}) - xml = REXML::Document.new - root = xml.add_element('request') - root.add_element('store_id').text = options[:login] - root.add_element('api_token').text = options[:password] - root.add_element(transaction_element(action, parameters)) - - xml.to_s - end - - def transaction_element(action, parameters) - transaction = REXML::Element.new(action) - - # Must add the elements in the correct order - actions[action].each do |key| - case key - when :avs_info - transaction.add_element(avs_element(parameters[:address])) if @avs_enabled && parameters[:address] - when :cvd_info - transaction.add_element(cvd_element(parameters[:cvd_value])) if @cvv_enabled - when :ach_info - transaction.add_element(ach_element(parameters[:ach_info])) - else - transaction.add_element(key.to_s).text = parameters[key] unless parameters[key].blank? - end - end - - transaction - end - - def avs_element(address) - full_address = "#{address[:address1]} #{address[:address2]}" - tokens = full_address.split(/\s+/) - - element = REXML::Element.new('avs_info') - element.add_element('avs_street_number').text = tokens.select { |x| x =~ /\d/ }.join(' ') - element.add_element('avs_street_name').text = tokens.reject { |x| x =~ /\d/ }.join(' ') - element.add_element('avs_zipcode').text = address[:zip] - element - end - - def cvd_element(cvd_value) - element = REXML::Element.new('cvd_info') - if cvd_value - element.add_element('cvd_indicator').text = '1' - element.add_element('cvd_value').text = cvd_value - else - element.add_element('cvd_indicator').text = '0' - end - element - end - - def ach_element(ach_info) - element = REXML::Element.new('ach_info') - actions['ach_info'].each do |key| - element.add_element(key.to_s).text = ach_info[key] unless ach_info[key].blank? - end - element - end - - def message_from(message) - return 'Unspecified error' if message.blank? - message.gsub(/[^\w]/, ' ').split.join(' ').capitalize - end - - def actions - { - 'us_purchase' => [:order_id, :cust_id, :amount, :pan, :expdate, :crypt_type, :avs_info, :cvd_info], - 'us_preauth' => [:order_id, :cust_id, :amount, :pan, :expdate, :crypt_type, :avs_info, :cvd_info], - 'us_command' => [:order_id], - 'us_refund' => [:order_id, :amount, :txn_number, :crypt_type], - 'us_indrefund' => [:order_id, :cust_id, :amount, :pan, :expdate, :crypt_type], - 'us_completion' => [:order_id, :comp_amount, :txn_number, :crypt_type], - 'us_purchasecorrection' => [:order_id, :txn_number, :crypt_type], - 'us_cavvpurcha' => [:order_id, :cust_id, :amount, :pan, :expdate, :cav], - 'us_cavvpreaut' => [:order_id, :cust_id, :amount, :pan, :expdate, :cavv], - 'us_transact' => [:order_id, :cust_id, :amount, :pan, :expdate, :crypt_type], - 'us_Batchcloseall' => [], - 'us_opentotals' => [:ecr_number], - 'us_batchclose' => [:ecr_number], - 'us_res_add_cc' => [:pan, :expdate, :crypt_type], - 'us_res_delete' => [:data_key], - 'us_res_update_cc' => [:data_key, :pan, :expdate, :crypt_type], - 'us_res_purchase_cc' => [:data_key, :order_id, :cust_id, :amount, :crypt_type], - 'us_res_preauth_cc' => [:data_key, :order_id, :cust_id, :amount, :crypt_type], - 'us_ach_debit' => [:order_id, :cust_id, :amount, :ach_info], - 'us_res_add_ach' => [:order_id, :cust_id, :amount, :ach_info], - 'us_res_update_ach' => [:order_id, :data_key, :cust_id, :amount, :ach_info], - 'ach_info' => [:sec, :cust_first_name, :cust_last_name, :cust_address1, :cust_address2, :cust_city, :cust_state, :cust_zip, :routing_num, :account_num, :check_num, :account_type] - } - end - end - end -end diff --git a/lib/active_merchant/billing/gateways/money_movers.rb b/lib/active_merchant/billing/gateways/money_movers.rb index 8a7a1e9e9a4..0a16b4ea5dc 100644 --- a/lib/active_merchant/billing/gateways/money_movers.rb +++ b/lib/active_merchant/billing/gateways/money_movers.rb @@ -8,7 +8,7 @@ class MoneyMoversGateway < Gateway self.homepage_url = 'http://mmoa.us/' self.display_name = 'MoneyMovers' self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] def initialize(options = {}) requires!(options, :login, :password) @@ -45,7 +45,7 @@ def void(authorization, options = {}) end def refund(money, authorization, options = {}) - commit('refund', money, options.merge(:transactionid => authorization)) + commit('refund', money, options.merge(transactionid: authorization)) end def credit(money, authorization, options = {}) @@ -114,11 +114,10 @@ def commit(action, money, parameters) message = message_from(response) Response.new(success?(response), message, response, - :test => test?, - :authorization => response['transactionid'], - :avs_result => {:code => response['avsresponse']}, - :cvv_result => response['cvvresponse'] - ) + test: test?, + authorization: response['transactionid'], + avs_result: { code: response['avsresponse'] }, + cvv_result: response['cvvresponse']) end def success?(response) diff --git a/lib/active_merchant/billing/gateways/mundipagg.rb b/lib/active_merchant/billing/gateways/mundipagg.rb index 447a708c0fb..bbb4f9672b4 100644 --- a/lib/active_merchant/billing/gateways/mundipagg.rb +++ b/lib/active_merchant/billing/gateways/mundipagg.rb @@ -5,7 +5,7 @@ class MundipaggGateway < Gateway self.supported_countries = ['US'] self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :alelo] + self.supported_cardtypes = %i[visa master american_express discover alelo] self.homepage_url = 'https://www.mundipagg.com/' self.display_name = 'Mundipagg' @@ -28,48 +28,50 @@ class MundipaggGateway < Gateway '500' => 'An internal error occurred;' } - def initialize(options={}) + def initialize(options = {}) requires!(options, :api_key) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) post = {} add_invoice(post, money, options) add_customer_data(post, options) unless payment.is_a?(String) add_shipping_address(post, options) add_payment(post, payment, options) + add_submerchant(post, options) commit('sale', post) end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) post = {} add_invoice(post, money, options) add_customer_data(post, options) unless payment.is_a?(String) add_shipping_address(post, options) add_payment(post, payment, options) add_capture_flag(post, payment) + add_submerchant(post, options) commit('authonly', post) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) post = {} post[:code] = authorization add_invoice(post, money, options) commit('capture', post, authorization) end - def refund(money, authorization, options={}) - add_invoice(post={}, money, options) + def refund(money, authorization, options = {}) + add_invoice(post = {}, money, options) commit('refund', post, authorization) end - def void(authorization, options={}) + def void(authorization, options = {}) commit('void', nil, authorization) end - def store(payment, options={}) + def store(payment, options = {}) post = {} options.update(name: payment.name) options = add_customer(options) unless options[:customer_id] @@ -77,7 +79,7 @@ def store(payment, options={}) commit('store', post, options[:customer_id]) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -198,9 +200,35 @@ def add_voucher(post, payment, options) def voucher?(payment) return false if payment.is_a?(String) + %w[sodexo vr].include? card_brand(payment) end + def add_submerchant(post, options) + if submerchant = options[:submerchant] + post[:SubMerchant] = {} + post[:SubMerchant][:Merchant_Category_Code] = submerchant[:merchant_category_code] if submerchant[:merchant_category_code] + post[:SubMerchant][:Payment_Facilitator_Code] = submerchant[:payment_facilitator_code] if submerchant[:payment_facilitator_code] + post[:SubMerchant][:Code] = submerchant[:code] if submerchant[:code] + post[:SubMerchant][:Name] = submerchant[:name] if submerchant[:name] + post[:SubMerchant][:Document] = submerchant[:document] if submerchant[:document] + post[:SubMerchant][:Type] = submerchant[:type] if submerchant[:type] + post[:SubMerchant][:Phone] = {} + post[:SubMerchant][:Phone][:Country_Code] = submerchant[:phone][:country_code] if submerchant.dig(:phone, :country_code) + post[:SubMerchant][:Phone][:Number] = submerchant[:phone][:number] if submerchant.dig(:phone, :number) + post[:SubMerchant][:Phone][:Area_Code] = submerchant[:phone][:area_code] if submerchant.dig(:phone, :area_code) + post[:SubMerchant][:Address] = {} + post[:SubMerchant][:Address][:Street] = submerchant[:address][:street] if submerchant.dig(:address, :street) + post[:SubMerchant][:Address][:Number] = submerchant[:address][:number] if submerchant.dig(:address, :number) + post[:SubMerchant][:Address][:Complement] = submerchant[:address][:complement] if submerchant.dig(:address, :complement) + post[:SubMerchant][:Address][:Neighborhood] = submerchant[:address][:neighborhood] if submerchant.dig(:address, :neighborhood) + post[:SubMerchant][:Address][:City] = submerchant[:address][:city] if submerchant.dig(:address, :city) + post[:SubMerchant][:Address][:State] = submerchant[:address][:state] if submerchant.dig(:address, :state) + post[:SubMerchant][:Address][:Country] = submerchant[:address][:country] if submerchant.dig(:address, :country) + post[:SubMerchant][:Address][:Zip_Code] = submerchant[:address][:zip_code] if submerchant.dig(:address, :zip_code) + end + end + def headers { 'Authorization' => 'Basic ' + Base64.strict_encode64("#{@options[:api_key]}:"), @@ -274,7 +302,7 @@ def get_error_messages(error) parsed_response_body = parse(error.response.body) message = parsed_response_body['message'] - parsed_response_body['errors']&.each do |type, descriptions| + parsed_response_body['errors']&.each do |_type, descriptions| message += ' | ' message += descriptions.join(', ') end @@ -290,7 +318,7 @@ def gateway_response_errors(response) error_string = '' response['last_transaction']['gateway_response']['errors']&.each do |error| - error.each do |key, value| + error.each do |_key, value| error_string += ' | ' unless error_string.blank? error_string += value end @@ -301,6 +329,7 @@ def gateway_response_errors(response) def authorization_from(response, action) return "#{response['customer']['id']}|#{response['id']}" if action == 'store' + response['id'] end @@ -313,7 +342,10 @@ def post_data(parameters = {}) end def error_code_from(response) - STANDARD_ERROR_CODE[:processing_error] unless success_from(response) + return if success_from(response) + return response['last_transaction']['acquirer_return_code'] if response['last_transaction'] + + STANDARD_ERROR_CODE[:processing_error] end end end diff --git a/lib/active_merchant/billing/gateways/nab_transact.rb b/lib/active_merchant/billing/gateways/nab_transact.rb index 6715c0e1afb..723063781a0 100644 --- a/lib/active_merchant/billing/gateways/nab_transact.rb +++ b/lib/active_merchant/billing/gateways/nab_transact.rb @@ -16,7 +16,7 @@ class NabTransactGateway < Gateway self.live_periodic_url = 'https://transact.nab.com.au/xmlapi/periodic' self.supported_countries = ['AU'] - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :jcb] + self.supported_cardtypes = %i[visa master american_express diners_club jcb] self.homepage_url = 'http://transact.nab.com.au' self.display_name = 'NAB Transact' @@ -25,21 +25,21 @@ class NabTransactGateway < Gateway # Transactions currently accepted by NAB Transact XML API TRANSACTIONS = { - :purchase => 0, # Standard Payment - :refund => 4, # Refund - :void => 6, # Client Reversal (Void) - :unmatched_refund => 666, # Unmatched Refund - :authorization => 10, # Preauthorise - :capture => 11 # Preauthorise Complete (Advice) + purchase: 0, # Standard Payment + refund: 4, # Refund + void: 6, # Client Reversal (Void) + unmatched_refund: 666, # Unmatched Refund + authorization: 10, # Preauthorise + capture: 11 # Preauthorise Complete (Advice) } PERIODIC_TYPES = { - :addcrn => 5, - :deletecrn => 5, - :trigger => 8 + addcrn: 5, + deletecrn: 5, + trigger: 8 } - SUCCESS_CODES = [ '00', '08', '11', '16', '77' ] + SUCCESS_CODES = %w[00 08 11 16 77] def initialize(options = {}) requires!(options, :login, :password) @@ -84,6 +84,7 @@ def supports_scrubbing? def scrub(transcript) return '' if transcript.blank? + transcript. gsub(%r(()[^<]+(<))i, '\1[FILTERED]\2'). gsub(%r(()[^<]+(<))i, '\1[FILTERED]\2'). @@ -95,8 +96,8 @@ def scrub(transcript) def add_metadata(xml, options) if options[:merchant_name] || options[:merchant_location] xml.tag! 'metadata' do - xml.tag! 'meta', :name => 'ca_name', :value => options[:merchant_name] if options[:merchant_name] - xml.tag! 'meta', :name => 'ca_location', :value => options[:merchant_location] if options[:merchant_location] + xml.tag! 'meta', name: 'ca_name', value: options[:merchant_name] if options[:merchant_name] + xml.tag! 'meta', name: 'ca_location', value: options[:merchant_location] if options[:merchant_location] end end end @@ -233,17 +234,15 @@ def commit(action, request) response = parse(ssl_post(test? ? self.test_url : self.live_url, build_request(action, request))) Response.new(success?(response), message_from(response), response, - :test => test?, - :authorization => authorization_from(action, response) - ) + test: test?, + authorization: authorization_from(action, response)) end def commit_periodic(action, request) response = parse(ssl_post(test? ? self.test_periodic_url : self.live_periodic_url, build_periodic_request(action, request))) Response.new(success?(response), message_from(response), response, - :test => test?, - :authorization => authorization_from(action, response) - ) + test: test?, + authorization: authorization_from(action, response)) end def success?(response) @@ -295,7 +294,6 @@ def generate_timestamp def request_timeout @options[:request_timeout] || 60 end - end end end diff --git a/lib/active_merchant/billing/gateways/ncr_secure_pay.rb b/lib/active_merchant/billing/gateways/ncr_secure_pay.rb index 1a595dd196d..4db01742e62 100644 --- a/lib/active_merchant/billing/gateways/ncr_secure_pay.rb +++ b/lib/active_merchant/billing/gateways/ncr_secure_pay.rb @@ -8,17 +8,17 @@ class NcrSecurePayGateway < Gateway self.supported_countries = ['US'] self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://www.ncrretailonline.com' self.display_name = 'NCR Secure Pay' - def initialize(options={}) + def initialize(options = {}) requires!(options, :username, :password) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) post = {} add_invoice(post, money, options) add_payment(post, payment) @@ -27,7 +27,7 @@ def purchase(money, payment, options={}) commit('sale', post) end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) post = {} add_invoice(post, money, options) add_payment(post, payment) @@ -36,7 +36,7 @@ def authorize(money, payment, options={}) commit('preauth', post) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) post = {} add_reference(post, authorization) add_invoice(post, money, options) @@ -44,7 +44,7 @@ def capture(money, authorization, options={}) commit('preauthcomplete', post) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) post = {} add_reference(post, authorization) add_invoice(post, money, options) @@ -52,13 +52,13 @@ def refund(money, authorization, options={}) commit('credit', post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} add_reference(post, authorization) commit('void', post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -141,7 +141,7 @@ def authorization_from(response) end def request_body(action, parameters = {}) - Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml| + Nokogiri::XML::Builder.new(encoding: 'utf-8') do |xml| xml.MonetraTrans do xml.Trans(identifier: parameters.delete(:identifier) || '1') do xml.username(options[:username]) @@ -156,9 +156,7 @@ def request_body(action, parameters = {}) end def error_code_from(response) - unless success_from(response) - response[:msoft_code] || response[:phard_code] - end + response[:msoft_code] || response[:phard_code] unless success_from(response) end end end diff --git a/lib/active_merchant/billing/gateways/net_registry.rb b/lib/active_merchant/billing/gateways/net_registry.rb index 8f199a88ca8..bb3c11d63f3 100644 --- a/lib/active_merchant/billing/gateways/net_registry.rb +++ b/lib/active_merchant/billing/gateways/net_registry.rb @@ -24,7 +24,7 @@ module Billing class NetRegistryGateway < Gateway self.live_url = self.test_url = 'https://paygate.ssllock.net/external2.pl' - FILTERED_PARAMS = [ 'card_no', 'card_expiry', 'receipt_array' ] + FILTERED_PARAMS = %w[card_no card_expiry receipt_array] self.supported_countries = ['AU'] @@ -32,16 +32,16 @@ class NetRegistryGateway < Gateway # steps in setting up your account, as detailed in # "Programming for NetRegistry's E-commerce Gateway." # [http://rubyurl.com/hNG] - self.supported_cardtypes = [:visa, :master, :diners_club, :american_express, :jcb] + self.supported_cardtypes = %i[visa master diners_club american_express jcb] self.display_name = 'NetRegistry' self.homepage_url = 'http://www.netregistry.com.au' TRANSACTIONS = { - :authorization => 'preauth', - :purchase => 'purchase', - :capture => 'completion', - :status => 'status', - :refund => 'refund' + authorization: 'preauth', + purchase: 'purchase', + capture: 'completion', + status: 'status', + refund: 'refund' } # Create a new NetRegistry gateway. @@ -145,8 +145,7 @@ def commit(action, params) response = parse(ssl_post(self.live_url, post_data(action, params))) Response.new(response['status'] == 'approved', message_from(response), response, - :authorization => authorization_from(response, action) - ) + authorization: authorization_from(response, action)) end def post_data(action, params) diff --git a/lib/active_merchant/billing/gateways/netaxept.rb b/lib/active_merchant/billing/gateways/netaxept.rb index 6681259e657..a3377284cc5 100644 --- a/lib/active_merchant/billing/gateways/netaxept.rb +++ b/lib/active_merchant/billing/gateways/netaxept.rb @@ -7,10 +7,10 @@ class NetaxeptGateway < Gateway self.live_url = 'https://epayment.bbs.no/' # The countries the gateway supports merchants from as 2 digit ISO country codes - self.supported_countries = ['NO', 'DK', 'SE', 'FI'] + self.supported_countries = %w[NO DK SE FI] # The card types supported by the payment gateway - self.supported_cardtypes = [:visa, :master, :american_express] + self.supported_cardtypes = %i[visa master american_express] # The homepage URL of the gateway self.homepage_url = 'http://www.betalingsterminal.no/Netthandel-forside/' @@ -94,12 +94,12 @@ def query_transaction(authorization, options) commit('Netaxept/query.aspx', post) end - def add_credentials(post, options, secure=true) + def add_credentials(post, options, secure = true) post[:merchantId] = @options[:login] post[:token] = @options[:password] if secure end - def add_authorization(post, authorization, money=nil) + def add_authorization(post, authorization, money = nil) post[:transactionId] = authorization post[:transactionAmount] = amount(money) if money end @@ -118,12 +118,12 @@ def add_creditcard(post, options) post[:securityCode] = options.verification_value end - def commit(path, parameters, xml=true) + def commit(path, parameters, xml = true) raw = parse(ssl_get(build_url(path, parameters)), xml) success = false authorization = (raw['TransactionId'] || parameters[:transactionId]) - if raw[:container] =~ /Exception|Error/ + if /Exception|Error/.match?(raw[:container]) message = (raw['Message'] || raw['Error']['Message']) elsif raw['Error'] && !raw['Error'].empty? message = (raw['Error']['ResponseText'] || raw['Error']['ResponseCode']) @@ -136,17 +136,17 @@ def commit(path, parameters, xml=true) success, message, raw, - :test => test?, - :authorization => authorization + test: test?, + authorization: authorization ) end - def parse(result, expects_xml=true) + def parse(result, expects_xml = true) if expects_xml doc = REXML::Document.new(result) - extract_xml(doc.root).merge(:container => doc.root.name) + extract_xml(doc.root).merge(container: doc.root.name) else - {:result => result} + { result: result } end end @@ -162,7 +162,7 @@ def extract_xml(element) end end - def build_url(base, parameters=nil) + def build_url(base, parameters = nil) url = (test? ? self.test_url : self.live_url).dup url << base if parameters diff --git a/lib/active_merchant/billing/gateways/netbanx.rb b/lib/active_merchant/billing/gateways/netbanx.rb index 88e53fe1298..b50053583df 100644 --- a/lib/active_merchant/billing/gateways/netbanx.rb +++ b/lib/active_merchant/billing/gateways/netbanx.rb @@ -7,14 +7,14 @@ class NetbanxGateway < Gateway self.supported_countries = %w(AF AX AL DZ AS AD AO AI AQ AG AR AM AW AU AT AZ BS BH BD BB BY BE BZ BJ BM BT BO BQ BA BW BV BR IO BN BG BF BI KH CM CA CV KY CF TD CL CN CX CC CO KM CG CD CK CR CI HR CU CW CY CZ DK DJ DM DO EC EG SV GQ ER EE ET FK FO FJ FI FR GF PF TF GA GM GE DE GH GI GR GL GD GP GU GT GG GN GW GY HT HM HN HK HU IS IN ID IR IQ IE IM IL IT JM JP JE JO KZ KE KI KP KR KW KG LA LV LB LS LR LY LI LT LU MO MK MG MW MY MV ML MT MH MQ MR MU YT MX FM MD MC MN ME MS MA MZ MM NA NR NP NC NZ NI NE NG NU NF MP NO OM PK PW PS PA PG PY PE PH PN PL PT PR QA RE RO RU RW BL SH KN LC MF VC WS SM ST SA SN RS SC SL SG SX SK SI SB SO ZA GS SS ES LK PM SD SR SJ SZ SE CH SY TW TJ TZ TH NL TL TG TK TO TT TN TR TM TC TV UG UA AE GB US UM UY UZ VU VA VE VN VG VI WF EH YE ZM ZW) self.default_currency = 'CAD' - self.supported_cardtypes = [ - :american_express, - :diners_club, - :discover, - :jcb, - :master, - :maestro, - :visa + self.supported_cardtypes = %i[ + american_express + diners_club + discover + jcb + master + maestro + visa ] self.money_format = :cents @@ -22,56 +22,98 @@ class NetbanxGateway < Gateway self.homepage_url = 'https://processing.paysafe.com/' self.display_name = 'Netbanx by PaySafe' - def initialize(options={}) + AVS_CODE_CONVERTER = { + 'MATCH' => 'X', + 'MATCH_ADDRESS_ONLY' => 'A', + 'MATCH_ZIP_ONLY' => 'Z', + 'NO_MATCH' => 'N', + 'NOT_PROCESSED' => 'U', + 'UNKNOWN' => 'Q' + } + + CVV_CODE_CONVERTER = { + 'MATCH' => 'M', + 'NO_MATCH' => 'N', + 'NOT_PROCESSED' => 'P', + 'UNKNOWN' => 'U' + } + + def initialize(options = {}) requires!(options, :account_number, :api_key) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) + # Do a Verification with AVS prior to purchase + verification_response = verify(payment, options) + return verification_response if verification_response.message != 'OK' + post = {} add_invoice(post, money, options) add_settle_with_auth(post) add_payment(post, payment, options) + add_customer_detail_data(post, options) commit(:post, 'auths', post) end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) + # Do a Verification with AVS prior to Auth + Settle + verification_response = verify(payment, options) + return verification_response if verification_response.message != 'OK' + post = {} add_invoice(post, money, options) add_payment(post, payment, options) + add_customer_detail_data(post, options) commit(:post, 'auths', post) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) post = {} add_invoice(post, money, options) commit(:post, "auths/#{authorization}/settlements", post) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) + # If the transactions that are pending, API call needs to be Cancellation + settlement_data = get_settlement(authorization) + return settlement_data if settlement_data.message != 'OK' + post = {} - add_invoice(post, money, options) + if settlement_data.params['status'] == 'PENDING' && money == settlement_data.params['amount'] + post[:status] = 'CANCELLED' + commit(:put, "settlements/#{authorization}", post) + elsif settlement_data.params['status'] == 'PENDING' && (money < settlement_data.params['amount'] || money > settlement_data.params['amount']) + return Response.new(false, 'Transaction not settled. Either do a full refund or try partial refund after settlement.') + else + add_invoice(post, money, options) + + # Setting merchantRefNumber to a unique id for each refund + # This is to support multiple partial refunds for the same order + post[:merchantRefNum] = SecureRandom.uuid - # Setting merchantRefNumber to a unique id for each refund - # This is to support multiple partial refunds for the same order - post[:merchantRefNum] = SecureRandom.uuid + commit(:post, "settlements/#{authorization}/refunds", post) + end + end - commit(:post, "settlements/#{authorization}/refunds", post) + def get_settlement(authorization) + post = {} + commit(:get, "settlements/#{authorization}", post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} add_order_id(post, options) commit(:post, "auths/#{authorization}/voidauths", post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) post = {} - add_payment(post, credit_card) + add_payment(post, credit_card, options) add_order_id(post, options) commit(:post, 'verifications', post) @@ -79,7 +121,7 @@ def verify(credit_card, options={}) # note: when passing options[:customer] we only attempt to add the # card to the profile_id passed as the options[:customer] - def store(credit_card, options={}) + def store(credit_card, options = {}) # locale can only be one of en_US, fr_CA, en_GB requires!(options, :locale) post = {} @@ -123,15 +165,24 @@ def add_customer_data(post, options) post[:locale] = options[:locale] end + def add_customer_detail_data(post, options) + post[:profile] ||= {} + post[:profile][:email] = options[:email] if options[:email] + post[:customerIp] = options[:ip] if options[:ip] + if (billing_address = options[:billing_address]) + post[:profile][:firstName], post[:profile][:lastName] = split_names(billing_address[:name]) + end + end + def add_credit_card(post, credit_card, options = {}) post[:card] ||= {} post[:card][:cardNum] = credit_card.number post[:card][:holderName] = credit_card.name post[:card][:cvv] = credit_card.verification_value post[:card][:cardExpiry] = expdate(credit_card) - if options[:billing_address] - post[:card][:billingAddress] = map_address(options[:billing_address]) - end + + post[:authentication] = map_3ds(options[:three_d_secure]) if options[:three_d_secure] + post[:card][:billingAddress] = map_address(options[:billing_address]) if options[:billing_address] end def add_invoice(post, money, options) @@ -139,18 +190,19 @@ def add_invoice(post, money, options) add_order_id(post, options) end - def add_payment(post, credit_card_or_reference, options = {}) + def add_payment(post, credit_card_reference, options = {}) post[:card] ||= {} - if credit_card_or_reference.is_a?(String) - post[:card][:paymentToken] = credit_card_or_reference + if credit_card_reference.is_a?(String) + post[:card][:paymentToken] = credit_card_reference else - post[:card][:cardNum] = credit_card_or_reference.number - post[:card][:cvv] = credit_card_or_reference.verification_value - post[:card][:cardExpiry] = expdate(credit_card_or_reference) + post[:card][:cardNum] = credit_card_reference.number + post[:card][:cvv] = credit_card_reference.verification_value + post[:card][:cardExpiry] = expdate(credit_card_reference) end post[:currencyCode] = options[:currency] if options[:currency] post[:billingDetails] = map_address(options[:billing_address]) if options[:billing_address] + post[:authentication] = map_3ds(options[:three_d_secure]) if options[:three_d_secure] end def expdate(credit_card) @@ -158,7 +210,7 @@ def expdate(credit_card) month = format(credit_card.month, :two_digits) # returns a hash (necessary in the card JSON object) - { :month => month, :year => year } + { month: month, year: year } end def add_order_id(post, options) @@ -167,45 +219,75 @@ def add_order_id(post, options) def map_address(address) return {} if address.nil? + country = Country.find(address[:country]) if address[:country] mapped = { - :street => address[:address1], - :city => address[:city], - :zip => address[:zip], - :state => address[:state], + street: address[:address1], + city: address[:city], + zip: address[:zip], + state: address[:state] } mapped[:country] = country.code(:alpha2).value unless country.blank? mapped end + def map_3ds(three_d_secure_options) + mapped = { + eci: three_d_secure_options[:eci], + cavv: three_d_secure_options[:cavv], + xid: three_d_secure_options[:xid], + threeDResult: three_d_secure_options[:directory_response_status], + threeDSecureVersion: three_d_secure_options[:version], + directoryServerTransactionId: three_d_secure_options[:ds_transaction_id] + } + + mapped + end + def parse(body) body.blank? ? {} : JSON.parse(body) end def commit(method, uri, parameters) params = parameters.to_json unless parameters.nil? - response = begin - parse(ssl_request(method, get_url(uri), params, headers)) - rescue ResponseError => e - return Response.new(false, 'Invalid Login') if(e.response.code == '401') - parse(e.response.body) - end + response = + begin + if method == :get + parse(ssl_request(method, get_url(uri), nil, headers)) + else + parse(ssl_request(method, get_url(uri), params, headers)) + end + rescue ResponseError => e + return Response.new(false, 'Invalid Login') if e.response.code == '401' + + parse(e.response.body) + end success = success_from(response) Response.new( success, message_from(success, response), response, - :test => test?, - :error_code => error_code_from(response), - :authorization => authorization_from(success, get_url(uri), method, response) + test: test?, + error_code: error_code_from(response), + authorization: authorization_from(success, get_url(uri), method, response), + avs_result: avs_result(response), + cvv_result: cvv_result(response) ) end + def avs_result(response) + AVSResult.new(code: AVS_CODE_CONVERTER[response['avsResponse']]) + end + + def cvv_result(response) + CVVResult.new(CVV_CODE_CONVERTER[response['cvvVerification']]) + end + def get_url(uri) url = (test? ? test_url : live_url) - if uri =~ /^customervault/ + if /^customervault/.match?(uri) "#{url}#{uri}" else "#{url}cardpayments/v1/accounts/#{@options[:account_number]}/#{uri}" diff --git a/lib/active_merchant/billing/gateways/netbilling.rb b/lib/active_merchant/billing/gateways/netbilling.rb index 296d9e198ad..08f0e57a398 100644 --- a/lib/active_merchant/billing/gateways/netbilling.rb +++ b/lib/active_merchant/billing/gateways/netbilling.rb @@ -14,16 +14,16 @@ class NetbillingGateway < Gateway self.live_url = self.test_url = 'https://secure.netbilling.com:1402/gw/sas/direct3.1' TRANSACTIONS = { - :authorization => 'A', - :purchase => 'S', - :refund => 'R', - :credit => 'C', - :capture => 'D', - :void => 'U', - :quasi => 'Q' + authorization: 'A', + purchase: 'S', + refund: 'R', + credit: 'C', + capture: 'D', + void: 'U', + quasi: 'Q' } - SUCCESS_CODES = [ '1', 'T' ] + SUCCESS_CODES = %w[1 T] SUCCESS_MESSAGE = 'The transaction was approved' FAILURE_MESSAGE = 'The transaction failed' TEST_LOGIN = '104901072025' @@ -31,7 +31,7 @@ class NetbillingGateway < Gateway self.display_name = 'NETbilling' self.homepage_url = 'http://www.netbilling.com' self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club] + self.supported_cardtypes = %i[visa master american_express discover jcb diners_club] def initialize(options = {}) requires!(options, :login) @@ -166,9 +166,7 @@ def add_payment_source(params, source) end def add_user_data(post, options) - if options[:order_id] - post[:user_data] = "order_id:#{options[:order_id]}" - end + post[:user_data] = "order_id:#{options[:order_id]}" if options[:order_id] end def add_transaction_id(post, transaction_id) @@ -196,14 +194,14 @@ def commit(action, parameters) response = parse(ssl_post(self.live_url, post_data(action, parameters))) Response.new(success?(response), message_from(response), response, - :test => test_response?(response), - :authorization => response[:trans_id], - :avs_result => { :code => response[:avs_code]}, - :cvv_result => response[:cvv2_code] - ) + test: test_response?(response), + authorization: response[:trans_id], + avs_result: { code: response[:avs_code] }, + cvv_result: response[:cvv2_code]) rescue ActiveMerchant::ResponseError => e - raise unless(e.response.code =~ /^[67]\d\d$/) - return Response.new(false, e.response.message, {:status_code => e.response.code}, :test => test?) + raise unless e.response.code =~ /^[67]\d\d$/ + + return Response.new(false, e.response.message, { status_code: e.response.code }, test: test?) end def test_response?(response) @@ -224,9 +222,8 @@ def post_data(action, parameters = {}) parameters[:pay_type] = 'C' parameters[:tran_type] = TRANSACTIONS[action] - parameters.reject { |k, v| v.blank? }.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join('&') + parameters.reject { |_k, v| v.blank? }.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join('&') end - end end end diff --git a/lib/active_merchant/billing/gateways/netpay.rb b/lib/active_merchant/billing/gateways/netpay.rb index 48e2a0a14d5..8c2ba44cb30 100644 --- a/lib/active_merchant/billing/gateways/netpay.rb +++ b/lib/active_merchant/billing/gateways/netpay.rb @@ -42,7 +42,7 @@ class NetpayGateway < Gateway self.default_currency = 'MXN' # The card types supported by the payment gateway - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club] + self.supported_cardtypes = %i[visa master american_express diners_club] # The homepage URL of the gateway self.homepage_url = 'http://www.netpay.com.mx' @@ -55,7 +55,7 @@ class NetpayGateway < Gateway } # The header keys that we will provide in the response params hash - RESPONSE_KEYS = ['ResponseMsg', 'ResponseText', 'ResponseCode', 'TimeIn', 'TimeOut', 'AuthCode', 'OrderId', 'CardTypeName', 'MerchantId', 'IssuerAuthDate'] + RESPONSE_KEYS = %w[ResponseMsg ResponseText ResponseCode TimeIn TimeOut AuthCode OrderId CardTypeName MerchantId IssuerAuthDate] def initialize(options = {}) requires!(options, :store_id, :login, :password) @@ -180,8 +180,8 @@ def parse(response, request_params) success = (response_params['ResponseCode'] == '00') message = response_params['ResponseText'] || response_params['ResponseMsg'] - options = @options.merge(:test => test?, - :authorization => build_authorization(request_params, response_params)) + options = @options.merge(test: test?, + authorization: build_authorization(request_params, response_params)) Response.new(success, message, response_params, options) end @@ -215,6 +215,7 @@ def params_from_response(response) def currency_code(currency) return currency if currency =~ /^\d+$/ + CURRENCY_CODES[currency] end end diff --git a/lib/active_merchant/billing/gateways/network_merchants.rb b/lib/active_merchant/billing/gateways/network_merchants.rb index aadc09d425f..4c1c2ef16d5 100644 --- a/lib/active_merchant/billing/gateways/network_merchants.rb +++ b/lib/active_merchant/billing/gateways/network_merchants.rb @@ -4,7 +4,7 @@ class NetworkMerchantsGateway < Gateway self.live_url = self.test_url = 'https://secure.networkmerchants.com/api/transact.php' self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://www.nmi.com/' self.display_name = 'Network Merchants (NMI)' @@ -190,7 +190,7 @@ def add_amount(post, money, options) end def commit_vault(action, parameters) - commit(nil, parameters.merge(:customer_vault => action)) + commit(nil, parameters.merge(customer_vault: action)) end def commit(action, parameters) @@ -201,11 +201,10 @@ def commit(action, parameters) authorization = authorization_from(success, parameters, raw) Response.new(success, raw['responsetext'], raw, - :test => test?, - :authorization => authorization, - :avs_result => { :code => raw['avsresponse']}, - :cvv_result => raw['cvvresponse'] - ) + test: test?, + authorization: authorization, + avs_result: { code: raw['avsresponse'] }, + cvv_result: raw['cvvresponse']) end def build_request(action, parameters) @@ -218,9 +217,7 @@ def authorization_from(success, parameters, response) return nil unless success authorization = response['transactionid'] - if(parameters[:customer_vault] && (authorization.nil? || authorization.empty?)) - authorization = response['customer_vault_id'] - end + authorization = response['customer_vault_id'] if parameters[:customer_vault] && (authorization.nil? || authorization.empty?) authorization end diff --git a/lib/active_merchant/billing/gateways/nmi.rb b/lib/active_merchant/billing/gateways/nmi.rb index 7d5339d6d70..44d6c86daeb 100644 --- a/lib/active_merchant/billing/gateways/nmi.rb +++ b/lib/active_merchant/billing/gateways/nmi.rb @@ -9,7 +9,7 @@ class NmiGateway < Gateway self.default_currency = 'USD' self.money_format = :dollars self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://nmi.com/' self.display_name = 'NMI' @@ -27,7 +27,7 @@ def initialize(options = {}) super end - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method, options) @@ -36,11 +36,12 @@ def purchase(amount, payment_method, options={}) add_vendor_data(post, options) add_merchant_defined_fields(post, options) add_level3_fields(post, options) + add_three_d_secure(post, options) commit('sale', post) end - def authorize(amount, payment_method, options={}) + def authorize(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method, options) @@ -49,11 +50,12 @@ def authorize(amount, payment_method, options={}) add_vendor_data(post, options) add_merchant_defined_fields(post, options) add_level3_fields(post, options) + add_three_d_secure(post, options) commit('auth', post) end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) post = {} add_invoice(post, amount, options) add_reference(post, authorization) @@ -62,7 +64,7 @@ def capture(amount, authorization, options={}) commit('capture', post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} add_reference(post, authorization) add_payment_type(post, authorization) @@ -70,7 +72,7 @@ def void(authorization, options={}) commit('void', post) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) post = {} add_invoice(post, amount, options) add_reference(post, authorization) @@ -79,7 +81,7 @@ def refund(amount, authorization, options={}) commit('refund', post) end - def credit(amount, payment_method, options={}) + def credit(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method, options) @@ -90,7 +92,7 @@ def credit(amount, payment_method, options={}) commit('credit', post) end - def verify(payment_method, options={}) + def verify(payment_method, options = {}) post = {} add_payment_method(post, payment_method, options) add_customer_data(post, options) @@ -138,7 +140,7 @@ def supports_network_tokenization? private def add_level3_fields(post, options) - add_fields_to_post_if_present(post, options, [:tax, :shipping, :ponumber]) + add_fields_to_post_if_present(post, options, %i[tax shipping ponumber]) end def add_invoice(post, money, options) @@ -153,14 +155,14 @@ def add_invoice(post, money, options) end def add_payment_method(post, payment_method, options) - if(payment_method.is_a?(String)) - customer_vault_id, _ = split_authorization(payment_method) + if payment_method.is_a?(String) + customer_vault_id, = split_authorization(payment_method) post[:customer_vault_id] = customer_vault_id elsif payment_method.is_a?(NetworkTokenizationCreditCard) post[:ccnumber] = payment_method.number post[:ccexp] = exp_date(payment_method) post[:token_cryptogram] = payment_method.payment_cryptogram - elsif(card_brand(payment_method) == 'check') + elsif card_brand(payment_method) == 'check' post[:payment] = 'check' post[:firstname] = payment_method.first_name post[:lastname] = payment_method.last_name @@ -213,25 +215,25 @@ def add_customer_data(post, options) post[:ipaddress] = options[:ip] post[:customer_id] = options[:customer_id] || options[:customer] - if(billing_address = options[:billing_address] || options[:address]) + if (billing_address = options[:billing_address] || options[:address]) post[:company] = billing_address[:company] post[:address1] = billing_address[:address1] post[:address2] = billing_address[:address2] post[:city] = billing_address[:city] post[:state] = billing_address[:state] post[:country] = billing_address[:country] - post[:zip] = billing_address[:zip] + post[:zip] = billing_address[:zip] post[:phone] = billing_address[:phone] end - if(shipping_address = options[:shipping_address]) + if (shipping_address = options[:shipping_address]) post[:shipping_company] = shipping_address[:company] post[:shipping_address1] = shipping_address[:address1] post[:shipping_address2] = shipping_address[:address2] post[:shipping_city] = shipping_address[:city] post[:shipping_state] = shipping_address[:state] post[:shipping_country] = shipping_address[:country] - post[:shipping_zip] = shipping_address[:zip] + post[:shipping_zip] = shipping_address[:zip] post[:shipping_phone] = shipping_address[:phone] end end @@ -248,8 +250,20 @@ def add_merchant_defined_fields(post, options) end end + def add_three_d_secure(post, options) + return unless options[:three_d_secure] + + if (three_d_secure = options[:three_d_secure]) + post[:eci] = three_d_secure[:eci] + post[:cavv] = three_d_secure[:cavv] + post[:xid] = three_d_secure[:xid] + post[:three_ds_version] = three_d_secure[:version] + post[:directory_server_id] = three_d_secure[:ds_transaction_id] + end + end + def add_reference(post, authorization) - transaction_id, _ = split_authorization(authorization) + transaction_id, = split_authorization(authorization) post[:transactionid] = transaction_id end @@ -284,7 +298,7 @@ def commit(action, params) def authorization_from(response, payment_type, action) authorization = (action == 'add_customer' ? response[:customer_vault_id] : response[:transactionid]) - [ authorization, payment_type ].join('#') + [authorization, payment_type].join('#') end def split_authorization(authorization) @@ -292,7 +306,7 @@ def split_authorization(authorization) end def headers - { 'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8' } + { 'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8' } end def post_data(action, params) @@ -318,7 +332,6 @@ def message_from(succeeded, response) response[:responsetext] end end - end end end diff --git a/lib/active_merchant/billing/gateways/ogone.rb b/lib/active_merchant/billing/gateways/ogone.rb index 883ac94a05a..3223f5f41c8 100644 --- a/lib/active_merchant/billing/gateways/ogone.rb +++ b/lib/active_merchant/billing/gateways/ogone.rb @@ -122,10 +122,10 @@ class OgoneGateway < Gateway SUCCESS_MESSAGE = 'The transaction was successful' - THREE_D_SECURE_DISPLAY_WAYS = { :main_window => 'MAINW', # display the identification page in the main window (default value). + THREE_D_SECURE_DISPLAY_WAYS = { main_window: 'MAINW', # display the identification page in the main window (default value). - :pop_up => 'POPUP', # display the identification page in a pop-up window and return to the main window at the end. - :pop_ix => 'POPIX' } # display the identification page in a pop-up window and remain in the pop-up window. + pop_up: 'POPUP', # display the identification page in a pop-up window and return to the main window at the end. + pop_ix: 'POPIX' } # display the identification page in a pop-up window and remain in the pop-up window. OGONE_NO_SIGNATURE_DEPRECATION_MESSAGE = 'Signature usage will be the default for a future release of ActiveMerchant. You should either begin using it, or update your configuration to explicitly disable it (signature_encryptor: none)' OGONE_STORE_OPTION_DEPRECATION_MESSAGE = "The 'store' option has been renamed to 'billing_id', and its usage is deprecated." @@ -133,9 +133,9 @@ class OgoneGateway < Gateway self.test_url = 'https://secure.ogone.com/ncol/test/' self.live_url = 'https://secure.ogone.com/ncol/prod/' - self.supported_countries = ['BE', 'DE', 'FR', 'NL', 'AT', 'CH'] + self.supported_countries = %w[BE DE FR NL AT CH] # also supports Airplus and UATP - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :discover, :jcb, :maestro] + self.supported_cardtypes = %i[visa master american_express diners_club discover jcb maestro] self.homepage_url = 'http://www.ogone.com/' self.display_name = 'Ogone' self.default_currency = 'EUR' @@ -204,7 +204,7 @@ def refund(money, reference, options = {}) perform_reference_credit(money, reference, options) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -213,7 +213,7 @@ def verify(credit_card, options={}) # Store a credit card by creating an Ogone Alias def store(payment_source, options = {}) - options[:alias_operation] = 'BYPSP' unless(options.has_key?(:billing_id) || options.has_key?(:store)) + options[:alias_operation] = 'BYPSP' unless options.has_key?(:billing_id) || options.has_key?(:store) response = authorize(@options[:store_amount] || 1, payment_source, options) void(response.authorization) if response.success? response @@ -239,6 +239,7 @@ def reference_from(authorization) def reference_transaction?(identifier) return false unless identifier.is_a?(String) + _, action = identifier.split(';') !action.nil? end @@ -291,7 +292,7 @@ def add_d3d(post, options) add_pair post, 'DECLINEURL', options[:decline_url] if options[:decline_url] add_pair post, 'EXCEPTIONURL', options[:exception_url] if options[:exception_url] add_pair post, 'CANCELURL', options[:cancel_url] if options[:cancel_url] - add_pair post, 'PARAMVAR', options[:paramvar] if options[:paramvar] + add_pair post, 'PARAMVAR', options[:paramvar] if options[:paramvar] add_pair post, 'PARAMPLUS', options[:paramplus] if options[:paramplus] add_pair post, 'COMPLUS', options[:complus] if options[:complus] add_pair post, 'LANGUAGE', options[:language] if options[:language] @@ -322,6 +323,7 @@ def add_customer_data(post, options) def add_address(post, creditcard, options) return unless options[:billing_address] + add_pair post, 'Owneraddress', options[:billing_address][:address1] add_pair post, 'OwnerZip', options[:billing_address][:zip] add_pair post, 'ownertown', options[:billing_address][:city] @@ -364,10 +366,10 @@ def commit(action, parameters) response = parse(ssl_post(url(parameters['PAYID']), post_data(action, parameters))) options = { - :authorization => [response['PAYID'], action].join(';'), - :test => test?, - :avs_result => { :code => AVS_MAPPING[response['AAVCheck']] }, - :cvv_result => CVV_MAPPING[response['CVCCheck']] + authorization: [response['PAYID'], action].join(';'), + test: test?, + avs_result: { code: AVS_MAPPING[response['AAVCheck']] }, + cvv_result: CVV_MAPPING[response['CVCCheck']] } OgoneResponse.new(successful?(response), message_from(response), response, options) end @@ -408,7 +410,7 @@ def post_data(action, parameters = {}) def add_signature(parameters) if @options[:signature].blank? - ActiveMerchant.deprecated(OGONE_NO_SIGNATURE_DEPRECATION_MESSAGE) unless(@options[:signature_encryptor] == 'none') + ActiveMerchant.deprecated(OGONE_NO_SIGNATURE_DEPRECATION_MESSAGE) unless @options[:signature_encryptor] == 'none' return end @@ -418,20 +420,21 @@ def add_signature(parameters) def calculate_signature(signed_parameters, algorithm, secret) return legacy_calculate_signature(signed_parameters, secret) unless algorithm - sha_encryptor = case algorithm - when 'sha256' - Digest::SHA256 - when 'sha512' - Digest::SHA512 - when 'sha1' - Digest::SHA1 - else - raise "Unknown signature algorithm #{algorithm}" - end + sha_encryptor = + case algorithm + when 'sha256' + Digest::SHA256 + when 'sha512' + Digest::SHA512 + when 'sha1' + Digest::SHA1 + else + raise "Unknown signature algorithm #{algorithm}" + end - filtered_params = signed_parameters.select { |k, v| !v.blank? } + filtered_params = signed_parameters.select { |_k, v| !v.blank? } sha_encryptor.hexdigest( - filtered_params.sort_by { |k, v| k.upcase }.map { |k, v| "#{k.upcase}=#{v}#{secret}" }.join('') + filtered_params.sort_by { |k, _v| k.upcase }.map { |k, v| "#{k.upcase}=#{v}#{secret}" }.join('') ).upcase end diff --git a/lib/active_merchant/billing/gateways/omise.rb b/lib/active_merchant/billing/gateways/omise.rb index 218b099590f..a53880fe4f4 100644 --- a/lib/active_merchant/billing/gateways/omise.rb +++ b/lib/active_merchant/billing/gateways/omise.rb @@ -21,13 +21,13 @@ class OmiseGateway < Gateway # Country supported by Omise # * Thailand - self.supported_countries = %w( TH JP ) + self.supported_countries = %w(TH JP) # Credit cards supported by Omise # * VISA # * MasterCard # * JCB - self.supported_cardtypes = [:visa, :master, :jcb] + self.supported_cardtypes = %i[visa master jcb] # Omise main page self.homepage_url = 'https://www.omise.co/' @@ -46,7 +46,7 @@ class OmiseGateway < Gateway # * :api_version -- Omise's API Version (OPTIONAL), default version is '2014-07-27' # See version at page https://dashboard.omise.co/api-version/edit - def initialize(options={}) + def initialize(options = {}) requires!(options, :public_key, :secret_key) @public_key = options[:public_key] @secret_key = options[:secret_key] @@ -79,7 +79,7 @@ def initialize(options={}) # # purchase(money, nil, { :customer_id => customer_id }) - def purchase(money, payment_method, options={}) + def purchase(money, payment_method, options = {}) create_charge(money, payment_method, options) end @@ -91,7 +91,7 @@ def purchase(money, payment_method, options={}) # * payment_method -- The CreditCard object # * options -- An optional parameters, such as token or capture - def authorize(money, payment_method, options={}) + def authorize(money, payment_method, options = {}) options[:capture] = 'false' create_charge(money, payment_method, options) end @@ -104,7 +104,7 @@ def authorize(money, payment_method, options={}) # * charge_id -- The CreditCard object # * options -- An optional parameters, such as token or capture - def capture(money, charge_id, options={}) + def capture(money, charge_id, options = {}) post = {} add_amount(post, money, options) commit(:post, "charges/#{CGI.escape(charge_id)}/capture", post, options) @@ -118,7 +118,7 @@ def capture(money, charge_id, options={}) # * charge_id -- The CreditCard object # * options -- An optional parameters, such as token or capture - def refund(money, charge_id, options={}) + def refund(money, charge_id, options = {}) options[:amount] = money if money commit(:post, "charges/#{CGI.escape(charge_id)}/refunds", options) end @@ -132,7 +132,7 @@ def refund(money, charge_id, options={}) # 'email' (A customer email) # 'description' (A customer description) - def store(payment_method, options={}) + def store(payment_method, options = {}) post, card_params = {}, {} add_customer_data(post, options) add_token(card_params, payment_method, options) @@ -145,7 +145,7 @@ def store(payment_method, options={}) # # * customer_id -- The Customer identifier (REQUIRED). - def unstore(customer_id, options={}) + def unstore(customer_id, options = {}) commit(:delete, "customers/#{CGI.escape(customer_id)}") end @@ -178,7 +178,7 @@ def create_charge(money, payment_method, options) commit(:post, 'charges', post, options) end - def headers(options={}) + def headers(options = {}) key = options[:key] || @secret_key { 'Content-Type' => 'application/json;utf-8', @@ -197,7 +197,7 @@ def post_data(parameters) parameters.present? ? parameters.to_json : nil end - def https_request(method, endpoint, parameters=nil, options={}) + def https_request(method, endpoint, parameters = nil, options = {}) raw_response = response = nil begin raw_response = ssl_request(method, url_for(endpoint), post_data(parameters), headers(options)) @@ -221,7 +221,7 @@ def json_error(raw_response) { message: msg } end - def commit(method, endpoint, params=nil, options={}) + def commit(method, endpoint, params = nil, options = {}) response = https_request(method, endpoint, params, options) Response.new( successful?(response), @@ -284,7 +284,7 @@ def get_token(post, credit_card) commit(:post, 'tokens', post, { key: @public_key }) end - def add_token(post, credit_card, options={}) + def add_token(post, credit_card, options = {}) if options[:token_id].present? post[:card] = options[:token_id] else @@ -304,11 +304,11 @@ def add_creditcard(post, payment_method) post[:card] = card end - def add_customer(post, options={}) + def add_customer(post, options = {}) post[:customer] = options[:customer_id] if options[:customer_id] end - def add_customer_data(post, options={}) + def add_customer_data(post, options = {}) post[:description] = options[:description] if options[:description] post[:email] = options[:email] if options[:email] end @@ -318,7 +318,6 @@ def add_amount(post, money, options) post[:currency] = (options[:currency] || currency(money)) post[:description] = options[:description] if options.key?(:description) end - end end end diff --git a/lib/active_merchant/billing/gateways/openpay.rb b/lib/active_merchant/billing/gateways/openpay.rb index 166f1f44b43..630e0ca111d 100644 --- a/lib/active_merchant/billing/gateways/openpay.rb +++ b/lib/active_merchant/billing/gateways/openpay.rb @@ -4,8 +4,8 @@ class OpenpayGateway < Gateway self.live_url = 'https://api.openpay.mx/v1/' self.test_url = 'https://sandbox-api.openpay.mx/v1/' - self.supported_countries = ['MX'] - self.supported_cardtypes = [:visa, :master, :american_express, :carnet] + self.supported_countries = %w(CO MX) + self.supported_cardtypes = %i[visa master american_express carnet] self.homepage_url = 'http://www.openpay.mx/' self.display_name = 'Openpay' self.default_currency = 'MXN' @@ -75,7 +75,7 @@ def store(creditcard, options = {}) MultiResponse.run(:first) do |r| r.process { commit(:post, 'customers', post, options) } - if(r.success? && !r.params['id'].blank?) + if r.success? && !r.params['id'].blank? customer_id = r.params['id'] r.process { commit(:post, "customers/#{customer_id}/cards", card, options) } end @@ -116,7 +116,7 @@ def create_post_for_auth_or_purchase(money, creditcard, options) post[:device_session_id] = options[:device_session_id] post[:currency] = (options[:currency] || currency(money)).upcase post[:use_card_points] = options[:use_card_points] if options[:use_card_points] - post[:payment_plan] = {payments: options[:payments]} if options[:payments] + post[:payment_plan] = { payments: options[:payments] } if options[:payments] add_creditcard(post, creditcard, options) post end @@ -151,6 +151,7 @@ def add_customer_data(post, creditcard, options) def add_address(card, options) return unless card.kind_of?(Hash) + if address = (options[:billing_address] || options[:address]) card[:address] = { line1: address[:address1], @@ -175,6 +176,7 @@ def headers(options = {}) def parse(body) return {} unless body + JSON.parse(body) end @@ -185,12 +187,11 @@ def commit(method, resource, parameters, options = {}) Response.new(success, (success ? response['error_code'] : response['description']), response, - :test => test?, - :authorization => response['id'] - ) + test: test?, + authorization: response['id']) end - def http_request(method, resource, parameters={}, options={}) + def http_request(method, resource, parameters = {}, options = {}) url = (test? ? self.test_url : self.live_url) + @merchant_id + '/' + resource raw_response = nil begin @@ -218,9 +219,9 @@ def json_error(raw_response) msg = 'Invalid response received from the Openpay API. Please contact soporte@openpay.mx if you continue to receive this message.' msg += " (The raw response returned by the API was #{raw_response.inspect})" { - 'category' => 'request', - 'error_code' => '9999', - 'description' => msg + 'category' => 'request', + 'error_code' => '9999', + 'description' => msg } end end diff --git a/lib/active_merchant/billing/gateways/opp.rb b/lib/active_merchant/billing/gateways/opp.rb index cdd4900e729..8dc6acf83ff 100644 --- a/lib/active_merchant/billing/gateways/opp.rb +++ b/lib/active_merchant/billing/gateways/opp.rb @@ -13,8 +13,7 @@ class OppGateway < Gateway # == Usage # # gateway = ActiveMerchant::Billing::OppGateway.new( - # user_id: 'merchant user id', - # password: 'password', + # access_token: 'access_token', # entity_id: 'entity id', # ) # @@ -113,46 +112,44 @@ class OppGateway < Gateway self.supported_countries = %w(AD AI AG AR AU AT BS BB BE BZ BM BR BN BG CA HR CY CZ DK DM EE FI FR DE GR GD GY HK HU IS IN IL IT JP LV LI LT LU MY MT MX MC MS NL PA PL PT KN LC MF VC SM SG SK SI ZA ES SR SE CH TR GB US UY) self.default_currency = 'EUR' - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :discover, :jcb, :maestro, :dankort] + self.supported_cardtypes = %i[visa master american_express diners_club discover jcb maestro dankort] self.homepage_url = 'https://docs.oppwa.com' self.display_name = 'Open Payment Platform' - def initialize(options={}) - requires!(options, :user_id, :password, :entity_id) + def initialize(options = {}) + requires!(options, :access_token, :entity_id) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) # debit - if payment.is_a?(String) - options[:registrationId] = payment - end - execute_dbpa(options[:risk_workflow] ? 'PA.CP': 'DB', + options[:registrationId] = payment if payment.is_a?(String) + execute_dbpa(options[:risk_workflow] ? 'PA.CP' : 'DB', money, payment, options) end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) # preauthorization PA execute_dbpa('PA', money, payment, options) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) # capture CP execute_referencing('CP', money, authorization, options) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) # refund RF execute_referencing('RF', money, authorization, options) end - def void(authorization, options={}) + def void(authorization, options = {}) # reversal RV execute_referencing('RV', nil, authorization, options) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -169,7 +166,7 @@ def supports_scrubbing? def scrub(transcript) transcript. - gsub(%r((authentication\.password=)\w+), '\1[FILTERED]'). + gsub(%r((Authorization: Bearer )\w+)i, '\1[FILTERED]'). gsub(%r((card\.number=)\d+), '\1[FILTERED]'). gsub(%r((card\.cvv=)\d+), '\1[FILTERED]') end @@ -205,7 +202,7 @@ def execute_referencing(txtype, money, authorization, options) end def add_authentication(post) - post[:authentication] = { entityId: @options[:entity_id], password: @options[:password], userId: @options[:user_id]} + post[:authentication] = { entityId: @options[:entity_id] } end def add_customer_data(post, payment, options) @@ -246,7 +243,7 @@ def address(post, address, prefix) city: address[:city], state: address[:state], postcode: address[:zip], - country: address[:country], + country: address[:country] } end @@ -260,9 +257,10 @@ def add_invoice(post, money, options) def add_payment_method(post, payment, options) return if payment.is_a?(String) + if options[:registrationId] post[:card] = { - cvv: payment.verification_value, + cvv: payment.verification_value } else post[:paymentBrand] = payment.brand.upcase @@ -271,7 +269,7 @@ def add_payment_method(post, payment, options) number: payment.number, expiryMonth: '%02d' % payment.month, expiryYear: payment.year, - cvv: payment.verification_value, + cvv: payment.verification_value } end end @@ -289,7 +287,7 @@ def add_3d_secure(post, options) def add_options(post, options) post[:createRegistration] = options[:create_registration] if options[:create_registration] && !options[:registrationId] post[:testMode] = options[:test_mode] if test? && options[:test_mode] - options.each { |key, value| post[key] = value if key.to_s.match('customParameters\[[a-zA-Z0-9\._]{3,64}\]') } + options.each { |key, value| post[key] = value if key.to_s =~ /'customParameters\[[a-zA-Z0-9\._]{3,64}\]'/ } post['customParameters[SHOPPER_pluginId]'] = 'activemerchant' post['customParameters[custom_disable3DSecure]'] = options[:disable_3d_secure] if options[:disable_3d_secure] end @@ -311,17 +309,18 @@ def commit(post, authorization, options) add_authentication(post) post = flatten_hash(post) - response = begin - parse( - ssl_post( - url, - post.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join('&'), - 'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8' + response = + begin + parse( + ssl_post( + url, + post.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join('&'), + headers + ) ) - ) - rescue ResponseError => e - parse(e.response.body) - end + rescue ResponseError => e + parse(e.response.body) + end success = success_from(response) @@ -335,6 +334,13 @@ def commit(post, authorization, options) ) end + def headers + { + 'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8', + 'Authorization' => "Bearer #{@options[:access_token]}" + } + end + def parse(body) JSON.parse(body) rescue JSON::ParserError @@ -343,7 +349,7 @@ def parse(body) def json_error(body) message = "Invalid response received #{body.inspect}" - { 'result' => {'description' => message, 'code' => 'unknown' } } + { 'result' => { 'description' => message, 'code' => 'unknown' } } end def success_from(response) @@ -351,7 +357,7 @@ def success_from(response) success_regex = /^(000\.000\.|000\.100\.1|000\.[36])/ - if success_regex =~ response['result']['code'] + if success_regex.match?(response['result']['code']) true else false diff --git a/lib/active_merchant/billing/gateways/optimal_payment.rb b/lib/active_merchant/billing/gateways/optimal_payment.rb index 30f7bf57e02..d6832282535 100644 --- a/lib/active_merchant/billing/gateways/optimal_payment.rb +++ b/lib/active_merchant/billing/gateways/optimal_payment.rb @@ -5,12 +5,12 @@ class OptimalPaymentGateway < Gateway self.live_url = 'https://webservices.optimalpayments.com/creditcardWS/CreditCardServlet/v1' # The countries the gateway supports merchants from as 2 digit ISO country codes - self.supported_countries = ['CA', 'US', 'GB', 'AU', 'AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', - 'EE', 'FI', 'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', - 'NL', 'NO', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'CH'] + self.supported_countries = %w[CA US GB AU AT BE BG HR CY CZ DK + EE FI DE GR HU IE IT LV LT LU MT + NL NO PL PT RO SK SI ES SE CH] # The card types supported by the payment gateway - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club] + self.supported_cardtypes = %i[visa master american_express discover diners_club] # The homepage URL of the gateway self.homepage_url = 'http://www.optimalpayments.com/' @@ -19,12 +19,12 @@ class OptimalPaymentGateway < Gateway self.display_name = 'Optimal Payments' def initialize(options = {}) - if(options[:login]) + if options[:login] ActiveMerchant.deprecated("The 'login' option is deprecated in favor of 'store_id' and will be removed in a future version.") options[:store_id] = options[:login] end - if(options[:account]) + if options[:account] ActiveMerchant.deprecated("The 'account' option is deprecated in favor of 'account_number' and will be removed in a future version.") options[:account_number] = options[:account] end @@ -65,6 +65,10 @@ def verify(credit_card, options = {}) commit('ccVerification', 0, options) end + def store(credit_card, options = {}) + verify(credit_card, options) + end + def supports_scrubbing? true end @@ -95,33 +99,33 @@ def parse(body) def commit(action, money, post) post[:order_id] ||= 'order_id' - xml = case action - when 'ccAuthorize', 'ccPurchase', 'ccVerification' - cc_auth_request(money, post) - when 'ccCredit', 'ccSettlement' - cc_post_auth_request(money, post) - when 'ccStoredDataAuthorize', 'ccStoredDataPurchase' - cc_stored_data_request(money, post) - when 'ccAuthorizeReversal' - cc_auth_reversal_request(post) - # when 'ccCancelSettle', 'ccCancelCredit', 'ccCancelPayment' - # cc_cancel_request(money, post) - # when 'ccPayment' - # cc_payment_request(money, post) - # when 'ccAuthenticate' - # cc_authenticate_request(money, post) - else - raise 'Unknown Action' - end + xml = + case action + when 'ccAuthorize', 'ccPurchase', 'ccVerification' + cc_auth_request(money, post) + when 'ccCredit', 'ccSettlement' + cc_post_auth_request(money, post) + when 'ccStoredDataAuthorize', 'ccStoredDataPurchase' + cc_stored_data_request(money, post) + when 'ccAuthorizeReversal' + cc_auth_reversal_request(post) + # when 'ccCancelSettle', 'ccCancelCredit', 'ccCancelPayment' + # cc_cancel_request(money, post) + # when 'ccPayment' + # cc_payment_request(money, post) + # when 'ccAuthenticate' + # cc_authenticate_request(money, post) + else + raise 'Unknown Action' + end txnRequest = escape_uri(xml) response = parse(ssl_post(test? ? self.test_url : self.live_url, "txnMode=#{action}&txnRequest=#{txnRequest}")) Response.new(successful?(response), message_from(response), hash_from_xml(response), - :test => test?, - :authorization => authorization_from(response), - :avs_result => { :code => avs_result_from(response) }, - :cvv_result => cvv_result_from(response) - ) + test: test?, + authorization: authorization_from(response), + avs_result: { code: avs_result_from(response) }, + cvv_result: cvv_result_from(response)) end # The upstream is picky and so we can't use CGI.escape like we want to @@ -135,9 +139,7 @@ def successful?(response) def message_from(response) REXML::XPath.each(response, '//detail') do |detail| - if detail.is_a?(REXML::Element) && detail.elements['tag'].text == 'InternalResponseDescription' - return detail.elements['value'].text - end + return detail.elements['value'].text if detail.is_a?(REXML::Element) && detail.elements['tag'].text == 'InternalResponseDescription' end nil end @@ -159,13 +161,13 @@ def hash_from_xml(response) %w(confirmationNumber authCode decision code description actionCode avsResponse cvdResponse - txnTime duplicateFound - ).each do |tag| + txnTime duplicateFound).each do |tag| node = REXML::XPath.first(response, "//#{tag}") hsh[tag] = node.text if node end REXML::XPath.each(response, '//detail') do |detail| next unless detail.is_a?(REXML::Element) + tag = detail.elements['tag'].text value = detail.elements['value'].text hsh[tag] = value @@ -174,7 +176,7 @@ def hash_from_xml(response) end def xml_document(root_tag) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.tag!(root_tag, schema) do yield xml end @@ -190,7 +192,7 @@ def cc_auth_request(money, opts) xml_document('ccAuthRequestV1') do |xml| build_merchant_account(xml) xml.merchantRefNum opts[:order_id] - xml.amount(money/100.0) + xml.amount(money / 100.0) build_card(xml, opts) build_billing_details(xml, opts) build_shipping_details(xml, opts) @@ -211,7 +213,7 @@ def cc_post_auth_request(money, opts) build_merchant_account(xml) xml.confirmationNumber opts[:confirmationNumber] xml.merchantRefNum opts[:order_id] - xml.amount(money/100.0) + xml.amount(money / 100.0) end end @@ -220,7 +222,7 @@ def cc_stored_data_request(money, opts) build_merchant_account(xml) xml.merchantRefNum opts[:order_id] xml.confirmationNumber opts[:confirmationNumber] - xml.amount(money/100.0) + xml.amount(money / 100.0) end end @@ -254,8 +256,7 @@ def cc_stored_data_request(money, opts) def schema { 'xmlns' => 'http://www.optimalpayments.com/creditcard/xmlschema/v1', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', - 'xsi:schemaLocation' => 'http://www.optimalpayments.com/creditcard/xmlschema/v1' - } + 'xsi:schemaLocation' => 'http://www.optimalpayments.com/creditcard/xmlschema/v1' } end def build_merchant_account(xml) @@ -321,12 +322,10 @@ def build_address(xml, addr) def card_type(key) { 'visa' => 'VI', 'master' => 'MC', - 'american_express'=> 'AM', + 'american_express' => 'AM', 'discover' => 'DI', - 'diners_club' => 'DC', - }[key] + 'diners_club' => 'DC' }[key] end - end end end diff --git a/lib/active_merchant/billing/gateways/orbital.rb b/lib/active_merchant/billing/gateways/orbital.rb index aad16855ea2..50272b034d0 100644 --- a/lib/active_merchant/billing/gateways/orbital.rb +++ b/lib/active_merchant/billing/gateways/orbital.rb @@ -30,11 +30,11 @@ module Billing #:nodoc: class OrbitalGateway < Gateway include Empty - API_VERSION = '7.7' + API_VERSION = '8.1' POST_HEADERS = { 'MIME-Version' => '1.1', - 'Content-Type' => "application/PTI#{API_VERSION.gsub(/\./, '')}", + 'Content-Type' => "application/PTI#{API_VERSION.delete('.')}", 'Content-transfer-encoding' => 'text', 'Request-number' => '1', 'Document-type' => 'Request', @@ -60,7 +60,8 @@ class OrbitalGateway < Gateway '93', # Approved high fraud '94', # Approved fraud service unavailable 'E7', # Stored - 'PA' # Partial approval + 'PA', # Partial approval + 'P1' # ECP - AVS - Account Status Verification and/or AOA data is in a positive status. ] class_attribute :secondary_test_url, :secondary_live_url @@ -71,16 +72,16 @@ class OrbitalGateway < Gateway self.live_url = 'https://orbital1.chasepaymentech.com/authorize' self.secondary_live_url = 'https://orbital2.chasepaymentech.com/authorize' - self.supported_countries = ['US', 'CA'] + self.supported_countries = %w[US CA] self.default_currency = 'CAD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb] + self.supported_cardtypes = %i[visa master american_express discover diners_club jcb] self.display_name = 'Orbital Paymentech' self.homepage_url = 'http://chasepaymentech.com/' self.money_format = :cents - AVS_SUPPORTED_COUNTRIES = ['US', 'CA', 'UK', 'GB'] + AVS_SUPPORTED_COUNTRIES = %w[US CA UK GB] CURRENCY_CODES = { 'AUD' => '036', @@ -181,7 +182,13 @@ class OrbitalGateway < Gateway USE_ORDER_ID = 'O' # Use OrderID field USE_COMMENTS = 'D' # Use Comments field - SENSITIVE_FIELDS = [:account_num, :cc_account_num] + SENSITIVE_FIELDS = %i[account_num cc_account_num] + + # Bank account types to be used for check processing + ACCOUNT_TYPE = { + 'savings' => 'S', + 'checking' => 'C' + } def initialize(options = {}) requires!(options, :merchant_id) @@ -191,16 +198,16 @@ def initialize(options = {}) end # A – Authorization request - def authorize(money, creditcard, options = {}) - order = build_new_order_xml(AUTH_ONLY, money, creditcard, options) do |xml| - add_creditcard(xml, creditcard, options[:currency]) - add_address(xml, creditcard, options) + def authorize(money, payment_source, options = {}) + order = build_new_order_xml(AUTH_ONLY, money, payment_source, options) do |xml| + add_payment_source(xml, payment_source, options) + add_address(xml, payment_source, options) if @options[:customer_profiles] - add_customer_data(xml, creditcard, options) + add_customer_data(xml, payment_source, options) add_managed_billing(xml, options) end end - commit(order, :authorize, options[:trace_number]) + commit(order, :authorize, options[:retry_logic], options[:trace_number]) end def verify(creditcard, options = {}) @@ -211,45 +218,50 @@ def verify(creditcard, options = {}) end # AC – Authorization and Capture - def purchase(money, creditcard, options = {}) - order = build_new_order_xml(AUTH_AND_CAPTURE, money, creditcard, options) do |xml| - add_creditcard(xml, creditcard, options[:currency]) - add_address(xml, creditcard, options) + def purchase(money, payment_source, options = {}) + order = build_new_order_xml(options[:force_capture] ? FORCE_AUTH_AND_CAPTURE : AUTH_AND_CAPTURE, money, payment_source, options) do |xml| + add_payment_source(xml, payment_source, options) + add_address(xml, payment_source, options) if @options[:customer_profiles] - add_customer_data(xml, creditcard, options) + add_customer_data(xml, payment_source, options) add_managed_billing(xml, options) end end - commit(order, :purchase, options[:trace_number]) + commit(order, :purchase, options[:retry_logic], options[:trace_number]) end # MFC - Mark For Capture def capture(money, authorization, options = {}) - commit(build_mark_for_capture_xml(money, authorization, options), :capture) + commit(build_mark_for_capture_xml(money, authorization, options), :capture, options[:retry_logic], options[:trace_number]) end # R – Refund request def refund(money, authorization, options = {}) - order = build_new_order_xml(REFUND, money, nil, options.merge(:authorization => authorization)) do |xml| - add_refund(xml, options[:currency]) + payment_method = options[:payment_method] + order = build_new_order_xml(REFUND, money, payment_method, options.merge(authorization: authorization)) do |xml| + if payment_method.is_a?(Check) + add_echeck(xml, payment_method, options) + else + add_refund(xml, options[:currency]) + end xml.tag! :CustomerRefNum, options[:customer_ref_num] if @options[:customer_profiles] && options[:profile_txn] end - commit(order, :refund, options[:trace_number]) + commit(order, :refund, options[:retry_logic], options[:trace_number]) end - def credit(money, authorization, options= {}) + def credit(money, authorization, options = {}) ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE refund(money, authorization, options) end def void(authorization, options = {}, deprecated = {}) - if(!options.kind_of?(Hash)) + if !options.kind_of?(Hash) ActiveMerchant.deprecated('Calling the void method with an amount parameter is deprecated and will be removed in a future version.') - return void(options, deprecated.merge(:amount => authorization)) + return void(options, deprecated.merge(amount: authorization)) end order = build_void_request_xml(authorization, options) - commit(order, :void, options[:trace_number]) + commit(order, :void, options[:retry_logic], options[:trace_number]) end # ==== Customer Profiles @@ -286,13 +298,13 @@ def update_customer_profile(creditcard, options = {}) end def retrieve_customer_profile(customer_ref_num) - options = {:customer_profile_action => RETRIEVE, :customer_ref_num => customer_ref_num} + options = { customer_profile_action: RETRIEVE, customer_ref_num: customer_ref_num } order = build_customer_request_xml(nil, options) commit(order, :retrieve_customer_profile) end def delete_customer_profile(customer_ref_num) - options = {:customer_profile_action => DELETE, :customer_ref_num => customer_ref_num} + options = { customer_profile_action: DELETE, customer_ref_num: customer_ref_num } order = build_customer_request_xml(nil, options) commit(order, :delete_customer_profile) end @@ -306,10 +318,12 @@ def scrub(transcript) gsub(%r(().+()), '\1[FILTERED]\2'). gsub(%r(().+()), '\1[FILTERED]\2'). gsub(%r(().+()), '\1[FILTERED]\2'). - gsub(%r(().+()), '\1[FILTERED]\2'). + # the response sometimes contains a new line that cuts off the end of the closing tag + gsub(%r(().+().+()), '\1[FILTERED]\2'). gsub(%r(().+()), '\1[FILTERED]\2'). - gsub(%r(().+()), '\1[FILTERED]\2') + gsub(%r(().+()), '\1[FILTERED]\2'). + gsub(%r(().+()), '\1[FILTERED]\2') end private @@ -327,9 +341,7 @@ def add_customer_data(xml, creditcard, options) xml.tag! :CustomerRefNum, options[:customer_ref_num] else if options[:customer_ref_num] - if creditcard - xml.tag! :CustomerProfileFromOrderInd, USE_CUSTOMER_REF_NUM - end + xml.tag! :CustomerProfileFromOrderInd, USE_CUSTOMER_REF_NUM if creditcard xml.tag! :CustomerRefNum, options[:customer_ref_num] else xml.tag! :CustomerProfileFromOrderInd, AUTO_GENERATE @@ -356,48 +368,100 @@ def add_soft_descriptors_from_hash(xml, soft_desc) xml.tag! :SDMerchantEmail, soft_desc[:merchant_email] || nil end - def add_level_2_tax(xml, options={}) - if (level_2 = options[:level_2_data]) - xml.tag! :TaxInd, level_2[:tax_indicator] if [TAX_NOT_PROVIDED, TAX_INCLUDED, NON_TAXABLE_TRANSACTION].include?(level_2[:tax_indicator].to_i) - xml.tag! :Tax, level_2[:tax].to_i if level_2[:tax] + def add_level2_tax(xml, options = {}) + if (level2 = options[:level_2_data]) + xml.tag! :TaxInd, level2[:tax_indicator] if [TAX_NOT_PROVIDED, TAX_INCLUDED, NON_TAXABLE_TRANSACTION].include?(level2[:tax_indicator].to_i) + xml.tag! :Tax, level2[:tax].to_i if level2[:tax] + end + end + + def add_level3_tax(xml, options = {}) + if (level3 = options[:level_3_data]) + xml.tag! :PC3VATtaxAmt, byte_limit(level3[:vat_tax], 12) if level3[:vat_tax] + xml.tag! :PC3AltTaxAmt, byte_limit(level3[:alt_tax], 9) if level3[:alt_tax] + xml.tag! :PC3VATtaxRate, byte_limit(level3[:vat_rate], 4) if level3[:vat_rate] + xml.tag! :PC3AltTaxInd, byte_limit(level3[:alt_ind], 15) if level3[:alt_ind] + end + end + + def add_level2_advice_addendum(xml, options = {}) + if (level2 = options[:level_2_data]) + xml.tag! :AMEXTranAdvAddn1, byte_limit(level2[:advice_addendum_1], 40) if level2[:advice_addendum_1] + xml.tag! :AMEXTranAdvAddn2, byte_limit(level2[:advice_addendum_2], 40) if level2[:advice_addendum_2] + xml.tag! :AMEXTranAdvAddn3, byte_limit(level2[:advice_addendum_3], 40) if level2[:advice_addendum_3] + xml.tag! :AMEXTranAdvAddn4, byte_limit(level2[:advice_addendum_4], 40) if level2[:advice_addendum_4] end end - def add_level_2_advice_addendum(xml, options={}) - if (level_2 = options[:level_2_data]) - xml.tag! :AMEXTranAdvAddn1, byte_limit(level_2[:advice_addendum_1], 40) if level_2[:advice_addendum_1] - xml.tag! :AMEXTranAdvAddn2, byte_limit(level_2[:advice_addendum_2], 40) if level_2[:advice_addendum_2] - xml.tag! :AMEXTranAdvAddn3, byte_limit(level_2[:advice_addendum_3], 40) if level_2[:advice_addendum_3] - xml.tag! :AMEXTranAdvAddn4, byte_limit(level_2[:advice_addendum_4], 40) if level_2[:advice_addendum_4] + def add_level2_purchase(xml, options = {}) + if (level2 = options[:level_2_data]) + xml.tag! :PCOrderNum, byte_limit(level2[:purchase_order], 17) if level2[:purchase_order] + xml.tag! :PCDestZip, byte_limit(format_address_field(level2[:zip]), 10) if level2[:zip] + xml.tag! :PCDestName, byte_limit(format_address_field(level2[:name]), 30) if level2[:name] + xml.tag! :PCDestAddress1, byte_limit(format_address_field(level2[:address1]), 30) if level2[:address1] + xml.tag! :PCDestAddress2, byte_limit(format_address_field(level2[:address2]), 30) if level2[:address2] + xml.tag! :PCDestCity, byte_limit(format_address_field(level2[:city]), 20) if level2[:city] + xml.tag! :PCDestState, byte_limit(format_address_field(level2[:state]), 2) if level2[:state] end end - def add_level_2_purchase(xml, options={}) - if (level_2 = options[:level_2_data]) - xml.tag! :PCOrderNum, byte_limit(level_2[:purchase_order], 17) if level_2[:purchase_order] - xml.tag! :PCDestZip, byte_limit(format_address_field(level_2[:zip]), 10) if level_2[:zip] - xml.tag! :PCDestName, byte_limit(format_address_field(level_2[:name]), 30) if level_2[:name] - xml.tag! :PCDestAddress1, byte_limit(format_address_field(level_2[:address1]), 30) if level_2[:address1] - xml.tag! :PCDestAddress2, byte_limit(format_address_field(level_2[:address2]), 30) if level_2[:address2] - xml.tag! :PCDestCity, byte_limit(format_address_field(level_2[:city]), 20) if level_2[:city] - xml.tag! :PCDestState, byte_limit(format_address_field(level_2[:state]), 2) if level_2[:state] + def add_level3_purchase(xml, options = {}) + if (level3 = options[:level_3_data]) + xml.tag! :PC3FreightAmt, byte_limit(level3[:freight_amount], 12) if level3[:freight_amount] + xml.tag! :PC3DutyAmt, byte_limit(level3[:duty_amount], 12) if level3[:duty_amount] + xml.tag! :PC3DestCountryCd, byte_limit(level3[:dest_country], 3) if level3[:dest_country] + xml.tag! :PC3ShipFromZip, byte_limit(level3[:ship_from_zip], 10) if level3[:ship_from_zip] + xml.tag! :PC3DiscAmt, byte_limit(level3[:discount_amount], 12) if level3[:discount_amount] end end - def add_address(xml, creditcard, options) - if(address = (options[:billing_address] || options[:address])) + def add_line_items(xml, options = {}) + xml.tag! :PC3LineItemCount, byte_limit(options[:line_items].count, 2) + xml.tag! :PC3LineItemArray do + options[:line_items].each_with_index do |line_item, index| + xml.tag! :PC3LineItem do + xml.tag! :PC3DtlIndex, byte_limit(index + 1, 2) + line_item.each do |key, value| + if [:line_tot, 'line_tot'].include? key + formatted_key = :PC3Dtllinetot + else + formatted_key = "PC3Dtl#{key.to_s.camelize}".to_sym + end + xml.tag! formatted_key, value + end + end + end + end + end + + def add_card_indicators(xml, options) + xml.tag! :CardIndicators, options[:card_indicators] if options[:card_indicators] + end + + def add_address(xml, payment_source, options) + address = (options[:billing_address] || options[:address]) + + # always send the AVSname if the payment is a check regardless + # if there's an address or not + if payment_source.is_a?(Check) && address.blank? + xml.tag! :AVSname, (payment_source&.name ? payment_source.name[0..29] : nil) + + return + end + + unless address.blank? avs_supported = AVS_SUPPORTED_COUNTRIES.include?(address[:country].to_s) || empty?(address[:country]) if avs_supported - xml.tag! :AVSzip, byte_limit(format_address_field(address[:zip]), 10) + xml.tag! :AVSzip, byte_limit(format_address_field(address[:zip]), 10) xml.tag! :AVSaddress1, byte_limit(format_address_field(address[:address1]), 30) xml.tag! :AVSaddress2, byte_limit(format_address_field(address[:address2]), 30) - xml.tag! :AVScity, byte_limit(format_address_field(address[:city]), 20) - xml.tag! :AVSstate, byte_limit(format_address_field(address[:state]), 2) + xml.tag! :AVScity, byte_limit(format_address_field(address[:city]), 20) + xml.tag! :AVSstate, byte_limit(format_address_field(address[:state]), 2) xml.tag! :AVSphoneNum, (address[:phone] ? address[:phone].scan(/\d/).join.to_s[0..13] : nil) end - xml.tag! :AVSname, (creditcard&.name ? creditcard.name[0..29] : nil) + xml.tag! :AVSname, (payment_source&.name ? payment_source.name[0..29] : nil) xml.tag! :AVScountryCode, (avs_supported ? byte_limit(format_address_field(address[:country]), 2) : '') # Needs to come after AVScountryCode @@ -423,7 +487,7 @@ def add_destination_address(xml, address) # For Profile requests def add_customer_address(xml, options) - if(address = (options[:billing_address] || options[:address])) + if (address = (options[:billing_address] || options[:address])) avs_supported = AVS_SUPPORTED_COUNTRIES.include?(address[:country].to_s) xml.tag! :CustomerAddress1, byte_limit(format_address_field(address[:address1]), 30) @@ -437,7 +501,37 @@ def add_customer_address(xml, options) end end - def add_creditcard(xml, creditcard, currency=nil) + # Payment can be done through either Credit Card or Electronic Check + def add_payment_source(xml, payment_source, options = {}) + if payment_source.is_a?(Check) + add_echeck(xml, payment_source, options) + else + add_creditcard(xml, payment_source, options[:currency]) + end + end + + # Adds Electronic Check attributes + def add_echeck(xml, check, options = {}) + xml.tag! :CardBrand, 'EC' + xml.tag! :CurrencyCode, currency_code(options[:currency]) + xml.tag! :CurrencyExponent, currency_exponents(options[:currency]) + unless check.nil? + + xml.tag! :BCRtNum, check.routing_number + xml.tag! :CheckDDA, check.account_number if check.account_number + xml.tag! :BankAccountType, ACCOUNT_TYPE[check.account_type] if ACCOUNT_TYPE[check.account_type] + xml.tag! :ECPAuthMethod, options[:auth_method] if options[:auth_method] + + if options[:payment_delivery] + xml.tag! :BankPmtDelv, options[:payment_delivery] + else + xml.tag! :BankPmtDelv, 'B' + end + end + end + + # Adds Credit Card attributes + def add_creditcard(xml, creditcard, currency = nil) unless creditcard.nil? xml.tag! :AccountNum, creditcard.number xml.tag! :Exp, expiry_date(creditcard) @@ -457,10 +551,8 @@ def add_creditcard(xml, creditcard, currency=nil) # - http://download.chasepaymentech.com/docs/orbital/orbital_gateway_xml_specification.pdf unless creditcard.nil? if creditcard.verification_value? - if %w( visa discover ).include?(creditcard.brand) - xml.tag! :CardSecValInd, '1' - end - xml.tag! :CardSecVal, creditcard.verification_value + xml.tag! :CardSecValInd, '1' if %w(visa discover).include?(creditcard.brand) + xml.tag! :CardSecVal, creditcard.verification_value end end end @@ -476,13 +568,9 @@ def add_eci(xml, creditcard, three_d_secure) end def add_xid(xml, creditcard, three_d_secure) - xid = if three_d_secure && creditcard.brand == 'visa' - three_d_secure[:xid] - elsif creditcard.is_a?(NetworkTokenizationCreditCard) - creditcard.transaction_id - end + return unless three_d_secure && creditcard.brand == 'visa' - xml.tag!(:XID, xid) if xid + xml.tag!(:XID, three_d_secure[:xid]) if three_d_secure[:xid] end def add_cavv(xml, creditcard, three_d_secure) @@ -497,6 +585,24 @@ def add_aav(xml, creditcard, three_d_secure) xml.tag!(:AAV, three_d_secure[:cavv]) end + def add_mc_program_protocol(xml, creditcard, three_d_secure) + return unless three_d_secure && creditcard.brand == 'master' + + xml.tag!(:MCProgramProtocol, three_d_secure[:version]) if three_d_secure[:version] + end + + def add_mc_directory_trans_id(xml, creditcard, three_d_secure) + return unless three_d_secure && creditcard.brand == 'master' + + xml.tag!(:MCDirectoryTransID, three_d_secure[:ds_transaction_id]) if three_d_secure[:ds_transaction_id] + end + + def add_ucafind(xml, creditcard, three_d_secure) + return unless three_d_secure && creditcard.brand == 'master' + + xml.tag! :UCAFInd, '4' + end + def add_dpanind(xml, creditcard) return unless creditcard.is_a?(NetworkTokenizationCreditCard) @@ -521,7 +627,7 @@ def add_pymt_brand_program_code(xml, creditcard, three_d_secure) xml.tag!(:PymtBrandProgramCode, 'ASK') end - def add_refund(xml, currency=nil) + def add_refund(xml, currency = nil) xml.tag! :AccountNum, nil xml.tag! :CurrencyCode, currency_code(currency) @@ -552,8 +658,43 @@ def add_managed_billing(xml, options) end end + def add_ews_details(xml, payment_source, parameters = {}) + xml.tag! :EWSFirstName, payment_source.first_name + xml.tag! :EWSLastName, payment_source.last_name + xml.tag! :EWSBusinessName, parameters[:company] if payment_source.first_name.empty? && payment_source.last_name.empty? + + if (address = (parameters[:billing_address] || parameters[:address])) + xml.tag! :EWSAddressLine1, byte_limit(format_address_field(address[:address1]), 30) + xml.tag! :EWSAddressLine2, byte_limit(format_address_field(address[:address2]), 30) + xml.tag! :EWSCity, byte_limit(format_address_field(address[:city]), 20) + xml.tag! :EWSState, byte_limit(format_address_field(address[:state]), 2) + xml.tag! :EWSZip, byte_limit(format_address_field(address[:zip]), 10) + end + + xml.tag! :EWSPhoneType, parameters[:phone_type] + xml.tag! :EWSPhoneNumber, parameters[:phone_number] + xml.tag! :EWSCheckSerialNumber, payment_source.account_number unless parameters[:auth_method].eql?('I') + end + + # Adds ECP conditional attributes depending on other attribute values + def add_ecp_details(xml, payment_source, parameters = {}) + requires!(payment_source.account_number) if parameters[:auth_method]&.eql?('A') || parameters[:auth_method]&.eql?('P') + xml.tag! :ECPActionCode, parameters[:action_code] if parameters[:action_code] + xml.tag! :ECPCheckSerialNumber, payment_source.account_number if parameters[:auth_method]&.eql?('A') || parameters[:auth_method]&.eql?('P') + if parameters[:auth_method]&.eql?('P') + xml.tag! :ECPTerminalCity, parameters[:terminal_city] if parameters[:terminal_city] + xml.tag! :ECPTerminalState, parameters[:terminal_state] if parameters[:terminal_state] + xml.tag! :ECPImageReferenceNumber, parameters[:image_reference_number] if parameters[:image_reference_number] + end + if parameters[:action_code]&.eql?('W3') || parameters[:action_code]&.eql?('W5') || + parameters[:action_code]&.eql?('W7') || parameters[:action_code]&.eql?('W9') + add_ews_details(xml, payment_source, parameters) + end + end + def add_stored_credentials(xml, parameters) return unless parameters[:mit_stored_credential_ind] == 'Y' || parameters[:stored_credential] && !parameters[:stored_credential].values.all?(&:nil?) + if msg_type = get_msg_type(parameters) xml.tag! :MITMsgType, msg_type end @@ -569,15 +710,18 @@ def get_msg_type(parameters) return parameters[:mit_msg_type] if parameters[:mit_msg_type] return 'CSTO' if parameters[:stored_credential][:initial_transaction] return unless parameters[:stored_credential][:initiator] && parameters[:stored_credential][:reason_type] - initiator = case parameters[:stored_credential][:initiator] - when 'customer' then 'C' - when 'merchant' then 'M' - end - reason = case parameters[:stored_credential][:reason_type] - when 'recurring' then 'REC' - when 'installment' then 'INS' - when 'unscheduled' then 'USE' - end + + initiator = + case parameters[:stored_credential][:initiator] + when 'cardholder', 'customer' then 'C' + when 'merchant' then 'M' + end + reason = + case parameters[:stored_credential][:reason_type] + when 'recurring' then 'REC' + when 'installment' then 'INS' + when 'unscheduled' then 'USE' + end "#{initiator}#{reason}" end @@ -604,32 +748,32 @@ def recurring_parse_element(response, node) end end - def commit(order, message_type, trace_number=nil) + def commit(order, message_type, retry_logic = nil, trace_number = nil) headers = POST_HEADERS.merge('Content-length' => order.size.to_s) - if @options[:retry_logic] && trace_number + if (@options[:retry_logic] || retry_logic) && trace_number headers['Trace-number'] = trace_number.to_s headers['Merchant-Id'] = @options[:merchant_id] end request = ->(url) { parse(ssl_post(url, order, headers)) } # Failover URL will be attempted in the event of a connection error - response = begin - request.call(remote_url) - rescue ConnectionError - request.call(remote_url(:secondary)) - end + response = + begin + request.call(remote_url) + rescue ConnectionError + request.call(remote_url(:secondary)) + end Response.new(success?(response, message_type), message_from(response), response, { - :authorization => authorization_string(response[:tx_ref_num], response[:order_id]), - :test => self.test?, - :avs_result => OrbitalGateway::AVSResult.new(response[:avs_resp_code]), - :cvv_result => OrbitalGateway::CVVResult.new(response[:cvv2_resp_code]) - } - ) + authorization: authorization_string(response[:tx_ref_num], response[:order_id]), + test: self.test?, + avs_result: OrbitalGateway::AVSResult.new(response[:avs_resp_code]), + cvv_result: OrbitalGateway::CVVResult.new(response[:cvv2_resp_code]) + }) end - def remote_url(url=:primary) + def remote_url(url = :primary) if url == :primary (self.test? ? self.test_url : self.live_url) else @@ -638,13 +782,13 @@ def remote_url(url=:primary) end def success?(response, message_type) - if [:refund, :void].include?(message_type) + if %i[refund void].include?(message_type) response[:proc_status] == SUCCESS elsif response[:customer_profile_action] response[:profile_proc_status] == SUCCESS else response[:proc_status] == SUCCESS && - APPROVED.include?(response[:resp_code]) + APPROVED.include?(response[:resp_code]) end end @@ -656,7 +800,7 @@ def ip_authentication? @options[:ip_authentication] == true end - def build_new_order_xml(action, money, creditcard, parameters = {}) + def build_new_order_xml(action, money, payment_source, parameters = {}) requires!(parameters, :order_id) xml = xml_envelope xml.tag! :Request do @@ -681,41 +825,51 @@ def build_new_order_xml(action, money, creditcard, parameters = {}) three_d_secure = parameters[:three_d_secure] - add_eci(xml, creditcard, three_d_secure) - add_cavv(xml, creditcard, three_d_secure) - add_xid(xml, creditcard, three_d_secure) + add_eci(xml, payment_source, three_d_secure) + add_cavv(xml, payment_source, three_d_secure) + add_xid(xml, payment_source, three_d_secure) xml.tag! :OrderID, format_order_id(parameters[:order_id]) xml.tag! :Amount, amount(money) xml.tag! :Comments, parameters[:comments] if parameters[:comments] - add_level_2_tax(xml, parameters) - add_level_2_advice_addendum(xml, parameters) + add_level2_tax(xml, parameters) + add_level2_advice_addendum(xml, parameters) - add_aav(xml, creditcard, three_d_secure) + add_aav(xml, payment_source, three_d_secure) # CustomerAni, AVSPhoneType and AVSDestPhoneType could be added here. - add_dpanind(xml, creditcard) - add_aevv(xml, creditcard, three_d_secure) - add_digital_token_cryptogram(xml, creditcard) - if parameters[:soft_descriptors].is_a?(OrbitalSoftDescriptors) add_soft_descriptors(xml, parameters[:soft_descriptors]) elsif parameters[:soft_descriptors].is_a?(Hash) add_soft_descriptors_from_hash(xml, parameters[:soft_descriptors]) end + add_dpanind(xml, payment_source) + add_aevv(xml, payment_source, three_d_secure) + add_digital_token_cryptogram(xml, payment_source) + + xml.tag! :ECPSameDayInd, parameters[:same_day] if parameters[:same_day] && payment_source.is_a?(Check) + set_recurring_ind(xml, parameters) # Append Transaction Reference Number at the end for Refund transactions if action == REFUND - tx_ref_num, _ = split_authorization(parameters[:authorization]) + tx_ref_num, = split_authorization(parameters[:authorization]) xml.tag! :TxRefNum, tx_ref_num end - add_level_2_purchase(xml, parameters) + add_level2_purchase(xml, parameters) + add_level3_purchase(xml, parameters) + add_level3_tax(xml, parameters) + add_line_items(xml, parameters) if parameters[:line_items] + add_ecp_details(xml, payment_source, parameters) if payment_source.is_a?(Check) + add_card_indicators(xml, parameters) add_stored_credentials(xml, parameters) - add_pymt_brand_program_code(xml, creditcard, three_d_secure) + add_pymt_brand_program_code(xml, payment_source, three_d_secure) + add_mc_program_protocol(xml, payment_source, three_d_secure) + add_mc_directory_trans_id(xml, payment_source, three_d_secure) + add_ucafind(xml, payment_source, three_d_secure) end end xml.target! @@ -727,6 +881,7 @@ def build_new_order_xml(action, money, creditcard, parameters = {}) def set_recurring_ind(xml, parameters) if parameters[:recurring_ind] raise 'RecurringInd must be set to either "RF" or "RS"' unless %w(RF RS).include?(parameters[:recurring_ind]) + xml.tag! :RecurringInd, parameters[:recurring_ind] end end @@ -739,11 +894,13 @@ def build_mark_for_capture_xml(money, authorization, parameters = {}) add_xml_credentials(xml) xml.tag! :OrderID, format_order_id(order_id) xml.tag! :Amount, amount(money) - add_level_2_tax(xml, parameters) + add_level2_tax(xml, parameters) add_bin_merchant_and_terminal(xml, parameters) xml.tag! :TxRefNum, tx_ref_num - add_level_2_purchase(xml, parameters) - add_level_2_advice_addendum(xml, parameters) + add_level2_purchase(xml, parameters) + add_level2_advice_addendum(xml, parameters) + add_level3_purchase(xml, parameters) + add_level3_tax(xml, parameters) end end xml.target! @@ -784,8 +941,8 @@ def bin end def xml_envelope - xml = Builder::XmlMarkup.new(:indent => 2) - xml.instruct!(:xml, :version => '1.0', :encoding => 'UTF-8') + xml = Builder::XmlMarkup.new(indent: 2) + xml.instruct!(:xml, version: '1.0', encoding: 'UTF-8') xml end @@ -813,7 +970,7 @@ def salem_mid? # 3. PINless Debit transactions can only use uppercase and lowercase alpha (A-Z, a-z) and numeric (0-9) def format_order_id(order_id) illegal_characters = /[^,$@&\- \w]/ - order_id = order_id.to_s.gsub(/\./, '-') + order_id = order_id.to_s.tr('.', '-') order_id.gsub!(illegal_characters, '') order_id.lstrip! order_id[0...22] @@ -831,7 +988,8 @@ def byte_limit(value, byte_length) limited_value = '' value.to_s.each_char do |c| - break if((limited_value.bytesize + c.bytesize) > byte_length) + break if (limited_value.bytesize + c.bytesize) > byte_length + limited_value << c end @@ -894,55 +1052,55 @@ def build_customer_request_xml(creditcard, options = {}) # class AVSResult < ActiveMerchant::Billing::AVSResult CODES = { - '1' => 'No address supplied', - '2' => 'Bill-to address did not pass Auth Host edit checks', - '3' => 'AVS not performed', - '4' => 'Issuer does not participate in AVS', - '5' => 'Edit-error - AVS data is invalid', - '6' => 'System unavailable or time-out', - '7' => 'Address information unavailable', - '8' => 'Transaction Ineligible for AVS', - '9' => 'Zip Match/Zip 4 Match/Locale match', - 'A' => 'Zip Match/Zip 4 Match/Locale no match', - 'B' => 'Zip Match/Zip 4 no Match/Locale match', - 'C' => 'Zip Match/Zip 4 no Match/Locale no match', - 'D' => 'Zip No Match/Zip 4 Match/Locale match', - 'E' => 'Zip No Match/Zip 4 Match/Locale no match', - 'F' => 'Zip No Match/Zip 4 No Match/Locale match', - 'G' => 'No match at all', - 'H' => 'Zip Match/Locale match', - 'J' => 'Issuer does not participate in Global AVS', - 'JA' => 'International street address and postal match', - 'JB' => 'International street address match. Postal code not verified', - 'JC' => 'International street address and postal code not verified', - 'JD' => 'International postal code match. Street address not verified', - 'M1' => 'Cardholder name matches', - 'M2' => 'Cardholder name, billing address, and postal code matches', - 'M3' => 'Cardholder name and billing code matches', - 'M4' => 'Cardholder name and billing address match', - 'M5' => 'Cardholder name incorrect, billing address and postal code match', - 'M6' => 'Cardholder name incorrect, billing postal code matches', - 'M7' => 'Cardholder name incorrect, billing address matches', - 'M8' => 'Cardholder name, billing address and postal code are all incorrect', - 'N3' => 'Address matches, ZIP not verified', - 'N4' => 'Address and ZIP code not verified due to incompatible formats', - 'N5' => 'Address and ZIP code match (International only)', - 'N6' => 'Address not verified (International only)', - 'N7' => 'ZIP matches, address not verified', - 'N8' => 'Address and ZIP code match (International only)', - 'N9' => 'Address and ZIP code match (UK only)', - 'R' => 'Issuer does not participate in AVS', - 'UK' => 'Unknown', - 'X' => 'Zip Match/Zip 4 Match/Address Match', - 'Z' => 'Zip Match/Locale no match', + '1' => 'No address supplied', + '2' => 'Bill-to address did not pass Auth Host edit checks', + '3' => 'AVS not performed', + '4' => 'Issuer does not participate in AVS', + '5' => 'Edit-error - AVS data is invalid', + '6' => 'System unavailable or time-out', + '7' => 'Address information unavailable', + '8' => 'Transaction Ineligible for AVS', + '9' => 'Zip Match/Zip 4 Match/Locale match', + 'A' => 'Zip Match/Zip 4 Match/Locale no match', + 'B' => 'Zip Match/Zip 4 no Match/Locale match', + 'C' => 'Zip Match/Zip 4 no Match/Locale no match', + 'D' => 'Zip No Match/Zip 4 Match/Locale match', + 'E' => 'Zip No Match/Zip 4 Match/Locale no match', + 'F' => 'Zip No Match/Zip 4 No Match/Locale match', + 'G' => 'No match at all', + 'H' => 'Zip Match/Locale match', + 'J' => 'Issuer does not participate in Global AVS', + 'JA' => 'International street address and postal match', + 'JB' => 'International street address match. Postal code not verified', + 'JC' => 'International street address and postal code not verified', + 'JD' => 'International postal code match. Street address not verified', + 'M1' => 'Cardholder name matches', + 'M2' => 'Cardholder name, billing address, and postal code matches', + 'M3' => 'Cardholder name and billing code matches', + 'M4' => 'Cardholder name and billing address match', + 'M5' => 'Cardholder name incorrect, billing address and postal code match', + 'M6' => 'Cardholder name incorrect, billing postal code matches', + 'M7' => 'Cardholder name incorrect, billing address matches', + 'M8' => 'Cardholder name, billing address and postal code are all incorrect', + 'N3' => 'Address matches, ZIP not verified', + 'N4' => 'Address and ZIP code not verified due to incompatible formats', + 'N5' => 'Address and ZIP code match (International only)', + 'N6' => 'Address not verified (International only)', + 'N7' => 'ZIP matches, address not verified', + 'N8' => 'Address and ZIP code match (International only)', + 'N9' => 'Address and ZIP code match (UK only)', + 'R' => 'Issuer does not participate in AVS', + 'UK' => 'Unknown', + 'X' => 'Zip Match/Zip 4 Match/Address Match', + 'Z' => 'Zip Match/Locale no match' } # Map vendor's AVS result code to a postal match code ORBITAL_POSTAL_MATCH_CODE = { - 'Y' => %w( 9 A B C H JA JD M2 M3 M5 N5 N8 N9 X Z ), - 'N' => %w( D E F G M8 ), - 'X' => %w( 4 J R ), - nil => %w( 1 2 3 5 6 7 8 JB JC M1 M4 M6 M7 N3 N4 N6 N7 UK ) + 'Y' => %w(9 A B C H JA JD M2 M3 M5 N5 N8 N9 X Z), + 'N' => %w(D E F G M8), + 'X' => %w(4 J R), + nil => %w(1 2 3 5 6 7 8 JB JC M1 M4 M6 M7 N3 N4 N6 N7 UK) }.inject({}) do |map, (type, codes)| codes.each { |code| map[code] = type } map @@ -950,10 +1108,10 @@ class AVSResult < ActiveMerchant::Billing::AVSResult # Map vendor's AVS result code to a street match code ORBITAL_STREET_MATCH_CODE = { - 'Y' => %w( 9 B D F H JA JB M2 M4 M5 M6 M7 N3 N5 N7 N8 N9 X ), - 'N' => %w( A C E G M8 Z ), - 'X' => %w( 4 J R ), - nil => %w( 1 2 3 5 6 7 8 JC JD M1 M3 N4 N6 UK ) + 'Y' => %w(9 B D F H JA JB M2 M4 M5 M6 M7 N3 N5 N7 N8 N9 X), + 'N' => %w(A C E G M8 Z), + 'X' => %w(4 J R), + nil => %w(1 2 3 5 6 7 8 JC JD M1 M3 N4 N6 UK) }.inject({}) do |map, (type, codes)| codes.each { |code| map[code] = type } map diff --git a/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb b/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb index da1d82d0ca0..5b7f4517a69 100644 --- a/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +++ b/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb @@ -30,13 +30,11 @@ def validate errors << [:merchant_name, 'is required'] if self.merchant_name.blank? errors << [:merchant_name, 'is required to be 25 bytes or less'] if self.merchant_name.bytesize > 25 - if(!empty?(self.merchant_phone) && !self.merchant_phone.match(PHONE_FORMAT_1) && !self.merchant_phone.match(PHONE_FORMAT_2)) - errors << [:merchant_phone, 'is required to follow "NNN-NNN-NNNN" or "NNN-AAAAAAA" format'] - end + errors << [:merchant_phone, 'is required to follow "NNN-NNN-NNNN" or "NNN-AAAAAAA" format'] if !empty?(self.merchant_phone) && !self.merchant_phone.match(PHONE_FORMAT_1) && !self.merchant_phone.match(PHONE_FORMAT_2) - [:merchant_email, :merchant_url].each do |attr| + %i[merchant_email merchant_url].each do |attr| unless self.send(attr).blank? - errors << [attr, 'is required to be 13 bytes or less'] if(self.send(attr).bytesize > 13) + errors << [attr, 'is required to be 13 bytes or less'] if self.send(attr).bytesize > 13 end end diff --git a/lib/active_merchant/billing/gateways/pac_net_raven.rb b/lib/active_merchant/billing/gateways/pac_net_raven.rb index 952684b1943..2cb24b07107 100644 --- a/lib/active_merchant/billing/gateways/pac_net_raven.rb +++ b/lib/active_merchant/billing/gateways/pac_net_raven.rb @@ -1,7 +1,6 @@ module ActiveMerchant #:nodoc: module Billing #:nodoc: class PacNetRavenGateway < Gateway - AVS_ADDRESS_CODES = { 'avs_address_unavailable' => 'X', 'avs_address_not_checked' => 'X', @@ -29,7 +28,7 @@ class PacNetRavenGateway < Gateway self.test_url = self.live_url self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master] + self.supported_cardtypes = %i[visa master] self.money_format = :cents self.default_currency = 'USD' self.homepage_url = 'https://www.deepcovelabs.com/raven' @@ -123,15 +122,14 @@ def commit(action, money, parameters) test_mode = test? || message =~ /TESTMODE/ Response.new(success?(response), message, response, - :test => test_mode, - :authorization => response['TrackingNumber'], - :fraud_review => fraud_review?(response), - :avs_result => { - :postal_match => AVS_POSTAL_CODES[response['AVSPostalResponseCode']], - :street_match => AVS_ADDRESS_CODES[response['AVSAddressResponseCode']] - }, - :cvv_result => CVV2_CODES[response['CVV2ResponseCode']] - ) + test: test_mode, + authorization: response['TrackingNumber'], + fraud_review: fraud_review?(response), + avs_result: { + postal_match: AVS_POSTAL_CODES[response['AVSPostalResponseCode']], + street_match: AVS_ADDRESS_CODES[response['AVSAddressResponseCode']] + }, + cvv_result: CVV2_CODES[response['CVV2ResponseCode']]) end def url(action) @@ -140,6 +138,7 @@ def url(action) def endpoint(action) return 'void' if action == 'void' + 'submit' end @@ -149,9 +148,9 @@ def fraud_review?(response) def success?(response) if %w(cc_settle cc_debit cc_preauth cc_refund).include?(response[:action]) - !response['ApprovalCode'].nil? and response['ErrorCode'].nil? and response['Status'] == 'Approved' + !response['ApprovalCode'].nil? && response['ErrorCode'].nil? && (response['Status'] == 'Approved') elsif response[:action] = 'void' - !response['ApprovalCode'].nil? and response['ErrorCode'].nil? and response['Status'] == 'Voided' + !response['ApprovalCode'].nil? && response['ErrorCode'].nil? && (response['Status'] == 'Voided') end end @@ -192,13 +191,14 @@ def request_id end def signature(action, post, parameters = {}) - string = if %w(cc_settle cc_debit cc_preauth cc_refund).include?(action) - post['UserName'] + post['Timestamp'] + post['RequestID'] + post['PymtType'] + parameters['Amount'].to_s + parameters['Currency'] - elsif action == 'void' - post['UserName'] + post['Timestamp'] + post['RequestID'] + parameters['TrackingNumber'] - else - post['UserName'] - end + string = + if %w(cc_settle cc_debit cc_preauth cc_refund).include?(action) + post['UserName'] + post['Timestamp'] + post['RequestID'] + post['PymtType'] + parameters['Amount'].to_s + parameters['Currency'] + elsif action == 'void' + post['UserName'] + post['Timestamp'] + post['RequestID'] + parameters['TrackingNumber'] + else + post['UserName'] + end OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new(@options[:secret]), @options[:secret], string) end end diff --git a/lib/active_merchant/billing/gateways/pagarme.rb b/lib/active_merchant/billing/gateways/pagarme.rb index 26545c7c2d3..67726c8ff61 100644 --- a/lib/active_merchant/billing/gateways/pagarme.rb +++ b/lib/active_merchant/billing/gateways/pagarme.rb @@ -6,24 +6,24 @@ class PagarmeGateway < Gateway self.supported_countries = ['BR'] self.default_currency = 'BRL' self.money_format = :cents - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club] + self.supported_cardtypes = %i[visa master american_express discover diners_club] self.homepage_url = 'https://pagar.me/' self.display_name = 'Pagar.me' STANDARD_ERROR_CODE_MAPPING = { 'refused' => STANDARD_ERROR_CODE[:card_declined], - 'processing_error' => STANDARD_ERROR_CODE[:processing_error], + 'processing_error' => STANDARD_ERROR_CODE[:processing_error] } - def initialize(options={}) + def initialize(options = {}) requires!(options, :api_key) @api_key = options[:api_key] super end - def purchase(money, payment_method, options={}) + def purchase(money, payment_method, options = {}) post = {} add_amount(post, money) add_payment_method(post, payment_method) @@ -32,7 +32,7 @@ def purchase(money, payment_method, options={}) commit(:post, 'transactions', post) end - def authorize(money, payment_method, options={}) + def authorize(money, payment_method, options = {}) post = {} add_amount(post, money) add_payment_method(post, payment_method) @@ -43,33 +43,27 @@ def authorize(money, payment_method, options={}) commit(:post, 'transactions', post) end - def capture(money, authorization, options={}) - if authorization.nil? - return Response.new(false, 'Não é possível capturar uma transação sem uma prévia autorização.') - end + def capture(money, authorization, options = {}) + return Response.new(false, 'Não é possível capturar uma transação sem uma prévia autorização.') if authorization.nil? post = {} commit(:post, "transactions/#{authorization}/capture", post) end - def refund(money, authorization, options={}) - if authorization.nil? - return Response.new(false, 'Não é possível estornar uma transação sem uma prévia captura.') - end + def refund(money, authorization, options = {}) + return Response.new(false, 'Não é possível estornar uma transação sem uma prévia captura.') if authorization.nil? void(authorization, options) end - def void(authorization, options={}) - if authorization.nil? - return Response.new(false, 'Não é possível estornar uma transação autorizada sem uma prévia autorização.') - end + def void(authorization, options = {}) + return Response.new(false, 'Não é possível estornar uma transação autorizada sem uma prévia autorização.') if authorization.nil? post = {} commit(:post, "transactions/#{authorization}/refund", post) end - def verify(payment_method, options={}) + def verify(payment_method, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(127, payment_method, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -105,7 +99,7 @@ def add_credit_card(post, credit_card) post[:card_cvv] = credit_card.verification_value end - def add_metadata(post, options={}) + def add_metadata(post, options = {}) post[:metadata] = {} post[:metadata][:order_id] = options[:order_id] post[:metadata][:ip] = options[:ip] @@ -125,6 +119,7 @@ def post_data(params) params.map do |key, value| next if value != false && value.blank? + if value.is_a?(Hash) h = {} value.each do |k, v| @@ -212,7 +207,7 @@ def message_from(response) when 'refunded' 'Transação estornada' else - "Transação com status '#{response["status"]}'" + "Transação com status '#{response['status']}'" end elsif failure_from(response) 'Transação recusada' @@ -225,9 +220,7 @@ def message_from(response) end def authorization_from(response) - if success_from(response) - response['id'] - end + response['id'] if success_from(response) end def test? diff --git a/lib/active_merchant/billing/gateways/pago_facil.rb b/lib/active_merchant/billing/gateways/pago_facil.rb index 85793fbb369..7021c057c3d 100644 --- a/lib/active_merchant/billing/gateways/pago_facil.rb +++ b/lib/active_merchant/billing/gateways/pago_facil.rb @@ -6,17 +6,17 @@ class PagoFacilGateway < Gateway self.supported_countries = ['MX'] self.default_currency = 'MXN' - self.supported_cardtypes = [:visa, :master, :american_express, :jcb] + self.supported_cardtypes = %i[visa master american_express jcb] self.homepage_url = 'http://www.pagofacil.net/' self.display_name = 'PagoFacil' - def initialize(options={}) + def initialize(options = {}) requires!(options, :branch_id, :merchant_id, :service_id) super end - def purchase(money, credit_card, options={}) + def purchase(money, credit_card, options = {}) post = {} add_invoice(post, money, options) add_payment(post, credit_card) @@ -53,9 +53,7 @@ def add_invoice(post, money, options) def add_currency(post, money, options) currency = options.fetch(:currency, currency(money)) - unless currency == self.class.default_currency - post[:divisa] = currency - end + post[:divisa] = currency unless currency == self.class.default_currency end def add_payment(post, credit_card) diff --git a/lib/active_merchant/billing/gateways/pay_conex.rb b/lib/active_merchant/billing/gateways/pay_conex.rb index d0ae08146e8..c3d953446f4 100644 --- a/lib/active_merchant/billing/gateways/pay_conex.rb +++ b/lib/active_merchant/billing/gateways/pay_conex.rb @@ -8,36 +8,36 @@ class PayConexGateway < Gateway self.supported_countries = %w(US CA) self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club] + self.supported_cardtypes = %i[visa master american_express discover jcb diners_club] self.homepage_url = 'http://www.bluefincommerce.com/' self.display_name = 'PayConex' - def initialize(options={}) + def initialize(options = {}) requires!(options, :account_id, :api_accesskey) super end - def purchase(money, payment_method, options={}) + def purchase(money, payment_method, options = {}) post = {} add_auth_purchase_params(post, money, payment_method, options) commit('SALE', post) end - def authorize(money, payment_method, options={}) + def authorize(money, payment_method, options = {}) post = {} add_auth_purchase_params(post, money, payment_method, options) commit('AUTHORIZATION', post) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) post = {} add_reference_params(post, authorization, options) add_amount(post, money, options) commit('CAPTURE', post) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) post = {} add_reference_params(post, authorization, options) add_amount(post, money, options) @@ -50,21 +50,19 @@ def void(authorization, options = {}) commit('REVERSAL', post) end - def credit(money, payment_method, options={}) - if payment_method.is_a?(String) - raise ArgumentError, 'Reference credits are not supported. Please supply the original credit card or use the #refund method.' - end + def credit(money, payment_method, options = {}) + raise ArgumentError, 'Reference credits are not supported. Please supply the original credit card or use the #refund method.' if payment_method.is_a?(String) post = {} add_auth_purchase_params(post, money, payment_method, options) commit('CREDIT', post) end - def verify(payment_method, options={}) + def verify(payment_method, options = {}) authorize(0, payment_method, options) end - def store(payment_method, options={}) + def store(payment_method, options = {}) post = {} add_credentials(post) add_payment_method(post, payment_method) @@ -88,7 +86,8 @@ def scrub(transcript) def force_utf8(string) return nil unless string - binary = string.encode('BINARY', invalid: :replace, undef: :replace, replace: '?') # Needed for Ruby 2.0 since #encode is a no-op if the string is already UTF-8. It's not needed for Ruby 2.1 and up since it's not a no-op there. + + binary = string.encode('BINARY', invalid: :replace, undef: :replace, replace: '?') # Needed for Ruby 2.0 since #encode is a no-op if the string is already UTF-8. It's not needed for Ruby 2.1 and up since it's not a no-op there. binary.encode('UTF-8', invalid: :replace, undef: :replace, replace: '?') end @@ -209,8 +208,8 @@ def commit(action, params) message_from(response), response, authorization: response['transaction_id'], - :avs_result => AVSResult.new(code: response['avs_response']), - :cvv_result => CVVResult.new(response['cvv2_response']), + avs_result: AVSResult.new(code: response['avs_response']), + cvv_result: CVVResult.new(response['cvv2_response']), test: test? ) rescue JSON::ParserError @@ -239,7 +238,6 @@ def unparsable_response(raw_response) message += " (The raw response returned by the API was #{raw_response.inspect})" return Response.new(false, message) end - end end end diff --git a/lib/active_merchant/billing/gateways/pay_gate_xml.rb b/lib/active_merchant/billing/gateways/pay_gate_xml.rb index 35261aaf564..7d97405afac 100644 --- a/lib/active_merchant/billing/gateways/pay_gate_xml.rb +++ b/lib/active_merchant/billing/gateways/pay_gate_xml.rb @@ -76,10 +76,10 @@ class PayGateXmlGateway < Gateway self.live_url = 'https://www.paygate.co.za/payxml/process.trans' # The countries the gateway supports merchants from as 2 digit ISO country codes - self.supported_countries = ['US', 'ZA'] + self.supported_countries = %w[US ZA] # The card types supported by the payment gateway - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club] + self.supported_cardtypes = %i[visa master american_express diners_club] # The homepage URL of the gateway self.homepage_url = 'http://paygate.co.za/' @@ -106,7 +106,7 @@ class PayGateXmlGateway < Gateway 900002 => 'Card Expired', 900003 => 'Insufficient Funds', 900004 => 'Invalid Card Number', - 900005 => 'Bank Interface Timeout', # indicates a communications failure between the banks systems + 900005 => 'Bank Interface Timeout', # indicates a communications failure between the banks systems 900006 => 'Invalid Card', 900007 => 'Declined', 900009 => 'Lost Card', @@ -117,7 +117,7 @@ class PayGateXmlGateway < Gateway 900014 => 'Excessive Card Usage', 900015 => 'Card Blacklisted', - 900207 => 'Declined; authentication failed', # indicates the cardholder did not enter their MasterCard SecureCode / Verified by Visa password correctly + 900207 => 'Declined; authentication failed', # indicates the cardholder did not enter their MasterCard SecureCode / Verified by Visa password correctly 990020 => 'Auth Declined', @@ -135,15 +135,15 @@ class PayGateXmlGateway < Gateway 990053 => 'Error processing transaction', # Miscellaneous - Unless otherwise noted, the TRANSACTION_STATUS will be 0. - 900209 => 'Transaction verification failed (phase 2)', # Indicates the verification data returned from MasterCard SecureCode / Verified by Visa has been altered - 900210 => 'Authentication complete; transaction must be restarted', # Indicates that the MasterCard SecuerCode / Verified by Visa transaction has already been completed. Most likely caused by the customer clicking the refresh button + 900209 => 'Transaction verification failed (phase 2)', # Indicates the verification data returned from MasterCard SecureCode / Verified by Visa has been altered + 900210 => 'Authentication complete; transaction must be restarted', # Indicates that the MasterCard SecuerCode / Verified by Visa transaction has already been completed. Most likely caused by the customer clicking the refresh button 990024 => 'Duplicate Transaction Detected. Please check before submitting', - 990028 => 'Transaction cancelled' # Customer clicks the 'Cancel' button on the payment page + 990028 => 'Transaction cancelled' # Customer clicks the 'Cancel' button on the payment page } - SUCCESS_CODES = %w( 990004 990005 990017 990012 990018 990031 ) + SUCCESS_CODES = %w(990004 990005 990017 990012 990018 990031) TRANSACTION_CODES = { 0 => 'Not Done', @@ -183,7 +183,7 @@ def capture(money, authorization, options = {}) commit(action, build_request(action, options), authorization) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) action = 'refundtx' options[:money] = money @@ -197,11 +197,11 @@ def successful?(response) SUCCESS_CODES.include?(response[:res]) end - def build_request(action, options={}) + def build_request(action, options = {}) xml = Builder::XmlMarkup.new xml.instruct! - xml.tag! 'protocol', :ver => API_VERSION, :pgid => (test? ? TEST_ID : @options[:login]), :pwd => @options[:password] do |protocol| + xml.tag! 'protocol', ver: API_VERSION, pgid: (test? ? TEST_ID : @options[:login]), pwd: @options[:password] do |protocol| money = options.delete(:money) authorization = options.delete(:authorization) creditcard = options.delete(:creditcard) @@ -220,31 +220,31 @@ def build_request(action, options={}) xml.target! end - def build_authorization(xml, money, creditcard, options={}) + def build_authorization(xml, money, creditcard, options = {}) xml.tag! 'authtx', { - :cref => options[:order_id], - :cname => creditcard.name, - :cc => creditcard.number, - :exp => "#{format(creditcard.month, :two_digits)}#{format(creditcard.year, :four_digits)}", - :budp => 0, - :amt => amount(money), - :cur => (options[:currency] || currency(money)), - :cvv => creditcard.verification_value, - :email => options[:email], - :ip => options[:ip] + cref: options[:order_id], + cname: creditcard.name, + cc: creditcard.number, + exp: "#{format(creditcard.month, :two_digits)}#{format(creditcard.year, :four_digits)}", + budp: 0, + amt: amount(money), + cur: (options[:currency] || currency(money)), + cvv: creditcard.verification_value, + email: options[:email], + ip: options[:ip] } end - def build_capture(xml, money, authorization, options={}) + def build_capture(xml, money, authorization, options = {}) xml.tag! 'settletx', { - :tid => authorization + tid: authorization } end - def build_refund(xml, money, authorization, options={}) + def build_refund(xml, money, authorization, options = {}) xml.tag! 'refundtx', { - :tid => authorization, - :amt => amount(money) + tid: authorization, + amt: amount(money) } end @@ -255,9 +255,7 @@ def parse(action, body) response_action = action.gsub(/tx/, 'rx') root = REXML::XPath.first(xml.root, response_action) # we might have gotten an error - if root.nil? - root = REXML::XPath.first(xml.root, 'errorrx') - end + root = REXML::XPath.first(xml.root, 'errorrx') if root.nil? root.attributes.each do |name, value| hash[name.to_sym] = value end @@ -267,9 +265,8 @@ def parse(action, body) def commit(action, request, authorization = nil) response = parse(action, ssl_post(self.live_url, request)) Response.new(successful?(response), message_from(response), response, - :test => test?, - :authorization => authorization || response[:tid] - ) + test: test?, + authorization: authorization || response[:tid]) end def message_from(response) diff --git a/lib/active_merchant/billing/gateways/pay_hub.rb b/lib/active_merchant/billing/gateways/pay_hub.rb index fdcc6c5d600..6f66cefaac1 100644 --- a/lib/active_merchant/billing/gateways/pay_hub.rb +++ b/lib/active_merchant/billing/gateways/pay_hub.rb @@ -5,7 +5,7 @@ class PayHubGateway < Gateway self.supported_countries = ['US'] self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://www.payhub.com/' self.display_name = 'PayHub' @@ -66,7 +66,7 @@ class PayHubGateway < Gateway '43' => STANDARD_ERROR_CODE[:pickup_card] } - def initialize(options={}) + def initialize(options = {}) requires!(options, :orgid, :username, :password, :tid) super @@ -82,7 +82,7 @@ def authorize(amount, creditcard, options = {}) commit(post) end - def purchase(amount, creditcard, options={}) + def purchase(amount, creditcard, options = {}) post = setup_post('sale') add_creditcard(post, creditcard) add_amount(post, amount) @@ -92,7 +92,7 @@ def purchase(amount, creditcard, options={}) commit(post) end - def refund(amount, trans_id, options={}) + def refund(amount, trans_id, options = {}) # Attempt a void in case the transaction is unsettled post = setup_post('void') add_reference(post, trans_id) @@ -115,7 +115,7 @@ def capture(amount, trans_id, options = {}) # No void, as PayHub's void does not work on authorizations - def verify(creditcard, options={}) + def verify(creditcard, options = {}) authorize(100, creditcard, options) end @@ -145,6 +145,7 @@ def add_customer_data(post, options = {}) def add_address(post, address) return unless address + post[:address1] = address[:address1] post[:address2] = address[:address2] post[:zip] = address[:zip] @@ -153,7 +154,7 @@ def add_address(post, address) end def add_amount(post, amount) - post[:amount] = amount(amount) + post[:amount] = amount(amount) end def add_creditcard(post, creditcard) @@ -171,7 +172,7 @@ def commit(post) success = false begin - raw_response = ssl_post(live_url, post.to_json, {'Content-Type' => 'application/json'}) + raw_response = ssl_post(live_url, post.to_json, { 'Content-Type' => 'application/json' }) response = parse(raw_response) success = (response['RESPONSE_CODE'] == '00') rescue ResponseError => e @@ -185,11 +186,10 @@ def commit(post) response_message(response), response, test: test?, - avs_result: {code: response['AVS_RESULT_CODE']}, + avs_result: { code: response['AVS_RESULT_CODE'] }, cvv_result: response['VERIFICATION_RESULT_CODE'], error_code: (success ? nil : STANDARD_ERROR_CODE_MAPPING[response['RESPONSE_CODE']]), - authorization: response['TRANSACTION_ID'] - ) + authorization: response['TRANSACTION_ID']) end def response_error(raw_response) diff --git a/lib/active_merchant/billing/gateways/pay_junction.rb b/lib/active_merchant/billing/gateways/pay_junction.rb index 68a24d6f8fc..0017dfe99ae 100644 --- a/lib/active_merchant/billing/gateways/pay_junction.rb +++ b/lib/active_merchant/billing/gateways/pay_junction.rb @@ -97,7 +97,7 @@ module Billing #:nodoc: # See example use above for address AVS fields # See #recurring for periodic transaction fields class PayJunctionGateway < Gateway - API_VERSION = '1.2' + API_VERSION = '1.2' class_attribute :test_url, :live_url @@ -107,7 +107,7 @@ class PayJunctionGateway < Gateway TEST_LOGIN = 'pj-ql-01' TEST_PASSWORD = 'pj-ql-01p' - SUCCESS_CODES = ['00', '85'] + SUCCESS_CODES = %w[00 85] SUCCESS_MESSAGE = 'The transaction was approved.' FAILURE_MESSAGE = 'The transaction was declined.' @@ -150,7 +150,7 @@ class PayJunctionGateway < Gateway 'AB' => 'Aborted because of an upstream system error, please try again later.' } - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.supported_countries = ['US'] self.homepage_url = 'http://www.payjunction.com/' self.display_name = 'PayJunction' @@ -165,7 +165,7 @@ def initialize(options = {}) # transaction_id that can be used later to postauthorize (capture) the funds. def authorize(money, payment_source, options = {}) parameters = { - :transaction_amount => amount(money), + transaction_amount: amount(money) } add_payment_source(parameters, payment_source) @@ -178,7 +178,7 @@ def authorize(money, payment_source, options = {}) # Execute authorization and capture in a single step. def purchase(money, payment_source, options = {}) parameters = { - :transaction_amount => amount(money), + transaction_amount: amount(money) } add_payment_source(parameters, payment_source) @@ -191,8 +191,8 @@ def purchase(money, payment_source, options = {}) # Retrieve funds that have been previously authorized with _authorization_ def capture(money, authorization, options = {}) parameters = { - :transaction_id => authorization, - :posture => 'capture' + transaction_id: authorization, + posture: 'capture' } add_optional_fields(parameters, options) @@ -203,8 +203,8 @@ def capture(money, authorization, options = {}) # _authorization_ should be the transaction id of the transaction we are returning. def refund(money, authorization, options = {}) parameters = { - :transaction_amount => amount(money), - :transaction_id => authorization + transaction_amount: amount(money), + transaction_id: authorization } commit('CREDIT', parameters) @@ -219,8 +219,8 @@ def credit(money, authorization, options = {}) # through the batch process. def void(authorization, options = {}) parameters = { - :transaction_id => authorization, - :posture => 'void' + transaction_id: authorization, + posture: 'void' } add_optional_fields(parameters, options) @@ -241,16 +241,17 @@ def void(authorization, options = {}) def recurring(money, payment_source, options = {}) ActiveMerchant.deprecated RECURRING_DEPRECATION_MESSAGE - requires!(options, [:periodicity, :monthly, :weekly, :daily], :payments) + requires!(options, %i[periodicity monthly weekly daily], :payments) - periodic_type = case options[:periodicity] - when :monthly - 'month' - when :weekly - 'week' - when :daily - 'day' - end + periodic_type = + case options[:periodicity] + when :monthly + 'month' + when :weekly + 'week' + when :daily + 'day' + end if options[:starting_at].nil? start_date = Time.now.strftime('%Y-%m-%d') @@ -262,12 +263,12 @@ def recurring(money, payment_source, options = {}) end parameters = { - :transaction_amount => amount(money), - :schedule_periodic_type => periodic_type, - :schedule_create => 'true', - :schedule_limit => options[:payments].to_i > 1 ? options[:payments] : 1, - :schedule_periodic_number => 1, - :schedule_start => start_date + transaction_amount: amount(money), + schedule_periodic_type: periodic_type, + schedule_create: 'true', + schedule_limit: options[:payments].to_i > 1 ? options[:payments] : 1, + schedule_periodic_number: 1, + schedule_start: start_date } add_payment_source(parameters, payment_source) @@ -318,7 +319,7 @@ def add_address(params, options) address = options[:billing_address] || options[:address] if address - params[:address] = address[:address1] unless address[:address1].blank? + params[:address] = address[:address1] unless address[:address1].blank? params[:city] = address[:city] unless address[:city].blank? params[:state] = address[:state] unless address[:state].blank? params[:zipcode] = address[:zip] unless address[:zip].blank? @@ -337,9 +338,8 @@ def commit(action, parameters) response = parse(ssl_post(url, post_data(action, parameters))) Response.new(successful?(response), message_from(response), response, - :test => test?, - :authorization => response[:transaction_id] || parameters[:transaction_id] - ) + test: test?, + authorization: response[:transaction_id] || parameters[:transaction_id]) end def successful?(response) @@ -366,7 +366,7 @@ def post_data(action, params) params[:version] = API_VERSION params[:transaction_type] = action - params.reject { |k, v| v.blank? }.collect { |k, v| "dc_#{k}=#{CGI.escape(v.to_s)}" }.join('&') + params.reject { |_k, v| v.blank? }.collect { |k, v| "dc_#{k}=#{CGI.escape(v.to_s)}" }.join('&') end def parse(body) diff --git a/lib/active_merchant/billing/gateways/pay_junction_v2.rb b/lib/active_merchant/billing/gateways/pay_junction_v2.rb index aed266facd6..57b237b28be 100644 --- a/lib/active_merchant/billing/gateways/pay_junction_v2.rb +++ b/lib/active_merchant/billing/gateways/pay_junction_v2.rb @@ -10,31 +10,33 @@ class PayJunctionV2Gateway < Gateway self.supported_countries = ['US'] self.default_currency = 'USD' self.money_format = :dollars - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] - def initialize(options={}) + def initialize(options = {}) requires!(options, :api_login, :api_password, :api_key) super end - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_payment_method(post, payment_method) + add_address(post, options) commit('purchase', post) end - def authorize(amount, payment_method, options={}) + def authorize(amount, payment_method, options = {}) post = {} post[:status] = 'HOLD' add_invoice(post, amount, options) add_payment_method(post, payment_method) + add_address(post, options) commit('authorize', post) end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) post = {} post[:status] = 'CAPTURE' post[:transactionId] = authorization @@ -43,7 +45,7 @@ def capture(amount, authorization, options={}) commit('capture', post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} post[:status] = 'VOID' post[:transactionId] = authorization @@ -51,7 +53,7 @@ def void(authorization, options={}) commit('void', post) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) post = {} post[:action] = 'REFUND' post[:transactionId] = authorization @@ -60,7 +62,7 @@ def refund(amount, authorization, options={}) commit('refund', post) end - def credit(amount, payment_method, options={}) + def credit(amount, payment_method, options = {}) post = {} post[:action] = 'REFUND' add_invoice(post, amount, options) @@ -69,7 +71,7 @@ def credit(amount, payment_method, options={}) commit('credit', post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -110,12 +112,27 @@ def add_payment_method(post, payment_method) end end - def commit(action, params) - response = begin - parse(ssl_invoke(action, params)) - rescue ResponseError => e - parse(e.response.body) + def add_address(post, options) + if address = options[:billing_address] + post[:billingFirstName] = address[:first_name] if address[:first_name] + post[:billingLastName] = address[:last_name] if address[:last_name] + post[:billingCompanyName] = address[:company] if address[:company] + post[:billingPhone] = address[:phone_number] if address[:phone_number] + post[:billingAddress] = address[:address1] if address[:address1] + post[:billingCity] = address[:city] if address[:city] + post[:billingState] = address[:state] if address[:state] + post[:billingCountry] = address[:country] if address[:country] + post[:billingZip] = address[:zip] if address[:zip] end + end + + def commit(action, params) + response = + begin + parse(ssl_invoke(action, params)) + rescue ResponseError => e + parse(e.response.body) + end success = success_from(response) Response.new( @@ -129,7 +146,7 @@ def commit(action, params) end def ssl_invoke(action, params) - if ['purchase', 'authorize', 'refund', 'credit'].include?(action) + if %w[purchase authorize refund credit].include?(action) ssl_post(url(), post_data(params), headers) else ssl_request(:put, url(params), post_data(params), headers) @@ -140,8 +157,8 @@ def headers { 'Authorization' => 'Basic ' + Base64.encode64("#{@options[:api_login]}:#{@options[:api_password]}").strip, 'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8', - 'Accept' => 'application/json', - 'X-PJ-Application-Key' => @options[:api_key].to_s + 'Accept' => 'application/json', + 'X-PJ-Application-Key' => @options[:api_key].to_s } end @@ -149,7 +166,7 @@ def post_data(params) params.map { |k, v| "#{k}=#{CGI.escape(v.to_s)}" }.join('&') end - def url(params={}) + def url(params = {}) test? ? "#{test_url}/#{params[:transactionId]}" : "#{live_url}/#{params[:transactionId]}" end @@ -167,6 +184,7 @@ def parse(body) def success_from(response) return response['response']['approved'] if response['response'] + false end diff --git a/lib/active_merchant/billing/gateways/pay_secure.rb b/lib/active_merchant/billing/gateways/pay_secure.rb index 76c13578379..db7de9bdb4b 100644 --- a/lib/active_merchant/billing/gateways/pay_secure.rb +++ b/lib/active_merchant/billing/gateways/pay_secure.rb @@ -8,10 +8,10 @@ class PaySecureGateway < Gateway # Currently Authorization and Capture is not implemented because # capturing requires the original credit card information TRANSACTIONS = { - :purchase => 'PURCHASE', - :authorization => 'AUTHORISE', - :capture => 'ADVICE', - :credit => 'REFUND' + purchase: 'PURCHASE', + authorization: 'AUTHORISE', + capture: 'ADVICE', + credit: 'REFUND' } SUCCESS = 'Accepted' @@ -20,7 +20,7 @@ class PaySecureGateway < Gateway self.supported_countries = ['AU'] self.homepage_url = 'http://www.commsecure.com.au/paysecure.shtml' self.display_name = 'PaySecure' - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club] + self.supported_cardtypes = %i[visa master american_express diners_club] def initialize(options = {}) requires!(options, :login, :password) @@ -43,7 +43,7 @@ def purchase(money, credit_card, options = {}) # Used for capturing, which is currently not supported. def add_reference(post, identification) auth, trans_id = identification.split(';') - post[:authnum] = auth + post[:authnum] = auth post[:transid] = trans_id end @@ -69,9 +69,8 @@ def commit(action, money, parameters) response = parse(ssl_post(self.live_url, post_data(action, parameters))) Response.new(successful?(response), message_from(response), response, - :test => test_response?(response), - :authorization => authorization_from(response) - ) + test: test_response?(response), + authorization: authorization_from(response)) end def successful?(response) @@ -79,7 +78,7 @@ def successful?(response) end def authorization_from(response) - [ response[:authnum], response[:transid] ].compact.join(';') + [response[:authnum], response[:transid]].compact.join(';') end def test_response?(response) @@ -104,7 +103,7 @@ def post_data(action, parameters = {}) parameters[:merchant_id] = @options[:login] parameters[:password] = @options[:password] - parameters.reject { |k, v| v.blank? }.collect { |key, value| "#{key.to_s.upcase}=#{CGI.escape(value.to_s)}" }.join('&') + parameters.reject { |_k, v| v.blank? }.collect { |key, value| "#{key.to_s.upcase}=#{CGI.escape(value.to_s)}" }.join('&') end end end diff --git a/lib/active_merchant/billing/gateways/paybox_direct.rb b/lib/active_merchant/billing/gateways/paybox_direct.rb index de236330928..850eead7cac 100644 --- a/lib/active_merchant/billing/gateways/paybox_direct.rb +++ b/lib/active_merchant/billing/gateways/paybox_direct.rb @@ -12,34 +12,34 @@ class PayboxDirectGateway < Gateway # Transactions hash TRANSACTIONS = { - :authorization => '00001', - :capture => '00002', - :purchase => '00003', - :unreferenced_credit => '00004', - :void => '00005', - :refund => '00014' + authorization: '00001', + capture: '00002', + purchase: '00003', + unreferenced_credit: '00004', + void: '00005', + refund: '00014' } CURRENCY_CODES = { - 'AUD'=> '036', - 'CAD'=> '124', - 'CZK'=> '203', - 'DKK'=> '208', - 'HKD'=> '344', - 'ICK'=> '352', - 'JPY'=> '392', - 'NOK'=> '578', - 'SGD'=> '702', - 'SEK'=> '752', - 'CHF'=> '756', - 'GBP'=> '826', - 'USD'=> '840', - 'EUR'=> '978', - 'XPF'=> '953' + 'AUD' => '036', + 'CAD' => '124', + 'CZK' => '203', + 'DKK' => '208', + 'HKD' => '344', + 'ICK' => '352', + 'JPY' => '392', + 'NOK' => '578', + 'SGD' => '702', + 'SEK' => '752', + 'CHF' => '756', + 'GBP' => '826', + 'USD' => '840', + 'EUR' => '978', + 'XPF' => '953' } SUCCESS_CODES = ['00000'] - UNAVAILABILITY_CODES = ['00001', '00097', '00098'] + UNAVAILABILITY_CODES = %w[00001 00097 00098] SUCCESS_MESSAGE = 'The transaction was approved' FAILURE_MESSAGE = 'The transaction failed' @@ -51,7 +51,7 @@ class PayboxDirectGateway < Gateway self.supported_countries = ['FR'] # The card types supported by the payment gateway - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :jcb] + self.supported_cardtypes = %i[visa master american_express diners_club jcb] # The homepage URL of the gateway self.homepage_url = 'http://www.paybox.com/' @@ -64,10 +64,31 @@ def initialize(options = {}) super end + def add_3dsecure(post, options) + # ECI=02 => MasterCard success + # ECI=05 => Visa, Amex or JCB success + if options[:eci] == '02' || options[:eci] == '05' + post[:"3DSTATUS"] = 'Y' + post[:"3DENROLLED"] = 'Y' + post[:"3DSIGNVAL"] = 'Y' + post[:"3DERROR"] = '0' + else + post[:"3DSTATUS"] = 'N' + post[:"3DENROLLED"] = 'N' + post[:"3DSIGNVAL"] = 'N' + post[:"3DERROR"] = '10000' + end + post[:"3DECI"] = options[:eci] + post[:"3DXID"] = options[:xid] + post[:"3DCAVV"] = options[:cavv] + post[:"3DCAVVALGO"] = options[:cavv_algorithm] + end + def authorize(money, creditcard, options = {}) post = {} add_invoice(post, options) add_creditcard(post, creditcard) + add_3dsecure(post, options[:three_d_secure]) if options[:three_d_secure] add_amount(post, money, options) commit('authorization', money, post) @@ -77,6 +98,7 @@ def purchase(money, creditcard, options = {}) post = {} add_invoice(post, options) add_creditcard(post, creditcard) + add_3dsecure(post, options[:three_d_secure]) if options[:three_d_secure] add_amount(post, money, options) commit('purchase', money, post) @@ -95,7 +117,7 @@ def capture(money, authorization, options = {}) def void(identification, options = {}) requires!(options, :order_id, :amount) - post ={} + post = {} add_invoice(post, options) add_reference(post, identification) add_amount(post, options[:amount], options) @@ -153,12 +175,14 @@ def commit(action, money = nil, parameters = nil) request_data = post_data(action, parameters) response = parse(ssl_post(test? ? self.test_url : self.live_url, request_data)) response = parse(ssl_post(self.live_url_backup, request_data)) if service_unavailable?(response) && !test? - Response.new(success?(response), message_from(response), response.merge( - :timestamp => parameters[:dateq]), - :test => test?, - :authorization => response[:numappel].to_s + response[:numtrans].to_s, - :fraud_review => false, - :sent_params => parameters.delete_if { |key, value| ['porteur', 'dateval', 'cvv'].include?(key.to_s) } + Response.new( + success?(response), + message_from(response), + response.merge(timestamp: parameters[:dateq]), + test: test?, + authorization: response[:numappel].to_s + response[:numtrans].to_s, + fraud_review: false, + sent_params: parameters.delete_if { |key, _value| %w[porteur dateval cvv].include?(key.to_s) } ) end @@ -171,20 +195,20 @@ def service_unavailable?(response) end def message_from(response) - success?(response) ? SUCCESS_MESSAGE : (response[:commentaire] || FAILURE_MESSAGE) + success?(response) ? SUCCESS_MESSAGE : (response[:commentaire] || FAILURE_MESSAGE) end def post_data(action, parameters = {}) parameters.update( - :version => API_VERSION, - :type => TRANSACTIONS[action.to_sym], - :dateq => Time.now.strftime('%d%m%Y%H%M%S'), - :numquestion => unique_id(parameters[:order_id]), - :site => @options[:login].to_s[0, 7], - :rang => @options[:rang] || @options[:login].to_s[7..-1], - :cle => @options[:password], - :pays => '', - :archivage => parameters[:order_id] + version: API_VERSION, + type: TRANSACTIONS[action.to_sym], + dateq: Time.now.strftime('%d%m%Y%H%M%S'), + numquestion: unique_id(parameters[:order_id]), + site: @options[:login].to_s[0, 7], + rang: @options[:rang] || @options[:login].to_s[7..-1], + cle: @options[:password], + pays: '', + archivage: parameters[:order_id] ) parameters.collect { |key, value| "#{key.to_s.upcase}=#{CGI.escape(value.to_s)}" }.join('&') diff --git a/lib/active_merchant/billing/gateways/payeezy.rb b/lib/active_merchant/billing/gateways/payeezy.rb index b1ac0632f4c..d65100efb4b 100644 --- a/lib/active_merchant/billing/gateways/payeezy.rb +++ b/lib/active_merchant/billing/gateways/payeezy.rb @@ -11,7 +11,7 @@ class PayeezyGateway < Gateway self.money_format = :cents self.supported_countries = %w(US CA) - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club] + self.supported_cardtypes = %i[visa master american_express discover jcb diners_club] self.homepage_url = 'https://developer.payeezy.com/' self.display_name = 'Payeezy' @@ -45,7 +45,7 @@ def purchase(amount, payment_method, options = {}) end def authorize(amount, payment_method, options = {}) - params = {transaction_type: 'authorize'} + params = { transaction_type: 'authorize' } add_invoice(params, options) add_reversal_id(params, options) @@ -59,7 +59,7 @@ def authorize(amount, payment_method, options = {}) end def capture(amount, authorization, options = {}) - params = {transaction_type: 'capture'} + params = { transaction_type: 'capture' } add_authorization_info(params, authorization) add_amount(params, amount, options) @@ -69,7 +69,7 @@ def capture(amount, authorization, options = {}) end def refund(amount, authorization, options = {}) - params = {transaction_type: 'refund'} + params = { transaction_type: 'refund' } add_authorization_info(params, authorization) add_amount(params, (amount || amount_from_authorization(authorization)), options) @@ -78,7 +78,7 @@ def refund(amount, authorization, options = {}) end def store(payment_method, options = {}) - params = {transaction_type: 'store'} + params = { transaction_type: 'store' } add_creditcard_for_tokenization(params, payment_method, options) @@ -86,7 +86,7 @@ def store(payment_method, options = {}) end def void(authorization, options = {}) - params = {transaction_type: 'void'} + params = { transaction_type: 'void' } add_authorization_info(params, authorization, options) add_amount(params, amount_from_authorization(authorization), options) @@ -94,7 +94,7 @@ def void(authorization, options = {}) commit(params, options) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(0, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -136,7 +136,7 @@ def amount_from_authorization(authorization) end def add_authorization_info(params, authorization, options = {}) - transaction_id, transaction_tag, method, _ = authorization.split('|') + transaction_id, transaction_tag, method, = authorization.split('|') params[:method] = method == 'token' ? 'credit_card' : method if options[:reversal_id] @@ -155,7 +155,7 @@ def add_creditcard_for_tokenization(params, payment_method, options) params[:auth] = 'false' end - def is_store_action?(params) + def store_action?(params) params[:transaction_type] == 'store' end @@ -247,16 +247,34 @@ def add_soft_descriptors(params, options) end def add_stored_credentials(params, options) - if options[:sequence] + if options[:sequence] || options[:stored_credential] params[:stored_credentials] = {} - params[:stored_credentials][:cardbrand_original_transaction_id] = options[:cardbrand_original_transaction_id] if options[:cardbrand_original_transaction_id] - params[:stored_credentials][:sequence] = options[:sequence] - params[:stored_credentials][:initiator] = options[:initiator] if options[:initiator] - params[:stored_credentials][:is_scheduled] = options[:is_scheduled] + params[:stored_credentials][:cardbrand_original_transaction_id] = original_transaction_id(options) if original_transaction_id(options) + params[:stored_credentials][:initiator] = initiator(options) if initiator(options) + params[:stored_credentials][:sequence] = options[:sequence] || sequence(options[:stored_credential][:initial_transaction]) + params[:stored_credentials][:is_scheduled] = options[:is_scheduled] || is_scheduled(options[:stored_credential][:reason_type]) params[:stored_credentials][:auth_type_override] = options[:auth_type_override] if options[:auth_type_override] end end + def original_transaction_id(options) + return options[:cardbrand_original_transaction_id] if options[:cardbrand_original_transaction_id] + return options[:stored_credential][:network_transaction_id] if options.dig(:stored_credential, :network_transaction_id) + end + + def initiator(options) + return options[:initiator] if options[:initiator] + return options[:stored_credential][:initiator].upcase if options.dig(:stored_credential, :initiator) + end + + def sequence(initial_transaction) + initial_transaction ? 'FIRST' : 'SUBSEQUENT' + end + + def is_scheduled(reason_type) + reason_type == 'recurring' ? 'true' : 'false' + end + def commit(params, options) url = base_url(options) + endpoint(params) @@ -272,15 +290,16 @@ def commit(params, options) response = json_error(e.response.body) end + success = success_from(response) Response.new( - success_from(response), - handle_message(response, success_from(response)), + success, + handle_message(response, success), response, test: test?, authorization: authorization_from(params, response), - avs_result: {code: response['avs']}, + avs_result: { code: response['avs'] }, cvv_result: response['cvv2'], - error_code: error_code(response, success_from(response)) + error_code: success ? nil : error_code_from(response) ) end @@ -295,7 +314,7 @@ def base_url(options) end def endpoint(params) - is_store_action?(params) ? '/transactions/tokens' : '/transactions' + store_action?(params) ? '/transactions/tokens' : '/transactions' end def api_request(url, params) @@ -305,7 +324,8 @@ def api_request(url, params) def post_data(params) return nil unless params - params.reject { |k, v| v.blank? }.collect { |k, v| "#{k}=#{CGI.escape(v.to_s)}" }.join('&') + + params.reject { |_k, v| v.blank? }.collect { |k, v| "#{k}=#{CGI.escape(v.to_s)}" }.join('&') end def generate_hmac(nonce, current_timestamp, payload) @@ -333,9 +353,16 @@ def headers(payload) } end - def error_code(response, success) - return if success - response['Error'].to_h['messages'].to_a.map { |e| e['code'] }.join(', ') + def error_code_from(response) + error_code = nil + if response['bank_resp_code'] == '100' + return + elsif response['bank_resp_code'] + error_code = response['bank_resp_code'] + elsif error_code = response['Error'].to_h['messages'].to_a.map { |e| e['code'] }.join(', ') + end + + error_code end def success_from(response) @@ -371,7 +398,7 @@ def handle_message(response, success) end def authorization_from(params, response) - if is_store_action?(params) + if store_action?(params) if success_from(response) [ response['token']['type'], @@ -403,7 +430,7 @@ def response_error(raw_response) end def json_error(raw_response) - {'error' => "Unable to parse response: #{raw_response.inspect}"} + { 'error' => "Unable to parse response: #{raw_response.inspect}" } end end end diff --git a/lib/active_merchant/billing/gateways/payex.rb b/lib/active_merchant/billing/gateways/payex.rb index c43e36bb13f..3d63b8957a0 100644 --- a/lib/active_merchant/billing/gateways/payex.rb +++ b/lib/active_merchant/billing/gateways/payex.rb @@ -12,8 +12,8 @@ class PayexGateway < Gateway self.test_confined_url = 'https://test-confined.payex.com/' self.money_format = :cents - self.supported_countries = ['DK', 'FI', 'NO', 'SE'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_countries = %w[DK FI NO SE] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://payex.com/' self.display_name = 'Payex' self.default_currency = 'EUR' @@ -25,18 +25,18 @@ class PayexGateway < Gateway authorize: '3', cancel: '4', failure: '5', - capture: '6', + capture: '6' } SOAP_ACTIONS = { initialize: { name: 'Initialize8', url: 'pxorder/pxorder.asmx', xmlns: 'http://external.payex.com/PxOrder/' }, - purchasecc: { name: 'PurchaseCC', url: 'pxconfined/pxorder.asmx', xmlns: 'http://confined.payex.com/PxOrder/', confined: true}, + purchasecc: { name: 'PurchaseCC', url: 'pxconfined/pxorder.asmx', xmlns: 'http://confined.payex.com/PxOrder/', confined: true }, cancel: { name: 'Cancel2', url: 'pxorder/pxorder.asmx', xmlns: 'http://external.payex.com/PxOrder/' }, capture: { name: 'Capture5', url: 'pxorder/pxorder.asmx', xmlns: 'http://external.payex.com/PxOrder/' }, credit: { name: 'Credit5', url: 'pxorder/pxorder.asmx', xmlns: 'http://external.payex.com/PxOrder/' }, create_agreement: { name: 'CreateAgreement3', url: 'pxagreement/pxagreement.asmx', xmlns: 'http://external.payex.com/PxAgreement/' }, delete_agreement: { name: 'DeleteAgreement', url: 'pxagreement/pxagreement.asmx', xmlns: 'http://external.payex.com/PxAgreement/' }, - autopay: { name: 'AutoPay3', url: 'pxagreement/pxagreement.asmx', xmlns: 'http://external.payex.com/PxAgreement/' }, + autopay: { name: 'AutoPay3', url: 'pxagreement/pxagreement.asmx', xmlns: 'http://external.payex.com/PxAgreement/' } } def initialize(options = {}) @@ -117,7 +117,7 @@ def capture(money, authorization, options = {}) # options - A standard ActiveMerchant options hash # # Returns an ActiveMerchant::Billing::Response object - def void(authorization, options={}) + def void(authorization, options = {}) send_cancel(authorization) end @@ -155,7 +155,7 @@ def store(creditcard, options = {}) amount = amount(1) # 1 cent for authorization MultiResponse.run(:first) do |r| r.process { send_create_agreement(options) } - r.process { send_initialize(amount, true, options.merge({agreement_ref: r.authorization})) } + r.process { send_initialize(amount, true, options.merge({ agreement_ref: r.authorization })) } order_ref = r.params['orderref'] r.process { send_purchasecc(creditcard, order_ref) } end @@ -193,9 +193,9 @@ def send_initialize(amount, is_auth, options = {}) cancelUrl: nil, clientLanguage: nil } - hash_fields = [:accountNumber, :purchaseOperation, :price, :priceArgList, :currency, :vat, :orderID, - :productNumber, :description, :clientIPAddress, :clientIdentifier, :additionalValues, - :externalID, :returnUrl, :view, :agreementRef, :cancelUrl, :clientLanguage] + hash_fields = %i[accountNumber purchaseOperation price priceArgList currency vat orderID + productNumber description clientIPAddress clientIdentifier additionalValues + externalID returnUrl view agreementRef cancelUrl clientLanguage] add_request_hash(properties, hash_fields) soap_action = SOAP_ACTIONS[:initialize] request = build_xml_request(soap_action, properties) @@ -213,8 +213,8 @@ def send_purchasecc(payment_method, order_ref) cardHolderName: payment_method.name, cardNumberCVC: payment_method.verification_value } - hash_fields = [:accountNumber, :orderRef, :transactionType, :cardNumber, :cardNumberExpireMonth, - :cardNumberExpireYear, :cardNumberCVC, :cardHolderName] + hash_fields = %i[accountNumber orderRef transactionType cardNumber cardNumberExpireMonth + cardNumberExpireYear cardNumberCVC cardHolderName] add_request_hash(properties, hash_fields) soap_action = SOAP_ACTIONS[:purchasecc] @@ -231,9 +231,9 @@ def send_autopay(amount, authorization, is_auth, options = {}) description: options[:description] || options[:order_id], orderId: options[:order_id], purchaseOperation: is_auth ? 'AUTHORIZATION' : 'SALE', - currency: (options[:currency] || default_currency), + currency: (options[:currency] || default_currency) } - hash_fields = [:accountNumber, :agreementRef, :price, :productNumber, :description, :orderId, :purchaseOperation, :currency] + hash_fields = %i[accountNumber agreementRef price productNumber description orderId purchaseOperation currency] add_request_hash(properties, hash_fields) soap_action = SOAP_ACTIONS[:autopay] @@ -250,7 +250,7 @@ def send_capture(amount, transaction_number, options = {}) vatAmount: options[:vat_amount] || 0, additionalValues: '' } - hash_fields = [:accountNumber, :transactionNumber, :amount, :orderId, :vatAmount, :additionalValues] + hash_fields = %i[accountNumber transactionNumber amount orderId vatAmount additionalValues] add_request_hash(properties, hash_fields) soap_action = SOAP_ACTIONS[:capture] @@ -267,7 +267,7 @@ def send_credit(transaction_number, amount, options = {}) vatAmount: options[:vat_amount] || 0, additionalValues: '' } - hash_fields = [:accountNumber, :transactionNumber, :amount, :orderId, :vatAmount, :additionalValues] + hash_fields = %i[accountNumber transactionNumber amount orderId vatAmount additionalValues] add_request_hash(properties, hash_fields) soap_action = SOAP_ACTIONS[:credit] @@ -278,9 +278,9 @@ def send_credit(transaction_number, amount, options = {}) def send_cancel(transaction_number) properties = { accountNumber: @options[:account], - transactionNumber: transaction_number, + transactionNumber: transaction_number } - hash_fields = [:accountNumber, :transactionNumber] + hash_fields = %i[accountNumber transactionNumber] add_request_hash(properties, hash_fields) soap_action = SOAP_ACTIONS[:cancel] @@ -299,7 +299,7 @@ def send_create_agreement(options) startDate: options[:startDate] || '', stopDate: options[:stopDate] || '' } - hash_fields = [:accountNumber, :merchantRef, :description, :purchaseOperation, :maxAmount, :notifyUrl, :startDate, :stopDate] + hash_fields = %i[accountNumber merchantRef description purchaseOperation maxAmount notifyUrl startDate stopDate] add_request_hash(properties, hash_fields) soap_action = SOAP_ACTIONS[:create_agreement] @@ -310,9 +310,9 @@ def send_create_agreement(options) def send_delete_agreement(authorization) properties = { accountNumber: @options[:account], - agreementRef: authorization, + agreementRef: authorization } - hash_fields = [:accountNumber, :agreementRef] + hash_fields = %i[accountNumber agreementRef] add_request_hash(properties, hash_fields) soap_action = SOAP_ACTIONS[:delete_agreement] @@ -341,9 +341,9 @@ def add_request_hash(properties, fields) def build_xml_request(soap_action, properties) builder = Nokogiri::XML::Builder.new - builder.__send__('soap12:Envelope', {'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + builder.__send__('soap12:Envelope', { 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema', - 'xmlns:soap12' => 'http://www.w3.org/2003/05/soap-envelope'}) do |root| + 'xmlns:soap12' => 'http://www.w3.org/2003/05/soap-envelope' }) do |root| root.__send__('soap12:Body') do |body| body.__send__(soap_action[:name], xmlns: soap_action[:xmlns]) do |doc| properties.each do |key, val| @@ -389,8 +389,7 @@ def commit(soap_action, request) message_from(response), response, test: test?, - authorization: build_authorization(response) - ) + authorization: build_authorization(response)) end def build_authorization(response) diff --git a/lib/active_merchant/billing/gateways/payflow.rb b/lib/active_merchant/billing/gateways/payflow.rb index e12b5ba1309..a4a0455d59b 100644 --- a/lib/active_merchant/billing/gateways/payflow.rb +++ b/lib/active_merchant/billing/gateways/payflow.rb @@ -8,9 +8,9 @@ module Billing #:nodoc: class PayflowGateway < Gateway include PayflowCommonAPI - RECURRING_ACTIONS = Set.new([:add, :modify, :cancel, :inquiry, :reactivate, :payment]) + RECURRING_ACTIONS = Set.new(%i[add modify cancel inquiry reactivate payment]) - self.supported_cardtypes = [:visa, :master, :american_express, :jcb, :discover, :diners_club] + self.supported_cardtypes = %i[visa master american_express jcb discover diners_club] self.homepage_url = 'https://www.paypal.com/cgi-bin/webscr?cmd=_payflow-pro-overview-outside' self.display_name = 'PayPal Payflow Pro' @@ -45,7 +45,7 @@ def refund(money, reference, options = {}) commit(build_reference_request(:credit, money, reference, options), options) end - def verify(payment, options={}) + def verify(payment, options = {}) if credit_card_type(payment) == 'Amex' MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, payment, options) } @@ -80,21 +80,21 @@ def recurring(money, credit_card, options = {}) request = build_recurring_request(options[:profile_id] ? :modify : :add, money, options) do |xml| add_credit_card(xml, credit_card, options) if credit_card end - commit(request, options.merge(:request_type => :recurring)) + commit(request, options.merge(request_type: :recurring)) end def cancel_recurring(profile_id) ActiveMerchant.deprecated RECURRING_DEPRECATION_MESSAGE - request = build_recurring_request(:cancel, 0, :profile_id => profile_id) - commit(request, options.merge(:request_type => :recurring)) + request = build_recurring_request(:cancel, 0, profile_id: profile_id) + commit(request, options.merge(request_type: :recurring)) end def recurring_inquiry(profile_id, options = {}) ActiveMerchant.deprecated RECURRING_DEPRECATION_MESSAGE - request = build_recurring_request(:inquiry, nil, options.update(:profile_id => profile_id)) - commit(request, options.merge(:request_type => :recurring)) + request = build_recurring_request(:inquiry, nil, options.update(profile_id: profile_id)) + commit(request, options.merge(request_type: :recurring)) end def express @@ -136,7 +136,7 @@ def build_reference_sale_or_authorization_request(action, money, reference, opti xml.tag! 'Description', options[:description] unless options[:description].blank? xml.tag! 'OrderDesc', options[:order_desc] unless options[:order_desc].blank? xml.tag! 'Comment', options[:comment] unless options[:comment].blank? - xml.tag!('ExtData', 'Name'=> 'COMMENT2', 'Value'=> options[:comment2]) unless options[:comment2].blank? + xml.tag!('ExtData', 'Name' => 'COMMENT2', 'Value' => options[:comment2]) unless options[:comment2].blank? xml.tag! 'TaxAmt', options[:taxamt] unless options[:taxamt].blank? xml.tag! 'FreightAmt', options[:freightamt] unless options[:freightamt].blank? xml.tag! 'DutyAmt', options[:dutyamt] unless options[:dutyamt].blank? @@ -150,10 +150,11 @@ def build_reference_sale_or_authorization_request(action, money, reference, opti end xml.tag! 'Tender' do xml.tag! 'Card' do - xml.tag! 'ExtData', 'Name' => 'ORIGID', 'Value' => reference + xml.tag! 'ExtData', 'Name' => 'ORIGID', 'Value' => reference end end end + xml.tag! 'ExtData', 'Name' => 'BUTTONSOURCE', 'Value' => application_id unless application_id.blank? end xml.target! end @@ -169,7 +170,7 @@ def build_credit_card_request(action, money, credit_card, options) xml.tag! 'OrderDesc', options[:order_desc] unless options[:order_desc].blank? # Comment and Comment2 will show up in manager.paypal.com as Comment1 and Comment2 xml.tag! 'Comment', options[:comment] unless options[:comment].blank? - xml.tag!('ExtData', 'Name'=> 'COMMENT2', 'Value'=> options[:comment2]) unless options[:comment2].blank? + xml.tag!('ExtData', 'Name' => 'COMMENT2', 'Value' => options[:comment2]) unless options[:comment2].blank? xml.tag! 'TaxAmt', options[:taxamt] unless options[:taxamt].blank? xml.tag! 'FreightAmt', options[:freightamt] unless options[:freightamt].blank? xml.tag! 'DutyAmt', options[:dutyamt] unless options[:dutyamt].blank? @@ -187,6 +188,7 @@ def build_credit_card_request(action, money, credit_card, options) add_credit_card(xml, credit_card, options) end end + xml.tag! 'ExtData', 'Name' => 'BUTTONSOURCE', 'Value' => application_id unless application_id.blank? end add_level_two_three_fields(xml.target!, options) end @@ -250,6 +252,7 @@ def build_check_request(action, money, check, options) end end end + xml.tag! 'ExtData', 'Name' => 'BUTTONSOURCE', 'Value' => application_id unless application_id.blank? end add_level_two_three_fields(xml.target!, options) end @@ -264,7 +267,7 @@ def add_credit_card(xml, credit_card, options = {}) add_three_d_secure(options, xml) - xml.tag! 'ExtData', 'Name' => 'LASTNAME', 'Value' => credit_card.last_name + xml.tag! 'ExtData', 'Name' => 'LASTNAME', 'Value' => credit_card.last_name end end @@ -312,15 +315,13 @@ def startdate(creditcard) end def build_recurring_request(action, money, options) - unless RECURRING_ACTIONS.include?(action) - raise StandardError, "Invalid Recurring Profile Action: #{action}" - end + raise StandardError, "Invalid Recurring Profile Action: #{action}" unless RECURRING_ACTIONS.include?(action) xml = Builder::XmlMarkup.new xml.tag! 'RecurringProfiles' do xml.tag! 'RecurringProfile' do xml.tag! action.to_s.capitalize do - unless [:cancel, :inquiry].include?(action) + unless %i[cancel inquiry].include?(action) xml.tag! 'RPData' do xml.tag! 'Name', options[:name] unless options[:name].nil? xml.tag! 'TotalAmt', amount(money), 'Currency' => options[:currency] || currency(money) @@ -331,7 +332,7 @@ def build_recurring_request(action, money, options) xml.tag! 'MaxFailPayments', options[:max_fail_payments] unless options[:max_fail_payments].nil? if initial_tx = options[:initial_transaction] - requires!(initial_tx, [:type, :authorization, :purchase]) + requires!(initial_tx, %i[type authorization purchase]) requires!(initial_tx, :amount) if initial_tx[:type] == :purchase xml.tag! 'OptionalTrans', TRANSACTIONS[initial_tx[:type]] @@ -354,9 +355,7 @@ def build_recurring_request(action, money, options) yield xml end end - if action != :add - xml.tag! 'ProfileID', options[:profile_id] - end + xml.tag! 'ProfileID', options[:profile_id] if action != :add if action == :inquiry xml.tag! 'PaymentHistory', (options[:history] ? 'Y' : 'N') end @@ -366,7 +365,7 @@ def build_recurring_request(action, money, options) end def get_pay_period(options) - requires!(options, [:periodicity, :bimonthly, :monthly, :biweekly, :weekly, :yearly, :daily, :semimonthly, :quadweekly, :quarterly, :semiyearly]) + requires!(options, %i[periodicity bimonthly monthly biweekly weekly yearly daily semimonthly quadweekly quarterly semiyearly]) case options[:periodicity] when :weekly then 'Weekly' when :biweekly then 'Bi-weekly' diff --git a/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb b/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb index 4ad1bd00739..8ac48f67d1f 100644 --- a/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +++ b/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb @@ -10,7 +10,7 @@ def self.included(base) # Set the default partner to PayPal base.partner = 'PayPal' - base.supported_countries = ['US', 'CA', 'NZ', 'AU'] + base.supported_countries = %w[US CA NZ AU] base.class_attribute :timeout base.timeout = 60 @@ -37,20 +37,20 @@ def self.included(base) XMLNS = 'http://www.paypal.com/XMLPay' CARD_MAPPING = { - :visa => 'Visa', - :master => 'MasterCard', - :discover => 'Discover', - :american_express => 'Amex', - :jcb => 'JCB', - :diners_club => 'DinersClub', + visa: 'Visa', + master: 'MasterCard', + discover: 'Discover', + american_express: 'Amex', + jcb: 'JCB', + diners_club: 'DinersClub' } TRANSACTIONS = { - :purchase => 'Sale', - :authorization => 'Authorization', - :capture => 'Capture', - :void => 'Void', - :credit => 'Credit' + purchase: 'Sale', + authorization: 'Authorization', + capture: 'Capture', + void: 'Void', + credit: 'Credit' } CVV_CODE = { @@ -117,7 +117,7 @@ def build_reference_request(action, money, authorization, options) xml.tag!('TotalAmt', amount(money), 'Currency' => options[:currency] || currency(money)) xml.tag!('Description', options[:description]) unless options[:description].blank? xml.tag!('Comment', options[:comment]) unless options[:comment].blank? - xml.tag!('ExtData', 'Name'=> 'COMMENT2', 'Value'=> options[:comment2]) unless options[:comment2].blank? + xml.tag!('ExtData', 'Name' => 'COMMENT2', 'Value' => options[:comment2]) unless options[:comment2].blank? xml.tag!( 'ExtData', 'Name' => 'CAPTURECOMPLETE', @@ -132,6 +132,7 @@ def build_reference_request(action, money, authorization, options) def add_address(xml, tag, address, options) return if address.nil? + xml.tag! tag do xml.tag! 'Name', address[:name] unless address[:name].blank? xml.tag! 'EMail', options[:email] unless options[:email].blank? @@ -159,9 +160,7 @@ def parse(data) # REXML::XPath in Ruby 1.8.6 is now unable to match nodes based on their attributes tx_result = root.xpath('.//TransactionResult').first - if tx_result && tx_result.attributes['Duplicate'].to_s == 'true' - response[:duplicate] = true - end + response[:duplicate] = true if tx_result && tx_result.attributes['Duplicate'].to_s == 'true' root.xpath('.//*').each do |node| parse_element(response, node) @@ -182,7 +181,7 @@ def parse_element(response, node) node.xpath('.//*').each { |e| parse_element(payment_result_response, e) } when node.xpath('.//*').to_a.any? node.xpath('.//*').each { |e| parse_element(response, e) } - when node_name.to_s =~ /amt$/ + when /amt$/.match?(node_name.to_s) # *Amt elements don't put the value in the #text - instead they use a Currency attribute response[node_name] = node.attributes['Currency'].to_s when node_name == :ext_data diff --git a/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb b/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb index 3c43642265f..b63a083cb30 100644 --- a/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +++ b/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb @@ -35,8 +35,7 @@ def address 'state' => @params['state'], 'country' => @params['country'], 'zip' => @params['zip'], - 'phone' => phone, - } + 'phone' => phone } end end end diff --git a/lib/active_merchant/billing/gateways/payflow_express.rb b/lib/active_merchant/billing/gateways/payflow_express.rb index 9676d2b1cf2..393d9077368 100644 --- a/lib/active_merchant/billing/gateways/payflow_express.rb +++ b/lib/active_merchant/billing/gateways/payflow_express.rb @@ -110,7 +110,7 @@ def details_for(token) private def build_get_express_details_request(token) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.tag! 'GetExpressCheckout' do xml.tag! 'Authorization' do xml.tag! 'PayData' do @@ -126,7 +126,7 @@ def build_get_express_details_request(token) end def build_setup_express_sale_or_authorization_request(action, money, options = {}) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.tag! 'SetExpressCheckout' do xml.tag! action do add_pay_data xml, money, options @@ -136,7 +136,7 @@ def build_setup_express_sale_or_authorization_request(action, money, options = { end def build_sale_or_authorization_request(action, money, options) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.tag! 'DoExpressCheckout' do xml.tag! action do add_pay_data xml, money, options @@ -155,7 +155,7 @@ def add_pay_data(xml, money, options) # Comment, Comment2 should make it to the backend at manager.paypal.com, as with Payflow credit card transactions # but that doesn't seem to work (yet?). See: https://www.x.com/thread/51908?tstart=0 xml.tag! 'Comment', options[:comment] unless options[:comment].nil? - xml.tag!('ExtData', 'Name'=> 'COMMENT2', 'Value'=> options[:comment2]) unless options[:comment2].nil? + xml.tag!('ExtData', 'Name' => 'COMMENT2', 'Value' => options[:comment2]) unless options[:comment2].nil? billing_address = options[:billing_address] || options[:address] add_address(xml, 'BillTo', billing_address, options) if billing_address diff --git a/lib/active_merchant/billing/gateways/payflow_uk.rb b/lib/active_merchant/billing/gateways/payflow_uk.rb index e963c152ef0..d44a9910a8c 100644 --- a/lib/active_merchant/billing/gateways/payflow_uk.rb +++ b/lib/active_merchant/billing/gateways/payflow_uk.rb @@ -11,7 +11,7 @@ def express @express ||= PayflowExpressUkGateway.new(@options) end - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.supported_countries = ['GB'] self.homepage_url = 'https://www.paypal.com/uk/webapps/mpp/pro' self.display_name = 'PayPal Payments Pro (UK)' diff --git a/lib/active_merchant/billing/gateways/payment_express.rb b/lib/active_merchant/billing/gateways/payment_express.rb index ff89eb8cb08..0378ba4fecd 100644 --- a/lib/active_merchant/billing/gateways/payment_express.rb +++ b/lib/active_merchant/billing/gateways/payment_express.rb @@ -13,12 +13,12 @@ class PaymentExpressGateway < Gateway # VISA, Mastercard, Diners Club and Farmers cards are supported # # However, regular accounts with DPS only support VISA and Mastercard - self.supported_cardtypes = [ :visa, :master, :american_express, :diners_club, :jcb ] + self.supported_cardtypes = %i[visa master american_express diners_club jcb] - self.supported_countries = %w[ AU FJ GB HK IE MY NZ PG SG US ] + self.supported_countries = %w[AU FJ GB HK IE MY NZ PG SG US] - self.homepage_url = 'http://www.paymentexpress.com/' - self.display_name = 'PaymentExpress' + self.homepage_url = 'https://www.windcave.com/' + self.display_name = 'Windcave (formerly PaymentExpress)' self.live_url = 'https://sec.paymentexpress.com/pxpost.aspx' self.test_url = 'https://uat.paymentexpress.com/pxpost.aspx' @@ -26,11 +26,11 @@ class PaymentExpressGateway < Gateway APPROVED = '1' TRANSACTIONS = { - :purchase => 'Purchase', - :credit => 'Refund', - :authorization => 'Auth', - :capture => 'Complete', - :validate => 'Validate' + purchase: 'Purchase', + credit: 'Refund', + authorization: 'Auth', + capture: 'Complete', + validate: 'Validate' } # We require the DPS gateway username and password when the object is created. @@ -86,6 +86,11 @@ def credit(money, identification, options = {}) refund(money, identification, options) end + def verify(payment_source, options = {}) + request = build_purchase_or_authorization_request(nil, payment_source, options) + commit(:validate, request) + end + # Token Based Billing # # Instead of storing the credit card details locally, you can store them inside the @@ -118,7 +123,7 @@ def credit(money, identification, options = {}) # # Note, once stored, PaymentExpress does not support unstoring a stored card. def store(credit_card, options = {}) - request = build_token_request(credit_card, options) + request = build_token_request(credit_card, options) commit(:validate, request) end @@ -149,7 +154,7 @@ def build_purchase_or_authorization_request(money, payment_source, options) add_credit_card(result, payment_source) end - add_amount(result, money, options) + add_amount(result, money, options) if money add_invoice(result, options) add_address_verification_data(result, options) add_optional_elements(result, options) @@ -302,9 +307,8 @@ def commit(action, request) # Return a response PaymentExpressResponse.new(response[:success] == APPROVED, message_from(response), response, - :test => response[:test_mode] == '1', - :authorization => authorization_from(action, response) - ) + test: response[:test_mode] == '1', + authorization: authorization_from(action, response)) end # Response XML documentation: http://www.paymentexpress.com/technical_resources/ecommerce_nonhosted/pxpost.html#XMLTxnOutput @@ -335,7 +339,7 @@ def message_from(response) def authorization_from(action, response) case action when :validate - (response[:billing_id] || response[:dps_billing_id]) + (response[:billing_id] || response[:dps_billing_id] || response[:dps_txn_ref]) else response[:dps_txn_ref] end @@ -362,7 +366,7 @@ class PaymentExpressResponse < Response # add a method to response so we can easily get the token # for Validate transactions def token - @params['billing_id'] || @params['dps_billing_id'] + @params['billing_id'] || @params['dps_billing_id'] || @params['dps_txn_ref'] end end end diff --git a/lib/active_merchant/billing/gateways/paymentez.rb b/lib/active_merchant/billing/gateways/paymentez.rb index 50463010ea2..0dcad25be14 100644 --- a/lib/active_merchant/billing/gateways/paymentez.rb +++ b/lib/active_merchant/billing/gateways/paymentez.rb @@ -7,9 +7,9 @@ class PaymentezGateway < Gateway #:nodoc: self.test_url = 'https://ccapi-stg.paymentez.com/v2/' self.live_url = 'https://ccapi.paymentez.com/v2/' - self.supported_countries = %w[MX EC VE CO BR CL] + self.supported_countries = %w[MX EC CO BR CL PE] self.default_currency = 'USD' - self.supported_cardtypes = %i[visa master american_express diners_club elo] + self.supported_cardtypes = %i[visa master american_express diners_club elo alia olimpica] self.homepage_url = 'https://secure.paymentez.com/' self.display_name = 'Paymentez' @@ -72,16 +72,16 @@ def authorize(money, payment, options = {}) def capture(money, authorization, _options = {}) post = { - transaction: { id: authorization } + transaction: { id: authorization } } - post[:order] = {amount: amount(money).to_f} if money + post[:order] = { amount: amount(money).to_f } if money commit_transaction('capture', post) end def refund(money, authorization, options = {}) - post = {transaction: {id: authorization}} - post[:order] = {amount: amount(money).to_f} if money + post = { transaction: { id: authorization } } + post[:order] = { amount: amount(money).to_f } if money commit_transaction('refund', post) end @@ -113,7 +113,7 @@ def store(credit_card, options = {}) end def unstore(identification, options = {}) - post = { card: { token: identification }, user: { id: options[:user_id] }} + post = { card: { token: identification }, user: { id: options[:user_id] } } commit_card('delete', post) end @@ -175,9 +175,29 @@ def add_extra_params(post, options) extra_params = {} extra_params.merge!(options[:extra_params]) if options[:extra_params] + add_external_mpi_fields(extra_params, options) + post['extra_params'] = extra_params unless extra_params.empty? end + def add_external_mpi_fields(extra_params, options) + three_d_secure_options = options[:three_d_secure] + return unless three_d_secure_options + + auth_data = { + cavv: three_d_secure_options[:cavv], + xid: three_d_secure_options[:xid], + eci: three_d_secure_options[:eci], + version: three_d_secure_options[:version], + reference_id: three_d_secure_options[:three_ds_server_trans_id], + status: three_d_secure_options[:authentication_response_status] || three_d_secure_options[:directory_response_status] + }.compact + + return if auth_data.empty? + + extra_params[:auth_data] = auth_data + end + def parse(body) JSON.parse(body) end @@ -194,7 +214,7 @@ def commit_raw(object, action, parameters) begin parse(raw_response) rescue JSON::ParserError - {'status' => 'Internal server error'} + { 'status' => 'Internal server error' } end end @@ -236,10 +256,13 @@ def success_from(response) def card_success_from(response) return false if response.include?('error') return true if response['message'] == 'card deleted' + response['card']['status'] == 'valid' end def message_from(response) + return response['detail'] if response['detail'].present? + if !success_from(response) && response['error'] response['error'] && response['error']['type'] else @@ -274,11 +297,10 @@ def post_data(parameters = {}) def error_code_from(response) return if success_from(response) + if response['transaction'] detail = response['transaction']['status_detail'] - if STANDARD_ERROR_CODE_MAPPING.include?(detail) - return STANDARD_ERROR_CODE[STANDARD_ERROR_CODE_MAPPING[detail]] - end + return STANDARD_ERROR_CODE[STANDARD_ERROR_CODE_MAPPING[detail]] if STANDARD_ERROR_CODE_MAPPING.include?(detail) elsif response['error'] return STANDARD_ERROR_CODE[:config_error] end diff --git a/lib/active_merchant/billing/gateways/paymill.rb b/lib/active_merchant/billing/gateways/paymill.rb index ba4dbeb8f9d..e0777d56099 100644 --- a/lib/active_merchant/billing/gateways/paymill.rb +++ b/lib/active_merchant/billing/gateways/paymill.rb @@ -5,7 +5,7 @@ class PaymillGateway < Gateway GI GR HR HU IE IL IM IS IT LI LT LU LV MC MT NL NO PL PT RO SE SI SK TR VA) - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :discover, :union_pay, :jcb] + self.supported_cardtypes = %i[visa master american_express diners_club discover union_pay jcb] self.homepage_url = 'https://paymill.com' self.display_name = 'PAYMILL' self.money_format = :cents @@ -17,7 +17,7 @@ def initialize(options = {}) super end - def purchase(money, payment_method, options={}) + def purchase(money, payment_method, options = {}) action_with_token(:purchase, money, payment_method, options) end @@ -35,7 +35,7 @@ def capture(money, authorization, options = {}) commit(:post, 'transactions', post) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) post = {} post[:amount] = amount(money) @@ -43,11 +43,11 @@ def refund(money, authorization, options={}) commit(:post, "refunds/#{transaction_id(authorization)}", post) end - def void(authorization, options={}) + def void(authorization, options = {}) commit(:delete, "preauthorizations/#{preauth(authorization)}") end - def store(credit_card, options={}) + def store(credit_card, options = {}) # The store request requires a currency and amount of at least $1 USD. # This is used for an authorization that is handled internally by Paymill. options[:currency] = 'USD' @@ -86,7 +86,7 @@ def add_credit_card(post, credit_card, options) post['account.expiry.year'] = sprintf('%.4i', credit_card.year) post['account.verification'] = credit_card.verification_value post['account.email'] = (options[:email] || nil) - post['presentation.amount3D'] = (options[:money] || nil) + post['presentation.amount3D'] = (options[:money] || nil) post['presentation.currency3D'] = (options[:currency] || currency(options[:money])) end @@ -94,7 +94,7 @@ def headers { 'Authorization' => ('Basic ' + Base64.strict_encode64("#{@options[:private_key]}:X").chomp) } end - def commit(method, action, parameters=nil) + def commit(method, action, parameters = nil) begin raw_response = ssl_request(method, live_url + action, post_data(parameters), headers) rescue ResponseError => e @@ -112,8 +112,8 @@ def commit(method, action, parameters=nil) def response_from(raw_response) parsed = JSON.parse(raw_response) options = { - :authorization => authorization_from(parsed), - :test => (parsed['mode'] == 'test'), + authorization: authorization_from(parsed), + test: (parsed['mode'] == 'test') } succeeded = (parsed['data'] == []) || (parsed['data']['response_code'].to_i == 20000) @@ -181,7 +181,7 @@ def save_card(credit_card, options) end def response_for_save_from(raw_response) - options = { :test => test? } + options = { test: test? } parser = ResponseParser.new(raw_response, options) parser.generate_response @@ -198,7 +198,7 @@ def save_card_url def post_data(params) return nil unless params - no_blanks = params.reject { |key, value| value.blank? } + no_blanks = params.reject { |_key, value| value.blank? } no_blanks.map { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join('&') end @@ -328,7 +328,7 @@ def response_message(parsed_response) class ResponseParser attr_reader :raw_response, :parsed, :succeeded, :message, :options - def initialize(raw_response='', options={}) + def initialize(raw_response = '', options = {}) @raw_response = raw_response @options = options end @@ -357,12 +357,10 @@ def handle_response_parse_error def handle_response_correct_parsing @message = parsed['transaction']['processing']['return']['message'] - if @succeeded = is_ack? - @options[:authorization] = parsed['transaction']['identification']['uniqueId'] - end + @options[:authorization] = parsed['transaction']['identification']['uniqueId'] if @succeeded = ack? end - def is_ack? + def ack? parsed['transaction']['processing']['result'] == 'ACK' end end diff --git a/lib/active_merchant/billing/gateways/paypal.rb b/lib/active_merchant/billing/gateways/paypal.rb index 3563a40410d..10e42e5aaab 100644 --- a/lib/active_merchant/billing/gateways/paypal.rb +++ b/lib/active_merchant/billing/gateways/paypal.rb @@ -8,8 +8,8 @@ class PaypalGateway < Gateway include PaypalCommonAPI include PaypalRecurringApi - self.supported_cardtypes = [:visa, :master, :american_express, :discover] - self.supported_countries = ['CA', 'NZ', 'GB', 'US'] + self.supported_countries = %w[CA NZ GB US] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'https://www.paypal.com/us/webapps/mpp/paypal-payments-pro' self.display_name = 'PayPal Payments Pro (US)' @@ -55,10 +55,10 @@ def build_sale_or_authorization_request(action, money, credit_card_or_referenced billing_address = options[:billing_address] || options[:address] currency_code = options[:currency] || currency(money) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.tag! transaction_type + 'Req', 'xmlns' => PAYPAL_NAMESPACE do xml.tag! transaction_type + 'Request', 'xmlns:n2' => EBAY_NAMESPACE do - xml.tag! 'n2:Version', API_VERSION + xml.tag! 'n2:Version', api_version(options) xml.tag! 'n2:' + transaction_type + 'RequestDetails' do xml.tag! 'n2:ReferenceID', reference_id if transaction_type == 'DoReferenceTransaction' xml.tag! 'n2:PaymentAction', action @@ -73,6 +73,12 @@ def build_sale_or_authorization_request(action, money, credit_card_or_referenced xml.target! end + def api_version(options) + return API_VERSION_3DS2 if options.dig(:three_d_secure, :version) =~ /^2/ + + API_VERSION + end + def add_credit_card(xml, credit_card, address, options) xml.tag! 'n2:CreditCard' do xml.tag! 'n2:CreditCardType', credit_card_type(card_brand(credit_card)) @@ -104,10 +110,12 @@ def add_three_d_secure(xml, options) three_d_secure = options[:three_d_secure] xml.tag! 'ThreeDSecureRequest' do xml.tag! 'MpiVendor3ds', 'Y' - xml.tag! 'AuthStatus3ds', three_d_secure[:trans_status] unless three_d_secure[:trans_status].blank? + xml.tag! 'AuthStatus3ds', three_d_secure[:authentication_response_status] || three_d_secure[:trans_status] if three_d_secure[:authentication_response_status] || three_d_secure[:trans_status] xml.tag! 'Cavv', three_d_secure[:cavv] unless three_d_secure[:cavv].blank? xml.tag! 'Eci3ds', three_d_secure[:eci] unless three_d_secure[:eci].blank? xml.tag! 'Xid', three_d_secure[:xid] unless three_d_secure[:xid].blank? + xml.tag! 'ThreeDSVersion', three_d_secure[:version] unless three_d_secure[:version].blank? + xml.tag! 'DSTransactionId', three_d_secure[:ds_transaction_id] unless three_d_secure[:ds_transaction_id].blank? end end diff --git a/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb b/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb index fe3146eac55..a02d4bff1b6 100644 --- a/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +++ b/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb @@ -5,6 +5,7 @@ module PaypalCommonAPI include Empty API_VERSION = '124' + API_VERSION_3DS2 = '214.0' URLS = { :test => { :certificate => 'https://api.sandbox.paypal.com/2.0/', @@ -586,7 +587,7 @@ def add_payment_details(xml, money, currency_code, options = {}) xml.tag! 'n2:OrderTotal', localized_amount(money, currency_code), 'currencyID' => currency_code # All of the values must be included together and add up to the order total - if [:subtotal, :shipping, :handling, :tax].all?{ |o| options.has_key?(o) } + if [:subtotal, :shipping, :handling, :tax].all?{ |o| options[o].present? } xml.tag! 'n2:ItemTotal', localized_amount(options[:subtotal], currency_code), 'currencyID' => currency_code xml.tag! 'n2:ShippingTotal', localized_amount(options[:shipping], currency_code),'currencyID' => currency_code xml.tag! 'n2:HandlingTotal', localized_amount(options[:handling], currency_code),'currencyID' => currency_code diff --git a/lib/active_merchant/billing/gateways/paypal_ca.rb b/lib/active_merchant/billing/gateways/paypal_ca.rb index 91fb551d342..74d63ee4c9e 100644 --- a/lib/active_merchant/billing/gateways/paypal_ca.rb +++ b/lib/active_merchant/billing/gateways/paypal_ca.rb @@ -4,7 +4,7 @@ module ActiveMerchant #:nodoc: module Billing #:nodoc: # The PayPal gateway for PayPal Website Payments Pro Canada only supports Visa and MasterCard class PaypalCaGateway < PaypalGateway - self.supported_cardtypes = [:visa, :master] + self.supported_cardtypes = %i[visa master] self.supported_countries = ['CA'] self.homepage_url = 'https://www.paypal.com/cgi-bin/webscr?cmd=_wp-pro-overview-outside' self.display_name = 'PayPal Website Payments Pro (CA)' diff --git a/lib/active_merchant/billing/gateways/paypal_digital_goods.rb b/lib/active_merchant/billing/gateways/paypal_digital_goods.rb index 653a8c59015..2ed090226c1 100644 --- a/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +++ b/lib/active_merchant/billing/gateways/paypal_digital_goods.rb @@ -31,6 +31,7 @@ def redirect_url_for(token, options = {}) def build_setup_request(action, money, options) requires!(options, :items) raise ArgumentError, 'Must include at least 1 Item' unless options[:items].length > 0 + options[:items].each do |item| requires!(item, :name, :number, :quantity, :amount, :description, :category) raise ArgumentError, "Each of the items must have the category 'Digital'" unless item[:category] == 'Digital' @@ -38,7 +39,6 @@ def build_setup_request(action, money, options) super end - end end end diff --git a/lib/active_merchant/billing/gateways/paypal_express.rb b/lib/active_merchant/billing/gateways/paypal_express.rb index 60d659437f9..9f87a32ed30 100644 --- a/lib/active_merchant/billing/gateways/paypal_express.rb +++ b/lib/active_merchant/billing/gateways/paypal_express.rb @@ -73,7 +73,7 @@ def agreement_details(reference_id, options = {}) end def authorize_reference_transaction(money, options = {}) - requires!(options, :reference_id, :payment_type, :invoice_id, :description, :ip) + requires!(options, :reference_id) commit 'DoReferenceTransaction', build_reference_transaction_request('Authorization', money, options) end diff --git a/lib/active_merchant/billing/gateways/paypal_express_common.rb b/lib/active_merchant/billing/gateways/paypal_express_common.rb index 7cb72b82745..4da80ed71a2 100644 --- a/lib/active_merchant/billing/gateways/paypal_express_common.rb +++ b/lib/active_merchant/billing/gateways/paypal_express_common.rb @@ -17,7 +17,7 @@ def redirect_url end def redirect_url_for(token, options = {}) - options = {:review => true, :mobile => false}.update(options) + options = { review: true, mobile: false }.update(options) cmd = options[:mobile] ? '_express-checkout-mobile' : '_express-checkout' url = "#{redirect_url}?cmd=#{cmd}&token=#{token}" diff --git a/lib/active_merchant/billing/gateways/payscout.rb b/lib/active_merchant/billing/gateways/payscout.rb index d2ad18b5a16..4c2f418a8c8 100644 --- a/lib/active_merchant/billing/gateways/payscout.rb +++ b/lib/active_merchant/billing/gateways/payscout.rb @@ -4,7 +4,7 @@ class PayscoutGateway < Gateway self.live_url = self.test_url = 'https://secure.payscout.com/api/transact.php' self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.default_currency = 'USD' self.homepage_url = 'http://www.payscout.com/' self.display_name = 'Payscout' @@ -62,7 +62,7 @@ def add_address(post, options) post[:address1] = address[:address1].to_s post[:address2] = address[:address2].to_s post[:city] = address[:city].to_s - post[:state] = (address[:state].blank? ? 'n/a' : address[:state]) + post[:state] = (address[:state].blank? ? 'n/a' : address[:state]) post[:zip] = address[:zip].to_s post[:country] = address[:country].to_s post[:phone] = address[:phone].to_s @@ -78,7 +78,7 @@ def add_address(post, options) post[:shipping_address2] = address[:address2].to_s post[:shipping_city] = address[:city].to_s post[:shipping_country] = address[:country].to_s - post[:shipping_state] = (address[:state].blank? ? 'n/a' : address[:state]) + post[:shipping_state] = (address[:state].blank? ? 'n/a' : address[:state]) post[:shipping_zip] = address[:zip].to_s post[:shipping_email] = address[:email].to_s end @@ -116,12 +116,11 @@ def commit(action, money, parameters) message = message_from(response) test_mode = (test? || message =~ /TESTMODE/) Response.new(success?(response), message, response, - :test => test_mode, - :authorization => response['transactionid'], - :fraud_review => fraud_review?(response), - :avs_result => { :code => response['avsresponse'] }, - :cvv_result => response['cvvresponse'] - ) + test: test_mode, + authorization: response['transactionid'], + fraud_review: fraud_review?(response), + avs_result: { code: response['avsresponse'] }, + cvv_result: response['cvvresponse']) end def message_from(response) diff --git a/lib/active_merchant/billing/gateways/paystation.rb b/lib/active_merchant/billing/gateways/paystation.rb index 0c2afac4358..e7557ce5419 100644 --- a/lib/active_merchant/billing/gateways/paystation.rb +++ b/lib/active_merchant/billing/gateways/paystation.rb @@ -1,7 +1,6 @@ module ActiveMerchant #:nodoc: module Billing #:nodoc: class PaystationGateway < Gateway - self.live_url = self.test_url = 'https://www.paystation.co.nz/direct/paystation.dll' # an "error code" of "0" means "No error - transaction successful" @@ -14,7 +13,7 @@ class PaystationGateway < Gateway self.supported_countries = ['NZ'] # TODO: check this with paystation (amex and diners need to be enabled) - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club ] + self.supported_cardtypes = %i[visa master american_express diners_club] self.homepage_url = 'http://paystation.co.nz' self.display_name = 'Paystation' @@ -75,7 +74,7 @@ def store(credit_card, options = {}) commit(post) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) post = new_request add_amount(post, money, options) add_invoice(post, options) @@ -84,7 +83,7 @@ def refund(money, authorization, options={}) commit(post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) authorize(0, credit_card, options) end @@ -128,7 +127,7 @@ def add_credit_card(post, credit_card) end def add_token(post, token) - post[:fp] = 't' # turn on "future payments" - what paystation calls Token Billing + post[:fp] = 't' # turn on "future payments" - what paystation calls Token Billing post[:ft] = token end @@ -179,9 +178,8 @@ def commit(post) message = message_from(response) PaystationResponse.new(success?(response), message, response, - :test => (response[:tm]&.casecmp('t')&.zero?), - :authorization => response[:paystation_transaction_id] - ) + test: (response[:tm]&.casecmp('t')&.zero?), + authorization: response[:paystation_transaction_id]) end def success?(response) @@ -195,7 +193,6 @@ def message_from(response) def format_date(month, year) "#{format(year, :two_digits)}#{format(month, :two_digits)}" end - end class PaystationResponse < Response diff --git a/lib/active_merchant/billing/gateways/payu_in.rb b/lib/active_merchant/billing/gateways/payu_in.rb index eabc32c1cd6..304c7ff0886 100644 --- a/lib/active_merchant/billing/gateways/payu_in.rb +++ b/lib/active_merchant/billing/gateways/payu_in.rb @@ -11,17 +11,17 @@ class PayuInGateway < Gateway self.supported_countries = ['IN'] self.default_currency = 'INR' - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :maestro] + self.supported_cardtypes = %i[visa master american_express diners_club maestro] self.homepage_url = 'https://www.payu.in/' self.display_name = 'PayU India' - def initialize(options={}) + def initialize(options = {}) requires!(options, :key, :salt) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) requires!(options, :order_id) post = {} @@ -33,7 +33,7 @@ def purchase(money, payment, options={}) MultiResponse.run do |r| r.process { commit(url('purchase'), post) } - if(r.params['enrolled'].to_s == '0') + if r.params['enrolled'].to_s == '0' r.process { commit(r.params['post_uri'], r.params['form_post_vars']) } else r.process { handle_3dsecure(r) } @@ -41,7 +41,7 @@ def purchase(money, payment, options={}) end end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) raise ArgumentError, 'Amount is required' unless money post = {} @@ -154,20 +154,21 @@ def add_payment(post, payment) def clean(value, format, maxlength) value ||= '' - value = case format - when :alphanumeric - value.gsub(/[^A-Za-z0-9]/, '') - when :name - value.gsub(/[^A-Za-z ]/, '') - when :numeric - value.gsub(/[^0-9]/, '') - when :text - value.gsub(/[^A-Za-z0-9@\-_\/\. ]/, '') - when nil - value - else - raise "Unknown format #{format} for #{value}" - end + value = + case format + when :alphanumeric + value.gsub(/[^A-Za-z0-9]/, '') + when :name + value.gsub(/[^A-Za-z ]/, '') + when :numeric + value.gsub(/[^0-9]/, '') + when :text + value.gsub(/[^A-Za-z0-9@\-_\/\. ]/, '') + when nil + value + else + raise "Unknown format #{format} for #{value}" + end value[0...maxlength] end diff --git a/lib/active_merchant/billing/gateways/payu_latam.rb b/lib/active_merchant/billing/gateways/payu_latam.rb index aef7ea42e89..43d0c2236d5 100644 --- a/lib/active_merchant/billing/gateways/payu_latam.rb +++ b/lib/active_merchant/billing/gateways/payu_latam.rb @@ -9,10 +9,10 @@ class PayuLatamGateway < Gateway self.test_url = 'https://sandbox.api.payulatam.com/payments-api/4.0/service.cgi' self.live_url = 'https://api.payulatam.com/payments-api/4.0/service.cgi' - self.supported_countries = ['AR', 'BR', 'CL', 'CO', 'MX', 'PA', 'PE'] + self.supported_countries = %w[AR BR CL CO MX PA PE] self.default_currency = 'USD' self.money_format = :dollars - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :naranja, :cabal] + self.supported_cardtypes = %i[visa master american_express diners_club naranja cabal] BRAND_MAP = { 'visa' => 'VISA', @@ -30,24 +30,24 @@ class PayuLatamGateway < Gateway 'PEN' => 500 } - def initialize(options={}) + def initialize(options = {}) requires!(options, :merchant_id, :account_id, :api_login, :api_key, :payment_country) super end - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) post = {} auth_or_sale(post, 'AUTHORIZATION_AND_CAPTURE', amount, payment_method, options) commit('purchase', post) end - def authorize(amount, payment_method, options={}) + def authorize(amount, payment_method, options = {}) post = {} auth_or_sale(post, 'AUTHORIZATION', amount, payment_method, options) commit('auth', post) end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) post = {} add_credentials(post, 'SUBMIT_TRANSACTION', options) @@ -62,7 +62,7 @@ def capture(amount, authorization, options={}) commit('capture', post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} add_credentials(post, 'SUBMIT_TRANSACTION', options) @@ -72,17 +72,24 @@ def void(authorization, options={}) commit('void', post) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) post = {} add_credentials(post, 'SUBMIT_TRANSACTION', options) - add_transaction_elements(post, 'REFUND', options) - add_reference(post, authorization) + if options[:partial_refund] + add_transaction_elements(post, 'PARTIAL_REFUND', options) + post[:transaction][:additionalValues] ||= {} + post[:transaction][:additionalValues][:TX_VALUE] = invoice_for(amount, options)[:TX_VALUE] + else + add_transaction_elements(post, 'REFUND', options) + end + + add_reference(post, authorization) commit('refund', post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) minimum = MINIMUMS[options[:currency].upcase] if options[:currency] amount = options[:verify_amount] || minimum || 100 @@ -96,7 +103,7 @@ def store(payment_method, options = {}) post = {} add_credentials(post, 'CREATE_TOKEN') - add_payment_method_to_be_tokenized(post, payment_method) + add_payment_method_to_be_tokenized(post, payment_method, options) commit('store', post) end @@ -133,7 +140,7 @@ def auth_or_sale(post, transaction_type, amount, payment_method, options) add_extra_parameters(post, options) end - def add_credentials(post, command, options={}) + def add_credentials(post, command, options = {}) post[:test] = test? unless command == 'CREATE_TOKEN' post[:language] = options[:language] || 'en' post[:command] = command @@ -180,12 +187,13 @@ def add_payer(post, payment_method, options) def billing_address_fields(options) return unless address = options[:billing_address] + billing_address = {} billing_address[:street1] = address[:address1] billing_address[:street2] = address[:address2] billing_address[:city] = address[:city] billing_address[:state] = address[:state] - billing_address[:country] = address[:country] + billing_address[:country] = address[:country] unless address[:country].blank? billing_address[:postalCode] = address[:zip] if @options[:payment_country] == 'MX' billing_address[:phone] = address[:phone] billing_address @@ -217,6 +225,7 @@ def add_buyer(post, payment_method, options) def shipping_address_fields(options) return unless address = options[:shipping_address] + shipping_address = {} shipping_address[:street1] = address[:address1] shipping_address[:street2] = address[:address2] @@ -292,6 +301,7 @@ def add_payment_method(post, payment_method, options) def add_process_without_cvv2(payment_method, options) return true if payment_method.verification_value.blank? && options[:cvv].blank? + false end @@ -310,15 +320,14 @@ def add_reference(post, authorization) post[:transaction][:reason] = 'n/a' end - def add_payment_method_to_be_tokenized(post, payment_method) + def add_payment_method_to_be_tokenized(post, payment_method, options) credit_card_token = {} - credit_card_token[:payerId] = generate_unique_id + credit_card_token[:payerId] = options[:payer_id] || generate_unique_id credit_card_token[:name] = payment_method.name.strip - credit_card_token[:identificationNumber] = generate_unique_id + credit_card_token[:identificationNumber] = options[:dni_number] credit_card_token[:paymentMethod] = BRAND_MAP[payment_method.brand.to_s] credit_card_token[:number] = payment_method.number credit_card_token[:expirationDate] = format(payment_method.year, :four_digits).to_s + '/' + format(payment_method.month, :two_digits).to_s - credit_card_token[:securityCode] = payment_method.verification_value post[:creditCardToken] = credit_card_token end @@ -344,8 +353,8 @@ def commit(action, params) def headers { - 'Content-Type' => 'application/json', - 'Accept' => 'application/json' + 'Content-Type' => 'application/json', + 'Accept' => 'application/json' } end @@ -379,18 +388,24 @@ def message_from(action, success, response) case action when 'store' return response['code'] if success + error_description = response['creditCardToken']['errorDescription'] if response['creditCardToken'] response['error'] || error_description || 'FAILED' when 'verify_credentials' return 'VERIFIED' if success + 'FAILED' else if response['transactionResponse'] response_message = response['transactionResponse']['responseMessage'] + response_code = response['transactionResponse']['responseCode'] || response['transactionResponse']['pendingReason'] + + response_message = response_code + ' | ' + response['transactionResponse']['paymentNetworkResponseErrorMessage'] unless response['transactionResponse']['paymentNetworkResponseErrorMessage'].nil? end return response_code if success - response['error'] || response_message || response_code || 'FAILED' + + response_message || response['error'] || response_code || 'FAILED' end end @@ -435,7 +450,7 @@ def response_error(raw_response) false, message_from('', false, response), response, - :test => test? + test: test? ) end diff --git a/lib/active_merchant/billing/gateways/payway.rb b/lib/active_merchant/billing/gateways/payway.rb index b80e5f937a1..e5980c8ce04 100644 --- a/lib/active_merchant/billing/gateways/payway.rb +++ b/lib/active_merchant/billing/gateways/payway.rb @@ -3,8 +3,8 @@ module Billing class PaywayGateway < Gateway self.live_url = self.test_url = 'https://ccapi.client.qvalent.com/payway/ccapi' - self.supported_countries = [ 'AU' ] - self.supported_cardtypes = [ :visa, :master, :diners_club, :american_express, :bankcard ] + self.supported_countries = ['AU'] + self.supported_cardtypes = %i[visa master diners_club american_express bankcard] self.display_name = 'Pay Way' self.homepage_url = 'http://www.payway.com.au' self.default_currency = 'AUD' @@ -17,7 +17,7 @@ class PaywayGateway < Gateway '3' => 'Rejected' } - RESPONSE_CODES= { + RESPONSE_CODES = { '00' => 'Completed Successfully', '01' => 'Refer to card issuer', '03' => 'Invalid merchant', @@ -74,16 +74,16 @@ class PaywayGateway < Gateway 'QZ' => 'Zero value transaction' } - TRANSACTIONS = { - :authorize => 'preauth', - :purchase => 'capture', - :capture => 'captureWithoutAuth', - :status => 'query', - :refund => 'refund', - :store => 'registerAccount' + TRANSACTIONS = { + authorize: 'preauth', + purchase: 'capture', + capture: 'captureWithoutAuth', + status: 'query', + refund: 'refund', + store: 'registerAccount' } - def initialize(options={}) + def initialize(options = {}) @options = options @options[:merchant] ||= 'TEST' if test? @@ -92,7 +92,7 @@ def initialize(options={}) @options[:eci] ||= 'SSL' end - def authorize(amount, payment_method, options={}) + def authorize(amount, payment_method, options = {}) requires!(options, :order_id) post = {} @@ -101,7 +101,7 @@ def authorize(amount, payment_method, options={}) commit(:authorize, post) end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) requires!(options, :order_id) post = {} @@ -110,7 +110,7 @@ def capture(amount, authorization, options={}) commit(:capture, post) end - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) requires!(options, :order_id) post = {} @@ -119,7 +119,7 @@ def purchase(amount, payment_method, options={}) commit(:purchase, post) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) requires!(options, :order_id) post = {} @@ -128,7 +128,7 @@ def refund(amount, authorization, options={}) commit(:refund, post) end - def store(credit_card, options={}) + def store(credit_card, options = {}) requires!(options, :billing_id) post = {} @@ -137,7 +137,7 @@ def store(credit_card, options={}) commit(:store, post) end - def status(options={}) + def status(options = {}) requires!(options, :order_id) commit(:status, 'customer.orderNumber' => options[:order_id]) @@ -193,14 +193,14 @@ def commit(action, post) success = (params[:summary_code] ? (params[:summary_code] == '0') : (params[:response_code] == '00')) Response.new(success, message, params, - :test => (@options[:merchant].to_s == 'TEST'), - :authorization => post[:order_number] - ) + test: (@options[:merchant].to_s == 'TEST'), + authorization: post[:order_number]) rescue ActiveMerchant::ResponseError => e raise unless e.response.code == '403' - return Response.new(false, 'Invalid credentials', {}, :test => test?) + + return Response.new(false, 'Invalid credentials', {}, test: test?) rescue ActiveMerchant::ClientCertificateError - return Response.new(false, 'Invalid certificate', {}, :test => test?) + return Response.new(false, 'Invalid certificate', {}, test: test?) end end end diff --git a/lib/active_merchant/billing/gateways/payway_dot_com.rb b/lib/active_merchant/billing/gateways/payway_dot_com.rb new file mode 100644 index 00000000000..2796616d17f --- /dev/null +++ b/lib/active_merchant/billing/gateways/payway_dot_com.rb @@ -0,0 +1,252 @@ +module ActiveMerchant #:nodoc: + module Billing #:nodoc: + class PaywayDotComGateway < Gateway + self.test_url = 'https://devedgilpayway.net/PaywayWS/Payment/CreditCard' + self.live_url = 'https://edgilpayway.com/PaywayWS/Payment/CreditCard' + + self.supported_countries = %w[US CA] + self.default_currency = 'USD' + self.supported_cardtypes = %i[visa master american_express discover] + + self.money_format = :cents + + self.homepage_url = 'http://www.payway.com' + self.display_name = 'Payway Gateway' + + STANDARD_ERROR_CODE_MAPPING = { + '5012' => STANDARD_ERROR_CODE[:card_declined], + '5035' => STANDARD_ERROR_CODE[:invalid_number], + '5037' => STANDARD_ERROR_CODE[:invalid_expiry_date], + '5045' => STANDARD_ERROR_CODE[:incorrect_zip] + } + + # Payway to standard AVSResult codes. + AVS_MAPPING = { + 'N1' => 'I', # No address given with order + 'N2' => 'I', # Bill-to address did not pass + '““' => 'R', # AVS not performed (Blanks returned) + 'IU' => 'G', # AVS not performed by Issuer + 'ID' => 'S', # Issuer does not participate in AVS + 'IE' => 'E', # Edit Error - AVS data is invalid + 'IS' => 'R', # System unavailable or time-out + 'IB' => 'B', # Street address match. Postal code not verified due to incompatible formats (both were sent). + 'IC' => 'C', # Street address and postal code not verified due to incompatible format (both were sent). + 'IP' => 'P', # Postal code match. Street address not verified due to incompatible formats (both were sent). + 'A1' => 'K', # Accountholder name matches + 'A3' => 'V', # Accountholder name, billing address and postal code. + 'A4' => 'L', # Accountholder name and billing postal code match + 'A7' => 'O', # Accountholder name and billing address match + 'B3' => 'H', # Accountholder name incorrect, billing address and postal code match + 'B4' => 'F', # Accountholder name incorrect, billing postal code matches + 'B7' => 'T', # Accountholder name incorrect, billing address matches + 'B8' => 'N', # Accountholder name, billing address and postal code are all incorrect + '??' => 'R', # A double question mark symbol indicates an unrecognized response from association + 'I1' => 'X', # Zip code +4 and Address Match + 'I2' => 'W', # Zip code +4 Match + 'I3' => 'Y', # Zip code and Address Match + 'I4' => 'Z', # Zip code Match + 'I5' => 'M', # +4 and Address Match + 'I6' => 'W', # +4 Match + 'I7' => 'A', # Address Match + 'I8' => 'C', # No Match + } + + PAYWAY_WS_SUCCESS = '5000' + + SCRUB_PATTERNS = [ + %r(("password\\?":\\?")[^\\]+), + %r(("fsv\\?":\\?")\d+), + %r(("accountNumber\\?":\\?")\d+) + ].freeze + + SCRUB_REPLACEMENT = '\1[FILTERED]' + + def initialize(options = {}) + requires!(options, :login, :password, :company_id) + super + end + + def purchase(money, payment, options = {}) + post = {} + add_common(post, options) + add_card_payment(post, payment, options) + add_card_transaction(post, money, options) + add_address(post, payment, options) + + commit('sale', post) + end + + def authorize(money, payment, options = {}) + post = {} + add_common(post, options) + add_card_payment(post, payment, options) + add_card_transaction(post, money, options) + add_address(post, payment, options) + + commit('authorize', post) + end + + def capture(money, authorization, options = {}) + post = {} + add_common(post, options) + add_card_transaction_name_and_source(post, authorization, options) + + commit('capture', post) + end + + def credit(money, payment, options = {}) + post = {} + add_common(post, options) + add_card_payment(post, payment, options) + add_card_transaction(post, money, options) + add_address(post, payment, options) + + commit('credit', post) + end + + def void(authorization, options = {}) + post = {} + add_common(post, options) + add_card_transaction_name_and_source(post, authorization, options) + + commit('void', post) + end + + def supports_scrubbing? + true + end + + def scrub(transcript) + SCRUB_PATTERNS.inject(transcript) do |text, pattern| + text.gsub(pattern, SCRUB_REPLACEMENT) + end + end + + private + + def add_common(post, options) + post[:userName] = @options[:login] + post[:password] = @options[:password] + post[:companyId] = @options[:company_id] + end + + def add_card_transaction_name_and_source(post, identifier, options) + post[:cardTransaction] ||= {} + post[:cardTransaction][:name] = identifier + post[:cardTransaction][:sourceId] = options[:source_id] if options[:source_id] + end + + def add_address(post, payment, options) + post[:cardAccount] ||= {} + address = options[:billing_address] || options[:address] || {} + first_name, last_name = split_names(address[:name]) + full_address = "#{address[:address1]} #{address[:address2]}".strip + phone = address[:phone] || address[:phone_number] + + post[:cardAccount][:firstName] = first_name if first_name + post[:cardAccount][:lastName] = last_name if last_name + post[:cardAccount][:address] = full_address if full_address + post[:cardAccount][:city] = address[:city] if address[:city] + post[:cardAccount][:state] = address[:state] if address[:state] + post[:cardAccount][:zip] = address[:zip] if address[:zip] + post[:cardAccount][:phone] = phone if phone + end + + def add_card_transaction(post, money, options) + post[:cardTransaction] ||= {} + post[:cardTransaction][:amount] = amount(money) + eci_type = options[:eci_type].nil? ? '1' : options[:eci_type] + post[:cardTransaction][:eciType] = eci_type + post[:cardTransaction][:sourceId] = options[:source_id] if options[:source_id] + post[:cardTransaction][:processorSoftDescriptor] = options[:processor_soft_descriptor] if options[:processor_soft_descriptor] + post[:cardTransaction][:tax] = options[:tax] if options[:tax] + end + + def add_card_payment(post, payment, options) + # credit_card + post[:accountInputMode] = 'primaryAccountNumber' + + post[:cardAccount] ||= {} + post[:cardAccount][:accountNumber] = payment.number + post[:cardAccount][:fsv] = payment.verification_value + post[:cardAccount][:expirationDate] = expdate(payment) + post[:cardAccount][:email] = options[:email] if options[:email] + end + + def expdate(credit_card) + year = format(credit_card.year, :four_digits) + month = format(credit_card.month, :two_digits) + + month + year + end + + def parse(body) + body.blank? ? {} : JSON.parse(body) + end + + def commit(action, parameters) + parameters[:request] = action + + url = (test? ? test_url : live_url) + payload = parameters.to_json unless parameters.nil? + + response = + begin + parse(ssl_request(:post, url, payload, headers)) + rescue ResponseError => e + return Response.new(false, 'Invalid Login') if e.response.code == '401' + + parse(e.response.body) + end + + success = success_from(response) + avs_result_code = response['cardTransaction'].nil? || response['cardTransaction']['addressVerificationResults'].nil? ? '' : response['cardTransaction']['addressVerificationResults'] + avs_result = AVSResult.new(code: AVS_MAPPING[avs_result_code]) + cvv_result = CVVResult.new(response['cardTransaction']['fraudSecurityResults']) if response['cardTransaction'] && response['cardTransaction']['fraudSecurityResults'] + + Response.new( + success, + message_from(success, response), + response, + test: test?, + error_code: error_code_from(response), + authorization: authorization_from(response), + avs_result: avs_result, + cvv_result: cvv_result + ) + end + + def success_from(response) + response['paywayCode'] == PAYWAY_WS_SUCCESS + end + + def error_code_from(response) + return '' if success_from(response) + + error = !STANDARD_ERROR_CODE_MAPPING[response['paywayCode']].nil? ? STANDARD_ERROR_CODE_MAPPING[response['paywayCode']] : STANDARD_ERROR_CODE[:processing_error] + return error + end + + def message_from(success, response) + return '' if response['paywayCode'].nil? + + return response['paywayCode'] + '-' + 'success' if success + + response['paywayCode'] + '-' + response['paywayMessage'] + end + + def authorization_from(response) + return '' if !success_from(response) || response['cardTransaction'].nil? + + response['cardTransaction']['name'] + end + + def headers + { + 'Accept' => 'application/json', + 'Content-type' => 'application/json' + } + end + end + end +end diff --git a/lib/active_merchant/billing/gateways/pin.rb b/lib/active_merchant/billing/gateways/pin.rb index 89e92895980..3a3aec38b75 100644 --- a/lib/active_merchant/billing/gateways/pin.rb +++ b/lib/active_merchant/billing/gateways/pin.rb @@ -7,7 +7,7 @@ class PinGateway < Gateway self.default_currency = 'AUD' self.money_format = :cents self.supported_countries = ['AU'] - self.supported_cardtypes = [:visa, :master, :american_express] + self.supported_cardtypes = %i[visa master american_express] self.homepage_url = 'http://www.pinpayments.com/' self.display_name = 'Pin Payments' @@ -30,6 +30,7 @@ def purchase(money, creditcard, options = {}) add_address(post, creditcard, options) add_capture(post, options) add_metadata(post, options) + add_3ds(post, options) commit(:post, 'charges', post, options) end @@ -47,7 +48,7 @@ def store(creditcard, options = {}) # Refund a transaction def refund(money, token, options = {}) - commit(:post, "charges/#{CGI.escape(token)}/refunds", { :amount => amount(money) }, options) + commit(:post, "charges/#{CGI.escape(token)}/refunds", { amount: amount(money) }, options) end # Authorize an amount on a credit card. Once authorized, you can later @@ -61,7 +62,7 @@ def authorize(money, creditcard, options = {}) # Captures a previously authorized charge. Capturing only part of the original # authorization is currently not supported. def capture(money, token, options = {}) - commit(:put, "charges/#{CGI.escape(token)}/capture", { :amount => amount(money) }, options) + commit(:put, "charges/#{CGI.escape(token)}/capture", { amount: amount(money) }, options) end # Updates the credit card for the customer. @@ -101,16 +102,17 @@ def add_customer_data(post, options) def add_address(post, creditcard, options) return if creditcard.kind_of?(String) + address = (options[:billing_address] || options[:address]) return unless address post[:card] ||= {} post[:card].merge!( - :address_line1 => address[:address1], - :address_city => address[:city], - :address_postcode => address[:zip], - :address_state => address[:state], - :address_country => address[:country] + address_line1: address[:address1], + address_city: address[:city], + address_postcode: address[:zip], + address_state: address[:state], + address_country: address[:country] ) end @@ -130,14 +132,14 @@ def add_creditcard(post, creditcard) post[:card] ||= {} post[:card].merge!( - :number => creditcard.number, - :expiry_month => creditcard.month, - :expiry_year => creditcard.year, - :cvc => creditcard.verification_value, - :name => creditcard.name + number: creditcard.number, + expiry_month: creditcard.month, + expiry_year: creditcard.year, + cvc: creditcard.verification_value, + name: creditcard.name ) elsif creditcard.kind_of?(String) - if creditcard =~ /^card_/ + if /^card_/.match?(creditcard) post[:card_token] = get_card_token(creditcard) else post[:customer_token] = creditcard @@ -157,6 +159,16 @@ def add_metadata(post, options) post[:metadata] = options[:metadata] if options[:metadata] end + def add_3ds(post, options) + if options[:three_d_secure] + post[:three_d_secure] = {} + post[:three_d_secure][:version] = options[:three_d_secure][:version] if options[:three_d_secure][:version] + post[:three_d_secure][:eci] = options[:three_d_secure][:eci] if options[:three_d_secure][:eci] + post[:three_d_secure][:cavv] = options[:three_d_secure][:cavv] if options[:three_d_secure][:cavv] + post[:three_d_secure][:transaction_id] = options[:three_d_secure][:ds_transaction_id] || options[:three_d_secure][:xid] + end + end + def headers(params = {}) result = { 'Content-Type' => 'application/json', @@ -193,8 +205,8 @@ def success_response(body) true, response['status_message'], body, - :authorization => token(response), - :test => test? + authorization: token(response), + test: test? ) end @@ -203,8 +215,8 @@ def error_response(body) false, body['error_description'], body, - :authorization => nil, - :test => test? + authorization: nil, + test: test? ) end diff --git a/lib/active_merchant/billing/gateways/plugnpay.rb b/lib/active_merchant/billing/gateways/plugnpay.rb index 36becf69ff8..e7343efde03 100644 --- a/lib/active_merchant/billing/gateways/plugnpay.rb +++ b/lib/active_merchant/billing/gateways/plugnpay.rb @@ -3,8 +3,8 @@ module Billing class PlugnpayGateway < Gateway class PlugnpayPostData < PostData # Fields that will be sent even if they are blank - self.required_fields = [:publisher_name, :publisher_password, - :card_amount, :card_name, :card_number, :card_exp, :orderID] + self.required_fields = %i[publisher_name publisher_password + card_amount card_name card_number card_exp orderID] end self.live_url = self.test_url = 'https://pay1.plugnpay.com/payment/pnpremote.cgi' @@ -16,7 +16,7 @@ class PlugnpayPostData < PostData 'U' => 'Issuer was not certified for card verification' } - CARD_CODE_ERRORS = %w( N S ) + CARD_CODE_ERRORS = %w(N S) AVS_MESSAGES = { 'A' => 'Street address matches billing information, zip/postal code does not', @@ -31,10 +31,10 @@ class PlugnpayPostData < PostData 'W' => '9-digit zip/postal code matches billing information, street address does not', 'X' => 'Street address and 9-digit zip/postal code matches billing information', 'Y' => 'Street address and 5-digit zip/postal code matches billing information', - 'Z' => '5-digit zip/postal code matches billing information, street address does not', + 'Z' => '5-digit zip/postal code matches billing information, street address does not' } - AVS_ERRORS = %w( A E N R W Z ) + AVS_ERRORS = %w(A E N R W Z) PAYMENT_GATEWAY_RESPONSES = { 'P01' => 'AVS Mismatch Failure', @@ -80,20 +80,20 @@ class PlugnpayPostData < PostData } TRANSACTIONS = { - :authorization => 'auth', - :purchase => 'auth', - :capture => 'mark', - :void => 'void', - :refund => 'return', - :credit => 'newreturn' + authorization: 'auth', + purchase: 'auth', + capture: 'mark', + void: 'void', + refund: 'return', + credit: 'newreturn' } - SUCCESS_CODES = [ 'pending', 'success' ] - FAILURE_CODES = [ 'badcard', 'fraud' ] + SUCCESS_CODES = %w[pending success] + FAILURE_CODES = %w[badcard fraud] self.default_currency = 'USD' self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://www.plugnpay.com/' self.display_name = "Plug'n Pay" @@ -179,11 +179,10 @@ def commit(action, post) message = success ? 'Success' : message_from(response) Response.new(success, message, response, - :test => test?, - :authorization => response[:orderid], - :avs_result => { :code => response[:avs_code] }, - :cvv_result => response[:cvvresp] - ) + test: test?, + authorization: response[:orderid], + avs_result: { code: response[:avs_code] }, + cvv_result: response[:cvvresp]) end def parse(body) @@ -219,7 +218,7 @@ def add_creditcard(post, creditcard) def add_customer_data(post, options) post[:email] = options[:email] - post[:dontsndmail] = 'yes' unless options[:send_email_confirmation] + post[:dontsndmail] = 'yes' unless options[:send_email_confirmation] post[:ipaddress] = options[:ip] end @@ -256,7 +255,7 @@ def add_addresses(post, options) post[:state] = shipping_address[:state] else post[:state] = 'ZZ' - post[:province] = shipping_address[:state] + post[:province] = shipping_address[:state] end post[:country] = shipping_address[:country] diff --git a/lib/active_merchant/billing/gateways/pro_pay.rb b/lib/active_merchant/billing/gateways/pro_pay.rb index dd286ad6fcb..a0dab56600f 100644 --- a/lib/active_merchant/billing/gateways/pro_pay.rb +++ b/lib/active_merchant/billing/gateways/pro_pay.rb @@ -6,10 +6,10 @@ class ProPayGateway < Gateway self.test_url = 'https://xmltest.propay.com/API/PropayAPI.aspx' self.live_url = 'https://epay.propay.com/api/propayapi.aspx' - self.supported_countries = ['US', 'CA'] + self.supported_countries = %w[US CA] self.default_currency = 'USD' self.money_format = :cents - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'https://www.propay.com/' self.display_name = 'ProPay' @@ -133,12 +133,12 @@ class ProPayGateway < Gateway '99' => 'Generic decline or unable to parse issuer response code' } - def initialize(options={}) + def initialize(options = {}) requires!(options, :cert_str) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) request = build_xml_request do |xml| add_invoice(xml, money, options) add_payment(xml, payment, options) @@ -151,7 +151,7 @@ def purchase(money, payment, options={}) commit(request) end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) request = build_xml_request do |xml| add_invoice(xml, money, options) add_payment(xml, payment, options) @@ -164,7 +164,7 @@ def authorize(money, payment, options={}) commit(request) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) request = build_xml_request do |xml| add_invoice(xml, money, options) add_account(xml, options) @@ -175,7 +175,7 @@ def capture(money, authorization, options={}) commit(request) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) request = build_xml_request do |xml| add_invoice(xml, money, options) add_account(xml, options) @@ -186,11 +186,11 @@ def refund(money, authorization, options={}) commit(request) end - def void(authorization, options={}) + def void(authorization, options = {}) refund(nil, authorization, options) end - def credit(money, payment, options={}) + def credit(money, payment, options = {}) request = build_xml_request do |xml| add_invoice(xml, money, options) add_payment(xml, payment, options) @@ -201,7 +201,7 @@ def credit(money, payment, options={}) commit(request) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -253,7 +253,7 @@ def add_recurring(xml, options) end def parse(body) - results = {} + results = {} xml = Nokogiri::XML(body) resp = xml.xpath('//XMLResponse/XMLTrans') resp.children.each do |element| @@ -284,6 +284,7 @@ def success_from(response) def message_from(response) return 'Success' if success_from(response) + message = STATUS_RESPONSE_CODES[response[:status]] message += " - #{TRANSACTION_RESPONSE_CODES[response[:response_code]]}" if response[:response_code] @@ -295,9 +296,7 @@ def authorization_from(response) end def error_code_from(response) - unless success_from(response) - response[:status] - end + response[:status] unless success_from(response) end def build_xml_request diff --git a/lib/active_merchant/billing/gateways/psigate.rb b/lib/active_merchant/billing/gateways/psigate.rb index b987dd1e74b..6fc9c8905e4 100644 --- a/lib/active_merchant/billing/gateways/psigate.rb +++ b/lib/active_merchant/billing/gateways/psigate.rb @@ -38,7 +38,7 @@ class PsigateGateway < Gateway self.test_url = 'https://realtimestaging.psigate.com/xml' self.live_url = 'https://realtime.psigate.com/xml' - self.supported_cardtypes = [:visa, :master, :american_express] + self.supported_cardtypes = %i[visa master american_express] self.supported_countries = ['CA'] self.homepage_url = 'http://www.psigate.com/' self.display_name = 'Psigate' @@ -103,11 +103,10 @@ def commit(money, creditcard, options = {}) response = parse(ssl_post(url, post_data(money, creditcard, options))) Response.new(successful?(response), message_from(response), response, - :test => test?, - :authorization => build_authorization(response), - :avs_result => { :code => response[:avsresult] }, - :cvv_result => response[:cardidresult] - ) + test: test?, + authorization: build_authorization(response), + avs_result: { code: response[:avsresult] }, + cvv_result: response[:cardidresult]) end def url @@ -119,7 +118,7 @@ def successful?(response) end def parse(xml) - response = {:message => 'Global Error Receipt', :complete => false} + response = { message: 'Global Error Receipt', complete: false } xml = REXML::Document.new(xml) xml.elements.each('//Result/*') do |node| @@ -144,26 +143,26 @@ def post_data(money, creditcard, options) def parameters(money, creditcard, options = {}) params = { # General order parameters - :StoreID => @options[:login], - :Passphrase => @options[:password], - :TestResult => options[:test_result], - :OrderID => options[:order_id], - :UserID => options[:user_id], - :Phone => options[:phone], - :Fax => options[:fax], - :Email => options[:email], - :TransRefNumber => options[:trans_ref_number], + StoreID: @options[:login], + Passphrase: @options[:password], + TestResult: options[:test_result], + OrderID: options[:order_id], + UserID: options[:user_id], + Phone: options[:phone], + Fax: options[:fax], + Email: options[:email], + TransRefNumber: options[:trans_ref_number], # Credit Card parameters - :PaymentType => 'CC', - :CardAction => options[:CardAction], + PaymentType: 'CC', + CardAction: options[:CardAction], # Financial parameters - :CustomerIP => options[:ip], - :SubTotal => amount(money), - :Tax1 => options[:tax1], - :Tax2 => options[:tax2], - :ShippingTotal => options[:shipping_total], + CustomerIP: options[:ip], + SubTotal: amount(money), + Tax1: options[:tax1], + Tax2: options[:tax2], + ShippingTotal: options[:shipping_total] } if creditcard @@ -172,15 +171,15 @@ def parameters(money, creditcard, options = {}) card_id_code = (creditcard.verification_value.blank? ? nil : '1') params.update( - :CardNumber => creditcard.number, - :CardExpMonth => exp_month, - :CardExpYear => exp_year, - :CardIDCode => card_id_code, - :CardIDNumber => creditcard.verification_value + CardNumber: creditcard.number, + CardExpMonth: exp_month, + CardExpYear: exp_year, + CardIDCode: card_id_code, + CardIDNumber: creditcard.verification_value ) end - if(address = (options[:billing_address] || options[:address])) + if (address = (options[:billing_address] || options[:address])) params[:Bname] = address[:name] || creditcard.name params[:Baddress1] = address[:address1] unless address[:address1].blank? params[:Baddress2] = address[:address2] unless address[:address2].blank? @@ -210,6 +209,7 @@ def message_from(response) return SUCCESS_MESSAGE else return FAILURE_MESSAGE if response[:errmsg].blank? + return response[:errmsg].gsub(/[^\w]/, ' ').split.join(' ').capitalize end end diff --git a/lib/active_merchant/billing/gateways/psl_card.rb b/lib/active_merchant/billing/gateways/psl_card.rb index 77da4a123db..ec688861457 100644 --- a/lib/active_merchant/billing/gateways/psl_card.rb +++ b/lib/active_merchant/billing/gateways/psl_card.rb @@ -21,7 +21,7 @@ class PslCardGateway < Gateway # American Express, Diners Club, JCB, International Maestro, # Style, Clydesdale Financial Services, Other - self.supported_cardtypes = [ :visa, :master, :american_express, :diners_club, :jcb, :maestro ] + self.supported_cardtypes = %i[visa master american_express diners_club jcb maestro] self.homepage_url = 'http://www.paymentsolutionsltd.com/' self.display_name = 'PSL Payment Solutions' @@ -183,7 +183,7 @@ def add_address(post, options) address = options[:billing_address] || options[:address] return if address.nil? - post[:QAAddress] = [:address1, :address2, :city, :state].collect { |a| address[a] }.reject(&:blank?).join(' ') + post[:QAAddress] = %i[address1 address2 city state].collect { |a| address[a] }.reject(&:blank?).join(' ') post[:QAPostcode] = address[:zip] end @@ -211,7 +211,7 @@ def add_amount(post, money, dispatch_type, options) def add_purchase_details(post) post[:EchoAmount] = 'YES' - post[:SCBI] = 'YES' # Return information about the transaction + post[:SCBI] = 'YES' # Return information about the transaction post[:MessageType] = MESSAGE_TYPE end @@ -260,11 +260,10 @@ def commit(request) response = parse(ssl_post(self.live_url, post_data(request))) Response.new(response[:ResponseCode] == APPROVED, response[:Message], response, - :test => test?, - :authorization => response[:CrossReference], - :cvv_result => CVV_CODE[response[:AVSCV2Check]], - :avs_result => { :code => AVS_CODE[response[:AVSCV2Check]] } - ) + test: test?, + authorization: response[:CrossReference], + cvv_result: CVV_CODE[response[:AVSCV2Check]], + avs_result: { code: AVS_CODE[response[:AVSCV2Check]] }) end # Put the passed data into a format that can be submitted to PSL diff --git a/lib/active_merchant/billing/gateways/qbms.rb b/lib/active_merchant/billing/gateways/qbms.rb index 5d37f900bf4..c709905a293 100644 --- a/lib/active_merchant/billing/gateways/qbms.rb +++ b/lib/active_merchant/billing/gateways/qbms.rb @@ -11,16 +11,16 @@ class QbmsGateway < Gateway self.homepage_url = 'http://payments.intuit.com/' self.display_name = 'QuickBooks Merchant Services' self.default_currency = 'USD' - self.supported_cardtypes = [ :visa, :master, :discover, :american_express, :diners_club, :jcb ] - self.supported_countries = [ 'US' ] + self.supported_cardtypes = %i[visa master discover american_express diners_club jcb] + self.supported_countries = ['US'] TYPES = { - :authorize => 'CustomerCreditCardAuth', - :capture => 'CustomerCreditCardCapture', - :purchase => 'CustomerCreditCardCharge', - :refund => 'CustomerCreditCardTxnVoidOrRefund', - :void => 'CustomerCreditCardTxnVoid', - :query => 'MerchantAccountQuery', + authorize: 'CustomerCreditCardAuth', + capture: 'CustomerCreditCardCapture', + purchase: 'CustomerCreditCardCharge', + refund: 'CustomerCreditCardTxnVoidOrRefund', + void: 'CustomerCreditCardTxnVoid', + query: 'MerchantAccountQuery' } # Creates a new QbmsGateway @@ -51,7 +51,7 @@ def initialize(options = {}) # * options -- A hash of optional parameters. # def authorize(money, creditcard, options = {}) - commit(:authorize, money, options.merge(:credit_card => creditcard)) + commit(:authorize, money, options.merge(credit_card: creditcard)) end # Perform a purchase, which is essentially an authorization and capture in a single operation. @@ -63,7 +63,7 @@ def authorize(money, creditcard, options = {}) # * options -- A hash of optional parameters. # def purchase(money, creditcard, options = {}) - commit(:purchase, money, options.merge(:credit_card => creditcard)) + commit(:purchase, money, options.merge(credit_card: creditcard)) end # Captures the funds from an authorized transaction. @@ -74,7 +74,7 @@ def purchase(money, creditcard, options = {}) # * authorization -- The authorization returned from the previous authorize request. # def capture(money, authorization, options = {}) - commit(:capture, money, options.merge(:transaction_id => authorization)) + commit(:capture, money, options.merge(transaction_id: authorization)) end # Void a previous transaction @@ -84,7 +84,7 @@ def capture(money, authorization, options = {}) # * authorization - The authorization returned from the previous authorize request. # def void(authorization, options = {}) - commit(:void, nil, options.merge(:transaction_id => authorization)) + commit(:void, nil, options.merge(transaction_id: authorization)) end # Credit an account. @@ -105,7 +105,7 @@ def credit(money, identification, options = {}) end def refund(money, identification, options = {}) - commit(:refund, money, options.merge(:transaction_id => identification)) + commit(:refund, money, options.merge(transaction_id: identification)) end # Query the merchant account status @@ -143,12 +143,11 @@ def commit(action, money, parameters) message = (response[:status_message] || '').strip Response.new(success?(response), message, response, - :test => test?, - :authorization => response[:credit_card_trans_id], - :fraud_review => fraud_review?(response), - :avs_result => { :code => avs_result(response) }, - :cvv_result => cvv_result(response) - ) + test: test?, + authorization: response[:credit_card_trans_id], + fraud_review: fraud_review?(response), + avs_result: { code: avs_result(response) }, + cvv_result: cvv_result(response)) end def success?(response) @@ -167,16 +166,16 @@ def parse(type, body) if status_code != 0 return { - :status_code => status_code, - :status_message => signon.attributes['statusMessage'], + status_code: status_code, + status_message: signon.attributes['statusMessage'] } end response = REXML::XPath.first(xml, "//QBMSXMLMsgsRs/#{type}Rs") results = { - :status_code => response.attributes['statusCode'].to_i, - :status_message => response.attributes['statusMessage'], + status_code: response.attributes['statusCode'].to_i, + status_message: response.attributes['statusMessage'] } response.elements.each do |e| @@ -195,10 +194,10 @@ def parse(type, body) end def build_request(type, money, parameters = {}) - xml = Builder::XmlMarkup.new(:indent => 0) + xml = Builder::XmlMarkup.new(indent: 0) - xml.instruct!(:xml, :version => '1.0', :encoding => 'utf-8') - xml.instruct!(:qbmsxml, :version => API_VERSION) + xml.instruct!(:xml, version: '1.0', encoding: 'utf-8') + xml.instruct!(:qbmsxml, version: API_VERSION) xml.tag!('QBMSXML') do xml.tag!('SignonMsgsRq') do diff --git a/lib/active_merchant/billing/gateways/quantum.rb b/lib/active_merchant/billing/gateways/quantum.rb index 4fd43ad07ca..104148b662b 100644 --- a/lib/active_merchant/billing/gateways/quantum.rb +++ b/lib/active_merchant/billing/gateways/quantum.rb @@ -13,7 +13,7 @@ class QuantumGateway < Gateway self.live_url = self.test_url = 'https://secure.quantumgateway.com/cgi/xml_requester.php' # visa, master, american_express, discover - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.supported_countries = ['US'] self.default_currency = 'USD' self.money_format = :dollars @@ -95,14 +95,14 @@ def build_auth_request(money, creditcard, options) def build_capture_request(money, authorization, options) xml = Builder::XmlMarkup.new add_common_credit_card_info(xml, 'PREVIOUS_SALE') - transaction_id, _ = authorization_parts_from(authorization) + transaction_id, = authorization_parts_from(authorization) add_transaction_id(xml, transaction_id) xml.target! end def build_purchase_request(money, creditcard, options) xml = Builder::XmlMarkup.new - add_common_credit_card_info(xml, @options[:ignore_avs] || @options[:ignore_cvv] ? 'SALES' : 'AUTH_CAPTURE') + add_common_credit_card_info(xml, @options[:ignore_avs] || @options[:ignore_cvv] ? 'SALES' : 'AUTH_CAPTURE') add_address(xml, creditcard, options[:billing_address], options) add_purchase_data(xml, money) add_creditcard(xml, creditcard) @@ -116,7 +116,7 @@ def build_purchase_request(money, creditcard, options) def build_void_request(authorization, options) xml = Builder::XmlMarkup.new add_common_credit_card_info(xml, 'VOID') - transaction_id, _ = authorization_parts_from(authorization) + transaction_id, = authorization_parts_from(authorization) add_transaction_id(xml, transaction_id) xml.target! end @@ -216,11 +216,10 @@ def commit(request, options) end Response.new(success, message, response, - :test => test?, - :authorization => authorization, - :avs_result => { :code => response[:AVSResponseCode] }, - :cvv_result => response[:CVV2ResponseCode] - ) + test: test?, + authorization: authorization, + avs_result: { code: response[:AVSResponseCode] }, + cvv_result: response[:CVV2ResponseCode]) end # Parse the SOAP response @@ -253,7 +252,7 @@ def parse_element(reply, node) if node.has_elements? node.elements.each { |e| parse_element(reply, e) } else - if node.parent.name =~ /item/ + if /item/.match?(node.parent.name) parent = node.parent.name + (node.parent.attributes['id'] ? '_' + node.parent.attributes['id'] : '') reply[(parent + '_' + node.name).to_sym] = node.text else @@ -270,7 +269,6 @@ def authorization_for(reply) def authorization_parts_from(authorization) authorization.split(/;/) end - end end end diff --git a/lib/active_merchant/billing/gateways/quickbooks.rb b/lib/active_merchant/billing/gateways/quickbooks.rb index 6759a57aee6..402637475e5 100644 --- a/lib/active_merchant/billing/gateways/quickbooks.rb +++ b/lib/active_merchant/billing/gateways/quickbooks.rb @@ -6,17 +6,14 @@ class QuickbooksGateway < Gateway self.supported_countries = ['US'] self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners] + self.supported_cardtypes = %i[visa master american_express discover diners] self.homepage_url = 'http://payments.intuit.com' self.display_name = 'QuickBooks Payments' - ENDPOINT = '/quickbooks/v4/payments/charges' - OAUTH_ENDPOINTS = { - site: 'https://oauth.intuit.com', - request_token_path: '/oauth/v1/get_request_token', - authorize_url: 'https://appcenter.intuit.com/Connect/Begin', - access_token_path: '/oauth/v1/get_access_token' - } + BASE = '/quickbooks/v4/payments' + ENDPOINT = "#{BASE}/charges" + VOID_ENDPOINT = "#{BASE}/txn-requests" + REFRESH_URI = 'https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer' # https://developer.intuit.com/docs/0150_payments/0300_developer_guides/error_handling @@ -45,13 +42,21 @@ class QuickbooksGateway < Gateway 'PMT-5001' => STANDARD_ERROR_CODE[:card_declined], # Merchant does not support given payment method # System Error - 'PMT-6000' => STANDARD_ERROR_CODE[:processing_error], # A temporary Issue prevented this request from being processed. + 'PMT-6000' => STANDARD_ERROR_CODE[:processing_error], # A temporary Issue prevented this request from being processed. } FRAUD_WARNING_CODES = ['PMT-1000', 'PMT-1001', 'PMT-1002', 'PMT-1003'] def initialize(options = {}) - requires!(options, :consumer_key, :consumer_secret, :access_token, :token_secret, :realm) + # Quickbooks is deprecating OAuth 1.0 on December 17, 2019. + # OAuth 2.0 requires a client_id, client_secret, access_token, and refresh_token + # To maintain backwards compatibility, check for the presence of a refresh_token (only specified for OAuth 2.0) + # When present, validate that all OAuth 2.0 options are present + if options[:refresh_token] + requires!(options, :client_id, :client_secret, :access_token, :refresh_token) + else + requires!(options, :consumer_key, :consumer_secret, :access_token, :token_secret, :realm) + end @options = options super end @@ -62,7 +67,8 @@ def purchase(money, payment, options = {}) add_charge_data(post, payment, options) post[:capture] = 'true' - commit(ENDPOINT, post) + response = commit(ENDPOINT, post) + check_token_response(response, ENDPOINT, post, options) end def authorize(money, payment, options = {}) @@ -71,30 +77,46 @@ def authorize(money, payment, options = {}) add_charge_data(post, payment, options) post[:capture] = 'false' - commit(ENDPOINT, post) + response = commit(ENDPOINT, post) + check_token_response(response, ENDPOINT, post, options) end def capture(money, authorization, options = {}) post = {} - capture_uri = "#{ENDPOINT}/#{CGI.escape(authorization)}/capture" + authorization, = split_authorization(authorization) post[:amount] = localized_amount(money, currency(money)) add_context(post, options) - commit(capture_uri, post) + response = commit(capture_uri(authorization), post) + check_token_response(response, capture_uri(authorization), post, options) end def refund(money, authorization, options = {}) post = {} post[:amount] = localized_amount(money, currency(money)) add_context(post, options) + authorization, = split_authorization(authorization) - commit(refund_uri(authorization), post) + response = commit(refund_uri(authorization), post) + check_token_response(response, refund_uri(authorization), post, options) + end + + def void(authorization, options = {}) + _, request_id = split_authorization(authorization) + + response = commit(void_uri(request_id)) + check_token_response(response, void_uri(request_id), {}, options) end def verify(credit_card, options = {}) authorize(1.00, credit_card, options) end + def refresh + response = refresh_access_token + response_object(response) + end + def supports_scrubbing? true end @@ -107,7 +129,12 @@ def scrub(transcript) gsub(%r((oauth_signature=\")[a-zA-Z%0-9]+), '\1[FILTERED]'). gsub(%r((oauth_token=\")\w+), '\1[FILTERED]'). gsub(%r((number\D+)\d{16}), '\1[FILTERED]'). - gsub(%r((cvc\D+)\d{3}), '\1[FILTERED]') + gsub(%r((cvc\D+)\d{3}), '\1[FILTERED]'). + gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]'). + gsub(%r((access_token\\?":\\?")[\w\-\.]+)i, '\1[FILTERED]'). + gsub(%r((refresh_token\\?":\\?")\w+), '\1[FILTERED]'). + gsub(%r((refresh_token=)\w+), '\1[FILTERED]'). + gsub(%r((Authorization: Bearer )[\w\-\.]+)i, '\1[FILTERED]\2') end private @@ -124,8 +151,9 @@ def add_address(post, options) if address = options[:billing_address] || options[:address] card_address[:streetAddress] = address[:address1] card_address[:city] = address[:city] - card_address[:region] = address[:state] || address[:region] - card_address[:country] = address[:country] + region = address[:state] || address[:region] + card_address[:region] = region if region.present? + card_address[:country] = address[:country] if address[:country].present? card_address[:postalCode] = address[:zip] if address[:zip] end post[:card][:address] = card_address @@ -170,30 +198,30 @@ def commit(uri, body = {}, method = :post) # The QuickBooks API returns HTTP 4xx on failed transactions, which causes a # ResponseError raise, so we have to inspect the response and discern between # a legitimate HTTP error and an actual gateway transactional error. - response = begin - case method - when :post - ssl_post(endpoint, post_data(body), headers(:post, endpoint)) - when :get - ssl_request(:get, endpoint, nil, headers(:get, endpoint)) - else - raise ArgumentError, "Invalid HTTP method: #{method}. Valid methods are :post and :get" + headers = {} + response = + begin + headers = headers(method, endpoint) + method == :post ? ssl_post(endpoint, post_data(body), headers) : ssl_request(:get, endpoint, nil, headers) + rescue ResponseError => e + extract_response_body_or_raise(e) end - rescue ResponseError => e - extract_response_body_or_raise(e) - end - response_object(response) + response_object(response, headers) end - def response_object(raw_response) + def response_object(raw_response, headers = {}) parsed_response = parse(raw_response) + # Include access_token and refresh_token in params for OAuth 2.0 + parsed_response['access_token'] = @options[:access_token] if @options[:refresh_token] + parsed_response['refresh_token'] = @options[:refresh_token] if @options[:refresh_token] + Response.new( success?(parsed_response), message_from(parsed_response), parsed_response, - authorization: authorization_from(parsed_response), + authorization: authorization_from(parsed_response, headers), test: test?, cvv_result: cvv_code_from(parsed_response), error_code: errors_from(parsed_response), @@ -210,7 +238,10 @@ def post_data(data = {}) end def headers(method, uri) - raise ArgumentError, "Invalid HTTP method: #{method}. Valid methods are :post and :get" unless [:post, :get].include?(method) + return oauth_v2_headers if @options[:refresh_token] + + raise ArgumentError, "Invalid HTTP method: #{method}. Valid methods are :post and :get" unless %i[post get].include?(method) + request_uri = URI.parse(uri) # Following the guidelines from http://nouncer.com/oauth/authentication.html @@ -229,7 +260,7 @@ def headers(method, uri) hmac_signature = OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha1'), oauth_signing_key, oauth_signature_base_string) # append signature to required OAuth parameters - oauth_parameters[:oauth_signature] = CGI.escape(Base64.encode64(hmac_signature).chomp.gsub(/\n/, '')) + oauth_parameters[:oauth_signature] = CGI.escape(Base64.encode64(hmac_signature).chomp.delete("\n")) # prepare Authorization header string oauth_parameters = Hash[oauth_parameters.sort_by { |k, _| k }] @@ -243,6 +274,45 @@ def headers(method, uri) } end + def oauth_v2_headers + { + 'Content-Type' => 'application/json', + 'Request-Id' => generate_unique_id, + 'Accept' => 'application/json', + 'Authorization' => "Bearer #{@options[:access_token]}" + } + end + + def check_token_response(response, endpoint, body = {}, options = {}) + return response unless @options[:refresh_token] + return response unless options[:allow_refresh] + return response unless response.params['code'] == 'AuthenticationFailed' + + refresh_access_token + commit(endpoint, body) + end + + def refresh_access_token + post = {} + post[:grant_type] = 'refresh_token' + post[:refresh_token] = @options[:refresh_token] + data = post.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join('&') + + basic_auth = Base64.strict_encode64("#{@options[:client_id]}:#{@options[:client_secret]}") + headers = { + 'Content-Type' => 'application/x-www-form-urlencoded', + 'Accept' => 'application/json', + 'Authorization' => "Basic #{basic_auth}" + } + + response = ssl_post(REFRESH_URI, data, headers) + json_response = JSON.parse(response) + + @options[:access_token] = json_response['access_token'] if json_response['access_token'] + @options[:refresh_token] = json_response['refresh_token'] if json_response['refresh_token'] + response + end + def cvv_code_from(response) if response['errors'].present? FRAUD_WARNING_CODES.include?(response['errors'].first['code']) ? 'I' : '' @@ -254,7 +324,7 @@ def cvv_code_from(response) def success?(response) return FRAUD_WARNING_CODES.concat(['0']).include?(response['errors'].first['code']) if response['errors'] - !['DECLINED', 'CANCELLED'].include?(response['status']) + !%w[DECLINED CANCELLED].include?(response['status']) && !%w[AuthenticationFailed AuthorizationFailed].include?(response['code']) end def message_from(response) @@ -262,11 +332,20 @@ def message_from(response) end def errors_from(response) - response['errors'].present? ? STANDARD_ERROR_CODE_MAPPING[response['errors'].first['code']] : '' + if %w[AuthenticationFailed AuthorizationFailed].include?(response['code']) + response['code'] + else + response['errors'].present? ? STANDARD_ERROR_CODE_MAPPING[response['errors'].first['code']] : '' + end + end + + def authorization_from(response, headers = {}) + [response['id'], headers['Request-Id']].join('|') end - def authorization_from(response) - response['id'] + def split_authorization(authorization) + authorization, request_id = authorization.split('|') + [authorization, request_id] end def fraud_review_status_from(response) @@ -283,7 +362,15 @@ def extract_response_body_or_raise(response_error) end def refund_uri(authorization) - "#{ENDPOINT}/#{CGI.escape(authorization)}/refunds" + "#{ENDPOINT}/#{CGI.escape(authorization.to_s)}/refunds" + end + + def capture_uri(authorization) + "#{ENDPOINT}/#{CGI.escape(authorization.to_s)}/capture" + end + + def void_uri(request_id) + "#{VOID_ENDPOINT}/#{CGI.escape(request_id.to_s)}/void" end end end diff --git a/lib/active_merchant/billing/gateways/quickpay.rb b/lib/active_merchant/billing/gateways/quickpay.rb index 5c1f6fb33bb..c6cd180d2da 100644 --- a/lib/active_merchant/billing/gateways/quickpay.rb +++ b/lib/active_merchant/billing/gateways/quickpay.rb @@ -19,7 +19,6 @@ def self.new(options = {}) QuickpayV10Gateway.new(options) end end - end end end diff --git a/lib/active_merchant/billing/gateways/quickpay/quickpay_common.rb b/lib/active_merchant/billing/gateways/quickpay/quickpay_common.rb index 930958e0cbb..25078bf9b5f 100644 --- a/lib/active_merchant/billing/gateways/quickpay/quickpay_common.rb +++ b/lib/active_merchant/billing/gateways/quickpay/quickpay_common.rb @@ -1,151 +1,151 @@ module QuickpayCommon MD5_CHECK_FIELDS = { 3 => { - :authorize => %w(protocol msgtype merchant ordernumber amount - currency autocapture cardnumber expirationdate - cvd cardtypelock testmode), + authorize: %w(protocol msgtype merchant ordernumber amount + currency autocapture cardnumber expirationdate + cvd cardtypelock testmode), - :capture => %w(protocol msgtype merchant amount finalize transaction), + capture: %w(protocol msgtype merchant amount finalize transaction), - :cancel => %w(protocol msgtype merchant transaction), + cancel: %w(protocol msgtype merchant transaction), - :refund => %w(protocol msgtype merchant amount transaction), + refund: %w(protocol msgtype merchant amount transaction), - :subscribe => %w(protocol msgtype merchant ordernumber cardnumber - expirationdate cvd cardtypelock description testmode), + subscribe: %w(protocol msgtype merchant ordernumber cardnumber + expirationdate cvd cardtypelock description testmode), - :recurring => %w(protocol msgtype merchant ordernumber amount - currency autocapture transaction), + recurring: %w(protocol msgtype merchant ordernumber amount + currency autocapture transaction), - :status => %w(protocol msgtype merchant transaction), + status: %w(protocol msgtype merchant transaction), - :chstatus => %w(protocol msgtype merchant) + chstatus: %w(protocol msgtype merchant) }, 4 => { - :authorize => %w(protocol msgtype merchant ordernumber amount - currency autocapture cardnumber expirationdate cvd - cardtypelock testmode fraud_remote_addr - fraud_http_accept fraud_http_accept_language - fraud_http_accept_encoding fraud_http_accept_charset - fraud_http_referer fraud_http_user_agent apikey), + authorize: %w(protocol msgtype merchant ordernumber amount + currency autocapture cardnumber expirationdate cvd + cardtypelock testmode fraud_remote_addr + fraud_http_accept fraud_http_accept_language + fraud_http_accept_encoding fraud_http_accept_charset + fraud_http_referer fraud_http_user_agent apikey), - :capture => %w(protocol msgtype merchant amount finalize transaction apikey), + capture: %w(protocol msgtype merchant amount finalize transaction apikey), - :cancel => %w(protocol msgtype merchant transaction apikey), + cancel: %w(protocol msgtype merchant transaction apikey), - :refund => %w(protocol msgtype merchant amount transaction apikey), + refund: %w(protocol msgtype merchant amount transaction apikey), - :subscribe => %w(protocol msgtype merchant ordernumber cardnumber - expirationdate cvd cardtypelock description testmode - fraud_remote_addr fraud_http_accept fraud_http_accept_language - fraud_http_accept_encoding fraud_http_accept_charset - fraud_http_referer fraud_http_user_agent apikey), + subscribe: %w(protocol msgtype merchant ordernumber cardnumber + expirationdate cvd cardtypelock description testmode + fraud_remote_addr fraud_http_accept fraud_http_accept_language + fraud_http_accept_encoding fraud_http_accept_charset + fraud_http_referer fraud_http_user_agent apikey), - :recurring => %w(protocol msgtype merchant ordernumber amount currency - autocapture transaction apikey), + recurring: %w(protocol msgtype merchant ordernumber amount currency + autocapture transaction apikey), - :status => %w(protocol msgtype merchant transaction apikey), + status: %w(protocol msgtype merchant transaction apikey), - :chstatus => %w(protocol msgtype merchant apikey) + chstatus: %w(protocol msgtype merchant apikey) }, 5 => { - :authorize => %w(protocol msgtype merchant ordernumber amount - currency autocapture cardnumber expirationdate cvd - cardtypelock testmode fraud_remote_addr - fraud_http_accept fraud_http_accept_language - fraud_http_accept_encoding fraud_http_accept_charset - fraud_http_referer fraud_http_user_agent apikey), + authorize: %w(protocol msgtype merchant ordernumber amount + currency autocapture cardnumber expirationdate cvd + cardtypelock testmode fraud_remote_addr + fraud_http_accept fraud_http_accept_language + fraud_http_accept_encoding fraud_http_accept_charset + fraud_http_referer fraud_http_user_agent apikey), - :capture => %w(protocol msgtype merchant amount finalize transaction apikey), + capture: %w(protocol msgtype merchant amount finalize transaction apikey), - :cancel => %w(protocol msgtype merchant transaction apikey), + cancel: %w(protocol msgtype merchant transaction apikey), - :refund => %w(protocol msgtype merchant amount transaction apikey), + refund: %w(protocol msgtype merchant amount transaction apikey), - :subscribe => %w(protocol msgtype merchant ordernumber cardnumber - expirationdate cvd cardtypelock description testmode - fraud_remote_addr fraud_http_accept fraud_http_accept_language - fraud_http_accept_encoding fraud_http_accept_charset - fraud_http_referer fraud_http_user_agent apikey), + subscribe: %w(protocol msgtype merchant ordernumber cardnumber + expirationdate cvd cardtypelock description testmode + fraud_remote_addr fraud_http_accept fraud_http_accept_language + fraud_http_accept_encoding fraud_http_accept_charset + fraud_http_referer fraud_http_user_agent apikey), - :recurring => %w(protocol msgtype merchant ordernumber amount currency - autocapture transaction apikey), + recurring: %w(protocol msgtype merchant ordernumber amount currency + autocapture transaction apikey), - :status => %w(protocol msgtype merchant transaction apikey), + status: %w(protocol msgtype merchant transaction apikey), - :chstatus => %w(protocol msgtype merchant apikey) + chstatus: %w(protocol msgtype merchant apikey) }, 6 => { - :authorize => %w(protocol msgtype merchant ordernumber amount - currency autocapture cardnumber expirationdate cvd - cardtypelock testmode fraud_remote_addr - fraud_http_accept fraud_http_accept_language - fraud_http_accept_encoding fraud_http_accept_charset - fraud_http_referer fraud_http_user_agent apikey), + authorize: %w(protocol msgtype merchant ordernumber amount + currency autocapture cardnumber expirationdate cvd + cardtypelock testmode fraud_remote_addr + fraud_http_accept fraud_http_accept_language + fraud_http_accept_encoding fraud_http_accept_charset + fraud_http_referer fraud_http_user_agent apikey), - :capture => %w(protocol msgtype merchant amount finalize transaction - apikey), + capture: %w(protocol msgtype merchant amount finalize transaction + apikey), - :cancel => %w(protocol msgtype merchant transaction apikey), + cancel: %w(protocol msgtype merchant transaction apikey), - :refund => %w(protocol msgtype merchant amount transaction apikey), + refund: %w(protocol msgtype merchant amount transaction apikey), - :subscribe => %w(protocol msgtype merchant ordernumber cardnumber - expirationdate cvd cardtypelock description testmode - fraud_remote_addr fraud_http_accept fraud_http_accept_language - fraud_http_accept_encoding fraud_http_accept_charset - fraud_http_referer fraud_http_user_agent apikey), + subscribe: %w(protocol msgtype merchant ordernumber cardnumber + expirationdate cvd cardtypelock description testmode + fraud_remote_addr fraud_http_accept fraud_http_accept_language + fraud_http_accept_encoding fraud_http_accept_charset + fraud_http_referer fraud_http_user_agent apikey), - :recurring => %w(protocol msgtype merchant ordernumber amount currency - autocapture transaction apikey), + recurring: %w(protocol msgtype merchant ordernumber amount currency + autocapture transaction apikey), - :status => %w(protocol msgtype merchant transaction apikey), + status: %w(protocol msgtype merchant transaction apikey), - :chstatus => %w(protocol msgtype merchant apikey) + chstatus: %w(protocol msgtype merchant apikey) }, 7 => { - :authorize => %w(protocol msgtype merchant ordernumber amount - currency autocapture cardnumber expirationdate cvd - acquirers cardtypelock testmode fraud_remote_addr - fraud_http_accept fraud_http_accept_language - fraud_http_accept_encoding fraud_http_accept_charset - fraud_http_referer fraud_http_user_agent apikey), + authorize: %w(protocol msgtype merchant ordernumber amount + currency autocapture cardnumber expirationdate cvd + acquirers cardtypelock testmode fraud_remote_addr + fraud_http_accept fraud_http_accept_language + fraud_http_accept_encoding fraud_http_accept_charset + fraud_http_referer fraud_http_user_agent apikey), - :capture => %w(protocol msgtype merchant amount finalize transaction - apikey), + capture: %w(protocol msgtype merchant amount finalize transaction + apikey), - :cancel => %w(protocol msgtype merchant transaction apikey), + cancel: %w(protocol msgtype merchant transaction apikey), - :refund => %w(protocol msgtype merchant amount transaction apikey), + refund: %w(protocol msgtype merchant amount transaction apikey), - :subscribe => %w(protocol msgtype merchant ordernumber amount currency - cardnumber expirationdate cvd acquirers cardtypelock - description testmode fraud_remote_addr fraud_http_accept - fraud_http_accept_language fraud_http_accept_encoding - fraud_http_accept_charset fraud_http_referer - fraud_http_user_agent apikey), + subscribe: %w(protocol msgtype merchant ordernumber amount currency + cardnumber expirationdate cvd acquirers cardtypelock + description testmode fraud_remote_addr fraud_http_accept + fraud_http_accept_language fraud_http_accept_encoding + fraud_http_accept_charset fraud_http_referer + fraud_http_user_agent apikey), - :recurring => %w(protocol msgtype merchant ordernumber amount currency - autocapture transaction apikey), + recurring: %w(protocol msgtype merchant ordernumber amount currency + autocapture transaction apikey), - :status => %w(protocol msgtype merchant transaction apikey), + status: %w(protocol msgtype merchant transaction apikey), - :chstatus => %w(protocol msgtype merchant apikey) + chstatus: %w(protocol msgtype merchant apikey) }, 10 => { - :authorize => %w(mobile_number acquirer autofee customer_id extras - zero_auth customer_ip), - :capture => %w( extras ), - :cancel => %w( extras ), - :refund => %w( extras ), - :subscribe => %w( variables branding_id), - :authorize_subscription => %w( mobile_number acquirer customer_ip), - :recurring => %w(auto_capture autofee zero_auth) + authorize: %w(mobile_number acquirer autofee customer_id extras + zero_auth customer_ip), + capture: %w(extras), + cancel: %w(extras), + refund: %w(extras), + subscribe: %w(variables branding_id), + authorize_subscription: %w(mobile_number acquirer customer_ip), + recurring: %w(auto_capture autofee zero_auth) } } @@ -168,9 +168,9 @@ def self.included(base) base.default_currency = 'DKK' base.money_format = :cents - base.supported_cardtypes = [:dankort, :forbrugsforeningen, :visa, :master, - :american_express, :diners_club, :jcb, :maestro] - base.supported_countries = ['DE', 'DK', 'ES', 'FI', 'FR', 'FO', 'GB', 'IS', 'NO', 'SE'] + base.supported_countries = %w[DE DK ES FI FR FO GB IS NO SE] + base.supported_cardtypes = %i[dankort forbrugsforeningen visa master + american_express diners_club jcb maestro] base.homepage_url = 'http://quickpay.net/' base.display_name = 'QuickPay' end diff --git a/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb b/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb index 565890a150e..91eeeff564e 100644 --- a/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +++ b/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb @@ -24,11 +24,11 @@ def purchase(money, credit_card_or_reference, options = {}) r.process { post = authorization_params(money, credit_card_or_reference, options) add_autocapture(post, false) - commit(synchronized_path("/payments/#{r.responses.last.params["id"]}/authorize"), post) + commit(synchronized_path("/payments/#{r.responses.last.params['id']}/authorize"), post) } r.process { post = capture_params(money, credit_card_or_reference, options) - commit(synchronized_path("/payments/#{r.responses.last.params["id"]}/capture"), post) + commit(synchronized_path("/payments/#{r.responses.last.params['id']}/capture"), post) } end end @@ -42,7 +42,7 @@ def authorize(money, credit_card_or_reference, options = {}) r.process { create_payment(money, options) } r.process { post = authorization_params(money, credit_card_or_reference, options) - commit(synchronized_path("/payments/#{r.responses.last.params["id"]}/authorize"), post) + commit(synchronized_path("/payments/#{r.responses.last.params['id']}/authorize"), post) } end end @@ -68,7 +68,7 @@ def refund(money, identification, options = {}) commit(synchronized_path("/payments/#{identification}/refund"), post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -154,9 +154,8 @@ def commit(action, params = {}) end Response.new(success, message_from(success, response), response, - :test => test?, - :authorization => authorization_from(response) - ) + test: test?, + authorization: authorization_from(response)) end def authorization_from(response) @@ -187,15 +186,11 @@ def add_order_id(post, options) def add_invoice(post, options) add_order_id(post, options) - if options[:billing_address] - post[:invoice_address] = map_address(options[:billing_address]) - end + post[:invoice_address] = map_address(options[:billing_address]) if options[:billing_address] - if options[:shipping_address] - post[:shipping_address] = map_address(options[:shipping_address]) - end + post[:shipping_address] = map_address(options[:shipping_address]) if options[:shipping_address] - [:metadata, :branding_id, :variables].each do |field| + %i[metadata branding_id variables].each do |field| post[field] = options[field] if options[field] end end @@ -208,7 +203,7 @@ def add_additional_params(action, post, options = {}) end def add_credit_card_or_reference(post, credit_card_or_reference, options = {}) - post[:card] ||= {} + post[:card] ||= {} if credit_card_or_reference.is_a?(String) post[:card][:token] = credit_card_or_reference else @@ -219,7 +214,7 @@ def add_credit_card_or_reference(post, credit_card_or_reference, options = {}) end if options[:three_d_secure] - post[:card][:cavv]= options.dig(:three_d_secure, :cavv) + post[:card][:cavv] = options.dig(:three_d_secure, :cavv) post[:card][:eci] = options.dig(:three_d_secure, :eci) post[:card][:xav] = options.dig(:three_d_secure, :xid) end @@ -253,21 +248,22 @@ def invalid_operation_message(response) def map_address(address) return {} if address.nil? + requires!(address, :name, :address1, :city, :zip, :country) country = Country.find(address[:country]) mapped = { - :name => address[:name], - :street => address[:address1], - :city => address[:city], - :region => address[:address2], - :zip_code => address[:zip], - :country_code => country.code(:alpha3).value + name: address[:name], + street: address[:address1], + city: address[:city], + region: address[:address2], + zip_code: address[:zip], + country_code: country.code(:alpha3).value } mapped end def format_order_id(order_id) - truncate(order_id.to_s.gsub(/#/, ''), 20) + truncate(order_id.to_s.delete('#'), 20) end def headers diff --git a/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb b/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb index 810d5cdefaa..bb00258a3f6 100644 --- a/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb +++ b/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb @@ -141,6 +141,7 @@ def add_description(post, options) def add_testmode(post) return if post[:transaction].present? + post[:testmode] = test? ? '1' : '0' end @@ -164,9 +165,8 @@ def commit(action, params) response = parse(ssl_post(self.live_url, post_data(action, params))) Response.new(successful?(response), message_from(response), response, - :test => test?, - :authorization => response[:transaction] - ) + test: test?, + authorization: response[:transaction]) end def successful?(response) diff --git a/lib/active_merchant/billing/gateways/qvalent.rb b/lib/active_merchant/billing/gateways/qvalent.rb index 420b8cccc96..d3142b7f259 100644 --- a/lib/active_merchant/billing/gateways/qvalent.rb +++ b/lib/active_merchant/billing/gateways/qvalent.rb @@ -10,18 +10,18 @@ class QvalentGateway < Gateway self.supported_countries = ['AU'] self.default_currency = 'AUD' self.money_format = :cents - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners] + self.supported_cardtypes = %i[visa master american_express discover jcb diners] CVV_CODE_MAPPING = { 'S' => 'D' } - def initialize(options={}) + def initialize(options = {}) requires!(options, :username, :password, :merchant, :pem, :pem_password) super end - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_order_number(post, options) @@ -34,7 +34,7 @@ def purchase(amount, payment_method, options={}) commit('capture', post) end - def authorize(amount, payment_method, options={}) + def authorize(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_order_number(post, options) @@ -47,7 +47,7 @@ def authorize(amount, payment_method, options={}) commit('preauth', post) end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) post = {} add_invoice(post, amount, options) add_reference(post, authorization, options) @@ -57,7 +57,7 @@ def capture(amount, authorization, options={}) commit('captureWithoutAuth', post) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) post = {} add_invoice(post, amount, options) add_reference(post, authorization, options) @@ -69,7 +69,7 @@ def refund(amount, authorization, options={}) end # Credit requires the merchant account to be enabled for "Adhoc Refunds" - def credit(amount, payment_method, options={}) + def credit(amount, payment_method, options = {}) post = {} add_invoice(post, amount, options) add_order_number(post, options) @@ -80,7 +80,7 @@ def credit(amount, payment_method, options={}) commit('refund', post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} add_reference(post, authorization, options) add_customer_data(post, options) @@ -110,7 +110,7 @@ def scrub(transcript) private - CURRENCY_CODES = Hash.new { |h, k| raise ArgumentError.new("Unsupported currency: #{k}") } + CURRENCY_CODES = Hash.new { |_h, k| raise ArgumentError.new("Unsupported currency: #{k}") } CURRENCY_CODES['AUD'] = 'AUD' CURRENCY_CODES['INR'] = 'INR' @@ -147,6 +147,7 @@ def add_stored_credential_data(post, payment_method, options) def stored_credential_usage(post, payment_method, options) return unless payment_method.brand == 'visa' + stored_credential = options[:stored_credential] if stored_credential[:initial_transaction] post['card.storedCredentialUsage'] = 'INITIAL_STORAGE' @@ -222,13 +223,14 @@ def commit(action, post) def cvv_result(succeeded, raw) return unless succeeded + code = CVV_CODE_MAPPING[raw['response.cvnResponse']] || raw['response.cvnResponse'] CVVResult.new(code) end def headers { - 'Content-Type' => 'application/x-www-form-urlencoded' + 'Content-Type' => 'application/x-www-form-urlencoded' } end @@ -278,7 +280,7 @@ def message_from(succeeded, response) '12' => STANDARD_ERROR_CODE[:card_declined], '06' => STANDARD_ERROR_CODE[:processing_error], '01' => STANDARD_ERROR_CODE[:call_issuer], - '04' => STANDARD_ERROR_CODE[:pickup_card], + '04' => STANDARD_ERROR_CODE[:pickup_card] } def error_code_from(succeeded, response) diff --git a/lib/active_merchant/billing/gateways/realex.rb b/lib/active_merchant/billing/gateways/realex.rb index ca402a5ca97..92b88bc1185 100644 --- a/lib/active_merchant/billing/gateways/realex.rb +++ b/lib/active_merchant/billing/gateways/realex.rb @@ -31,7 +31,7 @@ class RealexGateway < Gateway self.money_format = :cents self.default_currency = 'EUR' - self.supported_cardtypes = [ :visa, :master, :american_express, :diners_club ] + self.supported_cardtypes = %i[visa master american_express diners_club] self.supported_countries = %w(IE GB FR BE NL LU IT US CA ES) self.homepage_url = 'http://www.realexpayments.com/' self.display_name = 'Realex' @@ -107,8 +107,8 @@ def commit(request) (response[:result] == '00'), message_from(response), response, - :test => (response[:message] =~ %r{\[ test system \]}), - :authorization => authorization_from(response), + test: (response[:message] =~ %r{\[ test system \]}), + authorization: authorization_from(response), avs_result: AVSResult.new(code: response[:avspostcoderesponse]), cvv_result: CVVResult.new(response[:cvnresult]) ) @@ -138,7 +138,7 @@ def authorization_from(parsed) def build_purchase_or_authorization_request(action, money, credit_card, options) timestamp = new_timestamp - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.tag! 'request', 'timestamp' => timestamp, 'type' => 'auth' do add_merchant_details(xml, options) xml.tag! 'orderid', sanitize_order_id(options[:order_id]) @@ -159,7 +159,7 @@ def build_purchase_or_authorization_request(action, money, credit_card, options) def build_capture_request(money, authorization, options) timestamp = new_timestamp - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.tag! 'request', 'timestamp' => timestamp, 'type' => 'settle' do add_merchant_details(xml, options) add_amount(xml, money, options) @@ -172,7 +172,7 @@ def build_capture_request(money, authorization, options) def build_refund_request(money, authorization, options) timestamp = new_timestamp - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.tag! 'request', 'timestamp' => timestamp, 'type' => 'rebate' do add_merchant_details(xml, options) add_transaction_identifiers(xml, authorization, options) @@ -187,7 +187,7 @@ def build_refund_request(money, authorization, options) def build_credit_request(money, credit_card, options) timestamp = new_timestamp - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.tag! 'request', 'timestamp' => timestamp, 'type' => 'credit' do add_merchant_details(xml, options) xml.tag! 'orderid', sanitize_order_id(options[:order_id]) @@ -203,7 +203,7 @@ def build_credit_request(money, credit_card, options) def build_void_request(authorization, options) timestamp = new_timestamp - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.tag! 'request', 'timestamp' => timestamp, 'type' => 'void' do add_merchant_details(xml, options) add_transaction_identifiers(xml, authorization, options) @@ -216,7 +216,7 @@ def build_void_request(authorization, options) # Verify initiates an OTB (Open To Buy) request def build_verify_request(credit_card, options) timestamp = new_timestamp - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.tag! 'request', 'timestamp' => timestamp, 'type' => 'otb' do add_merchant_details(xml, options) xml.tag! 'orderid', sanitize_order_id(options[:order_id]) @@ -230,13 +230,14 @@ def build_verify_request(credit_card, options) def add_address_and_customer_info(xml, options) billing_address = options[:billing_address] || options[:address] shipping_address = options[:shipping_address] + ipv4_address = ipv4?(options[:ip]) ? options[:ip] : nil - return unless billing_address || shipping_address || options[:customer] || options[:invoice] || options[:ip] + return unless billing_address || shipping_address || options[:customer] || options[:invoice] || ipv4_address xml.tag! 'tssinfo' do xml.tag! 'custnum', options[:customer] if options[:customer] xml.tag! 'prodid', options[:invoice] if options[:invoice] - xml.tag! 'custipaddress', options[:ip] if options[:ip] + xml.tag! 'custipaddress', options[:ip] if ipv4_address if billing_address xml.tag! 'address', 'type' => 'billing' do @@ -256,9 +257,7 @@ def add_address_and_customer_info(xml, options) def add_merchant_details(xml, options) xml.tag! 'merchantid', @options[:login] - if options[:account] || @options[:account] - xml.tag! 'account', (options[:account] || @options[:account]) - end + xml.tag! 'account', (options[:account] || @options[:account]) if options[:account] || @options[:account] end def add_transaction_identifiers(xml, authorization, options) @@ -270,6 +269,7 @@ def add_transaction_identifiers(xml, authorization, options) def add_comments(xml, options) return unless options[:description] + xml.tag! 'comments' do xml.tag! 'comment', options[:description], 'id' => 1 end @@ -300,21 +300,23 @@ def add_network_tokenization_card(xml, payment) end xml.tag! 'supplementarydata' do xml.tag! 'item', 'type' => 'mobile' do - xml.tag! 'field01', payment.source.to_s.gsub('_', '-') + xml.tag! 'field01', payment.source.to_s.tr('_', '-') end end end def add_three_d_secure(xml, options) return unless three_d_secure = options[:three_d_secure] + version = three_d_secure.fetch(:version, '') xml.tag! 'mpi' do - if version =~ /^2/ + if /^2/.match?(version) xml.tag! 'authentication_value', three_d_secure[:cavv] xml.tag! 'ds_trans_id', three_d_secure[:ds_transaction_id] else xml.tag! 'cavv', three_d_secure[:cavv] xml.tag! 'xid', three_d_secure[:xid] + version = '1' end xml.tag! 'eci', three_d_secure[:eci] xml.tag! 'message_version', version @@ -369,6 +371,12 @@ def message_from(response) def sanitize_order_id(order_id) order_id.to_s.gsub(/[^a-zA-Z0-9\-_]/, '') end + + def ipv4?(ip_address) + return false if ip_address.nil? + + !ip_address.match(/\A\d+\.\d+\.\d+\.\d+\z/).nil? + end end end end diff --git a/lib/active_merchant/billing/gateways/redsys.rb b/lib/active_merchant/billing/gateways/redsys.rb index 0e58693dff2..db62e61d83d 100644 --- a/lib/active_merchant/billing/gateways/redsys.rb +++ b/lib/active_merchant/billing/gateways/redsys.rb @@ -36,7 +36,7 @@ module Billing #:nodoc: # # class RedsysGateway < Gateway - self.live_url = 'https://sis.sermepa.es/sis/operaciones' + self.live_url = 'https://sis.redsys.es/sis/operaciones' self.test_url = 'https://sis-t.redsys.es:25443/sis/operaciones' self.supported_countries = ['ES'] @@ -44,7 +44,7 @@ class RedsysGateway < Gateway self.money_format = :cents # Not all card types may be activated by the bank! - self.supported_cardtypes = [:visa, :master, :american_express, :jcb, :diners_club] + self.supported_cardtypes = %i[visa master american_express jcb diners_club unionpay] self.homepage_url = 'http://www.redsys.es/' self.display_name = 'Redsys' @@ -91,11 +91,11 @@ class RedsysGateway < Gateway # More operations are supported by the gateway itself, but # are not supported in this library. SUPPORTED_TRANSACTIONS = { - :purchase => 'A', - :authorize => '1', - :capture => '2', - :refund => '3', - :cancel => '9' + purchase: 'A', + authorize: '1', + capture: '2', + refund: '3', + cancel: '9' } # These are the text meanings sent back by the acquirer when @@ -126,6 +126,7 @@ class RedsysGateway < Gateway 184 => 'Authentication error', 190 => 'Refusal with no specific reason', 191 => 'Expiry date incorrect', + 195 => 'Requires SCA authentication', 201 => 'Card expired', 202 => 'Card blocked temporarily or under suspicion of fraud', @@ -170,6 +171,10 @@ class RedsysGateway < Gateway 9914 => 'KO Confirmation' } + # Expected values as per documentation + THREE_DS_V1 = '1.0.2' + THREE_DS_V2 = '2.1.0' + # Creates a new instance # # Redsys requires a login and secret_key, and optionally also accepts a @@ -197,7 +202,9 @@ def purchase(money, payment, options = {}) add_amount(data, money, options) add_order(data, options[:order_id]) add_payment(data, payment) + add_external_mpi_fields(data, options) add_threeds(data, options) if options[:execute_threed] + add_stored_credential_options(data, options) data[:description] = options[:description] data[:store_in_vault] = options[:store] data[:sca_exemption] = options[:sca_exemption] @@ -213,7 +220,9 @@ def authorize(money, payment, options = {}) add_amount(data, money, options) add_order(data, options[:order_id]) add_payment(data, payment) + add_external_mpi_fields(data, options) add_threeds(data, options) if options[:execute_threed] + add_stored_credential_options(data, options) data[:description] = options[:description] data[:store_in_vault] = options[:store] data[:sca_exemption] = options[:sca_exemption] @@ -225,7 +234,7 @@ def capture(money, authorization, options = {}) data = {} add_action(data, :capture) add_amount(data, money, options) - order_id, _, _ = split_authorization(authorization) + order_id, = split_authorization(authorization) add_order(data, order_id) data[:description] = options[:description] @@ -236,7 +245,7 @@ def void(authorization, options = {}) data = {} add_action(data, :cancel) order_id, amount, currency = split_authorization(authorization) - add_amount(data, amount, :currency => currency) + add_amount(data, amount, currency: currency) add_order(data, order_id) data[:description] = options[:description] @@ -247,7 +256,7 @@ def refund(money, authorization, options = {}) data = {} add_action(data, :refund) add_amount(data, money, options) - order_id, _, _ = split_authorization(authorization) + order_id, = split_authorization(authorization) add_order(data, order_id) data[:description] = options[:description] @@ -270,8 +279,10 @@ def scrub(transcript) gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]'). gsub(%r((%3CDS_MERCHANT_PAN%3E)\d+(%3C%2FDS_MERCHANT_PAN%3E))i, '\1[FILTERED]\2'). gsub(%r((%3CDS_MERCHANT_CVV2%3E)\d+(%3C%2FDS_MERCHANT_CVV2%3E))i, '\1[FILTERED]\2'). + gsub(%r((<DS_MERCHANT_PAN>)\d+(</DS_MERCHANT_PAN>))i, '\1[FILTERED]\2'). gsub(%r(()\d+())i, '\1[FILTERED]\2'). gsub(%r(()\d+())i, '\1[FILTERED]\2'). + gsub(%r((<DS_MERCHANT_CVV2>)\d+(</DS_MERCHANT_CVV2>))i, '\1[FILTERED]\2'). gsub(%r((DS_MERCHANT_CVV2)%2F%3E%0A%3C%2F)i, '\1[BLANK]'). gsub(%r((DS_MERCHANT_CVV2)%2F%3E%3C)i, '\1[BLANK]'). gsub(%r((DS_MERCHANT_CVV2%3E)(%3C%2FDS_MERCHANT_CVV2))i, '\1[BLANK]\2'). @@ -300,7 +311,7 @@ def url end def threeds_url - test? ? 'https://sis-t.redsys.es:25443/sis/services/SerClsWSEntradaV2': 'https://sis.redsys.es/sis/services/SerClsWSEntradaV2' + test? ? 'https://sis-t.redsys.es:25443/sis/services/SerClsWSEntradaV2' : 'https://sis.redsys.es/sis/services/SerClsWSEntradaV2' end def add_payment(data, card) @@ -311,18 +322,56 @@ def add_payment(data, card) year = sprintf('%.4i', card.year) month = sprintf('%.2i', card.month) data[:card] = { - :name => name, - :pan => card.number, - :date => "#{year[2..3]}#{month}", - :cvv => card.verification_value + name: name, + pan: card.number, + date: "#{year[2..3]}#{month}", + cvv: card.verification_value } end end - def add_threeds(data, options) - if options[:execute_threed] == true - data[:threeds] = {threeDSInfo: 'CardData'} + def add_external_mpi_fields(data, options) + return unless options[:three_d_secure] + + if options[:three_d_secure][:version] == THREE_DS_V2 + data[:threeDSServerTransID] = options[:three_d_secure][:three_ds_server_trans_id] if options[:three_d_secure][:three_ds_server_trans_id] + data[:dsTransID] = options[:three_d_secure][:ds_transaction_id] if options[:three_d_secure][:ds_transaction_id] + data[:authenticacionValue] = options[:three_d_secure][:cavv] if options[:three_d_secure][:cavv] + data[:protocolVersion] = options[:three_d_secure][:version] if options[:three_d_secure][:version] + data[:authenticacionMethod] = options[:authentication_method] if options[:authentication_method] + data[:authenticacionType] = options[:authentication_type] if options[:authentication_type] + data[:authenticacionFlow] = options[:authentication_flow] if options[:authentication_flow] + data[:eci_v2] = options[:three_d_secure][:eci] if options[:three_d_secure][:eci] + elsif options[:three_d_secure][:version] == THREE_DS_V1 + data[:txid] = options[:three_d_secure][:xid] if options[:three_d_secure][:xid] + data[:cavv] = options[:three_d_secure][:cavv] if options[:three_d_secure][:cavv] + data[:eci_v1] = options[:three_d_secure][:eci] if options[:three_d_secure][:eci] + end + end + + def add_stored_credential_options(data, options) + return unless options[:stored_credential] + + case options[:stored_credential][:initial_transaction] + when true + data[:DS_MERCHANT_COF_INI] = 'S' + when false + data[:DS_MERCHANT_COF_INI] = 'N' + data[:DS_MERCHANT_COF_TXNID] = options[:stored_credential][:network_transaction_id] if options[:stored_credential][:network_transaction_id] end + + case options[:stored_credential][:reason_type] + when 'recurring' + data[:DS_MERCHANT_COF_TYPE] = 'R' + when 'installment' + data[:DS_MERCHANT_COF_TYPE] = 'I' + when 'unscheduled' + return + end + end + + def add_threeds(data, options) + data[:threeds] = { threeDSInfo: 'CardData' } if options[:execute_threed] == true end def determine_3ds_action(threeds_hash) @@ -334,7 +383,7 @@ def determine_3ds_action(threeds_hash) def commit(data, options = {}) if data[:threeds] action = determine_3ds_action(data[:threeds]) - request = <<-EOS + request = <<-REQUEST @@ -345,18 +394,18 @@ def commit(data, options = {}) - EOS + REQUEST parse(ssl_post(threeds_url, request, headers(action)), action) else parse(ssl_post(url, "entrada=#{CGI.escape(xml_request_from(data, options))}", headers), action) end end - def headers(action=nil) + def headers(action = nil) if action { 'Content-Type' => 'text/xml', - 'SOAPAction' => action + 'SOAPAction' => action } else { @@ -375,9 +424,9 @@ def xml_request_from(data, options = {}) def build_signature(data) str = data[:amount] + - data[:order_id].to_s + - @options[:login].to_s + - data[:currency] + data[:order_id].to_s + + @options[:login].to_s + + data[:currency] if card = data[:card] str << card[:pan] @@ -407,7 +456,7 @@ def build_sha256_xml_request(data, options = {}) end def build_sha1_xml_request(data, options = {}) - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 build_merchant_data(xml, data, options) xml.target! end @@ -419,6 +468,8 @@ def merchant_data_xml(data, options = {}) end def build_merchant_data(xml, data, options = {}) + # See https://sis-t.redsys.es:25443/sis/services/SerClsWSEntradaV2/wsdl/SerClsWSEntradaV2.wsdl + # (which results from calling #threeds_url + '?WSDL', https://sis-t.redsys.es:25443/sis/services/SerClsWSEntradaV2?WSDL) xml.DATOSENTRADA do # Basic elements xml.DS_Version 0.1 @@ -426,7 +477,11 @@ def build_merchant_data(xml, data, options = {}) xml.DS_MERCHANT_AMOUNT data[:amount] xml.DS_MERCHANT_ORDER data[:order_id] xml.DS_MERCHANT_TRANSACTIONTYPE data[:action] - xml.DS_MERCHANT_PRODUCTDESCRIPTION data[:description] + if data[:description] && data[:threeds] + xml.DS_MERCHANT_PRODUCTDESCRIPTION CGI.escape(data[:description]) + else + xml.DS_MERCHANT_PRODUCTDESCRIPTION data[:description] + end xml.DS_MERCHANT_TERMINAL options[:terminal] || @options[:terminal] xml.DS_MERCHANT_MERCHANTCODE @options[:login] xml.DS_MERCHANT_MERCHANTSIGNATURE build_signature(data) unless sha256_authentication? @@ -434,11 +489,18 @@ def build_merchant_data(xml, data, options = {}) # Only when card is present if data[:card] - xml.DS_MERCHANT_TITULAR data[:card][:name] + if data[:card][:name] && data[:threeds] + xml.DS_MERCHANT_TITULAR CGI.escape(data[:card][:name]) + else + xml.DS_MERCHANT_TITULAR data[:card][:name] + end xml.DS_MERCHANT_PAN data[:card][:pan] xml.DS_MERCHANT_EXPIRYDATE data[:card][:date] xml.DS_MERCHANT_CVV2 data[:card][:cvv] xml.DS_MERCHANT_IDENTIFIER 'REQUIRED' if data[:store_in_vault] + + build_merchant_mpi_external(xml, data) + elsif data[:credit_card_token] xml.DS_MERCHANT_IDENTIFIER data[:credit_card_token] xml.DS_MERCHANT_DIRECTPAYMENT 'true' @@ -446,36 +508,48 @@ def build_merchant_data(xml, data, options = {}) # Set moto flag only if explicitly requested via moto field # Requires account configuration to be able to use - if options.dig(:moto) && options.dig(:metadata, :manual_entry) - xml.DS_MERCHANT_DIRECTPAYMENT 'moto' - end + xml.DS_MERCHANT_DIRECTPAYMENT 'moto' if options.dig(:moto) && options.dig(:metadata, :manual_entry) + + xml.DS_MERCHANT_EMV3DS data[:threeds].to_json if data[:threeds] - if data[:threeds] - xml.DS_MERCHANT_EMV3DS data[:threeds].to_json + if options[:stored_credential] + xml.DS_MERCHANT_COF_INI data[:DS_MERCHANT_COF_INI] + xml.DS_MERCHANT_COF_TYPE data[:DS_MERCHANT_COF_TYPE] + xml.DS_MERCHANT_COF_TXNID data[:DS_MERCHANT_COF_TXNID] if data[:DS_MERCHANT_COF_TXNID] end end end + def build_merchant_mpi_external(xml, data) + return unless data[:txid] || data[:threeDSServerTransID] + + ds_merchant_mpi_external = {} + ds_merchant_mpi_external[:TXID] = data[:txid] if data[:txid] + ds_merchant_mpi_external[:CAVV] = data[:cavv] if data[:cavv] + ds_merchant_mpi_external[:ECI] = data[:eci_v1] if data[:eci_v1] + + ds_merchant_mpi_external[:threeDSServerTransID] = data[:threeDSServerTransID] if data[:threeDSServerTransID] + ds_merchant_mpi_external[:dsTransID] = data[:dsTransID] if data[:dsTransID] + ds_merchant_mpi_external[:authenticacionValue] = data[:authenticacionValue] if data[:authenticacionValue] + ds_merchant_mpi_external[:protocolVersion] = data[:protocolVersion] if data[:protocolVersion] + ds_merchant_mpi_external[:Eci] = data[:eci_v2] if data[:eci_v2] + ds_merchant_mpi_external[:authenticacionMethod] = data[:authenticacionMethod] if data[:authenticacionMethod] + ds_merchant_mpi_external[:authenticacionType] = data[:authenticacionType] if data[:authenticacionType] + ds_merchant_mpi_external[:authenticacionFlow] = data[:authenticacionFlow] if data[:authenticacionFlow] + + xml.DS_MERCHANT_MPIEXTERNAL ds_merchant_mpi_external.to_json unless ds_merchant_mpi_external.empty? + xml.target! + end + def parse(data, action) params = {} success = false message = '' - options = @options.merge(:test => test?) + options = @options.merge(test: test?) xml = Nokogiri::XML(data) code = xml.xpath('//RETORNOXML/CODIGO').text - if ['iniciaPeticion', 'trataPeticion'].include?(action) - vxml = Nokogiri::XML(data).remove_namespaces!.xpath("//Envelope/Body/#{action}Response/#{action}Return").inner_text - xml = Nokogiri::XML(vxml) - node = (action == 'iniciaPeticion' ? 'INFOTARJETA' : 'OPERACION') - op = xml.xpath("//RETORNOXML/#{node}") - op.children.each do |element| - params[element.name.downcase.to_sym] = element.text - end - message = response_text_3ds(xml, params) - options[:authorization] = build_authorization(params) - success = params.size > 0 && is_success_response?(params[:ds_response]) - elsif code == '0' + if code == '0' && xml.xpath('//RETORNOXML/OPERACION').present? op = xml.xpath('//RETORNOXML/OPERACION') op.children.each do |element| params[element.name.downcase.to_sym] = element.text @@ -483,10 +557,21 @@ def parse(data, action) if validate_signature(params) message = response_text(params[:ds_response]) options[:authorization] = build_authorization(params) - success = is_success_response?(params[:ds_response]) + success = success_response?(params[:ds_response]) else message = 'Response failed validation check' end + elsif %w[iniciaPeticion trataPeticion].include?(action) + vxml = Nokogiri::XML(data).remove_namespaces!.xpath("//Envelope/Body/#{action}Response/#{action}Return").inner_text + xml = Nokogiri::XML(vxml) + node = (action == 'iniciaPeticion' ? 'INFOTARJETA' : 'OPERACION') + op = xml.xpath("//RETORNOXML/#{node}") + op.children.each do |element| + params[element.name.downcase.to_sym] = element.text + end + message = response_text_3ds(xml, params) + options[:authorization] = build_authorization(params) + success = params.size > 0 && success_response?(params[:ds_response]) else # Some kind of programmer error with the request! message = "#{code} ERROR" @@ -501,14 +586,14 @@ def validate_signature(data) sig.casecmp(data[:ds_signature].to_s).zero? else str = data[:ds_amount] + - data[:ds_order].to_s + - data[:ds_merchantcode] + - data[:ds_currency] + - data[:ds_response] + - data[:ds_cardnumber].to_s + - data[:ds_transactiontype].to_s + - data[:ds_securepayment].to_s + - @options[:secret_key] + data[:ds_order].to_s + + data[:ds_merchantcode] + + data[:ds_currency] + + data[:ds_response] + + data[:ds_cardnumber].to_s + + data[:ds_transactiontype].to_s + + data[:ds_securepayment].to_s + + @options[:secret_key] sig = Digest::SHA1.hexdigest(str) data[:ds_signature].to_s.downcase == sig @@ -527,6 +612,7 @@ def split_authorization(authorization) def currency_code(currency) return currency if currency =~ /^\d+$/ raise ArgumentError, "Unknown currency #{currency}" unless CURRENCY_CODES[currency] + CURRENCY_CODES[currency] end @@ -537,7 +623,7 @@ def transaction_code(type) def response_text(code) code = code.to_i code = 0 if code < 100 - RESPONSE_TEXTS[code] || 'Unkown code, please check in manual' + RESPONSE_TEXTS[code] || 'Unknown code, please check in manual' end def response_text_3ds(xml, params) @@ -554,13 +640,13 @@ def response_text_3ds(xml, params) message end - def is_success_response?(code) + def success_response?(code) (code.to_i < 100) || [400, 481, 500, 900].include?(code.to_i) end def clean_order_id(order_id) cleansed = order_id.gsub(/[^\da-zA-Z]/, '') - if cleansed =~ /^\d{4}/ + if /^\d{4}/.match?(cleansed) cleansed[0..11] else '%04d%s' % [rand(0..9999), cleansed[0...8]] @@ -597,15 +683,11 @@ def mac256(key, data) def xml_signed_fields(data) xml_signed_fields = data[:ds_amount] + data[:ds_order] + data[:ds_merchantcode] + - data[:ds_currency] + data[:ds_response] + data[:ds_currency] + data[:ds_response] - if data[:ds_cardnumber] - xml_signed_fields += data[:ds_cardnumber] - end + xml_signed_fields += data[:ds_cardnumber] if data[:ds_cardnumber] - if data[:ds_emv3ds] - xml_signed_fields += data[:ds_emv3ds] - end + xml_signed_fields += data[:ds_emv3ds] if data[:ds_emv3ds] xml_signed_fields + data[:ds_transactiontype] + data[:ds_securepayment] end diff --git a/lib/active_merchant/billing/gateways/s5.rb b/lib/active_merchant/billing/gateways/s5.rb index 9f36a91e54e..4dc62423313 100644 --- a/lib/active_merchant/billing/gateways/s5.rb +++ b/lib/active_merchant/billing/gateways/s5.rb @@ -8,7 +8,7 @@ class S5Gateway < Gateway self.supported_countries = ['DK'] self.default_currency = 'EUR' - self.supported_cardtypes = [:visa, :master, :maestro] + self.supported_cardtypes = %i[visa master maestro] self.homepage_url = 'http://www.s5.dk/' self.display_name = 'S5' @@ -22,12 +22,12 @@ class S5Gateway < Gateway 'store' => 'CC.RG' } - def initialize(options={}) + def initialize(options = {}) requires!(options, :sender, :channel, :login, :password) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) request = build_xml_request do |xml| add_identification(xml, options) add_payment(xml, money, 'sale', options) @@ -39,7 +39,7 @@ def purchase(money, payment, options={}) commit(request) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) request = build_xml_request do |xml| add_identification(xml, options, authorization) add_payment(xml, money, 'refund', options) @@ -48,7 +48,7 @@ def refund(money, authorization, options={}) commit(request) end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) request = build_xml_request do |xml| add_identification(xml, options) add_payment(xml, money, 'authonly', options) @@ -60,7 +60,7 @@ def authorize(money, payment, options={}) commit(request) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) request = build_xml_request do |xml| add_identification(xml, options, authorization) add_payment(xml, money, 'capture', options) @@ -69,7 +69,7 @@ def capture(money, authorization, options={}) commit(request) end - def void(authorization, options={}) + def void(authorization, options = {}) request = build_xml_request do |xml| add_identification(xml, options, authorization) add_payment(xml, nil, 'void', options) @@ -89,7 +89,7 @@ def store(payment, options = {}) commit(request) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -143,6 +143,7 @@ def add_account(xml, payment_method) def add_customer(xml, creditcard, options) return unless creditcard.respond_to?(:number) + address = options[:billing_address] xml.Customer do xml.Contact do @@ -180,7 +181,7 @@ def add_recurrence_mode(xml, options) end def parse(body) - results = {} + results = {} xml = Nokogiri::XML(body) resp = xml.xpath('//Response/Transaction/Identification') resp.children.each do |element| diff --git a/lib/active_merchant/billing/gateways/safe_charge.rb b/lib/active_merchant/billing/gateways/safe_charge.rb index 8d3cccd3cc6..87b9a4a8763 100644 --- a/lib/active_merchant/billing/gateways/safe_charge.rb +++ b/lib/active_merchant/billing/gateways/safe_charge.rb @@ -6,24 +6,35 @@ class SafeChargeGateway < Gateway self.test_url = 'https://process.sandbox.safecharge.com/service.asmx/Process' self.live_url = 'https://process.safecharge.com/service.asmx/Process' - self.supported_countries = ['AT', 'BE', 'BG', 'CY', 'CZ', 'DE', 'DK', 'EE', 'GR', 'ES', 'FI', 'FR', 'HR', 'HU', 'IE', 'IS', 'IT', 'LI', 'LT', 'LU', 'LV', 'MT', 'NL', 'NO', 'PL', 'PT', 'RO', 'SE', 'SI', 'SK', 'GB', 'US'] + self.supported_countries = %w[AT BE BG CY CZ DE DK EE GR ES FI FR GI HK HR HU IE IS IT LI LT LU LV MT MX NL NO PL PT RO SE SG SI SK GB US] self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master] + self.supported_cardtypes = %i[visa master] self.homepage_url = 'https://www.safecharge.com' self.display_name = 'SafeCharge' VERSION = '4.1.0' - def initialize(options={}) + def initialize(options = {}) requires!(options, :client_login_id, :client_password) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) post = {} - post[:sg_APIType] = 1 if options[:three_d_secure] - trans_type = options[:three_d_secure] ? 'Sale3D' : 'Sale' + + # Determine if 3DS is requested, or there is standard external MPI data + if options[:three_d_secure] + if options[:three_d_secure].is_a?(Hash) + add_external_mpi_data(post, options) + else + post[:sg_APIType] = 1 + trans_type = 'Sale3D' + end + end + + trans_type ||= 'Sale' + add_transaction_data(trans_type, post, money, options) add_payment(post, payment, options) add_customer_details(post, payment, options) @@ -31,8 +42,10 @@ def purchase(money, payment, options={}) commit(post) end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) post = {} + + add_external_mpi_data(post, options) if options[:three_d_secure]&.is_a?(Hash) add_transaction_data('Auth', post, money, options) add_payment(post, payment, options) add_customer_details(post, payment, options) @@ -40,10 +53,10 @@ def authorize(money, payment, options={}) commit(post) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) post = {} auth, transaction_id, token, exp_month, exp_year, _, original_currency = authorization.split('|') - add_transaction_data('Settle', post, money, options.merge!({currency: original_currency})) + add_transaction_data('Settle', post, money, options.merge!({ currency: original_currency })) post[:sg_AuthCode] = auth post[:sg_TransactionID] = transaction_id post[:sg_CCToken] = token @@ -53,10 +66,10 @@ def capture(money, authorization, options={}) commit(post) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) post = {} auth, transaction_id, token, exp_month, exp_year, _, original_currency = authorization.split('|') - add_transaction_data('Credit', post, money, options.merge!({currency: original_currency})) + add_transaction_data('Credit', post, money, options.merge!({ currency: original_currency })) post[:sg_CreditType] = 2 post[:sg_AuthCode] = auth post[:sg_TransactionID] = transaction_id @@ -67,19 +80,21 @@ def refund(money, authorization, options={}) commit(post) end - def credit(money, payment, options={}) + def credit(money, payment, options = {}) post = {} + add_payment(post, payment, options) add_transaction_data('Credit', post, money, options) + post[:sg_CreditType] = 1 commit(post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} auth, transaction_id, token, exp_month, exp_year, original_amount, original_currency = authorization.split('|') - add_transaction_data('Void', post, (original_amount.to_f * 100), options.merge!({currency: original_currency})) + add_transaction_data('Void', post, (original_amount.to_f * 100), options.merge!({ currency: original_currency })) post[:sg_CreditType] = 2 post[:sg_AuthCode] = auth post[:sg_TransactionID] = transaction_id @@ -90,7 +105,7 @@ def void(authorization, options={}) commit(post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -130,13 +145,21 @@ def add_transaction_data(trans_type, post, money, options) post[:sg_MerchantName] = options[:merchant_name] if options[:merchant_name] end - def add_payment(post, payment, options={}) - post[:sg_NameOnCard] = payment.name - post[:sg_CardNumber] = payment.number + def add_payment(post, payment, options = {}) post[:sg_ExpMonth] = format(payment.month, :two_digits) post[:sg_ExpYear] = format(payment.year, :two_digits) - post[:sg_CVV2] = payment.verification_value - post[:sg_StoredCredentialMode] = (options[:stored_credential_mode] == true ? 1 : 0) + post[:sg_CardNumber] = payment.number + + if payment.is_a?(NetworkTokenizationCreditCard) && payment.source == :network_token + post[:sg_CAVV] = payment.payment_cryptogram + post[:sg_ECI] = options[:three_d_secure] && options[:three_d_secure][:eci] || '05' + post[:sg_IsExternalMPI] = 1 + post[:sg_ExternalTokenProvider] = 5 + else + post[:sg_CVV2] = payment.verification_value + post[:sg_NameOnCard] = payment.name + post[:sg_StoredCredentialMode] = (options[:stored_credential_mode] == true ? 1 : 0) + end end def add_customer_details(post, payment, options) @@ -146,14 +169,24 @@ def add_customer_details(post, payment, options) post[:sg_Address] = address[:address1] if address[:address1] post[:sg_City] = address[:city] if address[:city] post[:sg_State] = address[:state] if address[:state] - post[:sg_Zip] = address[:zip] if address[:zip] - post[:sg_Country] = address[:country] if address[:country] - post[:sg_Phone] = address[:phone] if address[:phone] + post[:sg_Zip] = address[:zip] if address[:zip] + post[:sg_Country] = address[:country] if address[:country] + post[:sg_Phone] = address[:phone] if address[:phone] end post[:sg_Email] = options[:email] end + def add_external_mpi_data(post, options) + post[:sg_ECI] = options[:three_d_secure][:eci] if options[:three_d_secure][:eci] + post[:sg_CAVV] = options[:three_d_secure][:cavv] if options[:three_d_secure][:cavv] + post[:sg_dsTransID] = options[:three_d_secure][:ds_transaction_id] if options[:three_d_secure][:ds_transaction_id] + post[:sg_threeDSProtocolVersion] = options[:three_d_secure][:ds_transaction_id] ? '2' : '1' + post[:sg_Xid] = options[:three_d_secure][:xid] + post[:sg_IsExternalMPI] = 1 + post[:sg_EnablePartialApproval] = options[:is_partial_approval] + end + def parse(xml) response = {} @@ -207,6 +240,7 @@ def success_from(response) def message_from(response) return 'Success' if success_from(response) + response[:reason_codes] || response[:reason] end @@ -240,14 +274,13 @@ def post_data(params) params.map do |key, value| next if value != false && value.blank? + "#{key}=#{CGI.escape(value.to_s)}" end.compact.join('&') end def error_code_from(response) - unless success_from(response) - response[:ex_err_code] || response[:err_code] - end + response[:ex_err_code] || response[:err_code] unless success_from(response) end def underscore(camel_cased_word) diff --git a/lib/active_merchant/billing/gateways/sage.rb b/lib/active_merchant/billing/gateways/sage.rb index 3f3c9a96bcf..b0c56ee02e8 100644 --- a/lib/active_merchant/billing/gateways/sage.rb +++ b/lib/active_merchant/billing/gateways/sage.rb @@ -7,20 +7,20 @@ class SageGateway < Gateway self.homepage_url = 'Sage Payment Solutions' self.live_url = 'https://www.sagepayments.net/cgi-bin' - self.supported_countries = ['US', 'CA'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club] + self.supported_countries = %w[US CA] + self.supported_cardtypes = %i[visa master american_express discover jcb diners_club] TRANSACTIONS = { - :purchase => '01', - :authorization => '02', - :capture => '11', - :void => '04', - :credit => '06', - :refund => '10' + purchase: '01', + authorization: '02', + capture: '11', + void: '04', + credit: '06', + refund: '10' } SOURCE_CARD = 'bankcard' - SOURCE_ECHECK = 'virtual_check' + SOURCE_ECHECK = 'virtual_check' def initialize(options = {}) requires!(options, :login, :password) @@ -77,7 +77,7 @@ def credit(money, payment_method, options = {}) commit(:credit, post, source) end - def refund(money, reference, options={}) + def refund(money, reference, options = {}) post = {} add_reference(post, reference) add_transaction_data(post, money, options) @@ -115,7 +115,8 @@ def scrub(transcript) # use the same method as in pay_conex def force_utf8(string) return nil unless string - binary = string.encode('BINARY', invalid: :replace, undef: :replace, replace: '?') # Needed for Ruby 2.0 since #encode is a no-op if the string is already UTF-8. It's not needed for Ruby 2.1 and up since it's not a no-op there. + + binary = string.encode('BINARY', invalid: :replace, undef: :replace, replace: '?') # Needed for Ruby 2.0 since #encode is a no-op if the string is already UTF-8. It's not needed for Ruby 2.1 and up since it's not a no-op there. binary.encode('UTF-8', invalid: :replace, undef: :replace, replace: '?') end @@ -214,7 +215,7 @@ def add_invoice(post, options) end def add_reference(post, reference) - ref, _ = reference.to_s.split(';') + ref, = reference.to_s.split(';') post[:T_reference] = ref end @@ -227,7 +228,7 @@ def add_customer_data(post, options) end def add_addresses(post, options) - billing_address = options[:billing_address] || options[:address] || {} + billing_address = options[:billing_address] || options[:address] || {} post[:C_address] = billing_address[:address1] post[:C_city] = billing_address[:city] @@ -260,11 +261,10 @@ def commit(action, params, source) response = parse(ssl_post(url, post_data(action, params)), source) Response.new(success?(response), response[:message], response, - :test => test?, - :authorization => authorization_from(response, source), - :avs_result => { :code => response[:avs_result] }, - :cvv_result => response[:cvv_result] - ) + test: test?, + authorization: authorization_from(response, source), + avs_result: { code: response[:avs_result] }, + cvv_result: response[:cvv_result]) end def url(params, source) @@ -296,7 +296,6 @@ def vault end class SageVault - def initialize(options, gateway) @live_url = 'https://www.sagepayments.net/web_services/wsVault/wsVault.asmx' @options = options @@ -382,8 +381,7 @@ def commit(action, request) end Response.new(success, message, response, - authorization: response[:guid] - ) + authorization: response[:guid]) end ENVELOPE_NAMESPACES = { diff --git a/lib/active_merchant/billing/gateways/sage_pay.rb b/lib/active_merchant/billing/gateways/sage_pay.rb index a3cd5f7b657..ce28ac566ec 100644 --- a/lib/active_merchant/billing/gateways/sage_pay.rb +++ b/lib/active_merchant/billing/gateways/sage_pay.rb @@ -13,26 +13,26 @@ class SagePayGateway < Gateway APPROVED = 'OK' TRANSACTIONS = { - :purchase => 'PAYMENT', - :credit => 'REFUND', - :authorization => 'DEFERRED', - :capture => 'RELEASE', - :void => 'VOID', - :abort => 'ABORT', - :store => 'TOKEN', - :unstore => 'REMOVETOKEN', - :repeat => 'REPEAT' + purchase: 'PAYMENT', + credit: 'REFUND', + authorization: 'DEFERRED', + capture: 'RELEASE', + void: 'VOID', + abort: 'ABORT', + store: 'TOKEN', + unstore: 'REMOVETOKEN', + repeat: 'REPEAT' } CREDIT_CARDS = { - :visa => 'VISA', - :master => 'MC', - :delta => 'DELTA', - :maestro => 'MAESTRO', - :american_express => 'AMEX', - :electron => 'UKE', - :diners_club => 'DC', - :jcb => 'JCB' + visa: 'VISA', + master: 'MC', + delta: 'DELTA', + maestro: 'MAESTRO', + american_express: 'AMEX', + electron: 'UKE', + diners_club: 'DC', + jcb: 'JCB' } AVS_CODE = { @@ -69,8 +69,8 @@ class SagePayGateway < Gateway recipient_dob: :FIRecipientDoB } - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :maestro, :diners_club] - self.supported_countries = ['GB', 'IE'] + self.supported_countries = %w[GB IE] + self.supported_cardtypes = %i[visa master american_express discover jcb maestro diners_club] self.default_currency = 'GBP' self.homepage_url = 'http://www.sagepay.com' @@ -162,7 +162,7 @@ def unstore(token, options = {}) commit(:unstore, post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -213,18 +213,18 @@ def add_related_reference(post, identification) def add_amount(post, money, options) currency = options[:currency] || currency(money) - add_pair(post, :Amount, localized_amount(money, currency), :required => true) - add_pair(post, :Currency, currency, :required => true) + add_pair(post, :Amount, localized_amount(money, currency), required: true) + add_pair(post, :Currency, currency, required: true) end def add_currency(post, money, options) currency = options[:currency] || currency(money) - add_pair(post, :Currency, currency, :required => true) + add_pair(post, :Currency, currency, required: true) end # doesn't actually use the currency -- dodgy! def add_release_amount(post, money, options) - add_pair(post, :ReleaseAmount, amount(money), :required => true) + add_pair(post, :ReleaseAmount, amount(money), required: true) end def add_customer_data(post, options) @@ -248,7 +248,7 @@ def add_address(post, options) add_pair(post, :BillingAddress1, truncate(billing_address[:address1], 100)) add_pair(post, :BillingAddress2, truncate(billing_address[:address2], 100)) add_pair(post, :BillingCity, truncate(billing_address[:city], 40)) - add_pair(post, :BillingState, truncate(billing_address[:state], 2)) if is_usa(billing_address[:country]) + add_pair(post, :BillingState, truncate(billing_address[:state], 2)) if usa?(billing_address[:country]) add_pair(post, :BillingCountry, truncate(billing_address[:country], 2)) add_pair(post, :BillingPhone, sanitize_phone(billing_address[:phone])) add_pair(post, :BillingPostCode, truncate(billing_address[:zip], 10)) @@ -261,7 +261,7 @@ def add_address(post, options) add_pair(post, :DeliveryAddress1, truncate(shipping_address[:address1], 100)) add_pair(post, :DeliveryAddress2, truncate(shipping_address[:address2], 100)) add_pair(post, :DeliveryCity, truncate(shipping_address[:city], 40)) - add_pair(post, :DeliveryState, truncate(shipping_address[:state], 2)) if is_usa(shipping_address[:country]) + add_pair(post, :DeliveryState, truncate(shipping_address[:state], 2)) if usa?(shipping_address[:country]) add_pair(post, :DeliveryCountry, truncate(shipping_address[:country], 2)) add_pair(post, :DeliveryPhone, sanitize_phone(shipping_address[:phone])) add_pair(post, :DeliveryPostCode, truncate(shipping_address[:zip], 10)) @@ -269,7 +269,7 @@ def add_address(post, options) end def add_invoice(post, options) - add_pair(post, :VendorTxCode, sanitize_order_id(options[:order_id]), :required => true) + add_pair(post, :VendorTxCode, sanitize_order_id(options[:order_id]), required: true) add_pair(post, :Description, truncate(options[:description] || options[:order_id], 100)) end @@ -286,10 +286,10 @@ def add_payment_method(post, payment_method, options) end def add_credit_card(post, credit_card) - add_pair(post, :CardHolder, truncate(credit_card.name, 50), :required => true) - add_pair(post, :CardNumber, credit_card.number, :required => true) + add_pair(post, :CardHolder, truncate(credit_card.name, 50), required: true) + add_pair(post, :CardNumber, credit_card.number, required: true) - add_pair(post, :ExpiryDate, format_date(credit_card.month, credit_card.year), :required => true) + add_pair(post, :ExpiryDate, format_date(credit_card.month, credit_card.year), required: true) add_pair(post, :CardType, map_card_type(credit_card)) add_pair(post, :CV2, credit_card.verification_value) @@ -312,11 +312,12 @@ def sanitize_order_id(order_id) def sanitize_phone(phone) return nil unless phone + cleansed = phone.to_s.gsub(/[^0-9+]/, '') truncate(cleansed, 20) end - def is_usa(country) + def usa?(country) truncate(country, 2) == 'US' end @@ -346,14 +347,13 @@ def commit(action, parameters) response = parse(ssl_post(url_for(action), post_data(action, parameters))) Response.new(response['Status'] == APPROVED, message_from(response), response, - :test => test?, - :authorization => authorization_from(response, parameters, action), - :avs_result => { - :street_match => AVS_CODE[response['AddressResult']], - :postal_match => AVS_CODE[response['PostCodeResult']], + test: test?, + authorization: authorization_from(response, parameters, action), + avs_result: { + street_match: AVS_CODE[response['AddressResult']], + postal_match: AVS_CODE[response['PostCodeResult']] }, - :cvv_result => CVV_CODE[response['CV2Result']] - ) + cvv_result: CVV_CODE[response['CV2Result']]) end def authorization_from(response, params, action) @@ -361,11 +361,11 @@ def authorization_from(response, params, action) when :store response['Token'] else - [ params[:VendorTxCode], - response['VPSTxId'] || params[:VPSTxId], - response['TxAuthNo'], - response['SecurityKey'] || params[:SecurityKey], - action ].join(';') + [params[:VendorTxCode], + response['VPSTxId'] || params[:VPSTxId], + response['TxAuthNo'], + response['SecurityKey'] || params[:SecurityKey], + action].join(';') end end @@ -379,33 +379,32 @@ def url_for(action) end def build_url(action) - endpoint = case action - when :purchase, :authorization then 'vspdirect-register' - when :store then 'directtoken' - else TRANSACTIONS[action].downcase - end + endpoint = + case action + when :purchase, :authorization then 'vspdirect-register' + when :store then 'directtoken' + else TRANSACTIONS[action].downcase + end "#{test? ? self.test_url : self.live_url}/#{endpoint}.vsp" end def build_simulator_url(action) - endpoint = [ :purchase, :authorization ].include?(action) ? 'VSPDirectGateway.asp' : "VSPServerGateway.asp?Service=Vendor#{TRANSACTIONS[action].capitalize}Tx" + endpoint = %i[purchase authorization].include?(action) ? 'VSPDirectGateway.asp' : "VSPServerGateway.asp?Service=Vendor#{TRANSACTIONS[action].capitalize}Tx" "#{self.simulator_url}/#{endpoint}" end def message_from(response) - response['Status'] == APPROVED ? 'Success' : (response['StatusDetail'] || 'Unspecified error') # simonr 20080207 can't actually get non-nil blanks, so this is shorter + response['Status'] == APPROVED ? 'Success' : (response['StatusDetail'] || 'Unspecified error') # simonr 20080207 can't actually get non-nil blanks, so this is shorter end def post_data(action, parameters = {}) parameters.update( - :Vendor => @options[:login], - :TxType => TRANSACTIONS[action], - :VPSProtocol => @options.fetch(:protocol_version, '3.00') + Vendor: @options[:login], + TxType: TRANSACTIONS[action], + VPSProtocol: @options.fetch(:protocol_version, '3.00') ) - if(application_id && (application_id != Gateway.application_id)) - parameters.update(:ReferrerID => application_id) - end + parameters.update(ReferrerID: application_id) if application_id && (application_id != Gateway.application_id) parameters.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join('&') end @@ -427,6 +426,7 @@ def add_pair(post, key, value, options = {}) def past_purchase_reference?(payment_method) return false unless payment_method.is_a?(String) + payment_method.split(';').last == 'purchase' end end diff --git a/lib/active_merchant/billing/gateways/sallie_mae.rb b/lib/active_merchant/billing/gateways/sallie_mae.rb index 7e15f08e232..af13651eae0 100644 --- a/lib/active_merchant/billing/gateways/sallie_mae.rb +++ b/lib/active_merchant/billing/gateways/sallie_mae.rb @@ -7,7 +7,7 @@ class SallieMaeGateway < Gateway self.supported_countries = ['US'] # The card types supported by the payment gateway - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] # The homepage URL of the gateway self.homepage_url = 'http://www.salliemae.com/' @@ -121,9 +121,8 @@ def commit(action, money, parameters) response = parse(ssl_post(self.live_url, parameters.to_post_data) || '') Response.new(successful?(response), message_from(response), response, - :test => test?, - :authorization => response['refcode'] - ) + test: test?, + authorization: response['refcode']) end def successful?(response) diff --git a/lib/active_merchant/billing/gateways/secure_net.rb b/lib/active_merchant/billing/gateways/secure_net.rb index f3abdf29935..474babbd600 100644 --- a/lib/active_merchant/billing/gateways/secure_net.rb +++ b/lib/active_merchant/billing/gateways/secure_net.rb @@ -1,25 +1,24 @@ module ActiveMerchant #:nodoc: module Billing #:nodoc: class SecureNetGateway < Gateway - API_VERSION = '4.0' TRANSACTIONS = { - :auth_only => '0000', - :auth_capture => '0100', - :prior_auth_capture => '0200', - :void => '0400', - :credit => '0500' + auth_only: '0000', + auth_capture: '0100', + prior_auth_capture: '0200', + void: '0400', + credit: '0500' } XML_ATTRIBUTES = { - 'xmlns' => 'http://gateway.securenet.com/API/Contracts', - 'xmlns:i' => 'http://www.w3.org/2001/XMLSchema-instance' - } + 'xmlns' => 'http://gateway.securenet.com/API/Contracts', + 'xmlns:i' => 'http://www.w3.org/2001/XMLSchema-instance' + } NIL_ATTRIBUTE = { 'i:nil' => 'true' } self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://www.securenet.com/' self.display_name = 'SecureNet' @@ -28,8 +27,8 @@ class SecureNetGateway < Gateway APPROVED, DECLINED = 1, 2 - CARD_CODE_ERRORS = %w( N S ) - AVS_ERRORS = %w( A E N R W Z ) + CARD_CODE_ERRORS = %w(N S) + AVS_ERRORS = %w(A E N R W Z) def initialize(options = {}) requires!(options, :login, :password) @@ -81,11 +80,10 @@ def commit(request) response = parse(data) Response.new(success?(response), message_from(response), response, - :test => test?, - :authorization => build_authorization(response), - :avs_result => { :code => response[:avs_result_code] }, - :cvv_result => response[:card_code_response_code] - ) + test: test?, + authorization: build_authorization(response), + avs_result: { code: response[:avs_result_code] }, + cvv_result: response[:card_code_response_code]) end def build_request(request) @@ -136,13 +134,9 @@ def add_credit_card(xml, creditcard) end def add_customer_data(xml, options) - if options.has_key? :customer - xml.tag! 'CUSTOMERID', options[:customer] - end + xml.tag! 'CUSTOMERID', options[:customer] if options.has_key? :customer - if options.has_key? :ip - xml.tag! 'CUSTOMERIP', options[:ip] - end + xml.tag! 'CUSTOMERIP', options[:ip] if options.has_key? :ip end def add_address(xml, creditcard, options) @@ -161,7 +155,7 @@ def add_address(xml, creditcard, options) xml.tag! 'FIRSTNAME', creditcard.first_name xml.tag! 'LASTNAME', creditcard.last_name xml.tag! 'PHONE', address[:phone].to_s - xml.tag! 'STATE', address[:state].blank? ? 'n/a' : address[:state] + xml.tag! 'STATE', address[:state].blank? ? 'n/a' : address[:state] xml.tag! 'ZIP', address[:zip].to_s end end @@ -182,7 +176,7 @@ def add_address(xml, creditcard, options) xml.tag! 'LASTNAME', address[:last_name].to_s end - xml.tag! 'STATE', address[:state].blank? ? 'n/a' : address[:state] + xml.tag! 'STATE', address[:state].blank? ? 'n/a' : address[:state] xml.tag! 'ZIP', address[:zip].to_s end else @@ -261,7 +255,6 @@ def split_authorization(authorization) def build_authorization(response) [response[:transactionid], response[:transactionamount], response[:last4_digits]].join('|') end - end end end diff --git a/lib/active_merchant/billing/gateways/secure_pay.rb b/lib/active_merchant/billing/gateways/secure_pay.rb index 4cd0c8a63d3..2ad96517097 100644 --- a/lib/active_merchant/billing/gateways/secure_pay.rb +++ b/lib/active_merchant/billing/gateways/secure_pay.rb @@ -17,12 +17,12 @@ class SecurePayGateway < Gateway self.default_currency = 'USD' self.supported_countries = %w(US CA GB AU) - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb] + self.supported_cardtypes = %i[visa master american_express discover diners_club jcb] self.homepage_url = 'http://www.securepay.com/' self.display_name = 'SecurePay' - CARD_CODE_ERRORS = %w( N S ) - AVS_ERRORS = %w( A E N R W Z ) + CARD_CODE_ERRORS = %w(N S) + AVS_ERRORS = %w(A E N R W Z) AVS_REASON_CODES = %w(27 45) TRANSACTION_ALREADY_ACTIONED = %w(310 311) @@ -57,12 +57,11 @@ def commit(action, money, parameters) message = message_from(response) Response.new(success?(response), message, response, - :test => test?, - :authorization => response[:transaction_id], - :fraud_review => fraud_review?(response), - :avs_result => { :code => response[:avs_result_code] }, - :cvv_result => response[:card_code] - ) + test: test?, + authorization: response[:transaction_id], + fraud_review: fraud_review?(response), + avs_result: { code: response[:avs_result_code] }, + cvv_result: response[:card_code]) end def success?(response) @@ -77,14 +76,14 @@ def parse(body) fields = split(body) results = { - :response_code => fields[RESPONSE_CODE].to_i, - :response_reason_code => fields[RESPONSE_REASON_CODE], - :response_reason_text => fields[RESPONSE_REASON_TEXT], - :avs_result_code => fields[AVS_RESULT_CODE], - :transaction_id => fields[TRANSACTION_ID], - :card_code => fields[CARD_CODE_RESPONSE_CODE], - :authorization_code => fields[AUTHORIZATION_CODE], - :cardholder_authentication_code => fields[CARDHOLDER_AUTH_CODE] + response_code: fields[RESPONSE_CODE].to_i, + response_reason_code: fields[RESPONSE_REASON_CODE], + response_reason_text: fields[RESPONSE_REASON_TEXT], + avs_result_code: fields[AVS_RESULT_CODE], + transaction_id: fields[TRANSACTION_ID], + card_code: fields[CARD_CODE_RESPONSE_CODE], + authorization_code: fields[AUTHORIZATION_CODE], + cardholder_authentication_code: fields[CARDHOLDER_AUTH_CODE] } results end @@ -115,7 +114,7 @@ def add_invoice(post, options) post[:description] = options[:description] end - def add_creditcard(post, creditcard, options={}) + def add_creditcard(post, creditcard, options = {}) post[:card_num] = creditcard.number post[:card_code] = creditcard.verification_value if creditcard.verification_value? post[:exp_date] = expdate(creditcard) @@ -123,7 +122,7 @@ def add_creditcard(post, creditcard, options={}) post[:last_name] = creditcard.last_name end - def add_payment_source(params, source, options={}) + def add_payment_source(params, source, options = {}) add_creditcard(params, source, options) end @@ -137,17 +136,11 @@ def add_customer_data(post, options) post[:cust_id] = options[:customer] if Float(options[:customer]) rescue nil end - if options.has_key? :ip - post[:customer_ip] = options[:ip] - end + post[:customer_ip] = options[:ip] if options.has_key? :ip - if options.has_key? :cardholder_authentication_value - post[:cardholder_authentication_value] = options[:cardholder_authentication_value] - end + post[:cardholder_authentication_value] = options[:cardholder_authentication_value] if options.has_key? :cardholder_authentication_value - if options.has_key? :authentication_indicator - post[:authentication_indicator] = options[:authentication_indicator] - end + post[:authentication_indicator] = options[:authentication_indicator] if options.has_key? :authentication_indicator end # x_duplicate_window won't be sent by default, because sending it changes the response. @@ -165,7 +158,7 @@ def add_address(post, options) post[:zip] = address[:zip].to_s post[:city] = address[:city].to_s post[:country] = address[:country].to_s - post[:state] = address[:state].blank? ? 'n/a' : address[:state] + post[:state] = address[:state].blank? ? 'n/a' : address[:state] end if address = options[:shipping_address] @@ -177,16 +170,14 @@ def add_address(post, options) post[:ship_to_zip] = address[:zip].to_s post[:ship_to_city] = address[:city].to_s post[:ship_to_country] = address[:country].to_s - post[:ship_to_state] = address[:state].blank? ? 'n/a' : address[:state] + post[:ship_to_state] = address[:state].blank? ? 'n/a' : address[:state] end end def message_from(results) if results[:response_code] == DECLINED return CVVResult.messages[results[:card_code]] if CARD_CODE_ERRORS.include?(results[:card_code]) - if AVS_REASON_CODES.include?(results[:response_reason_code]) && AVS_ERRORS.include?(results[:avs_result_code]) - return AVSResult.messages[results[:avs_result_code]] - end + return AVSResult.messages[results[:avs_result_code]] if AVS_REASON_CODES.include?(results[:response_reason_code]) && AVS_ERRORS.include?(results[:avs_result_code]) end (results[:response_reason_text] ? results[:response_reason_text].chomp('.') : '') diff --git a/lib/active_merchant/billing/gateways/secure_pay_au.rb b/lib/active_merchant/billing/gateways/secure_pay_au.rb index 37a2845bbd5..fc993767a80 100644 --- a/lib/active_merchant/billing/gateways/secure_pay_au.rb +++ b/lib/active_merchant/billing/gateways/secure_pay_au.rb @@ -8,14 +8,14 @@ class SecurePayAuGateway < Gateway class_attribute :test_periodic_url, :live_periodic_url - self.test_url = 'https://api.securepay.com.au/test/payment' + self.test_url = 'https://test.api.securepay.com.au/xmlapi/payment' self.live_url = 'https://api.securepay.com.au/xmlapi/payment' self.test_periodic_url = 'https://test.securepay.com.au/xmlapi/periodic' self.live_periodic_url = 'https://api.securepay.com.au/xmlapi/periodic' self.supported_countries = ['AU'] - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :jcb] + self.supported_cardtypes = %i[visa master american_express diners_club jcb] # The homepage URL of the gateway self.homepage_url = 'http://securepay.com.au' @@ -35,26 +35,26 @@ class SecurePayAuGateway < Gateway # 10 Preauthorise # 11 Preauth Complete (Advice) TRANSACTIONS = { - :purchase => 0, - :authorization => 10, - :capture => 11, - :void => 6, - :refund => 4 + purchase: 0, + authorization: 10, + capture: 11, + void: 6, + refund: 4 } PERIODIC_ACTIONS = { - :add_triggered => 'add', - :remove_triggered => 'delete', - :trigger => 'trigger' + add_triggered: 'add', + remove_triggered: 'delete', + trigger: 'trigger' } PERIODIC_TYPES = { - :add_triggered => 4, - :remove_triggered => nil, - :trigger => nil + add_triggered: 4, + remove_triggered: nil, + trigger: nil } - SUCCESS_CODES = [ '00', '08', '11', '16', '77' ] + SUCCESS_CODES = %w[00 08 11 16 77] def initialize(options = {}) requires!(options, :login, :password) @@ -184,9 +184,8 @@ def commit(action, request) response = parse(ssl_post(test? ? self.test_url : self.live_url, build_request(action, request))) Response.new(success?(response), message_from(response), response, - :test => test?, - :authorization => authorization_from(response) - ) + test: test?, + authorization: authorization_from(response)) end def build_periodic_item(action, money, credit_card, options) @@ -241,9 +240,8 @@ def commit_periodic(request) response = parse(ssl_post(test? ? self.test_periodic_url : self.live_periodic_url, my_request)) Response.new(success?(response), message_from(response), response, - :test => test?, - :authorization => authorization_from(response) - ) + test: test?, + authorization: authorization_from(response)) end def success?(response) diff --git a/lib/active_merchant/billing/gateways/secure_pay_tech.rb b/lib/active_merchant/billing/gateways/secure_pay_tech.rb index b6980d4cf99..a866bddb17b 100644 --- a/lib/active_merchant/billing/gateways/secure_pay_tech.rb +++ b/lib/active_merchant/billing/gateways/secure_pay_tech.rb @@ -2,7 +2,7 @@ module ActiveMerchant #:nodoc: module Billing #:nodoc: class SecurePayTechGateway < Gateway class SecurePayTechPostData < PostData - self.required_fields = [ :OrderReference, :CardNumber, :CardExpiry, :CardHolderName, :CardType, :MerchantID, :MerchantKey, :Amount, :Currency ] + self.required_fields = %i[OrderReference CardNumber CardExpiry CardHolderName CardType MerchantID MerchantKey Amount Currency] end self.live_url = self.test_url = 'https://tx.securepaytech.com/web/HttpPostPurchase' @@ -21,7 +21,7 @@ class SecurePayTechPostData < PostData self.default_currency = 'NZD' self.supported_countries = ['NZ'] - self.supported_cardtypes = [:visa, :master, :american_express, :diners_club] + self.supported_cardtypes = %i[visa master american_express diners_club] self.homepage_url = 'http://www.securepaytech.com/' self.display_name = 'SecurePayTech' @@ -85,9 +85,8 @@ def commit(action, post) response = parse(ssl_post(self.live_url, post_data(action, post))) Response.new(response[:result_code] == 1, message_from(response), response, - :test => test?, - :authorization => response[:merchant_transaction_reference] - ) + test: test?, + authorization: response[:merchant_transaction_reference]) end def message_from(result) diff --git a/lib/active_merchant/billing/gateways/securion_pay.rb b/lib/active_merchant/billing/gateways/securion_pay.rb index 221920c2bb2..95a031c4d3d 100644 --- a/lib/active_merchant/billing/gateways/securion_pay.rb +++ b/lib/active_merchant/billing/gateways/securion_pay.rb @@ -9,7 +9,7 @@ class SecurionPayGateway < Gateway self.default_currency = 'USD' self.money_format = :cents - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club] + self.supported_cardtypes = %i[visa master american_express discover jcb diners_club] self.homepage_url = 'https://securionpay.com/' self.display_name = 'SecurionPay' @@ -31,17 +31,17 @@ class SecurionPayGateway < Gateway 'expired_token' => STANDARD_ERROR_CODE[:card_declined] } - def initialize(options={}) + def initialize(options = {}) requires!(options, :secret_key) super end - def purchase(money, payment, options={}) + def purchase(money, payment, options = {}) post = create_post_for_auth_or_purchase(money, payment, options) commit('charges', post, options) end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) post = create_post_for_auth_or_purchase(money, payment, options) post[:captured] = 'false' commit('charges', post, options) @@ -63,7 +63,7 @@ def void(authorization, options = {}) commit("charges/#{CGI.escape(authorization)}/refund", {}, options) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -169,6 +169,7 @@ def add_creditcard(post, creditcard, options) def add_address(post, options) return unless post[:card]&.kind_of?(Hash) + if address = options[:billing_address] post[:card][:addressLine1] = address[:address1] if address[:address1] post[:card][:addressLine2] = address[:address2] if address[:address2] @@ -208,8 +209,7 @@ def commit(url, parameters = nil, options = {}, method = nil) response, test: test?, authorization: (success ? response['id'] : response['error']['charge']), - error_code: (success ? nil : STANDARD_ERROR_CODE_MAPPING[response['error']['code']]) - ) + error_code: (success ? nil : STANDARD_ERROR_CODE_MAPPING[response['error']['code']])) end def headers(options = {}) @@ -233,6 +233,7 @@ def post_data(params) params.map do |key, value| next if value.to_s.blank? + if value.is_a?(Hash) h = {} value.each do |k, v| diff --git a/lib/active_merchant/billing/gateways/skip_jack.rb b/lib/active_merchant/billing/gateways/skip_jack.rb index 158742d58f7..8f8851808e1 100644 --- a/lib/active_merchant/billing/gateways/skip_jack.rb +++ b/lib/active_merchant/billing/gateways/skip_jack.rb @@ -12,16 +12,16 @@ class SkipJackGateway < Gateway ADVANCED_PATH = '/evolvcc/evolvcc.aspx' ACTIONS = { - :authorization => 'AuthorizeAPI', - :change_status => 'SJAPI_TransactionChangeStatusRequest', - :get_status => 'SJAPI_TransactionStatusRequest' + authorization: 'AuthorizeAPI', + change_status: 'SJAPI_TransactionChangeStatusRequest', + get_status: 'SJAPI_TransactionStatusRequest' } SUCCESS_MESSAGE = 'The transaction was successful.' MONETARY_CHANGE_STATUSES = ['SETTLE', 'AUTHORIZE', 'AUTHORIZE ADDITIONAL', 'CREDIT', 'SPLITSETTLE'] - CARD_CODE_ERRORS = %w( N S "" ) + CARD_CODE_ERRORS = %w(N S "") CARD_CODE_MESSAGES = { 'M' => 'Card verification number matched', @@ -32,7 +32,7 @@ class SkipJackGateway < Gateway '' => 'Transaction failed because incorrect card verification number was entered or no number was entered' } - AVS_ERRORS = %w( A B C E I N O P R W Z ) + AVS_ERRORS = %w(A B C E I N O P R W Z) AVS_MESSAGES = { 'A' => 'Street address matches billing information, zip/postal code does not', @@ -51,7 +51,7 @@ class SkipJackGateway < Gateway 'W' => '9-digit zip/postal code matches billing information, street address does not', 'X' => 'Street address and 9-digit zip/postal code matches billing information', 'Y' => 'Street address and 5-digit zip/postal code matches billing information', - 'Z' => '5-digit zip/postal code matches billing information, street address does not', + 'Z' => '5-digit zip/postal code matches billing information, street address does not' } CHANGE_STATUS_ERROR_MESSAGES = { @@ -160,8 +160,8 @@ class SkipJackGateway < Gateway '-117' => 'POS Check Invalid Cashier Number' } - self.supported_countries = ['US', 'CA'] - self.supported_cardtypes = [:visa, :master, :american_express, :jcb, :discover, :diners_club] + self.supported_countries = %w[US CA] + self.supported_cardtypes = %i[visa master american_express jcb discover diners_club] self.homepage_url = 'http://www.skipjack.com/' self.display_name = 'SkipJack' @@ -213,7 +213,7 @@ def purchase(money, creditcard, options = {}) # # * :force_settlement -- Force the settlement to occur as soon as possible. This option is not supported by other gateways. See the SkipJack API reference for more details def capture(money, authorization, options = {}) - post = { } + post = {} add_status_action(post, 'SETTLE') add_forced_settlement(post, options) add_transaction_id(post, authorization) @@ -242,7 +242,7 @@ def credit(money, identification, options = {}) end def status(order_id) - commit(:get_status, nil, :szOrderNumber => order_id) + commit(:get_status, nil, szOrderNumber: order_id) end private @@ -264,11 +264,10 @@ def commit(action, money, parameters) # Pass along the original transaction id in the case an update transaction Response.new(response[:success], message_from(response, action), response, - :test => test?, - :authorization => response[:szTransactionFileName] || parameters[:szTransactionId], - :avs_result => { :code => response[:szAVSResponseCode] }, - :cvv_result => response[:szCVV2ResponseCode] - ) + test: test?, + authorization: response[:szTransactionFileName] || parameters[:szTransactionId], + avs_result: { code: response[:szAVSResponseCode] }, + cvv_result: response[:szCVV2ResponseCode]) end def url_for(action) @@ -300,9 +299,9 @@ def parse(body, action) when :authorization parse_authorization_response(body) when :get_status - parse_status_response(body, [ :SerialNumber, :TransactionAmount, :TransactionStatusCode, :TransactionStatusMessage, :OrderNumber, :TransactionDateTime, :TransactionID, :ApprovalCode, :BatchNumber ]) + parse_status_response(body, %i[SerialNumber TransactionAmount TransactionStatusCode TransactionStatusMessage OrderNumber TransactionDateTime TransactionID ApprovalCode BatchNumber]) else - parse_status_response(body, [ :SerialNumber, :TransactionAmount, :DesiredStatus, :StatusResponse, :StatusResponseMessage, :OrderNumber, :AuditID ]) + parse_status_response(body, %i[SerialNumber TransactionAmount DesiredStatus StatusResponse StatusResponseMessage OrderNumber AuditID]) end end @@ -329,7 +328,7 @@ def parse_authorization_response(body) def parse_status_response(body, response_keys) lines = split_lines(body) - keys = [ :szSerialNumber, :szErrorCode, :szNumberRecords] + keys = %i[szSerialNumber szErrorCode szNumberRecords] values = split_line(lines[0])[0..2] result = Hash[*keys.zip(values).flatten] @@ -375,7 +374,7 @@ def add_invoice(post, options) end def add_creditcard(post, creditcard) - post[:AccountNumber] = creditcard.number + post[:AccountNumber] = creditcard.number post[:Month] = creditcard.month post[:Year] = creditcard.year post[:CVV2] = creditcard.verification_value if creditcard.verification_value? @@ -434,6 +433,7 @@ def message_from_authorization(response) return CARD_CODE_MESSAGES[response[:szCVV2ResponseCode]] if CARD_CODE_ERRORS.include?(response[:szCVV2ResponseCode]) return AVS_MESSAGES[response[:szAVSResponseMessage]] if AVS_ERRORS.include?(response[:szAVSResponseCode]) return RETURN_CODE_MESSAGES[response[:szReturnCode]] if response[:szReturnCode] != '1' + return response[:szAuthorizationDeclinedMessage] end end diff --git a/lib/active_merchant/billing/gateways/smart_ps.rb b/lib/active_merchant/billing/gateways/smart_ps.rb index 0e1b7c0a699..1c63532b9e0 100644 --- a/lib/active_merchant/billing/gateways/smart_ps.rb +++ b/lib/active_merchant/billing/gateways/smart_ps.rb @@ -3,7 +3,6 @@ module ActiveMerchant #:nodoc: module Billing #:nodoc: class SmartPs < Gateway #:nodoc: - ## # This is the base gateway for processors who use the smartPS processing system @@ -48,13 +47,13 @@ def purchase(money, payment_source, options = {}) end def capture(money, authorization, options = {}) - post ={} + post = {} post[:transactionid] = authorization commit('capture', money, post) end def void(authorization, options = {}) - post ={} + post = {} post[:transactionid] = authorization commit('void', nil, post) end @@ -118,37 +117,33 @@ def delete(vault_id) def store(payment_source, options = {}) post = {} billing_id = options.delete(:billing_id).to_s || true - add_payment_source(post, payment_source, :store => billing_id) + add_payment_source(post, payment_source, store: billing_id) add_address(post, options[:billing_address] || options[:address]) add_customer_data(post, options) commit(nil, nil, post) end - alias_method :unstore, :delete + alias unstore delete private def add_customer_data(post, options) - if options.has_key? :email - post[:email] = options[:email] - end + post[:email] = options[:email] if options.has_key? :email - if options.has_key? :ip - post[:ipaddress] = options[:ip] - end + post[:ipaddress] = options[:ip] if options.has_key? :ip end - def add_address(post, address, prefix='') - prefix +='_' unless prefix.blank? - unless address.blank? or address.values.blank? - post[prefix+'address1'] = address[:address1].to_s - post[prefix+'address2'] = address[:address2].to_s unless address[:address2].blank? - post[prefix+'company'] = address[:company].to_s - post[prefix+'phone'] = address[:phone].to_s - post[prefix+'zip'] = address[:zip].to_s - post[prefix+'city'] = address[:city].to_s - post[prefix+'country'] = address[:country].to_s - post[prefix+'state'] = address[:state].blank? ? 'n/a' : address[:state] + def add_address(post, address, prefix = '') + prefix += '_' unless prefix.blank? + unless address.blank? || address.values.blank? + post[prefix + 'address1'] = address[:address1].to_s + post[prefix + 'address2'] = address[:address2].to_s unless address[:address2].blank? + post[prefix + 'company'] = address[:company].to_s + post[prefix + 'phone'] = address[:phone].to_s + post[prefix + 'zip'] = address[:zip].to_s + post[prefix + 'city'] = address[:city].to_s + post[prefix + 'country'] = address[:country].to_s + post[prefix + 'state'] = address[:state].blank? ? 'n/a' : address[:state] end end @@ -168,7 +163,7 @@ def add_invoice(post, options) post[:orderid] = options[:order_id].to_s.gsub(/[^\w.]/, '') end - def add_payment_source(params, source, options={}) + def add_payment_source(params, source, options = {}) case determine_funding_source(source) when :vault then add_customer_vault_id(params, source) when :credit_card then add_creditcard(params, source, options) @@ -185,9 +180,9 @@ def add_creditcard(post, creditcard, options) post[:customer_vault] = 'add_customer' post[:customer_vault_id] = options[:store] unless options[:store] == true end - post[:ccnumber] = creditcard.number + post[:ccnumber] = creditcard.number post[:cvv] = creditcard.verification_value if creditcard.verification_value? - post[:ccexp] = expdate(creditcard) + post[:ccexp] = expdate(creditcard) post[:firstname] = creditcard.first_name post[:lastname] = creditcard.last_name end @@ -229,14 +224,13 @@ def parse(body) end def commit(action, money, parameters) - parameters[:amount] = localized_amount(money, parameters[:currency] || default_currency) if money + parameters[:amount] = localized_amount(money, parameters[:currency] || default_currency) if money response = parse(ssl_post(self.live_url, post_data(action, parameters))) Response.new(response['response'] == '1', message_from(response), response, - :authorization => (response['transactionid'] || response['customer_vault_id']), - :test => test?, - :cvv_result => response['cvvresponse'], - :avs_result => { :code => response['avsresponse'] } - ) + authorization: (response['transactionid'] || response['customer_vault_id']), + test: test?, + cvv_result: response['cvvresponse'], + avs_result: { code: response['avsresponse'] }) end def expdate(creditcard) @@ -259,7 +253,7 @@ def message_from(response) def post_data(action, parameters = {}) post = {} - post[:username] = @options[:login] + post[:username] = @options[:login] post[:password] = @options[:password] post[:type] = action if action diff --git a/lib/active_merchant/billing/gateways/so_easy_pay.rb b/lib/active_merchant/billing/gateways/so_easy_pay.rb index f0fa4523322..16b5ef79297 100644 --- a/lib/active_merchant/billing/gateways/so_easy_pay.rb +++ b/lib/active_merchant/billing/gateways/so_easy_pay.rb @@ -4,13 +4,13 @@ class SoEasyPayGateway < Gateway self.live_url = self.test_url = 'https://secure.soeasypay.com/gateway.asmx' self.money_format = :cents - self.supported_countries = [ - 'US', 'CA', 'AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', - 'FI', 'FR', 'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', - 'MT', 'NL', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'GB', - 'IS', 'NO', 'CH' + self.supported_countries = %w[ + US CA AT BE BG HR CY CZ DK EE + FI FR DE GR HU IE IT LV LT LU + MT NL PL PT RO SK SI ES SE GB + IS NO CH ] - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :maestro, :jcb, :diners_club] + self.supported_cardtypes = %i[visa master american_express discover maestro jcb diners_club] self.homepage_url = 'http://www.soeasypay.com/' self.display_name = 'SoEasyPay' @@ -39,11 +39,11 @@ def capture(money, authorization, options = {}) commit('CaptureTransaction', do_capture(money, authorization, options), options) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) commit('RefundTransaction', do_refund(money, authorization, options), options) end - def void(authorization, options={}) + def void(authorization, options = {}) commit('CancelTransaction', do_void(authorization, options), options) end @@ -139,7 +139,7 @@ def fill_card(soap, card) soap.tag!('cardExpireYear', card.year.to_s) end - def fill_order_info(soap, money, options, skip_currency=false) + def fill_order_info(soap, money, options, skip_currency = false) soap.tag!('orderID', options[:order_id].to_s) soap.tag!('orderDescription', "Order #{options[:order_id]}") soap.tag!('amount', amount(money).to_s) @@ -149,7 +149,7 @@ def fill_order_info(soap, money, options, skip_currency=false) def parse(response, action) result = {} document = REXML::Document.new(response) - response_element = document.root.get_elements("//[@xsi:type='tns:#{action}Response']").first + response_element = document.root.get_elements("//*[@xsi:type='tns:#{action}Response']").first response_element.elements.each do |element| result[element.name.underscore] = element.text end @@ -157,30 +157,31 @@ def parse(response, action) end def commit(soap_action, soap, options) - headers = {'SOAPAction' => "\"urn:Interface##{soap_action}\"", - 'Content-Type' => 'text/xml; charset=utf-8'} + headers = { 'SOAPAction' => "\"urn:Interface##{soap_action}\"", + 'Content-Type' => 'text/xml; charset=utf-8' } response_string = ssl_post(test? ? self.test_url : self.live_url, soap, headers) response = parse(response_string, soap_action) return Response.new(response['errorcode'] == '000', response['errormessage'], response, - :test => test?, - :authorization => response['transaction_id']) + test: test?, + authorization: response['transaction_id']) end def build_soap(request) - retval = Builder::XmlMarkup.new(:indent => 2) - retval.instruct!(:xml, :version => '1.0', :encoding => 'utf-8') + retval = Builder::XmlMarkup.new(indent: 2) + retval.instruct!(:xml, version: '1.0', encoding: 'utf-8') retval.tag!('soap:Envelope', { - 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', - 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema', - 'xmlns:soapenc' => 'http://schemas.xmlsoap.org/soap/encoding/', - 'xmlns:tns' => 'urn:Interface', - 'xmlns:types' => 'urn:Interface/encodedTypes', - 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/'}) do - retval.tag!('soap:Body', {'soap:encodingStyle'=>'http://schemas.xmlsoap.org/soap/encoding/'}) do + 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema', + 'xmlns:soapenc' => 'http://schemas.xmlsoap.org/soap/encoding/', + 'xmlns:tns' => 'urn:Interface', + 'xmlns:types' => 'urn:Interface/encodedTypes', + 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/' + }) do + retval.tag!('soap:Body', { 'soap:encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/' }) do retval.tag!("tns:#{request}") do - retval.tag!("#{request}Request", {'xsi:type'=>"tns:#{request}Request"}) do + retval.tag!("#{request}Request", { 'xsi:type' => "tns:#{request}Request" }) do yield retval end end @@ -188,7 +189,6 @@ def build_soap(request) end retval.target! end - end end end diff --git a/lib/active_merchant/billing/gateways/spreedly_core.rb b/lib/active_merchant/billing/gateways/spreedly_core.rb index 92e3f5ccbcc..8c2639a4548 100644 --- a/lib/active_merchant/billing/gateways/spreedly_core.rb +++ b/lib/active_merchant/billing/gateways/spreedly_core.rb @@ -14,7 +14,7 @@ class SpreedlyCoreGateway < Gateway MT MU MV MX MY NL NO NZ OM PH PL PT QA RO SA SE SG SI SK SM TR TT UM US VA VN ZA) - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'https://spreedly.com' self.display_name = 'Spreedly' self.money_format = :cents @@ -56,7 +56,7 @@ def authorize(money, payment_method, options = {}) commit("gateways/#{@options[:gateway_token]}/authorize.xml", request) end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) request = build_xml_request('transaction') do |doc| add_invoice(doc, money, options) end @@ -64,7 +64,7 @@ def capture(money, authorization, options={}) commit("transactions/#{authorization}/capture.xml", request) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) request = build_xml_request('transaction') do |doc| add_invoice(doc, money, options) add_extra_options(:gateway_specific_fields, doc, options) @@ -73,7 +73,7 @@ def refund(money, authorization, options={}) commit("transactions/#{authorization}/credit.xml", request) end - def void(authorization, options={}) + def void(authorization, options = {}) commit("transactions/#{authorization}/void.xml", '') end @@ -98,7 +98,7 @@ def verify(payment_method, options = {}) # # credit_card - The CreditCard to store # options - A standard ActiveMerchant options hash - def store(credit_card, options={}) + def store(credit_card, options = {}) retain = (options.has_key?(:retain) ? options[:retain] : true) save_card(retain, credit_card, options) end @@ -108,7 +108,7 @@ def store(credit_card, options={}) # # credit_card - The CreditCard to store # options - A standard ActiveMerchant options hash - def unstore(authorization, options={}) + def unstore(authorization, options = {}) commit("payment_methods/#{authorization}/redact.xml", '', :put) end @@ -117,7 +117,7 @@ def find(transaction_token) commit("transactions/#{transaction_token}.xml", nil, :get) end - alias_method :status, :find + alias status find def supports_scrubbing? true @@ -173,12 +173,8 @@ def add_invoice(doc, money, options) doc.ip(options[:ip]) if options[:ip] doc.description(options[:description]) if options[:description] - if options[:merchant_name_descriptor] - doc.merchant_name_descriptor(options[:merchant_name_descriptor]) - end - if options[:merchant_location_descriptor] - doc.merchant_location_descriptor(options[:merchant_location_descriptor]) - end + doc.merchant_name_descriptor(options[:merchant_name_descriptor]) if options[:merchant_name_descriptor] + doc.merchant_location_descriptor(options[:merchant_location_descriptor]) if options[:merchant_location_descriptor] end def add_payment_method(doc, payment_method, options) @@ -232,6 +228,7 @@ def add_extra_options(type, doc, options) def extra_options_to_doc(doc, value) return doc.text value unless value.kind_of? Hash + value.each do |k, v| doc.send(k) do extra_options_to_doc(doc, v) @@ -286,10 +283,10 @@ def commit(relative_url, request, method = :post, authorization_field = :token) def response_from(raw_response, authorization_field) parsed = parse(raw_response) options = { - :authorization => parsed[authorization_field], - :test => (parsed[:on_test_gateway] == 'true'), - :avs_result => { :code => parsed[:response_avs_code] }, - :cvv_result => parsed[:response_cvv_code] + authorization: parsed[authorization_field], + test: (parsed[:on_test_gateway] == 'true'), + avs_result: { code: parsed[:response_avs_code] }, + cvv_result: parsed[:response_cvv_code] } Response.new(parsed[:succeeded] == 'true', parsed[:message] || parsed[:error], parsed, options) diff --git a/lib/active_merchant/billing/gateways/stripe.rb b/lib/active_merchant/billing/gateways/stripe.rb index faa11772e66..cb7bdd45ed1 100644 --- a/lib/active_merchant/billing/gateways/stripe.rb +++ b/lib/active_merchant/billing/gateways/stripe.rb @@ -25,10 +25,10 @@ class StripeGateway < Gateway DEFAULT_API_VERSION = '2015-04-07' - self.supported_countries = %w(AT AU BE BR CA CH DE DK EE ES FI FR GB GR HK IE IT JP LT LU LV MX NL NO NZ PL PT SE SG SI SK US) + self.supported_countries = %w(AT AU BE BG BR CA CH CY CZ DE DK EE ES FI FR GB GR HK IE IT JP LT LU LV MT MX NL NO NZ PL PT RO SE SG SI SK US) self.default_currency = 'USD' self.money_format = :cents - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club, :maestro] + self.supported_cardtypes = %i[visa master american_express discover jcb diners_club maestro unionpay] self.currencies_without_fractions = %w(BIF CLP DJF GNF JPY KMF KRW MGA PYG RWF VND VUV XAF XOF XPF UGX) self.homepage_url = 'https://stripe.com/' @@ -53,7 +53,7 @@ class StripeGateway < Gateway BANK_ACCOUNT_HOLDER_TYPE_MAPPING = { 'personal' => 'individual', - 'business' => 'company', + 'business' => 'company' } MINIMUM_AUTHORIZE_AMOUNTS = { @@ -80,6 +80,11 @@ def initialize(options = {}) end def authorize(money, payment, options = {}) + if ach?(payment) + direct_bank_error = 'Direct bank account transactions are not supported for authorize.' + return Response.new(false, direct_bank_error) + end + MultiResponse.run do |r| if payment.is_a?(ApplePayPaymentToken) r.process { tokenize_apple_pay_token(payment) } @@ -87,11 +92,8 @@ def authorize(money, payment, options = {}) end r.process do post = create_post_for_auth_or_purchase(money, payment, options) - if emv_payment?(payment) - add_application_fee(post, options) - else - post[:capture] = 'false' - end + add_application_fee(post, options) if emv_payment?(payment) + post[:capture] = 'false' commit(:post, 'charges', post, options) end end.responses.last @@ -127,14 +129,17 @@ def capture(money, authorization, options = {}) post = {} if emv_tc_response = options.delete(:icc_data) - post[:card] = { emv_approval_data: emv_tc_response } - commit(:post, "charges/#{CGI.escape(authorization)}", post, options) + # update the charge with emv data if card present + update = {} + update[:card] = { emv_approval_data: emv_tc_response } + commit(:post, "charges/#{CGI.escape(authorization)}", update, options) else add_application_fee(post, options) add_amount(post, money, options) add_exchange_rate(post, options) - commit(:post, "charges/#{CGI.escape(authorization)}/capture", post, options) end + + commit(:post, "charges/#{CGI.escape(authorization)}/capture", post, options) end def void(identification, options = {}) @@ -198,6 +203,7 @@ def store(payment, options = {}) elsif payment.is_a?(Check) bank_token_response = tokenize_bank_account(payment) return bank_token_response unless bank_token_response.success? + params = { source: bank_token_response.params['token']['id'] } else add_creditcard(params, payment, options) @@ -215,13 +221,9 @@ def store(payment, options = {}) # The /cards endpoint does not update other customer parameters. r.process { commit(:post, "customers/#{CGI.escape(options[:customer])}/cards", params, options) } - if options[:set_default] and r.success? and !r.params['id'].blank? - post[:default_card] = r.params['id'] - end + post[:default_card] = r.params['id'] if options[:set_default] && r.success? && !r.params['id'].blank? - if post.count > 0 - r.process { update_customer(options[:customer], post) } - end + r.process { update_customer(options[:customer], post) } if post.count > 0 end else commit(:post, 'customers', post.merge(params), options) @@ -277,14 +279,14 @@ def scrub(transcript) transcript. gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]'). gsub(%r((&?three_d_secure\[cryptogram\]=)[\w=]*(&?)), '\1[FILTERED]\2'). - gsub(%r((card\[cryptogram\]=)[^&]+(&?)), '\1[FILTERED]\2'). - gsub(%r((card\[cvc\]=)\d+), '\1[FILTERED]'). - gsub(%r((card\[emv_approval_data\]=)[^&]+(&?)), '\1[FILTERED]\2'). - gsub(%r((card\[emv_auth_data\]=)[^&]+(&?)), '\1[FILTERED]\2'). - gsub(%r((card\[encrypted_pin\]=)[^&]+(&?)), '\1[FILTERED]\2'). - gsub(%r((card\[encrypted_pin_key_id\]=)[\w=]+(&?)), '\1[FILTERED]\2'). - gsub(%r((card\[number\]=)\d+), '\1[FILTERED]'). - gsub(%r((card\[swipe_data\]=)[^&]+(&?)), '\1[FILTERED]\2') + gsub(%r(((\[card\]|card)\[cryptogram\]=)[^&]+(&?)), '\1[FILTERED]\3'). + gsub(%r(((\[card\]|card)\[cvc\]=)\d+), '\1[FILTERED]'). + gsub(%r(((\[card\]|card)\[emv_approval_data\]=)[^&]+(&?)), '\1[FILTERED]\3'). + gsub(%r(((\[card\]|card)\[emv_auth_data\]=)[^&]+(&?)), '\1[FILTERED]\3'). + gsub(%r(((\[card\]|card)\[encrypted_pin\]=)[^&]+(&?)), '\1[FILTERED]\3'). + gsub(%r(((\[card\]|card)\[encrypted_pin_key_id\]=)[\w=]+(&?)), '\1[FILTERED]\3'). + gsub(%r(((\[card\]|card)\[number\]=)\d+), '\1[FILTERED]'). + gsub(%r(((\[card\]|card)\[swipe_data\]=)[^&]+(&?)), '\1[FILTERED]\3') end def supports_network_tokenization? @@ -307,8 +309,8 @@ def create_source(money, payment, type, options = {}) add_creditcard(post, payment, options, true) add_source_owner(post, payment, options) elsif type == 'three_d_secure' - post[:three_d_secure] = {card: payment} - post[:redirect] = {return_url: options[:redirect_url]} + post[:three_d_secure] = { card: payment } + post[:redirect] = { return_url: options[:redirect_url] } end commit(:post, 'sources', post, options) end @@ -365,6 +367,7 @@ def add_charge_details(post, money, payment, options) add_customer_data(post, options) post[:description] = options[:description] post[:statement_descriptor] = options[:statement_description] + post[:statement_descriptor_suffix] = options[:statement_descriptor_suffix] if options[:statement_descriptor_suffix] post[:receipt_email] = options[:receipt_email] if options[:receipt_email] add_customer(post, payment, options) add_flags(post, options) @@ -375,6 +378,7 @@ def add_charge_details(post, money, payment, options) add_exchange_rate(post, options) add_destination(post, options) add_level_three(post, options) + add_connected_account(post, options) post end @@ -410,9 +414,7 @@ def add_level_three(post, options) copy_when_present(level_three, [:shipping_amount], options) copy_when_present(level_three, [:line_items], options) - unless level_three.empty? - post[:level3] = level_three - end + post[:level3] = level_three unless level_three.empty? end def add_expand_parameters(post, options) @@ -422,13 +424,13 @@ def add_expand_parameters(post, options) def add_external_account(post, card_params, payment) external_account = {} - external_account[:object] ='card' + external_account[:object] = 'card' external_account[:currency] = (options[:currency] || currency(payment)).downcase post[:external_account] = external_account.merge(card_params[:card]) end def add_customer_data(post, options) - metadata_options = [:description, :ip, :user_agent, :referrer] + metadata_options = %i[description ip user_agent referrer] post.update(options.slice(*metadata_options)) post[:external_id] = options[:order_id] @@ -437,6 +439,7 @@ def add_customer_data(post, options) def add_address(post, options) return unless post[:card]&.kind_of?(Hash) + if address = options[:billing_address] || options[:address] post[:card][:address_line1] = address[:address1] if address[:address1] post[:card][:address_line2] = address[:address2] if address[:address2] @@ -449,7 +452,7 @@ def add_address(post, options) def add_statement_address(post, options) return unless statement_address = options[:statement_address] - return unless [:address1, :city, :zip, :state].all? { |key| statement_address[key].present? } + return unless %i[address1 city zip state].all? { |key| statement_address[key].present? } post[:statement_address] = {} post[:statement_address][:line1] = statement_address[:address1] @@ -516,10 +519,7 @@ def add_payment_token(post, token, options = {}) end def add_customer(post, payment, options) - if options[:customer] && !payment.respond_to?(:number) - ActiveMerchant.deprecated 'Passing the customer in the options is deprecated. Just use the response.authorization instead.' - post[:customer] = options[:customer] - end + post[:customer] = options[:customer] if options[:customer] && !payment.respond_to?(:number) end def add_flags(post, options) @@ -559,18 +559,31 @@ def add_source_owner(post, creditcard, options) end end + def add_connected_account(post, options = {}) + post[:on_behalf_of] = options[:on_behalf_of] if options[:on_behalf_of] + + return unless options[:transfer_destination] + + post[:transfer_data] = { destination: options[:transfer_destination] } + post[:transfer_data][:amount] = options[:transfer_amount] if options[:transfer_amount] + post[:transfer_group] = options[:transfer_group] if options[:transfer_group] + post[:application_fee_amount] = options[:application_fee_amount] if options[:application_fee_amount] + end + def parse(body) JSON.parse(body) end def post_data(params) return nil unless params + flatten_params([], params).join('&') end def flatten_params(flattened, params, prefix = nil) params.each do |key, value| next if value != false && value.blank? + flattened_key = prefix.nil? ? key : "#{prefix}[#{key}]" if value.is_a?(Hash) flatten_params(flattened, value, flattened_key) @@ -601,11 +614,11 @@ def headers(options = {}) idempotency_key = options[:idempotency_key] headers = { - 'Authorization' => 'Basic ' + Base64.encode64(key.to_s + ':').strip, + 'Authorization' => 'Basic ' + Base64.strict_encode64(key.to_s + ':').strip, 'User-Agent' => "Stripe/v1 ActiveMerchantBindings/#{ActiveMerchant::VERSION}", 'Stripe-Version' => api_version(options), 'X-Stripe-Client-User-Agent' => stripe_client_user_agent(options), - 'X-Stripe-Client-User-Metadata' => {:ip => options[:ip]}.to_json + 'X-Stripe-Client-User-Metadata' => { ip: options[:ip] }.to_json } headers['Idempotency-Key'] = idempotency_key if idempotency_key headers['Stripe-Account'] = options[:stripe_account] if options[:stripe_account] @@ -614,7 +627,8 @@ def headers(options = {}) def stripe_client_user_agent(options) return user_agent unless options[:application] - JSON.dump(JSON.parse(user_agent).merge!({application: options[:application]})) + + JSON.dump(JSON.parse(user_agent).merge!({ application: options[:application] })) end def api_version(options) @@ -639,22 +653,21 @@ def commit(method, url, parameters = nil, options = {}) add_expand_parameters(parameters, options) if parameters response = api_request(method, url, parameters, options) response['webhook_id'] = options[:webhook_id] if options[:webhook_id] - success = success_from(response) + success = success_from(response, options) card = card_from_response(response) - avs_code = AVS_CODE_TRANSLATOR["line1: #{card["address_line1_check"]}, zip: #{card["address_zip_check"]}"] + avs_code = AVS_CODE_TRANSLATOR["line1: #{card['address_line1_check']}, zip: #{card['address_zip_check']}"] cvc_code = CVC_CODE_TRANSLATOR[card['cvc_check']] Response.new(success, message_from(success, response), response, - :test => response_is_test?(response), - :authorization => authorization_from(success, url, method, response), - :avs_result => { :code => avs_code }, - :cvv_result => cvc_code, - :emv_authorization => emv_authorization_from_response(response), - :error_code => success ? nil : error_code_from(response) - ) + test: response_is_test?(response), + authorization: authorization_from(success, url, method, response), + avs_result: { code: avs_code }, + cvv_result: cvc_code, + emv_authorization: emv_authorization_from_response(response), + error_code: success ? nil : error_code_from(response)) end def authorization_from(success, url, method, response) @@ -670,10 +683,10 @@ def authorization_from(success, url, method, response) end def message_from(success, response) - success ? 'Transaction approved' : response.fetch('error', {'message' => 'No error details'})['message'] + success ? 'Transaction approved' : response.fetch('error', { 'message' => 'No error details' })['message'] end - def success_from(response) + def success_from(response, options) !response.key?('error') && response['status'] != 'failed' end @@ -742,7 +755,7 @@ def tokenize_bank_account(bank_account, options = {}) currency: 'usd', routing_number: bank_account.routing_number, name: bank_account.name, - account_holder_type: account_holder_type, + account_holder_type: account_holder_type } } @@ -767,6 +780,7 @@ def ach?(payment_method) def auth_minimum_amount(options) return 100 unless options[:currency] + return MINIMUM_AUTHORIZE_AMOUNTS[options[:currency].upcase] || 100 end @@ -774,6 +788,7 @@ def copy_when_present(dest, dest_path, source, source_path = nil) source_path ||= dest_path source_path.each do |key| return nil unless source[key] + source = source[key] end diff --git a/lib/active_merchant/billing/gateways/stripe_payment_intents.rb b/lib/active_merchant/billing/gateways/stripe_payment_intents.rb index f0f95bb8338..d284883d40b 100644 --- a/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +++ b/lib/active_merchant/billing/gateways/stripe_payment_intents.rb @@ -5,14 +5,13 @@ module Billing #:nodoc: # This gateway uses the current Stripe {Payment Intents API}[https://stripe.com/docs/api/payment_intents]. # For the legacy API, see the Stripe gateway class StripePaymentIntentsGateway < StripeGateway - - self.supported_countries = %w(AT AU BE BR CA CH DE DK EE ES FI FR GB GR HK IE IT JP LT LU LV MX NL NO NZ PL PT SE SG SI SK US) + self.supported_countries = %w(AT AU BE BG BR CA CH CY CZ DE DK EE ES FI FR GB GR HK IE IT JP LT LU LV MT MX NL NO NZ PL PT RO SE SG SI SK US) ALLOWED_METHOD_STATES = %w[automatic manual].freeze ALLOWED_CANCELLATION_REASONS = %w[duplicate fraudulent requested_by_customer abandoned].freeze - CREATE_INTENT_ATTRIBUTES = %i[description statement_descriptor receipt_email save_payment_method] + CREATE_INTENT_ATTRIBUTES = %i[description statement_descriptor_suffix statement_descriptor receipt_email save_payment_method] CONFIRM_INTENT_ATTRIBUTES = %i[receipt_email return_url save_payment_method setup_future_usage off_session] - UPDATE_INTENT_ATTRIBUTES = %i[description statement_descriptor receipt_email setup_future_usage] + UPDATE_INTENT_ATTRIBUTES = %i[description statement_descriptor_suffix statement_descriptor receipt_email setup_future_usage] DEFAULT_API_VERSION = '2019-05-16' def create_intent(money, payment_method, options = {}) @@ -21,13 +20,19 @@ def create_intent(money, payment_method, options = {}) add_capture_method(post, options) add_confirmation_method(post, options) add_customer(post, options) - add_payment_method_token(post, payment_method, options) + payment_method = add_payment_method_token(post, payment_method, options) + return payment_method if payment_method.is_a?(ActiveMerchant::Billing::Response) + + add_external_three_d_secure_auth_data(post, options) add_metadata(post, options) add_return_url(post, options) add_connected_account(post, options) add_shipping_address(post, options) setup_future_usage(post, options) add_exemption(post, options) + add_stored_credentials(post, options) + add_error_on_requires_action(post, options) + request_three_d_secure(post, options) CREATE_INTENT_ATTRIBUTES.each do |attribute| add_whitelisted_attribute(post, options, attribute) @@ -42,32 +47,41 @@ def show_intent(intent_id, options) def confirm_intent(intent_id, payment_method, options = {}) post = {} - add_payment_method_token(post, payment_method, options) + payment_method = add_payment_method_token(post, payment_method, options) + return payment_method if payment_method.is_a?(ActiveMerchant::Billing::Response) + CONFIRM_INTENT_ATTRIBUTES.each do |attribute| add_whitelisted_attribute(post, options, attribute) end - commit(:post, "payment_intents/#{intent_id}/confirm", post, options) end def create_payment_method(payment_method, options = {}) - post = {} - post[:type] = 'card' - post[:card] = {} - post[:card][:number] = payment_method.number - post[:card][:exp_month] = payment_method.month - post[:card][:exp_year] = payment_method.year - post[:card][:cvc] = payment_method.verification_value if payment_method.verification_value - add_billing_address(post, options) + post_data = create_payment_method_data(payment_method, options) - commit(:post, 'payment_methods', post, options) + options = format_idempotency_key(options, 'pm') + commit(:post, 'payment_methods', post_data, options) + end + + def create_payment_method_data(payment_method, options = {}) + post_data = {} + post_data[:type] = 'card' + post_data[:card] = {} + post_data[:card][:number] = payment_method.number + post_data[:card][:exp_month] = payment_method.month + post_data[:card][:exp_year] = payment_method.year + post_data[:card][:cvc] = payment_method.verification_value if payment_method.verification_value + add_billing_address(post_data, options) + post_data end def update_intent(money, intent_id, payment_method, options = {}) post = {} - post[:amount] = money if money + add_amount(post, money, options) + + payment_method = add_payment_method_token(post, payment_method, options) + return payment_method if payment_method.is_a?(ActiveMerchant::Billing::Response) - add_payment_method_token(post, payment_method, options) add_payment_method_types(post, options) add_customer(post, options) add_metadata(post, options) @@ -77,10 +91,35 @@ def update_intent(money, intent_id, payment_method, options = {}) UPDATE_INTENT_ATTRIBUTES.each do |attribute| add_whitelisted_attribute(post, options, attribute) end - commit(:post, "payment_intents/#{intent_id}", post, options) end + def create_setup_intent(payment_method, options = {}) + post = {} + add_customer(post, options) + payment_method = add_payment_method_token(post, payment_method, options) + return payment_method if payment_method.is_a?(ActiveMerchant::Billing::Response) + + add_metadata(post, options) + add_return_url(post, options) + post[:on_behalf_of] = options[:on_behalf_of] if options[:on_behalf_of] + post[:usage] = options[:usage] if %w(on_session off_session).include?(options[:usage]) + post[:description] = options[:description] if options[:description] + + commit(:post, 'setup_intents', post, options) + end + + def retrieve_setup_intent(setup_intent_id) + # Retrieving a setup_intent passing 'expand[]=latest_attempt' allows the caller to + # check for a network_transaction_id and ds_transaction_id + # eg (latest_attempt -> payment_method_details -> card -> network_transaction_id) + # + # Being able to retrieve these fields enables payment flows that rely on MIT exemptions, e.g: off_session + commit(:post, "setup_intents/#{setup_intent_id}", { + 'expand[]': 'latest_attempt' + }, {}) + end + def authorize(money, payment_method, options = {}) create_intent(money, payment_method, options.merge!(confirm: true, capture_method: 'manual')) end @@ -91,12 +130,14 @@ def purchase(money, payment_method, options = {}) def capture(money, intent_id, options = {}) post = {} - post[:amount_to_capture] = money + currency = options[:currency] || currency(money) + post[:amount_to_capture] = localized_amount(money, currency) if options[:transfer_amount] post[:transfer_data] = {} post[:transfer_data][:amount] = options[:transfer_amount] end post[:application_fee_amount] = options[:application_fee] if options[:application_fee] + options = format_idempotency_key(options, 'capture') commit(:post, "payment_intents/#{intent_id}/capture", post, options) end @@ -107,8 +148,22 @@ def void(intent_id, options = {}) end def refund(money, intent_id, options = {}) - intent = commit(:get, "payment_intents/#{intent_id}", nil, options) - charge_id = intent.params.dig('charges', 'data')[0].dig('id') + if intent_id.include?('pi_') + intent = api_request(:get, "payment_intents/#{intent_id}", nil, options) + + return Response.new(false, intent['error']['message'], intent) if intent['error'] + + charge_id = intent.try(:[], 'charges').try(:[], 'data').try(:[], 0).try(:[], 'id') + + if charge_id.nil? + error_message = "No associated charge for #{intent['id']}" + error_message << "; payment_intent has a status of #{intent['status']}" if intent.try(:[], 'status') && intent.try(:[], 'status') != 'succeeded' + return Response.new(false, error_message, intent) + end + else + charge_id = intent_id + end + super(money, charge_id, options) end @@ -122,17 +177,22 @@ def store(payment_method, options = {}) # If customer option is provided, create a payment method and attach to customer id # Otherwise, create a customer, then attach if payment_method.is_a?(StripePaymentToken) || payment_method.is_a?(ActiveMerchant::Billing::CreditCard) - add_payment_method_token(params, payment_method, options) + payment_method = add_payment_method_token(params, payment_method, options) + return payment_method if payment_method.is_a?(ActiveMerchant::Billing::Response) + if options[:customer] customer_id = options[:customer] else - post[:validate] = options[:validate] unless options[:validate].nil? post[:description] = options[:description] if options[:description] post[:email] = options[:email] if options[:email] + options = format_idempotency_key(options, 'customer') customer = commit(:post, 'customers', post, options) customer_id = customer.params['id'] end - commit(:post, "payment_methods/#{params[:payment_method]}/attach", { customer: customer_id }, options) + options = format_idempotency_key(options, 'attach') + attach_parameters = { customer: customer_id } + attach_parameters[:validate] = options[:validate] unless options[:validate].nil? + commit(:post, "payment_methods/#{params[:payment_method]}/attach", attach_parameters, options) else super(payment_method, options) end @@ -147,49 +207,66 @@ def unstore(identification, options = {}, deprecated_options = {}) end end + def verify(payment_method, options = {}) + create_setup_intent(payment_method, options.merge!(confirm: true)) + end + private + def off_session_request?(options = {}) + (options[:off_session] || options[:setup_future_usage]) && options[:confirm] == true + end + + def add_connected_account(post, options = {}) + super(post, options) + post[:application_fee_amount] = options[:application_fee] if options[:application_fee] + end + def add_whitelisted_attribute(post, options, attribute) post[attribute] = options[attribute] if options[attribute] - post end def add_capture_method(post, options) capture_method = options[:capture_method].to_s post[:capture_method] = capture_method if ALLOWED_METHOD_STATES.include?(capture_method) - post end def add_confirmation_method(post, options) confirmation_method = options[:confirmation_method].to_s post[:confirmation_method] = confirmation_method if ALLOWED_METHOD_STATES.include?(confirmation_method) - post end def add_customer(post, options) customer = options[:customer].to_s post[:customer] = customer if customer.start_with?('cus_') - post end def add_return_url(post, options) return unless options[:confirm] + post[:confirm] = options[:confirm] post[:return_url] = options[:return_url] if options[:return_url] - post end def add_payment_method_token(post, payment_method, options) return if payment_method.nil? if payment_method.is_a?(ActiveMerchant::Billing::CreditCard) - p = create_payment_method(payment_method, options) - payment_method = p.params['id'] + if off_session_request?(options) + post[:payment_method_data] = create_payment_method_data(payment_method, options) + return + else + p = create_payment_method(payment_method, options) + return p unless p.success? + + payment_method = p.params['id'] + end end - if payment_method.is_a?(StripePaymentToken) + case payment_method + when StripePaymentToken post[:payment_method] = payment_method.payment_data['id'] - elsif payment_method.is_a?(String) + when String if payment_method.include?('|') customer_id, payment_method_id = payment_method.split('|') token = payment_method_id @@ -199,6 +276,8 @@ def add_payment_method_token(post, payment_method, options) end post[:payment_method] = token end + + post end def add_payment_method_types(post, options) @@ -206,35 +285,65 @@ def add_payment_method_types(post, options) return if payment_method_types.nil? post[:payment_method_types] = Array(payment_method_types) - post end def add_exemption(post, options = {}) return unless options[:confirm] + post[:payment_method_options] ||= {} post[:payment_method_options][:card] ||= {} post[:payment_method_options][:card][:moto] = true if options[:moto] end - def setup_future_usage(post, options = {}) - post[:setup_future_usage] = options[:setup_future_usage] if %w( on_session off_session ).include?(options[:setup_future_usage]) - post[:off_session] = options[:off_session] if options[:off_session] && options[:confirm] == true - post + def add_stored_credentials(post, options = {}) + return unless options[:stored_credential] && !options[:stored_credential].values.all?(&:nil?) + + stored_credential = options[:stored_credential] + post[:payment_method_options] ||= {} + post[:payment_method_options][:card] ||= {} + post[:payment_method_options][:card][:mit_exemption] = {} + + # Stripe PI accepts network_transaction_id and ds_transaction_id via mit field under card. + post[:payment_method_options][:card][:mit_exemption][:network_transaction_id] = stored_credential[:network_transaction_id] if stored_credential[:network_transaction_id] + post[:payment_method_options][:card][:mit_exemption][:ds_transaction_id] = stored_credential[:ds_transaction_id] if stored_credential[:ds_transaction_id] end - def add_connected_account(post, options = {}) - return unless options[:transfer_destination] - post[:transfer_data] = {} - post[:transfer_data][:destination] = options[:transfer_destination] - post[:transfer_data][:amount] = options[:transfer_amount] if options[:transfer_amount] - post[:on_behalf_of] = options[:on_behalf_of] if options[:on_behalf_of] - post[:transfer_group] = options[:transfer_group] if options[:transfer_group] - post[:application_fee_amount] = options[:application_fee] if options[:application_fee] + def add_error_on_requires_action(post, options = {}) + return unless options[:confirm] + + post[:error_on_requires_action] = true if options[:error_on_requires_action] + end + + def request_three_d_secure(post, options = {}) + return unless options[:request_three_d_secure] && %w(any automatic).include?(options[:request_three_d_secure]) + + post[:payment_method_options] ||= {} + post[:payment_method_options][:card] ||= {} + post[:payment_method_options][:card][:request_three_d_secure] = options[:request_three_d_secure] + end + + def add_external_three_d_secure_auth_data(post, options = {}) + return unless options[:three_d_secure]&.is_a?(Hash) + + three_d_secure = options[:three_d_secure] + post[:payment_method_options] ||= {} + post[:payment_method_options][:card] ||= {} + post[:payment_method_options][:card][:three_d_secure] ||= {} + post[:payment_method_options][:card][:three_d_secure][:version] = three_d_secure[:version] || (three_d_secure[:ds_transaction_id] ? '2.2.0' : '1.0.2') + post[:payment_method_options][:card][:three_d_secure][:electronic_commerce_indicator] = three_d_secure[:eci] if three_d_secure[:eci] + post[:payment_method_options][:card][:three_d_secure][:cryptogram] = three_d_secure[:cavv] if three_d_secure[:cavv] + post[:payment_method_options][:card][:three_d_secure][:transaction_id] = three_d_secure[:ds_transaction_id] || three_d_secure[:xid] + end + + def setup_future_usage(post, options = {}) + post[:setup_future_usage] = options[:setup_future_usage] if %w(on_session off_session).include?(options[:setup_future_usage]) + post[:off_session] = options[:off_session] if off_session_request?(options) post end def add_billing_address(post, options = {}) return unless billing = options[:billing_address] || options[:address] + post[:billing_details] = {} post[:billing_details][:address] = {} post[:billing_details][:address][:city] = billing[:city] if billing[:city] @@ -246,11 +355,11 @@ def add_billing_address(post, options = {}) post[:billing_details][:email] = billing[:email] if billing[:email] post[:billing_details][:name] = billing[:name] if billing[:name] post[:billing_details][:phone] = billing[:phone] if billing[:phone] - post end def add_shipping_address(post, options = {}) return unless shipping = options[:shipping] + post[:shipping] = {} post[:shipping][:address] = {} post[:shipping][:address][:line1] = shipping[:address][:line1] @@ -264,7 +373,22 @@ def add_shipping_address(post, options = {}) post[:shipping][:carrier] = shipping[:carrier] if shipping[:carrier] post[:shipping][:phone] = shipping[:phone] if shipping[:phone] post[:shipping][:tracking_number] = shipping[:tracking_number] if shipping[:tracking_number] - post + end + + def format_idempotency_key(options, suffix) + return options unless options[:idempotency_key] + + options.merge(idempotency_key: "#{options[:idempotency_key]}-#{suffix}") + end + + def success_from(response, options) + if response['status'] == 'requires_action' && !options[:execute_threed] + response['error'] = {} + response['error']['message'] = 'Received unexpected 3DS authentication response. Use the execute_threed option to initiate a proper 3DS flow.' + return false + end + + super(response, options) end end end diff --git a/lib/active_merchant/billing/gateways/swipe_checkout.rb b/lib/active_merchant/billing/gateways/swipe_checkout.rb index aaf4002d355..f80621d0233 100644 --- a/lib/active_merchant/billing/gateways/swipe_checkout.rb +++ b/lib/active_merchant/billing/gateways/swipe_checkout.rb @@ -11,9 +11,9 @@ class SwipeCheckoutGateway < Gateway TRANSACTION_API = '/createShopifyTransaction.php' - self.supported_countries = %w[ NZ CA ] + self.supported_countries = %w[NZ CA] self.default_currency = 'NZD' - self.supported_cardtypes = [:visa, :master] + self.supported_cardtypes = %i[visa master] self.homepage_url = 'https://www.swipehq.com/checkout' self.display_name = 'Swipe Checkout' self.money_format = :dollars @@ -58,7 +58,7 @@ def add_customer_data(post, creditcard, options) post[:address] = "#{address[:address1]}, #{address[:address2]}" post[:city] = address[:city] post[:country] = address[:country] - post[:mobile] = address[:phone] # API only has a "mobile" field, no "phone" + post[:mobile] = address[:phone] # API only has a "mobile" field, no "phone" end def add_invoice(post, options) @@ -109,8 +109,7 @@ def commit(action, money, parameters) TRANSACTION_APPROVED_MSG : TRANSACTION_DECLINED_MSG, response, - :test => test? - ) + test: test?) else build_error_response(message, response) end @@ -125,7 +124,7 @@ def commit(action, money, parameters) end end - def call_api(api, params=nil) + def call_api(api, params = nil) params ||= {} params[:merchant_id] = @options[:login] params[:api_key] = @options[:api_key] @@ -139,12 +138,12 @@ def url(api) (test? ? self.test_url : self.live_url) + api end - def build_error_response(message, params={}) + def build_error_response(message, params = {}) Response.new( false, message, params, - :test => test? + test: test? ) end end diff --git a/lib/active_merchant/billing/gateways/telr.rb b/lib/active_merchant/billing/gateways/telr.rb index c39b0a17e34..76c47c1dba4 100644 --- a/lib/active_merchant/billing/gateways/telr.rb +++ b/lib/active_merchant/billing/gateways/telr.rb @@ -8,16 +8,16 @@ class TelrGateway < Gateway self.live_url = 'https://secure.telr.com/gateway/remote.xml' - self.supported_countries = ['AE', 'IN', 'SA'] + self.supported_countries = %w[AE IN SA] self.default_currency = 'AED' self.money_format = :dollars - self.supported_cardtypes = [:visa, :master, :american_express, :maestro, :jcb] + self.supported_cardtypes = %i[visa master american_express maestro jcb] CVC_CODE_TRANSLATOR = { 'Y' => 'M', 'N' => 'N', 'X' => 'P', - 'E' => 'U', + 'E' => 'U' } AVS_CODE_TRANSLATOR = { @@ -28,12 +28,12 @@ class TelrGateway < Gateway 'E' => 'R' } - def initialize(options={}) + def initialize(options = {}) requires!(options, :merchant_id, :api_key) super end - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) commit(:purchase, amount, options[:currency]) do |doc| add_invoice(doc, 'sale', amount, payment_method, options) add_payment_method(doc, payment_method, options) @@ -41,7 +41,7 @@ def purchase(amount, payment_method, options={}) end end - def authorize(amount, payment_method, options={}) + def authorize(amount, payment_method, options = {}) commit(:authorize, amount, options[:currency]) do |doc| add_invoice(doc, 'auth', amount, payment_method, options) add_payment_method(doc, payment_method, options) @@ -49,26 +49,26 @@ def authorize(amount, payment_method, options={}) end end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) commit(:capture) do |doc| add_invoice(doc, 'capture', amount, authorization, options) end end - def void(authorization, options={}) + def void(authorization, options = {}) _, amount, currency = split_authorization(authorization) commit(:void) do |doc| add_invoice(doc, 'void', amount.to_i, authorization, options.merge(currency: currency)) end end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) commit(:refund) do |doc| add_invoice(doc, 'refund', amount, authorization, options) end end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) commit(:verify) do |doc| add_invoice(doc, 'verify', 100, credit_card, options) add_payment_method(doc, credit_card, options) @@ -78,7 +78,7 @@ def verify(credit_card, options={}) def verify_credentials response = void('0') - !['01', '04'].include?(response.error_code) + !%w[01 04].include?(response.error_code) end def supports_scrubbing? @@ -109,6 +109,7 @@ def add_invoice(doc, action, money, payment_method, options) def add_payment_method(doc, payment_method, options) return if payment_method.is_a?(String) + doc.card do doc.number(payment_method.number) doc.cvv(payment_method.verification_value) @@ -121,6 +122,7 @@ def add_payment_method(doc, payment_method, options) def add_customer_data(doc, payment_method, options) return if payment_method.is_a?(String) + doc.billing do doc.name do doc.first(payment_method.first_name) @@ -140,15 +142,14 @@ def add_address(doc, options) doc.city(address[:city] || 'City') doc.line1(address[:address1] || 'Address') return unless address + doc.line2(address[:address2]) if address[:address2] doc.zip(address[:zip]) if address[:zip] doc.region(address[:state]) if address[:state] end def add_ref(doc, action, payment_method) - if ['capture', 'refund', 'void'].include?(action) || payment_method.is_a?(String) - doc.ref(split_authorization(payment_method)[0]) - end + doc.ref(split_authorization(payment_method)[0]) if %w[capture refund void].include?(action) || payment_method.is_a?(String) end def add_authentication(doc) @@ -161,7 +162,7 @@ def lookup_country_code(code) country.code(:alpha2) end - def commit(action, amount=nil, currency=nil) + def commit(action, amount = nil, currency = nil) currency = default_currency if currency == nil request = build_xml_request { |doc| yield(doc) } response = ssl_post(live_url, request, headers) @@ -251,9 +252,7 @@ def message_from(succeeded, response) end def error_code_from(succeeded, response) - unless succeeded - response[:code] - end + response[:code] unless succeeded end def cvv_result(parsed) diff --git a/lib/active_merchant/billing/gateways/tns.rb b/lib/active_merchant/billing/gateways/tns.rb index ac58f510120..15c47eadb82 100644 --- a/lib/active_merchant/billing/gateways/tns.rb +++ b/lib/active_merchant/billing/gateways/tns.rb @@ -20,8 +20,7 @@ class TnsGateway < Gateway self.homepage_url = 'http://www.tnsi.com/' self.supported_countries = %w(AR AU BR FR DE HK MX NZ SG GB US) self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb, :maestro] - + self.supported_cardtypes = %i[visa master american_express discover diners_club jcb maestro] end end end diff --git a/lib/active_merchant/billing/gateways/trans_first.rb b/lib/active_merchant/billing/gateways/trans_first.rb index 8b2c579683f..55215e8c0e0 100644 --- a/lib/active_merchant/billing/gateways/trans_first.rb +++ b/lib/active_merchant/billing/gateways/trans_first.rb @@ -5,7 +5,7 @@ class TransFirstGateway < Gateway self.live_url = 'https://webservices.primerchants.com' self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://www.transfirst.com/' self.display_name = 'TransFirst' @@ -18,7 +18,7 @@ class TransFirstGateway < Gateway purchase_echeck: 'ACHDebit', refund: 'CreditCardCredit', refund_echeck: 'ACHVoidTransaction', - void: 'CreditCardAutoRefundorVoid', + void: 'CreditCardAutoRefundorVoid' } ENDPOINTS = { @@ -46,7 +46,7 @@ def purchase(money, payment, options = {}) commit((payment.is_a?(Check) ? :purchase_echeck : :purchase), post) end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) post = {} transaction_id, payment_type = split_authorization(authorization) @@ -57,10 +57,10 @@ def refund(money, authorization, options={}) commit((payment_type == 'check' ? :refund_echeck : :refund), post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} - transaction_id, _ = split_authorization(authorization) + transaction_id, = split_authorization(authorization) add_pair(post, :TransID, transaction_id) commit(:void, post) @@ -133,6 +133,7 @@ def add_echeck(post, payment) def add_or_use_default(payment_data, default_value) return payment_data.capitalize if payment_data + return default_value end @@ -174,10 +175,10 @@ def commit(action, params) success_from(response), message_from(response), response, - :test => test?, - :authorization => authorization_from(response), - :avs_result => { :code => response[:avs_code] }, - :cvv_result => response[:cvv2_code] + test: test?, + authorization: authorization_from(response), + avs_result: { code: response[:avs_code] }, + cvv_result: response[:cvv2_code] ) end diff --git a/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb b/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb index f35fe0d9b78..b3a85c71648 100644 --- a/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +++ b/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb @@ -12,7 +12,7 @@ class TransFirstTransactionExpressGateway < Gateway self.supported_countries = ['US'] self.default_currency = 'USD' self.money_format = :cents - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club] + self.supported_cardtypes = %i[visa master american_express discover diners_club] V1_NAMESPACE = 'http://postilion/realtime/merchantframework/xsd/v1/' SOAPENV_NAMESPACE = 'http://schemas.xmlsoap.org/soap/envelope/' @@ -152,7 +152,7 @@ class TransFirstTransactionExpressGateway < Gateway 'R1' => 'The transaction was declined or returned, because the cardholder requested that payment of all recurring or installment payment transactions for a specific merchant account be stopped/ Reserved for client-specific use (declined)', 'Q1' => 'Card Authentication failed/ Reserved for client-specific use (declined)', 'XA' => 'Forward to Issuer/ Reserved for client-specific use (declined)', - 'XD' => 'Forward to Issuer/ Reserved for client-specific use (declined)', + 'XD' => 'Forward to Issuer/ Reserved for client-specific use (declined)' } EXTENDED_RESPONSE_MESSAGES = { @@ -179,15 +179,15 @@ class TransFirstTransactionExpressGateway < Gateway refund_echeck: 16, void_echeck: 16, - wallet_sale: 14, + wallet_sale: 14 } - def initialize(options={}) + def initialize(options = {}) requires!(options, :gateway_id, :reg_key) super end - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) if credit_card?(payment_method) action = :purchase request = build_xml_transaction_request do |doc| @@ -216,7 +216,7 @@ def purchase(amount, payment_method, options={}) commit(action, request) end - def authorize(amount, payment_method, options={}) + def authorize(amount, payment_method, options = {}) if credit_card?(payment_method) request = build_xml_transaction_request do |doc| add_credit_card(doc, payment_method) @@ -234,7 +234,7 @@ def authorize(amount, payment_method, options={}) commit(:authorize, request) end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) transaction_id = split_authorization(authorization)[1] request = build_xml_transaction_request do |doc| add_amount(doc, amount) @@ -244,7 +244,7 @@ def capture(amount, authorization, options={}) commit(:capture, request) end - def void(authorization, options={}) + def void(authorization, options = {}) action, transaction_id = split_authorization(authorization) request = build_xml_transaction_request do |doc| @@ -254,7 +254,7 @@ def void(authorization, options={}) commit(void_type(action), request) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) action, transaction_id = split_authorization(authorization) request = build_xml_transaction_request do |doc| @@ -265,7 +265,7 @@ def refund(amount, authorization, options={}) commit(refund_type(action), request) end - def credit(amount, payment_method, options={}) + def credit(amount, payment_method, options = {}) request = build_xml_transaction_request do |doc| add_pan(doc, payment_method) add_amount(doc, amount) @@ -274,7 +274,7 @@ def credit(amount, payment_method, options={}) commit(:credit, request) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) request = build_xml_transaction_request do |doc| add_credit_card(doc, credit_card) add_contact(doc, credit_card.name, options) @@ -283,7 +283,7 @@ def verify(credit_card, options={}) commit(:verify, request) end - def store(payment_method, options={}) + def store(payment_method, options = {}) store_customer_request = build_xml_payment_storage_request do |doc| store_customer_details(doc, payment_method.name, options) end @@ -291,6 +291,7 @@ def store(payment_method, options={}) MultiResponse.run do |r| r.process { commit(:store, store_customer_request) } return r unless r.success? && r.params['custId'] + customer_id = r.params['custId'] store_payment_method_request = build_xml_payment_storage_request do |doc| @@ -321,7 +322,7 @@ def scrub(transcript) private - CURRENCY_CODES = Hash.new { |h, k| raise ArgumentError.new("Unsupported currency: #{k}") } + CURRENCY_CODES = Hash.new { |_h, k| raise ArgumentError.new("Unsupported currency: #{k}") } CURRENCY_CODES['USD'] = '840' def headers @@ -333,11 +334,12 @@ def headers def commit(action, request) request = add_transaction_code_to_request(request, action) - raw_response = begin - ssl_post(url, request, headers) - rescue ActiveMerchant::ResponseError => e - e.response.body - end + raw_response = + begin + ssl_post(url, request, headers) + rescue ActiveMerchant::ResponseError => e + e.response.body + end response = parse(raw_response) @@ -383,6 +385,7 @@ def success_from(response) def error_code_from(succeeded, response) return if succeeded + response['errorCode'] || response['rspCode'] end @@ -459,7 +462,7 @@ def build_xml_payment_search_request end end - def build_xml_request(wrapper, merchant_product_type=nil) + def build_xml_request(wrapper, merchant_product_type = nil) Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml| xml['soapenv'].Envelope('xmlns:soapenv' => SOAPENV_NAMESPACE) do xml['soapenv'].Body do @@ -482,7 +485,7 @@ def add_transaction_code_to_request(request, action) doc.root.to_xml end - def add_merchant(doc, product_type=nil) + def add_merchant(doc, product_type = nil) doc['v1'].merc do doc['v1'].id @options[:gateway_id] doc['v1'].regKey @options[:reg_key] @@ -547,7 +550,7 @@ def add_contact(doc, fullname, options) doc['v1'].addrLn2 billing_address[:address2] unless billing_address[:address2].blank? doc['v1'].city billing_address[:city] if billing_address[:city] doc['v1'].state billing_address[:state] if billing_address[:state] - doc['v1'].zipCode billing_address[:zip] if billing_address[:zip] + doc['v1'].zipCode billing_address[:zip].delete('-') if billing_address[:zip] doc['v1'].ctry 'US' end @@ -562,7 +565,7 @@ def add_contact(doc, fullname, options) doc['v1'].addrLn2 shipping_address[:address2] unless shipping_address[:address2].blank? doc['v1'].city shipping_address[:city] if shipping_address[:city] doc['v1'].state shipping_address[:state] if shipping_address[:state] - doc['v1'].zipCode shipping_address[:zip] if shipping_address[:zip] + doc['v1'].zipCode shipping_address[:zip].delete('-') if shipping_address[:zip] doc['v1'].phone shipping_address[:phone].gsub(/\D/, '') if shipping_address[:phone] doc['v1'].email shipping_address[:email] if shipping_address[:email] end diff --git a/lib/active_merchant/billing/gateways/transact_pro.rb b/lib/active_merchant/billing/gateways/transact_pro.rb index 5aaa36d756d..bda2602c49d 100644 --- a/lib/active_merchant/billing/gateways/transact_pro.rb +++ b/lib/active_merchant/billing/gateways/transact_pro.rb @@ -12,17 +12,17 @@ class TransactProGateway < Gateway self.supported_countries = ['US'] self.default_currency = 'USD' self.money_format = :cents - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'https://www.transactpro.lv/business/online-payments-acceptance' self.display_name = 'Transact Pro' - def initialize(options={}) + def initialize(options = {}) requires!(options, :guid, :password, :terminal) super end - def purchase(amount, payment, options={}) + def purchase(amount, payment, options = {}) post = PostData.new add_invoice(post, amount, options) add_payment(post, payment) @@ -44,7 +44,7 @@ def purchase(amount, payment, options={}) end end - def authorize(amount, payment, options={}) + def authorize(amount, payment, options = {}) post = PostData.new add_invoice(post, amount, options) add_payment(post, payment) @@ -66,11 +66,9 @@ def authorize(amount, payment, options={}) end end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) identifier, original_amount = split_authorization(authorization) - if amount && (amount != original_amount) - raise ArgumentError.new("Partial capture is not supported, and #{amount.inspect} != #{original_amount.inspect}") - end + raise ArgumentError.new("Partial capture is not supported, and #{amount.inspect} != #{original_amount.inspect}") if amount && (amount != original_amount) post = PostData.new add_credentials(post) @@ -80,7 +78,7 @@ def capture(amount, authorization, options={}) commit('charge_hold', post, original_amount) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) identifier, original_amount = split_authorization(authorization) post = PostData.new @@ -91,7 +89,7 @@ def refund(amount, authorization, options={}) commit('refund', post) end - def void(authorization, options={}) + def void(authorization, options = {}) identifier, amount = split_authorization(authorization) post = PostData.new @@ -101,7 +99,7 @@ def void(authorization, options={}) commit('cancel_dms', post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -158,13 +156,13 @@ def add_payment_cc(post, credit_card) post[:expire] = "#{month}/#{year[2..3]}" end - def add_credentials(post, key=:guid) + def add_credentials(post, key = :guid) post[key] = @options[:guid] post[:pwd] = Digest::SHA1.hexdigest(@options[:password]) end def parse(body) - if body =~ /^ID:/ + if /^ID:/.match?(body) body.split('~').reduce(Hash.new) { |h, v| m = v.match('(.*?):(.*)') h.merge!(m[1].underscore.to_sym => m[2]) @@ -178,7 +176,7 @@ def parse(body) end end - def commit(action, parameters, amount=nil) + def commit(action, parameters, amount = nil) url = (test? ? test_url : live_url) response = parse(ssl_post(url, post_data(action, parameters))) @@ -199,7 +197,7 @@ def authorization_from(parameters, response, amount) end def split_authorization(authorization) - if authorization =~ /|/ + if /|/.match?(authorization) identifier, amount = authorization.split('|') [identifier, amount.to_i] else diff --git a/lib/active_merchant/billing/gateways/transax.rb b/lib/active_merchant/billing/gateways/transax.rb index 336a7fb31c3..7a40b9e2c00 100644 --- a/lib/active_merchant/billing/gateways/transax.rb +++ b/lib/active_merchant/billing/gateways/transax.rb @@ -9,14 +9,13 @@ class TransaxGateway < SmartPs self.supported_countries = ['US'] # The card types supported by the payment gateway - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] # The homepage URL of the gateway self.homepage_url = 'https://www.nelixtransax.com/' # The name of the gateway self.display_name = 'NELiX TransaX' - end end end diff --git a/lib/active_merchant/billing/gateways/trexle.rb b/lib/active_merchant/billing/gateways/trexle.rb index 42451539b2c..00ab2578c66 100644 --- a/lib/active_merchant/billing/gateways/trexle.rb +++ b/lib/active_merchant/billing/gateways/trexle.rb @@ -10,7 +10,7 @@ class TrexleGateway < Gateway GI GR HK HU ID IE IL IM IN IS IT JO KW LB LI LK LT LU LV MC MT MU MV MX MY NL NO NZ OM PH PL PT QA RO SA SE SG SI SK SM TR TT UM US VA VN ZA) - self.supported_cardtypes = [:visa, :master, :american_express] + self.supported_cardtypes = %i[visa master american_express] self.homepage_url = 'https://trexle.com' self.display_name = 'Trexle' @@ -106,6 +106,7 @@ def add_customer_data(post, options) def add_address(post, creditcard, options) return if creditcard.kind_of?(String) + address = (options[:billing_address] || options[:address]) return unless address @@ -136,7 +137,7 @@ def add_creditcard(post, creditcard) name: creditcard.name ) elsif creditcard.kind_of?(String) - if creditcard =~ /^token_/ + if /^token_/.match?(creditcard) post[:card_token] = creditcard else post[:customer_token] = creditcard @@ -181,6 +182,7 @@ def success_response(body) def error_response(body) return invalid_response unless body['error'] + Response.new( false, body['error'], @@ -207,6 +209,7 @@ def token(response) def parse(body) return {} if body.blank? + JSON.parse(body) end diff --git a/lib/active_merchant/billing/gateways/trust_commerce.rb b/lib/active_merchant/billing/gateways/trust_commerce.rb index 3018d9d1690..79f06ee67fa 100644 --- a/lib/active_merchant/billing/gateways/trust_commerce.rb +++ b/lib/active_merchant/billing/gateways/trust_commerce.rb @@ -67,7 +67,7 @@ module Billing #:nodoc: class TrustCommerceGateway < Gateway self.live_url = self.test_url = 'https://vault.trustcommerce.com/trans/' - SUCCESS_TYPES = ['approved', 'accepted'] + SUCCESS_TYPES = %w[approved accepted] DECLINE_CODES = { 'decline' => 'The credit card was declined', @@ -107,7 +107,7 @@ class TrustCommerceGateway < Gateway VOIDABLE_ACTIONS = %w(preauth sale postauth credit) self.money_format = :cents - self.supported_cardtypes = [:visa, :master, :discover, :american_express, :diners_club, :jcb] + self.supported_cardtypes = %i[visa master discover american_express diners_club jcb] self.supported_countries = ['US'] self.homepage_url = 'http://www.trustcommerce.com/' self.display_name = 'TrustCommerce' @@ -151,7 +151,7 @@ def test? def authorize(money, creditcard_or_billing_id, options = {}) parameters = { - :amount => amount(money), + amount: amount(money) } add_order_id(parameters, options) @@ -168,7 +168,7 @@ def authorize(money, creditcard_or_billing_id, options = {}) # to process a purchase are an amount in cents or a money object and a creditcard object or billingid string. def purchase(money, creditcard_or_billing_id, options = {}) parameters = { - :amount => amount(money), + amount: amount(money) } add_order_id(parameters, options) @@ -185,10 +185,10 @@ def purchase(money, creditcard_or_billing_id, options = {}) # postauth, we preserve active_merchant's nomenclature of capture() for consistency with the rest of the library. To process # a postauthorization with TC, you need an amount in cents or a money object, and a TC transid. def capture(money, authorization, options = {}) - transaction_id, _ = split_authorization(authorization) + transaction_id, = split_authorization(authorization) parameters = { - :amount => amount(money), - :transid => transaction_id, + amount: amount(money), + transid: transaction_id } add_aggregator(parameters, options) add_custom_fields(parameters, options) @@ -199,11 +199,11 @@ def capture(money, authorization, options = {}) # refund() allows you to return money to a card that was previously billed. You need to supply the amount, in cents or a money object, # that you want to refund, and a TC transid for the transaction that you are refunding. def refund(money, identification, options = {}) - transaction_id, _ = split_authorization(identification) + transaction_id, = split_authorization(identification) parameters = { - :amount => amount(money), - :transid => transaction_id + amount: amount(money), + transid: transaction_id } add_aggregator(parameters, options) @@ -239,7 +239,7 @@ def void(authorization, options = {}) action = (VOIDABLE_ACTIONS - ['preauth']).include?(original_action) ? 'void' : 'reversal' parameters = { - :transid => transaction_id, + transid: transaction_id } add_aggregator(parameters, options) @@ -262,29 +262,30 @@ def void(authorization, options = {}) def recurring(money, creditcard, options = {}) ActiveMerchant.deprecated RECURRING_DEPRECATION_MESSAGE - requires!(options, [:periodicity, :bimonthly, :monthly, :biweekly, :weekly, :yearly, :daily]) - - cycle = case options[:periodicity] - when :monthly - '1m' - when :bimonthly - '2m' - when :weekly - '1w' - when :biweekly - '2w' - when :yearly - '1y' - when :daily - '1d' - end + requires!(options, %i[periodicity bimonthly monthly biweekly weekly yearly daily]) + + cycle = + case options[:periodicity] + when :monthly + '1m' + when :bimonthly + '2m' + when :weekly + '1w' + when :biweekly + '2w' + when :yearly + '1y' + when :daily + '1d' + end parameters = { - :amount => amount(money), - :cycle => cycle, - :verify => options[:verify] || 'y', - :billingid => options[:billingid] || nil, - :payments => options[:payments] || nil, + amount: amount(money), + cycle: cycle, + verify: options[:verify] || 'y', + billingid: options[:billingid] || nil, + payments: options[:payments] || nil } add_creditcard(parameters, creditcard) @@ -298,8 +299,8 @@ def recurring(money, creditcard, options = {}) def store(creditcard, options = {}) parameters = { - :verify => options[:verify] || 'y', - :billingid => options[:billingid] || options[:billing_id] || nil, + verify: options[:verify] || 'y', + billingid: options[:billingid] || options[:billing_id] || nil } add_creditcard(parameters, creditcard) @@ -313,7 +314,7 @@ def store(creditcard, options = {}) # unstore() the information will be removed and a Response object will be returned indicating the success of the action. def unstore(identification, options = {}) parameters = { - :billingid => identification, + billingid: identification } add_custom_fields(parameters, options) @@ -416,9 +417,7 @@ def clean_and_stringify_params(parameters) # symbol keys. Before sending our input to TCLink, we convert all our keys to strings and dump the symbol keys. # We also remove any pairs with nil values, as these confuse TCLink. parameters.keys.reverse_each do |key| - if parameters[key] - parameters[key.to_s] = parameters[key] - end + parameters[key.to_s] = parameters[key] if parameters[key] parameters.delete(key) end end @@ -445,11 +444,10 @@ def commit(action, parameters) success = SUCCESS_TYPES.include?(data['status']) message = message_from(data) Response.new(success, message, data, - :test => test?, - :authorization => authorization_from(action, data), - :cvv_result => data['cvv'], - :avs_result => { :code => data['avs'] } - ) + test: test?, + authorization: authorization_from(action, data), + cvv_result: data['cvv'], + avs_result: { code: data['avs'] }) end def parse(body) diff --git a/lib/active_merchant/billing/gateways/usa_epay.rb b/lib/active_merchant/billing/gateways/usa_epay.rb index 0558311bc11..8e69dd08f4c 100644 --- a/lib/active_merchant/billing/gateways/usa_epay.rb +++ b/lib/active_merchant/billing/gateways/usa_epay.rb @@ -5,7 +5,6 @@ module Billing #:nodoc: # depending on options passed to new. # class UsaEpayGateway < Gateway - self.abstract_class = true ## @@ -13,7 +12,7 @@ class UsaEpayGateway < Gateway # :software id or :live_url are passed in the options hash it will # create an instance of UsaEpayAdvancedGateway. # - def self.new(options={}) + def self.new(options = {}) if options.has_key?(:software_id) || options.has_key?(:live_url) UsaEpayAdvancedGateway.new(options) else diff --git a/lib/active_merchant/billing/gateways/usa_epay_advanced.rb b/lib/active_merchant/billing/gateways/usa_epay_advanced.rb index 23077a0fd87..20a985a4fdd 100644 --- a/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +++ b/lib/active_merchant/billing/gateways/usa_epay_advanced.rb @@ -73,34 +73,34 @@ class UsaEpayAdvancedGateway < Gateway FAILURE_MESSAGE = 'Default Failure' #:nodoc: self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb] + self.supported_cardtypes = %i[visa master american_express discover diners_club jcb] self.homepage_url = 'http://www.usaepay.com/' self.display_name = 'USA ePay Advanced SOAP Interface' CUSTOMER_PROFILE_OPTIONS = { - :id => [:string, 'CustomerID'], # merchant assigned number - :notes => [:string, 'Notes'], - :data => [:string, 'CustomData'], - :url => [:string, 'URL'] + id: [:string, 'CustomerID'], # merchant assigned number + notes: [:string, 'Notes'], + data: [:string, 'CustomData'], + url: [:string, 'URL'] } #:nodoc: CUSTOMER_RECURRING_BILLING_OPTIONS = { - :enabled => [:boolean, 'Enabled'], - :schedule => [:string, 'Schedule'], - :number_left => [:integer, 'NumLeft'], - :currency => [:string, 'Currency'], - :description => [:string, 'Description'], - :order_id => [:string, 'OrderID'], - :user => [:string, 'User'], - :source => [:string, 'Source'], - :send_receipt => [:boolean, 'SendReceipt'], - :receipt_note => [:string, 'ReceiptNote'] + enabled: [:boolean, 'Enabled'], + schedule: [:string, 'Schedule'], + number_left: [:integer, 'NumLeft'], + currency: [:string, 'Currency'], + description: [:string, 'Description'], + order_id: [:string, 'OrderID'], + user: [:string, 'User'], + source: [:string, 'Source'], + send_receipt: [:boolean, 'SendReceipt'], + receipt_note: [:string, 'ReceiptNote'] } #:nodoc: CUSTOMER_POINT_OF_SALE_OPTIONS = { - :price_tier => [:string, 'PriceTier'], - :tax_class => [:string, 'TaxClass'], - :lookup_code => [:string, 'LookupCode'] + price_tier: [:string, 'PriceTier'], + tax_class: [:string, 'TaxClass'], + lookup_code: [:string, 'LookupCode'] } #:nodoc: CUSTOMER_OPTIONS = [ @@ -110,23 +110,23 @@ class UsaEpayAdvancedGateway < Gateway ].inject(:merge) #:nodoc: COMMON_ADDRESS_OPTIONS = { - :first_name => [:string, 'FirstName'], - :last_name => [:string, 'LastName'], - :city => [:string, 'City'], - :state => [:string, 'State'], - :zip => [:string, 'Zip'], - :country => [:string, 'Country'], - :phone => [:string, 'Phone'], - :email => [:string, 'Email'], - :fax => [:string, 'Fax'], - :company => [:string, 'Company'] + first_name: [:string, 'FirstName'], + last_name: [:string, 'LastName'], + city: [:string, 'City'], + state: [:string, 'State'], + zip: [:string, 'Zip'], + country: [:string, 'Country'], + phone: [:string, 'Phone'], + email: [:string, 'Email'], + fax: [:string, 'Fax'], + company: [:string, 'Company'] } #:nodoc: ADDRESS_OPTIONS = [ COMMON_ADDRESS_OPTIONS, { - :address1 => [:string, 'Street'], - :address2 => [:string, 'Street2'], + address1: [:string, 'Street'], + address2: [:string, 'Street2'] } ].inject(:merge) #:nodoc @@ -135,116 +135,116 @@ class UsaEpayAdvancedGateway < Gateway CUSTOMER_RECURRING_BILLING_OPTIONS, COMMON_ADDRESS_OPTIONS, { - :address1 => [:string, 'Address'], - :address2 => [:string, 'Address2'], + address1: [:string, 'Address'], + address2: [:string, 'Address2'] }, { - :card_number => [:string, 'CardNumber'], - :card_exp => [:string, 'CardExp'], - :account => [:string, 'Account'], - :routing => [:string, 'Routing'], - :check_format => [:string, 'CheckFormat'], - :record_type => [:string, 'RecordType'], + card_number: [:string, 'CardNumber'], + card_exp: [:string, 'CardExp'], + account: [:string, 'Account'], + routing: [:string, 'Routing'], + check_format: [:string, 'CheckFormat'], + record_type: [:string, 'RecordType'] } ].inject(:merge) #:nodoc CUSTOMER_TRANSACTION_REQUEST_OPTIONS = { - :command => [:string, 'Command'], - :ignore_duplicate => [:boolean, 'IgnoreDuplicate'], - :client_ip => [:string, 'ClientIP'], - :customer_receipt => [:boolean, 'CustReceipt'], - :customer_email => [:boolean, 'CustReceiptEmail'], - :customer_template => [:boolean, 'CustReceiptName'], - :merchant_receipt => [:boolean, 'MerchReceipt'], - :merchant_email => [:boolean, 'MerchReceiptEmail'], - :merchant_template => [:boolean, 'MerchReceiptName'], - :recurring => [:boolean, 'isRecurring'], - :verification_value => [:string, 'CardCode'], - :software => [:string, 'Software'] + command: [:string, 'Command'], + ignore_duplicate: [:boolean, 'IgnoreDuplicate'], + client_ip: [:string, 'ClientIP'], + customer_receipt: [:boolean, 'CustReceipt'], + customer_email: [:boolean, 'CustReceiptEmail'], + customer_template: [:boolean, 'CustReceiptName'], + merchant_receipt: [:boolean, 'MerchReceipt'], + merchant_email: [:boolean, 'MerchReceiptEmail'], + merchant_template: [:boolean, 'MerchReceiptName'], + recurring: [:boolean, 'isRecurring'], + verification_value: [:string, 'CardCode'], + software: [:string, 'Software'] } #:nodoc: TRANSACTION_REQUEST_OBJECT_OPTIONS = { - :command => [:string, 'Command'], - :ignore_duplicate => [:boolean, 'IgnoreDuplicate'], - :authorization_code => [:string, 'AuthCode'], - :reference_number => [:string, 'RefNum'], - :account_holder => [:string, 'AccountHolder'], - :client_ip => [:string, 'ClientIP'], - :customer_id => [:string, 'CustomerID'], - :customer_receipt => [:boolean, 'CustReceipt'], - :customer_template => [:boolean, 'CustReceiptName'], - :software => [:string, 'Software'] + command: [:string, 'Command'], + ignore_duplicate: [:boolean, 'IgnoreDuplicate'], + authorization_code: [:string, 'AuthCode'], + reference_number: [:string, 'RefNum'], + account_holder: [:string, 'AccountHolder'], + client_ip: [:string, 'ClientIP'], + customer_id: [:string, 'CustomerID'], + customer_receipt: [:boolean, 'CustReceipt'], + customer_template: [:boolean, 'CustReceiptName'], + software: [:string, 'Software'] } #:nodoc: TRANSACTION_DETAIL_OPTIONS = { - :invoice => [:string, 'Invoice'], - :po_number => [:string, 'PONum'], - :order_id => [:string, 'OrderID'], - :clerk => [:string, 'Clerk'], - :terminal => [:string, 'Terminal'], - :table => [:string, 'Table'], - :description => [:string, 'Description'], - :comments => [:string, 'Comments'], - :allow_partial_auth => [:boolean, 'AllowPartialAuth'], - :currency => [:string, 'Currency'], - :non_tax => [:boolean, 'NonTax'], + invoice: [:string, 'Invoice'], + po_number: [:string, 'PONum'], + order_id: [:string, 'OrderID'], + clerk: [:string, 'Clerk'], + terminal: [:string, 'Terminal'], + table: [:string, 'Table'], + description: [:string, 'Description'], + comments: [:string, 'Comments'], + allow_partial_auth: [:boolean, 'AllowPartialAuth'], + currency: [:string, 'Currency'], + non_tax: [:boolean, 'NonTax'] } #:nodoc: TRANSACTION_DETAIL_MONEY_OPTIONS = { - :amount => [:double, 'Amount'], - :tax => [:double, 'Tax'], - :tip => [:double, 'Tip'], - :non_tax => [:boolean, 'NonTax'], - :shipping => [:double, 'Shipping'], - :discount => [:double, 'Discount'], - :subtotal => [:double, 'Subtotal'] + amount: [:double, 'Amount'], + tax: [:double, 'Tax'], + tip: [:double, 'Tip'], + non_tax: [:boolean, 'NonTax'], + shipping: [:double, 'Shipping'], + discount: [:double, 'Discount'], + subtotal: [:double, 'Subtotal'] } #:nodoc: CREDIT_CARD_DATA_OPTIONS = { - :magnetic_stripe => [:string, 'MagStripe'], - :dukpt => [:string, 'DUKPT'], - :signature => [:string, 'Signature'], - :terminal_type => [:string, 'TermType'], - :magnetic_support => [:string, 'MagSupport'], - :xid => [:string, 'XID'], - :cavv => [:string, 'CAVV'], - :eci => [:integer, 'ECI'], - :internal_card_authorization => [:boolean, 'InternalCardAuth'], - :pares => [:string, 'Pares'] + magnetic_stripe: [:string, 'MagStripe'], + dukpt: [:string, 'DUKPT'], + signature: [:string, 'Signature'], + terminal_type: [:string, 'TermType'], + magnetic_support: [:string, 'MagSupport'], + xid: [:string, 'XID'], + cavv: [:string, 'CAVV'], + eci: [:integer, 'ECI'], + internal_card_authorization: [:boolean, 'InternalCardAuth'], + pares: [:string, 'Pares'] } #:nodoc: CHECK_DATA_OPTIONS = { - :drivers_license => [:string, 'DriversLicense'], - :drivers_license_state => [:string, 'DriversLicenseState'], - :record_type => [:string, 'RecordType'], - :aux_on_us => [:string, 'AuxOnUS'], - :epc_code => [:string, 'EpcCode'], - :front_image => [:string, 'FrontImage'], - :back_image => [:string, 'BackImage'] + drivers_license: [:string, 'DriversLicense'], + drivers_license_state: [:string, 'DriversLicenseState'], + record_type: [:string, 'RecordType'], + aux_on_us: [:string, 'AuxOnUS'], + epc_code: [:string, 'EpcCode'], + front_image: [:string, 'FrontImage'], + back_image: [:string, 'BackImage'] } #:nodoc: RECURRING_BILLING_OPTIONS = { - :schedule => [:string, 'Schedule'], - :number_left => [:integer, 'NumLeft'], - :enabled => [:boolean, 'Enabled'] + schedule: [:string, 'Schedule'], + number_left: [:integer, 'NumLeft'], + enabled: [:boolean, 'Enabled'] } #:nodoc: AVS_RESULTS = { - 'Y' => %w( YYY Y YYA YYD ), - 'Z' => %w( NYZ Z ), - 'A' => %w( YNA A YNY ), - 'N' => %w( NNN N NN ), - 'X' => %w( YYX X ), - 'W' => %w( NYW W ), - 'XXW' => %w( XXW ), - 'XXU' => %w( XXU ), - 'R' => %w( XXR R U E ), - 'S' => %w( XXS S ), - 'XXE' => %w( XXE ), - 'G' => %w( XXG G C I ), - 'B' => %w( YYG B M ), - 'D' => %w( GGG D ), - 'P' => %w( YGG P ) + 'Y' => %w(YYY Y YYA YYD), + 'Z' => %w(NYZ Z), + 'A' => %w(YNA A YNY), + 'N' => %w(NNN N NN), + 'X' => %w(YYX X), + 'W' => %w(NYW W), + 'XXW' => %w(XXW), + 'XXU' => %w(XXU), + 'R' => %w(XXR R U E), + 'S' => %w(XXS S), + 'XXE' => %w(XXE), + 'G' => %w(XXG G C I), + 'B' => %w(YYG B M), + 'D' => %w(GGG D), + 'P' => %w(YGG P) }.inject({}) do |map, (type, codes)| codes.each { |code| map[code] = type } map @@ -289,43 +289,43 @@ def initialize(options = {}) # # Note: See run_transaction for additional options. # - def purchase(money, creditcard, options={}) - run_sale(options.merge!(:amount => money, :payment_method => creditcard)) + def purchase(money, creditcard, options = {}) + run_sale(options.merge!(amount: money, payment_method: creditcard)) end # Authorize an amount on a credit card or account. # # Note: See run_transaction for additional options. # - def authorize(money, creditcard, options={}) - run_auth_only(options.merge!(:amount => money, :payment_method => creditcard)) + def authorize(money, creditcard, options = {}) + run_auth_only(options.merge!(amount: money, payment_method: creditcard)) end # Capture an authorized transaction. # # Note: See run_transaction for additional options. # - def capture(money, identification, options={}) - capture_transaction(options.merge!(:amount => money, :reference_number => identification)) + def capture(money, identification, options = {}) + capture_transaction(options.merge!(amount: money, reference_number: identification)) end # Void a previous transaction that has not been settled. # # Note: See run_transaction for additional options. # - def void(identification, options={}) - void_transaction(options.merge!(:reference_number => identification)) + def void(identification, options = {}) + void_transaction(options.merge!(reference_number: identification)) end # Refund a previous transaction. # # Note: See run_transaction for additional options. # - def refund(money, identification, options={}) - refund_transaction(options.merge!(:amount => money, :reference_number => identification)) + def refund(money, identification, options = {}) + refund_transaction(options.merge!(amount: money, reference_number: identification)) end - def credit(money, identification, options={}) + def credit(money, identification, options = {}) ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE refund(money, identification, options) end @@ -368,7 +368,7 @@ def credit(money, identification, options={}) # ==== Response # * #message -- customer number assigned by gateway # - def add_customer(options={}) + def add_customer(options = {}) request = build_request(__method__, options) commit(__method__, request) end @@ -381,7 +381,7 @@ def add_customer(options={}) # ==== Options # * Same as add_customer # - def update_customer(options={}) + def update_customer(options = {}) requires! options, :customer_number request = build_request(__method__, options) @@ -429,7 +429,7 @@ def update_customer(options={}) # ==== Response # * #message -- boolean; Returns true if successful. Exception thrown all failures. # - def quick_update_customer(options={}) + def quick_update_customer(options = {}) requires! options, :customer_number requires! options, :update_data @@ -444,7 +444,7 @@ def quick_update_customer(options={}) # ==== Required # * :customer_number # - def enable_customer(options={}) + def enable_customer(options = {}) requires! options, :customer_number request = build_request(__method__, options) @@ -456,7 +456,7 @@ def enable_customer(options={}) # ==== Required # * :customer_number # - def disable_customer(options={}) + def disable_customer(options = {}) requires! options, :customer_number request = build_request(__method__, options) @@ -479,7 +479,7 @@ def disable_customer(options={}) # ==== Response # * #message -- method_id of new customer payment method # - def add_customer_payment_method(options={}) + def add_customer_payment_method(options = {}) requires! options, :customer_number request = build_request(__method__, options) @@ -494,7 +494,7 @@ def add_customer_payment_method(options={}) # ==== Response # * #message -- either a single hash or an array of hashes of payment methods # - def get_customer_payment_methods(options={}) + def get_customer_payment_methods(options = {}) requires! options, :customer_number request = build_request(__method__, options) @@ -510,7 +510,7 @@ def get_customer_payment_methods(options={}) # ==== Response # * #message -- hash of payment method # - def get_customer_payment_method(options={}) + def get_customer_payment_method(options = {}) requires! options, :customer_number, :method_id request = build_request(__method__, options) @@ -531,7 +531,7 @@ def get_customer_payment_method(options={}) # ==== Response # * #message -- hash of payment method # - def update_customer_payment_method(options={}) + def update_customer_payment_method(options = {}) requires! options, :method_id request = build_request(__method__, options) @@ -544,7 +544,7 @@ def update_customer_payment_method(options={}) # * :customer_number # * :method_id # - def delete_customer_payment_method(options={}) + def delete_customer_payment_method(options = {}) requires! options, :customer_number, :method_id request = build_request(__method__, options) @@ -556,7 +556,7 @@ def delete_customer_payment_method(options={}) # ==== Required # * :customer_number # - def delete_customer(options={}) + def delete_customer(options = {}) requires! options, :customer_number request = build_request(__method__, options) @@ -607,7 +607,7 @@ def delete_customer(options={}) # ==== Response # * #message -- transaction response hash # - def run_customer_transaction(options={}) + def run_customer_transaction(options = {}) requires! options, :customer_number, :command, :amount request = build_request(__method__, options) @@ -671,14 +671,14 @@ def run_customer_transaction(options={}) # ==== Response # * #message -- transaction response hash # - def run_transaction(options={}) + def run_transaction(options = {}) request = build_request(__method__, options) commit(__method__, request) end - TRANSACTION_METHODS = [ - :run_sale, :run_auth_only, :run_credit, - :run_check_sale, :run_check_credit + TRANSACTION_METHODS = %i[ + run_sale run_auth_only run_credit + run_check_sale run_check_credit ] #:nodoc: TRANSACTION_METHODS.each do |method| @@ -699,7 +699,7 @@ def run_transaction(options={}) # ==== Response # * #message -- transaction response hash # - def post_auth(options={}) + def post_auth(options = {}) requires! options, :authorization_code request = build_request(__method__, options) @@ -721,7 +721,7 @@ def post_auth(options={}) # ==== Response # * #message -- transaction response hash # - def capture_transaction(options={}) + def capture_transaction(options = {}) requires! options, :reference_number request = build_request(__method__, options) @@ -738,7 +738,7 @@ def capture_transaction(options={}) # ==== Response # * #message -- transaction response hash # - def void_transaction(options={}) + def void_transaction(options = {}) requires! options, :reference_number request = build_request(__method__, options) @@ -757,7 +757,7 @@ def void_transaction(options={}) # ==== Response # * #message -- transaction response hash # - def refund_transaction(options={}) + def refund_transaction(options = {}) requires! options, :reference_number, :amount request = build_request(__method__, options) @@ -777,7 +777,7 @@ def refund_transaction(options={}) # ==== Response # * #message -- transaction response hash # - def override_transaction(options={}) + def override_transaction(options = {}) requires! options, :reference_number request = build_request(__method__, options) @@ -820,7 +820,7 @@ def override_transaction(options={}) # ==== Response # * #message -- transaction response hash # - def run_quick_sale(options={}) + def run_quick_sale(options = {}) requires! options, :reference_number, :amount request = build_request(__method__, options) @@ -858,7 +858,7 @@ def run_quick_sale(options={}) # ==== Response # * #message -- transaction response hash # - def run_quick_credit(options={}) + def run_quick_credit(options = {}) requires! options, :reference_number request = build_request(__method__, options) @@ -875,7 +875,7 @@ def run_quick_credit(options={}) # ==== Response # * #message -- transaction hash # - def get_transaction(options={}) + def get_transaction(options = {}) requires! options, :reference_number request = build_request(__method__, options) @@ -892,7 +892,7 @@ def get_transaction(options={}) # * response.message -- message of the referenced transaction # * response.authorization -- same as :reference_number in options # - def get_transaction_status(options={}) + def get_transaction_status(options = {}) requires! options, :reference_number request = build_request(__method__, options) @@ -990,7 +990,7 @@ def get_transaction_status(options={}) # ==== Response # * #message -- hash; keys are the field values # - def get_transaction_custom(options={}) + def get_transaction_custom(options = {}) requires! options, :reference_number, :fields request = build_request(__method__, options) @@ -1005,7 +1005,7 @@ def get_transaction_custom(options={}) # ==== Response # * #message -- check trace hash # - def get_check_trace(options={}) + def get_check_trace(options = {}) requires! options, :reference_number request = build_request(__method__, options) @@ -1031,7 +1031,7 @@ def get_account_details # Build soap header, etc. def build_request(action, options = {}) soap = Builder::XmlMarkup.new - soap.instruct!(:xml, :version => '1.0', :encoding => 'utf-8') + soap.instruct!(:xml, version: '1.0', encoding: 'utf-8') soap.tag! 'SOAP-ENV:Envelope', 'xmlns:SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/', 'xmlns:ns1' => 'urn:usaepay', @@ -1078,7 +1078,7 @@ def build_add_customer(soap, options) end end - def build_customer(soap, options, type, add_customer_data=false) + def build_customer(soap, options, type, add_customer_data = false) soap.tag! "ns1:#{type}" do build_token soap, options build_tag soap, :integer, 'CustNum', options[:customer_number] @@ -1310,7 +1310,7 @@ def build_customer_payments(soap, options) if options[:payment_methods] length = options[:payment_methods].length soap.PaymentMethods 'SOAP-ENC:arrayType' => "ns1:PaymentMethod[#{length}]", - 'xsi:type' =>'ns1:PaymentMethodArray' do + 'xsi:type' => 'ns1:PaymentMethodArray' do build_customer_payment_methods soap, options end end @@ -1336,7 +1336,7 @@ def build_credit_card_or_check(soap, payment_method) when payment_method[:method].kind_of?(ActiveMerchant::Billing::CreditCard) build_tag soap, :string, 'CardNumber', payment_method[:method].number build_tag soap, :string, 'CardExpiration', - "#{"%02d" % payment_method[:method].month}#{payment_method[:method].year.to_s[-2..-1]}" + "#{'%02d' % payment_method[:method].month}#{payment_method[:method].year.to_s[-2..-1]}" if options[:billing_address] build_tag soap, :string, 'AvsStreet', options[:billing_address][:address1] build_tag soap, :string, 'AvsZip', options[:billing_address][:zip] @@ -1345,9 +1345,7 @@ def build_credit_card_or_check(soap, payment_method) when payment_method[:method].kind_of?(ActiveMerchant::Billing::Check) build_tag soap, :string, 'Account', payment_method[:method].account_number build_tag soap, :string, 'Routing', payment_method[:method].routing_number - unless payment_method[:method].account_type.nil? - build_tag soap, :string, 'AccountType', payment_method[:method].account_type.capitalize - end + build_tag soap, :string, 'AccountType', payment_method[:method].account_type.capitalize unless payment_method[:method].account_type.nil? build_tag soap, :string, 'DriversLicense', options[:drivers_license] build_tag soap, :string, 'DriversLicenseState', options[:drivers_license_state] build_tag soap, :string, 'RecordType', options[:record_type] @@ -1380,7 +1378,7 @@ def build_customer_transaction(soap, options) # Transaction Helpers =========================================== - def build_transaction_request_object(soap, options, name='Params') + def build_transaction_request_object(soap, options, name = 'Params') soap.tag! name, 'xsi:type' => 'ns1:TransactionRequestObject' do TRANSACTION_REQUEST_OBJECT_OPTIONS.each do |k, v| build_tag soap, v[0], v[1], options[k] @@ -1434,9 +1432,7 @@ def build_credit_card_data(soap, options) def build_card_expiration(options) month = options[:payment_method].month year = options[:payment_method].year - unless month.nil? || year.nil? - "#{"%02d" % month}#{year.to_s[-2..-1]}" - end + "#{'%02d' % month}#{year.to_s[-2..-1]}" unless month.nil? || year.nil? end def build_check_data(soap, options) @@ -1476,9 +1472,7 @@ def build_transaction_field_array(soap, options) def build_billing_address(soap, options) if options[:billing_address] - if options[:billing_address][:name] - options[:billing_address][:first_name], options[:billing_address][:last_name] = split_names(options[:billing_address][:name]) - end + options[:billing_address][:first_name], options[:billing_address][:last_name] = split_names(options[:billing_address][:name]) if options[:billing_address][:name] soap.BillingAddress 'xsi:type' => 'ns1:Address' do ADDRESS_OPTIONS.each do |k, v| build_tag soap, v[0], v[1], options[:billing_address][k] @@ -1489,9 +1483,7 @@ def build_billing_address(soap, options) def build_shipping_address(soap, options) if options[:shipping_address] - if options[:shipping_address][:name] - options[:shipping_address][:first_name], options[:shipping_address][:last_name] = split_names(options[:shipping_address][:name]) - end + options[:shipping_address][:first_name], options[:shipping_address][:last_name] = split_names(options[:shipping_address][:name]) if options[:shipping_address][:name] soap.ShippingAddress 'xsi:type' => 'ns1:Address' do ADDRESS_OPTIONS.each do |k, v| build_tag soap, v[0], v[1], options[:shipping_address][k] @@ -1544,15 +1536,15 @@ def build_response(action, soap) success, message, response_params, - :test => test?, - :authorization => authorization, - :avs_result => avs_from(avs), - :cvv_result => cvv + test: test?, + authorization: authorization, + avs_result: avs_from(avs), + cvv_result: cvv ) end def avs_from(avs) - avs_params = { :code => avs } + avs_params = { code: avs } avs_params[:message] = AVS_CUSTOM_MESSAGES[avs] if AVS_CUSTOM_MESSAGES.key?(avs) avs_params end @@ -1560,7 +1552,7 @@ def avs_from(avs) def parse(action, soap) xml = REXML::Document.new(soap) root = REXML::XPath.first(xml, '//SOAP-ENV:Body') - response = root ? parse_element(root[0]) : { :response => soap } + response = root ? parse_element(root[0]) : { response: soap } success, message, authorization, avs, cvv = false, FAILURE_MESSAGE, nil, nil, nil @@ -1576,15 +1568,16 @@ def parse(action, soap) else success = true end - message = case action - when :get_customer_payment_methods - p['item'] - when :get_transaction_custom - items = p['item'].kind_of?(Array) ? p['item'] : [p['item']] - items.inject({}) { |hash, item| hash[item['field']] = item['value']; hash } - else - p - end + message = + case action + when :get_customer_payment_methods + p['item'] + when :get_transaction_custom + items = p['item'].kind_of?(Array) ? p['item'] : [p['item']] + items.inject({}) { |hash, item| hash[item['field']] = item['value']; hash } + else + p + end elsif response.respond_to?(:[]) && p = response[:response] message = p # when response is html end @@ -1614,7 +1607,6 @@ def parse_element(node) response end - end end end diff --git a/lib/active_merchant/billing/gateways/usa_epay_transaction.rb b/lib/active_merchant/billing/gateways/usa_epay_transaction.rb index e1cade9a52a..88045020897 100644 --- a/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +++ b/lib/active_merchant/billing/gateways/usa_epay_transaction.rb @@ -4,19 +4,19 @@ class UsaEpayTransactionGateway < Gateway self.live_url = 'https://www.usaepay.com/gate' self.test_url = 'https://sandbox.usaepay.com/gate' - self.supported_cardtypes = [:visa, :master, :american_express] + self.supported_cardtypes = %i[visa master american_express] self.supported_countries = ['US'] self.homepage_url = 'http://www.usaepay.com/' self.display_name = 'USA ePay' TRANSACTIONS = { - :authorization => 'cc:authonly', - :purchase => 'cc:sale', - :capture => 'cc:capture', - :refund => 'cc:refund', - :void => 'cc:void', - :void_release => 'cc:void:release', - :check_purchase => 'check:sale' + authorization: 'cc:authonly', + purchase: 'cc:sale', + capture: 'cc:capture', + refund: 'cc:refund', + void: 'cc:void', + void_release: 'cc:void:release', + check_purchase: 'check:sale' } STANDARD_ERROR_CODE_MAPPING = { @@ -82,7 +82,7 @@ def purchase(money, payment, options = {}) end def capture(money, authorization, options = {}) - post = { :refNum => authorization } + post = { refNum: authorization } add_amount(post, money) add_test_mode(post, options) @@ -90,7 +90,7 @@ def capture(money, authorization, options = {}) end def refund(money, authorization, options = {}) - post = { :refNum => authorization } + post = { refNum: authorization } add_amount(post, money) add_test_mode(post, options) @@ -107,7 +107,7 @@ def verify(creditcard, options = {}) # Pass `no_release: true` to keep the void from immediately settling def void(authorization, options = {}) command = (options[:no_release] ? :void : :void_release) - post = { :refNum => authorization } + post = { refNum: authorization } add_test_mode(post, options) commit(command, post) end @@ -153,13 +153,9 @@ def add_customer_data(post, options) end end - if options.has_key? :customer - post[:custid] = options[:customer] - end + post[:custid] = options[:customer] if options.has_key? :customer - if options.has_key? :ip - post[:ip] = options[:ip] - end + post[:ip] = options[:ip] if options.has_key? :ip end def add_address(post, payment, options) @@ -202,12 +198,13 @@ def add_invoice(post, options) post[:description] = options[:description] end - def add_payment(post, payment, options={}) + def add_payment(post, payment, options = {}) if payment.respond_to?(:routing_number) post[:checkformat] = options[:check_format] if options[:check_format] if payment.account_type account_type = payment.account_type.to_s.capitalize raise ArgumentError, 'account_type must be checking or savings' unless %w(Checking Savings).include?(account_type) + post[:accounttype] = account_type end post[:account] = payment.account_number @@ -232,6 +229,7 @@ def add_test_mode(post, options) # see: http://wiki.usaepay.com/developer/transactionapi#split_payments def add_split_payments(post, options) return unless options[:split_payments].is_a?(Array) + options[:split_payments].each_with_index do |payment, index| prefix = '%02d' % (index + 2) post["#{prefix}key"] = payment[:key] @@ -245,6 +243,7 @@ def add_split_payments(post, options) def add_recurring_fields(post, options) return unless options[:recurring_fields].is_a?(Hash) + options[:recurring_fields].each do |key, value| if value == true value = 'yes' @@ -252,9 +251,7 @@ def add_recurring_fields(post, options) next end - if key == :bill_amount - value = amount(value) - end + value = amount(value) if key == :bill_amount post[key.to_s.delete('_')] = value end @@ -274,6 +271,7 @@ def add_custom_fields(post, options) # see: https://wiki.usaepay.com/developer/transactionapi#line_item_details def add_line_items(post, options) return unless options[:line_items].is_a?(Array) + options[:line_items].each_with_index do |line_item, index| %w(product_ref_num sku qty name description taxable tax_rate tax_amount commodity_code discount_rate discount_amount).each do |key| post["line#{index}#{key.delete('_')}"] = line_item[key.to_sym] if line_item.has_key?(key.to_sym) @@ -281,7 +279,7 @@ def add_line_items(post, options) { quantity: 'qty', - unit: 'um', + unit: 'um' }.each do |key, umkey| post["line#{index}#{umkey}"] = line_item[key.to_sym] if line_item.has_key?(key.to_sym) end @@ -298,21 +296,21 @@ def parse(body) end { - :status => fields['UMstatus'], - :auth_code => fields['UMauthCode'], - :ref_num => fields['UMrefNum'], - :batch => fields['UMbatch'], - :avs_result => fields['UMavsResult'], - :avs_result_code => fields['UMavsResultCode'], - :cvv2_result => fields['UMcvv2Result'], - :cvv2_result_code => fields['UMcvv2ResultCode'], - :vpas_result_code => fields['UMvpasResultCode'], - :result => fields['UMresult'], - :error => fields['UMerror'], - :error_code => fields['UMerrorcode'], - :acs_url => fields['UMacsurl'], - :payload => fields['UMpayload'] - }.delete_if { |k, v| v.nil? } + status: fields['UMstatus'], + auth_code: fields['UMauthCode'], + ref_num: fields['UMrefNum'], + batch: fields['UMbatch'], + avs_result: fields['UMavsResult'], + avs_result_code: fields['UMavsResultCode'], + cvv2_result: fields['UMcvv2Result'], + cvv2_result_code: fields['UMcvv2ResultCode'], + vpas_result_code: fields['UMvpasResultCode'], + result: fields['UMresult'], + error: fields['UMerror'], + error_code: fields['UMerrorcode'], + acs_url: fields['UMacsurl'], + payload: fields['UMpayload'] + }.delete_if { |_k, v| v.nil? } end def commit(action, parameters) @@ -322,12 +320,11 @@ def commit(action, parameters) error_code = nil error_code = (STANDARD_ERROR_CODE_MAPPING[response[:error_code]] || STANDARD_ERROR_CODE[:processing_error]) unless approved Response.new(approved, message_from(response), response, - :test => test?, - :authorization => response[:ref_num], - :cvv_result => response[:cvv2_result_code], - :avs_result => { :code => response[:avs_result_code] }, - :error_code => error_code - ) + test: test?, + authorization: response[:ref_num], + cvv_result: response[:cvv2_result_code], + avs_result: { code: response[:avs_result_code] }, + error_code: error_code) end def message_from(response) @@ -335,6 +332,7 @@ def message_from(response) return 'Success' else return 'Unspecified error' if response[:error].blank? + return response[:error] end end diff --git a/lib/active_merchant/billing/gateways/vanco.rb b/lib/active_merchant/billing/gateways/vanco.rb index 546eedbca4e..03ae8a2464d 100644 --- a/lib/active_merchant/billing/gateways/vanco.rb +++ b/lib/active_merchant/billing/gateways/vanco.rb @@ -10,24 +10,24 @@ class VancoGateway < Gateway self.supported_countries = ['US'] self.default_currency = 'USD' - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://vancopayments.com/' self.display_name = 'Vanco Payment Solutions' - def initialize(options={}) + def initialize(options = {}) requires!(options, :user_id, :password, :client_id) super end - def purchase(money, payment_method, options={}) + def purchase(money, payment_method, options = {}) MultiResponse.run do |r| r.process { login } r.process { commit(purchase_request(money, payment_method, r.params['response_sessionid'], options), :response_transactionref) } end end - def refund(money, authorization, options={}) + def refund(money, authorization, options = {}) MultiResponse.run do |r| r.process { login } r.process { commit(refund_request(money, authorization, r.params['response_sessionid']), :response_creditrequestreceived) } @@ -108,6 +108,7 @@ def success_from(response, success_field_name) def message_from(succeeded, response) return 'Success' if succeeded + response[:error_message] end @@ -288,7 +289,6 @@ def headers 'Content-Type' => 'text/xml' } end - end end end diff --git a/lib/active_merchant/billing/gateways/verifi.rb b/lib/active_merchant/billing/gateways/verifi.rb index e435505d8be..a11a6fcc279 100644 --- a/lib/active_merchant/billing/gateways/verifi.rb +++ b/lib/active_merchant/billing/gateways/verifi.rb @@ -5,8 +5,8 @@ module Billing #:nodoc: class VerifiGateway < Gateway class VerifiPostData < PostData # Fields that will be sent even if they are blank - self.required_fields = [:amount, :type, :ccnumber, :ccexp, :firstname, :lastname, - :company, :address1, :address2, :city, :state, :zip, :country, :phone] + self.required_fields = %i[amount type ccnumber ccexp firstname lastname + company address1 address2 city state zip country phone] end self.live_url = self.test_url = 'https://secure.verifi.com/gw/api/transact.php' @@ -50,16 +50,16 @@ class VerifiPostData < PostData SUCCESS = 1 TRANSACTIONS = { - :authorization => 'auth', - :purchase => 'sale', - :capture => 'capture', - :void => 'void', - :credit => 'credit', - :refund => 'refund' + authorization: 'auth', + purchase: 'sale', + capture: 'capture', + void: 'void', + credit: 'credit', + refund: 'refund' } self.supported_countries = ['US'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'http://www.verifi.com/' self.display_name = 'Verifi' @@ -195,11 +195,10 @@ def commit(trx_type, money, post) response = parse(ssl_post(self.live_url, post_data(trx_type, post))) Response.new(response[:response].to_i == SUCCESS, message_from(response), response, - :test => test?, - :authorization => response[:transactionid], - :avs_result => { :code => response[:avsresponse] }, - :cvv_result => response[:cvvresponse] - ) + test: test?, + authorization: response[:transactionid], + avs_result: { code: response[:avsresponse] }, + cvv_result: response[:cvvresponse]) end def message_from(response) diff --git a/lib/active_merchant/billing/gateways/viaklix.rb b/lib/active_merchant/billing/gateways/viaklix.rb index b68a8ec3ac9..76bfc8e46ca 100644 --- a/lib/active_merchant/billing/gateways/viaklix.rb +++ b/lib/active_merchant/billing/gateways/viaklix.rb @@ -8,13 +8,13 @@ class ViaklixGateway < Gateway self.delimiter = "\r\n" self.actions = { - :purchase => 'SALE', - :credit => 'CREDIT' + purchase: 'SALE', + credit: 'CREDIT' } APPROVED = '0' - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] self.supported_countries = ['US'] self.display_name = 'ViaKLIX' self.homepage_url = 'http://viaklix.com' @@ -49,9 +49,7 @@ def purchase(money, creditcard, options = {}) # Make a credit to a card (Void can only be done from the virtual terminal) # Viaklix does not support credits by reference. You must pass in the credit card def credit(money, creditcard, options = {}) - if creditcard.is_a?(String) - raise ArgumentError, 'Reference credits are not supported. Please supply the original credit card' - end + raise ArgumentError, 'Reference credits are not supported. Please supply the original credit card' if creditcard.is_a?(String) form = {} add_invoice(form, options) @@ -109,9 +107,7 @@ def add_creditcard(form, creditcard) form[:card_number] = creditcard.number form[:exp_date] = expdate(creditcard) - if creditcard.verification_value? - add_verification_value(form, creditcard) - end + add_verification_value(form, creditcard) if creditcard.verification_value? form[:first_name] = creditcard.first_name.to_s.slice(0, 20) form[:last_name] = creditcard.last_name.to_s.slice(0, 30) @@ -141,11 +137,10 @@ def commit(action, money, parameters) response = parse(ssl_post(test? ? self.test_url : self.live_url, post_data(parameters))) Response.new(response['result'] == APPROVED, message_from(response), response, - :test => @options[:test] || test?, - :authorization => authorization_from(response), - :avs_result => { :code => response['avs_response'] }, - :cvv_result => response['cvv2_response'] - ) + test: @options[:test] || test?, + authorization: authorization_from(response), + avs_result: { code: response['avs_response'] }, + cvv_result: response['cvv2_response']) end def authorization_from(response) diff --git a/lib/active_merchant/billing/gateways/visanet_peru.rb b/lib/active_merchant/billing/gateways/visanet_peru.rb index 49473abc2f6..73adc366519 100644 --- a/lib/active_merchant/billing/gateways/visanet_peru.rb +++ b/lib/active_merchant/billing/gateways/visanet_peru.rb @@ -8,24 +8,24 @@ class VisanetPeruGateway < Gateway self.test_url = 'https://devapi.vnforapps.com/api.tokenization/api/v2/merchant' self.live_url = 'https://api.vnforapps.com/api.tokenization/api/v2/merchant' - self.supported_countries = ['US', 'PE'] + self.supported_countries = %w[US PE] self.default_currency = 'PEN' self.money_format = :dollars - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_cardtypes = %i[visa master american_express discover] - def initialize(options={}) + def initialize(options = {}) requires!(options, :access_key_id, :secret_access_key, :merchant_id) super end - def purchase(amount, payment_method, options={}) + def purchase(amount, payment_method, options = {}) MultiResponse.run() do |r| r.process { authorize(amount, payment_method, options) } - r.process { capture(r.authorization, options) } + r.process { capture(amount, r.authorization, options) } end end - def authorize(amount, payment_method, options={}) + def authorize(amount, payment_method, options = {}) params = {} add_invoice(params, amount, options) @@ -37,20 +37,20 @@ def authorize(amount, payment_method, options={}) commit('authorize', params, options) end - def capture(authorization, options={}) + def capture(amount, authorization, options = {}) params = {} options[:id_unico] = split_authorization(authorization)[1] add_auth_order_id(params, authorization, options) commit('deposit', params, options) end - def void(authorization, options={}) + def void(authorization, options = {}) params = {} add_auth_order_id(params, authorization, options) commit('void', params, options) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) params = {} params[:amount] = amount(amount) if amount add_auth_order_id(params, authorization, options) @@ -65,7 +65,7 @@ def refund(amount, authorization, options={}) commit('refund', params, options) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -85,7 +85,7 @@ def scrub(transcript) private - CURRENCY_CODES = Hash.new { |h, k| raise ArgumentError.new("Unsupported currency: #{k}") } + CURRENCY_CODES = Hash.new { |_h, k| raise ArgumentError.new("Unsupported currency: #{k}") } CURRENCY_CODES['USD'] = 840 CURRENCY_CODES['PEN'] = 604 @@ -98,7 +98,7 @@ def add_invoice(params, money, options) end def add_auth_order_id(params, authorization, options) - purchase_number, _ = split_authorization(authorization) + purchase_number, = split_authorization(authorization) params[:purchaseNumber] = purchase_number params[:externalTransactionId] = options[:order_id] end @@ -142,7 +142,7 @@ def split_authorization(authorization) authorization.split('|') end - def commit(action, params, options={}) + def commit(action, params, options = {}) raw_response = ssl_request(method(action), url(action, params, options), params.to_json, headers) response = parse(raw_response) rescue ResponseError => e @@ -155,9 +155,9 @@ def commit(action, params, options={}) success_from(response), message_from(response, options, action), response, - :test => test?, - :authorization => authorization_from(params, response, options), - :error_code => response['errorCode'] + test: test?, + authorization: authorization_from(params, response, options), + error_code: response['errorCode'] ) end @@ -168,7 +168,7 @@ def headers } end - def url(action, params, options={}) + def url(action, params, options = {}) if action == 'authorize' "#{base_url}/#{@options[:merchant_id]}" elsif action == 'refund' @@ -213,6 +213,7 @@ def message_from_messages(*args) def action_code_description(response) return nil unless response['data'] + response['data']['DSC_COD_ACCION'] end @@ -229,9 +230,9 @@ def response_error(raw_response, options, action) false, message_from(response, options, action), response, - :test => test?, - :authorization => response['transactionUUID'], - :error_code => response['errorCode'] + test: test?, + authorization: response['transactionUUID'], + error_code: response['errorCode'] ) end diff --git a/lib/active_merchant/billing/gateways/webpay.rb b/lib/active_merchant/billing/gateways/webpay.rb index 29636897892..492fa8fa5ac 100644 --- a/lib/active_merchant/billing/gateways/webpay.rb +++ b/lib/active_merchant/billing/gateways/webpay.rb @@ -8,7 +8,7 @@ class WebpayGateway < StripeGateway self.supported_countries = ['JP'] self.default_currency = 'JPY' self.money_format = :cents - self.supported_cardtypes = [:visa, :master, :american_express, :jcb, :diners_club] + self.supported_cardtypes = %i[visa master american_express jcb diners_club] self.homepage_url = 'https://webpay.jp/' self.display_name = 'WebPay' @@ -51,9 +51,9 @@ def store(creditcard, options = {}) MultiResponse.run(:first) do |r| r.process { commit(:post, "customers/#{CGI.escape(options[:customer])}/", post, options) } - return r unless options[:set_default] and r.success? and !r.params['id'].blank? + return r unless options[:set_default] && r.success? && !r.params['id'].blank? - r.process { update_customer(options[:customer], :default_card => r.params['id']) } + r.process { update_customer(options[:customer], default_card: r.params['id']) } end else commit(:post, 'customers', post, options) @@ -89,7 +89,7 @@ def headers(options = {}) 'Authorization' => 'Basic ' + Base64.encode64(@api_key.to_s + ':').strip, 'User-Agent' => "Webpay/v1 ActiveMerchantBindings/#{ActiveMerchant::VERSION}", 'X-Webpay-Client-User-Agent' => user_agent, - 'X-Webpay-Client-User-Metadata' => {:ip => options[:ip]}.to_json + 'X-Webpay-Client-User-Metadata' => { ip: options[:ip] }.to_json } end end diff --git a/lib/active_merchant/billing/gateways/wepay.rb b/lib/active_merchant/billing/gateways/wepay.rb index 9ec05da7f7f..10804147ec5 100644 --- a/lib/active_merchant/billing/gateways/wepay.rb +++ b/lib/active_merchant/billing/gateways/wepay.rb @@ -4,8 +4,8 @@ class WepayGateway < Gateway self.test_url = 'https://stage.wepayapi.com/v2' self.live_url = 'https://wepayapi.com/v2' - self.supported_countries = ['US', 'CA'] - self.supported_cardtypes = [:visa, :master, :american_express, :discover] + self.supported_countries = %w[US CA] + self.supported_cardtypes = %i[visa master american_express discover] self.homepage_url = 'https://www.wepay.com/' self.default_currency = 'USD' self.display_name = 'WePay' @@ -48,9 +48,7 @@ def capture(money, identifier, options = {}) post = {} post[:checkout_id] = checkout_id - if(money && (original_amount != amount(money))) - post[:amount] = amount(money) - end + post[:amount] = amount(money) if money && (original_amount != amount(money)) commit('/checkout/capture', post, options) end @@ -66,9 +64,7 @@ def refund(money, identifier, options = {}) post = {} post[:checkout_id] = checkout_id - if(money && (original_amount != amount(money))) - post[:amount] = amount(money) - end + post[:amount] = amount(money) if money && (original_amount != amount(money)) post[:refund_reason] = (options[:description] || 'Refund') post[:payer_email_message] = options[:payer_email_message] if options[:payer_email_message] post[:payee_email_message] = options[:payee_email_message] if options[:payee_email_message] @@ -85,12 +81,12 @@ def store(creditcard, options = {}) post[:expiration_month] = creditcard.month post[:expiration_year] = creditcard.year - if(billing_address = (options[:billing_address] || options[:address])) + if (billing_address = (options[:billing_address] || options[:address])) post[:address] = {} post[:address]['address1'] = billing_address[:address1] if billing_address[:address1] post[:address]['city'] = billing_address[:city] if billing_address[:city] post[:address]['country'] = billing_address[:country] if billing_address[:country] - post[:address]['region'] = billing_address[:state] if billing_address[:state] + post[:address]['region'] = billing_address[:state] if billing_address[:state] post[:address]['postal_code'] = billing_address[:zip] end @@ -172,13 +168,15 @@ def parse(response) JSON.parse(response) end - def commit(action, params, options={}) + def commit(action, params, options = {}) begin - response = parse(ssl_post( - ((test? ? test_url : live_url) + action), - params.to_json, - headers(options) - )) + response = parse( + ssl_post( + ((test? ? test_url : live_url) + action), + params.to_json, + headers(options) + ) + ) rescue ResponseError => e response = parse(e.response.body) end diff --git a/lib/active_merchant/billing/gateways/wirecard.rb b/lib/active_merchant/billing/gateways/wirecard.rb index 21218896b6a..699e37177b4 100644 --- a/lib/active_merchant/billing/gateways/wirecard.rb +++ b/lib/active_merchant/billing/gateways/wirecard.rb @@ -13,9 +13,9 @@ class WirecardGateway < Gateway 'xsi:noNamespaceSchemaLocation' => 'wirecard.xsd' } - PERMITTED_TRANSACTIONS = %w[ PREAUTHORIZATION CAPTURE PURCHASE ] + PERMITTED_TRANSACTIONS = %w[PREAUTHORIZATION CAPTURE PURCHASE] - RETURN_CODES = %w[ ACK NOK ] + RETURN_CODES = %w[ACK NOK] # Wirecard only allows phone numbers with a format like this: +xxx(yyy)zzz-zzzz-ppp, where: # xxx = Country code @@ -26,7 +26,7 @@ class WirecardGateway < Gateway # number 5551234 within area code 202 (country code 1). VALID_PHONE_FORMAT = /\+\d{1,3}(\(?\d{3}\)?)?\d{3}-\d{4}-\d{3}/ - self.supported_cardtypes = [ :visa, :master, :american_express, :diners_club, :jcb ] + self.supported_cardtypes = %i[visa master american_express diners_club jcb] self.supported_countries = %w(AD CY GI IM MT RO CH AT DK GR IT MC SM TR BE EE HU LV NL SK GB BG FI IS LI NO SI VA FR IL LT PL ES CZ DE IE LU PT SE) self.homepage_url = 'http://www.wirecard.com' self.display_name = 'Wirecard' @@ -180,11 +180,10 @@ def commit(action, money, options) authorization = response[:GuWID] Response.new(success, message, response, - :test => test?, - :authorization => authorization, - :avs_result => { :code => avs_code(response, options) }, - :cvv_result => response[:CVCResponseCode] - ) + test: test?, + authorization: authorization, + avs_result: { code: avs_code(response, options) }, + cvv_result: response[:CVCResponseCode]) rescue ResponseError => e if e.response.code == '401' return Response.new(false, 'Invalid Login') @@ -197,7 +196,7 @@ def commit(action, money, options) def build_request(action, money, options) options = prepare_options_hash(options) options[:action] = action - xml = Builder::XmlMarkup.new :indent => 2 + xml = Builder::XmlMarkup.new indent: 2 xml.instruct! xml.tag! 'WIRECARD_BXML' do xml.tag! 'W_REQUEST' do @@ -263,6 +262,7 @@ def add_amount(xml, money, options) # Includes the credit-card data to the transaction-xml def add_creditcard(xml, creditcard) raise 'Creditcard must be supplied!' if creditcard.nil? + xml.tag! 'CREDIT_CARD_DATA' do xml.tag! 'CreditCardNumber', creditcard.number xml.tag! 'CVC2', creditcard.verification_value @@ -275,6 +275,7 @@ def add_creditcard(xml, creditcard) # Includes the IP address of the customer to the transaction-xml def add_customer_data(xml, options) return unless options[:ip] + xml.tag! 'CONTACT_DATA' do xml.tag! 'IPAddress', options[:ip] end @@ -283,6 +284,7 @@ def add_customer_data(xml, options) # Includes the address to the transaction-xml def add_address(xml, address) return if address.nil? + xml.tag! 'CORPTRUSTCENTER_DATA' do xml.tag! 'ADDRESS' do xml.tag! 'Address1', address[:address1] @@ -290,9 +292,7 @@ def add_address(xml, address) xml.tag! 'City', address[:city] xml.tag! 'ZipCode', address[:zip] - if address[:state] =~ /[A-Za-z]{2}/ && address[:country] =~ /^(us|ca)$/i - xml.tag! 'State', address[:state].upcase - end + xml.tag! 'State', address[:state].upcase if address[:state] =~ /[A-Za-z]{2}/ && address[:country] =~ /^(us|ca)$/i xml.tag! 'Country', address[:country] xml.tag! 'Phone', address[:phone] if address[:phone] =~ VALID_PHONE_FORMAT @@ -331,9 +331,7 @@ def parse_response(response, root) status = nil root.elements.to_a.each do |node| - if node.name =~ /FNC_CC_/ - status = REXML::XPath.first(node, 'CC_TRANSACTION/PROCESSING_STATUS') - end + status = REXML::XPath.first(node, 'CC_TRANSACTION/PROCESSING_STATUS') if node.name =~ /FNC_CC_/ end message = '' @@ -392,7 +390,7 @@ def errors_to_string(root) string << error[:Message] if error[:Message] error[:Advice].each_with_index do |advice, index| string << ' (' if index == 0 - string << "#{index+1}. #{advice}" + string << "#{index + 1}. #{advice}" string << ' and ' if index < error[:Advice].size - 1 string << ')' if index == error[:Advice].size - 1 end diff --git a/lib/active_merchant/billing/gateways/world_net.rb b/lib/active_merchant/billing/gateways/world_net.rb index 70699b1a139..a0ad9df6fef 100644 --- a/lib/active_merchant/billing/gateways/world_net.rb +++ b/lib/active_merchant/billing/gateways/world_net.rb @@ -128,6 +128,7 @@ def add_customer_data(post, options) def add_address(post, _creditcard, options) address = options[:billing_address] || options[:address] return unless address + post[:address1] = address[:address1] post[:address2] = address[:address2] post[:city] = address[:city] @@ -278,49 +279,49 @@ def fields(action) # Gateway expects fields in fixed order below. case action when 'PAYMENT', 'PREAUTH' - [ - :orderid, - :terminalid, - :amount, - :datetime, - :cardnumber, :cardtype, :cardexpiry, :cardholdername, - :hash, - :currency, - :terminaltype, - :transactiontype, - :email, - :cvv, - :address1, :address2, - :postcode, - :description, - :city, :country, - :ipaddress + %i[ + orderid + terminalid + amount + datetime + cardnumber cardtype cardexpiry cardholdername + hash + currency + terminaltype + transactiontype + email + cvv + address1 address2 + postcode + description + city country + ipaddress ] when 'PREAUTHCOMPLETION' - [:uniqueref, :terminalid, :amount, :datetime, :hash] + %i[uniqueref terminalid amount datetime hash] when 'REFUND' - [:uniqueref, :terminalid, :amount, :datetime, :hash, - :operator, :reason] + %i[uniqueref terminalid amount datetime hash + operator reason] when 'VOID' [:uniqueref] when 'SECURECARDREGISTRATION' - [ - :merchantref, - :terminalid, - :datetime, - :cardnumber, :cardexpiry, :cardtype, :cardholdername, - :hash, - :dontchecksecurity, - :cvv, - :issueno + %i[ + merchantref + terminalid + datetime + cardnumber cardexpiry cardtype cardholdername + hash + dontchecksecurity + cvv + issueno ] when 'SECURECARDREMOVAL' - [ - :merchantref, - :cardreference, - :terminalid, - :datetime, - :hash + %i[ + merchantref + cardreference + terminalid + datetime + hash ] end end diff --git a/lib/active_merchant/billing/gateways/worldpay.rb b/lib/active_merchant/billing/gateways/worldpay.rb index a4546c4db0d..f5f37938045 100644 --- a/lib/active_merchant/billing/gateways/worldpay.rb +++ b/lib/active_merchant/billing/gateways/worldpay.rb @@ -9,7 +9,7 @@ class WorldpayGateway < Gateway self.default_currency = 'GBP' self.money_format = :cents self.supported_countries = %w(HK GB AU AD AR BE BR CA CH CN CO CR CY CZ DE DK ES FI FR GI GR HU IE IN IT JP LI LU MC MT MY MX NL NO NZ PA PE PL PT SE SG SI SM TR UM VA) - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :maestro, :elo, :naranja, :cabal] + self.supported_cardtypes = %i[visa master american_express discover jcb maestro elo naranja cabal unionpay] self.currencies_without_fractions = %w(HUF IDR ISK JPY KRW) self.currencies_with_three_decimal_places = %w(BHD KWD OMR RSD TND) self.homepage_url = 'http://www.worldpay.com/' @@ -26,6 +26,7 @@ class WorldpayGateway < Gateway 'elo' => 'ELO-SSL', 'naranja' => 'NARANJA-SSL', 'cabal' => 'CABAL-SSL', + 'unionpay' => 'CHINAUNIONPAY-SSL', 'unknown' => 'CARD-SSL' } @@ -57,7 +58,7 @@ def initialize(options = {}) def purchase(money, payment_method, options = {}) MultiResponse.run do |r| r.process { authorize(money, payment_method, options) } - r.process { capture(money, r.authorization, options.merge(:authorization_validated => true)) } + r.process { capture(money, r.authorization, options.merge(authorization_validated: true)) } unless options[:skip_capture] end end @@ -73,7 +74,7 @@ def capture(money, authorization, options = {}) r.process { inquire_request(authorization, options, 'AUTHORISED') } unless options[:authorization_validated] if r.params authorization_currency = r.params['amount_currency_code'] - options = options.merge(:currency => authorization_currency) if authorization_currency.present? + options = options.merge(currency: authorization_currency) if authorization_currency.present? end r.process { capture_request(money, authorization, options) } end @@ -94,10 +95,12 @@ def refund(money, authorization, options = {}) r.process { refund_request(money, authorization, options) } end - return response if response.success? - return response unless options[:force_full_refund_if_unsettled] - - void(authorization, options) if response.params['last_event'] == 'AUTHORISED' + if !response.success? && options[:force_full_refund_if_unsettled] && + response.params['last_event'] == 'AUTHORISED' + void(authorization, options) + else + response + end end # Credits only function on a Merchant ID/login/profile flagged for Payouts @@ -106,17 +109,17 @@ def refund(money, authorization, options = {}) # merchant ID. def credit(money, payment_method, options = {}) payment_details = payment_details_from(payment_method) - credit_request(money, payment_method, payment_details.merge(:credit => true, **options)) + credit_request(money, payment_method, payment_details.merge(credit: true, **options)) end - def verify(payment_method, options={}) + def verify(payment_method, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, payment_method, options) } - r.process(:ignore_result) { void(r.authorization, options.merge(:authorization_validated => true)) } + r.process(:ignore_result) { void(r.authorization, options.merge(authorization_validated: true)) } end end - def store(credit_card, options={}) + def store(credit_card, options = {}) requires!(options, :customer) store_request(credit_card, options) end @@ -163,10 +166,10 @@ def store_request(credit_card, options) end def build_request - xml = Builder::XmlMarkup.new :indent => 2 - xml.instruct! :xml, :encoding => 'UTF-8' + xml = Builder::XmlMarkup.new indent: 2 + xml.instruct! :xml, encoding: 'UTF-8' xml.declare! :DOCTYPE, :paymentService, :PUBLIC, '-//WorldPay//DTD WorldPay PaymentService v1//EN', 'http://dtd.worldpay.com/paymentService_v1.dtd' - xml.tag! 'paymentService', 'version' => '1.4', 'merchantCode' => @options[:login] do + xml.paymentService 'version' => '1.4', 'merchantCode' => @options[:login] do yield xml end xml.target! @@ -174,8 +177,8 @@ def build_request def build_order_modify_request(authorization) build_request do |xml| - xml.tag! 'modify' do - xml.tag! 'orderModification', 'orderCode' => authorization do + xml.modify do + xml.orderModification 'orderCode' => authorization do yield xml end end @@ -184,31 +187,29 @@ def build_order_modify_request(authorization) def build_order_inquiry_request(authorization, options) build_request do |xml| - xml.tag! 'inquiry' do - xml.tag! 'orderInquiry', 'orderCode' => authorization + xml.inquiry do + xml.orderInquiry 'orderCode' => authorization end end end def build_authorization_request(money, payment_method, options) build_request do |xml| - xml.tag! 'submit' do - xml.tag! 'order', order_tag_attributes(options) do + xml.submit do + xml.order order_tag_attributes(options) do xml.description(options[:description].blank? ? 'Purchase' : options[:description]) add_amount(xml, money, options) if options[:order_content] - xml.tag! 'orderContent' do + xml.orderContent do xml.cdata! options[:order_content] end end add_payment_method(xml, money, payment_method, options) add_shopper(xml, options) - if options[:hcg_additional_data] - add_hcg_additional_data(xml, options) - end - if options[:instalments] - add_instalments_data(xml, options) - end + add_statement_narrative(xml, options) + add_risk_data(xml, options[:risk_data]) if options[:risk_data] + add_hcg_additional_data(xml, options) if options[:hcg_additional_data] + add_instalments_data(xml, options) if options[:instalments] add_moto_flag(xml, options) if options.dig(:metadata, :manual_entry) add_additional_3ds_data(xml, options) if options[:execute_threed] && options[:three_ds_version] && options[:three_ds_version] =~ /^2/ add_3ds_exemption(xml, options) if options[:exemption_type] @@ -218,41 +219,39 @@ def build_authorization_request(money, payment_method, options) end def order_tag_attributes(options) - { 'orderCode' => options[:order_id], 'installationId' => options[:inst_id] || @options[:inst_id] }.reject { |_, v| !v } + { 'orderCode' => options[:order_id], 'installationId' => options[:inst_id] || @options[:inst_id] }.reject { |_, v| !v.present? } end def build_capture_request(money, authorization, options) build_order_modify_request(authorization) do |xml| - xml.tag! 'capture' do + xml.capture do time = Time.now - xml.tag! 'date', 'dayOfMonth' => time.day, 'month' => time.month, 'year'=> time.year + xml.date 'dayOfMonth' => time.day, 'month' => time.month, 'year' => time.year add_amount(xml, money, options) end end end def build_void_request(authorization, options) - build_order_modify_request(authorization) do |xml| - xml.tag! 'cancel' - end + build_order_modify_request(authorization, &:cancel) end def build_refund_request(money, authorization, options) build_order_modify_request(authorization) do |xml| - xml.tag! 'refund' do - add_amount(xml, money, options.merge(:debit_credit_indicator => 'credit')) + xml.refund do + add_amount(xml, money, options.merge(debit_credit_indicator: 'credit')) end end end def build_store_request(credit_card, options) build_request do |xml| - xml.tag! 'submit' do - xml.tag! 'paymentTokenCreate' do + xml.submit do + xml.paymentTokenCreate do add_authenticated_shopper_id(xml, options) - xml.tag! 'createToken' - xml.tag! 'paymentInstrument' do - xml.tag! 'cardDetails' do + xml.createToken + xml.paymentInstrument do + xml.cardDetails do add_card(xml, credit_card, options) end end @@ -262,11 +261,100 @@ def build_store_request(credit_card, options) end def add_additional_3ds_data(xml, options) - xml.tag! 'additional3DSData', 'dfReferenceId' => options[:session_id] + additional_data = { 'dfReferenceId' => options[:session_id] } + additional_data['challengeWindowSize'] = options[:browser_size] if options[:browser_size] + + xml.additional3DSData additional_data end def add_3ds_exemption(xml, options) - xml.tag! 'exemption', 'type' => options[:exemption_type], 'placement' => options[:exemption_placement] || 'AUTHORISATION' + xml.exemption 'type' => options[:exemption_type], 'placement' => options[:exemption_placement] || 'AUTHORISATION' + end + + def add_risk_data(xml, risk_data) + xml.riskData do + add_authentication_risk_data(xml, risk_data[:authentication_risk_data]) + add_shopper_account_risk_data(xml, risk_data[:shopper_account_risk_data]) + add_transaction_risk_data(xml, risk_data[:transaction_risk_data]) + end + end + + def add_authentication_risk_data(xml, authentication_risk_data) + return unless authentication_risk_data + + timestamp = authentication_risk_data.fetch(:authentication_date, {}) + + xml.authenticationRiskData('authenticationMethod' => authentication_risk_data[:authentication_method]) do + xml.authenticationTimestamp do + xml.date( + 'dayOfMonth' => timestamp[:day_of_month], + 'month' => timestamp[:month], + 'year' => timestamp[:year], + 'hour' => timestamp[:hour], + 'minute' => timestamp[:minute], + 'second' => timestamp[:second] + ) + end + end + end + + def add_shopper_account_risk_data(xml, shopper_account_risk_data) + return unless shopper_account_risk_data + + data = { + 'transactionsAttemptedLastDay' => shopper_account_risk_data[:transactions_attempted_last_day], + 'transactionsAttemptedLastYear' => shopper_account_risk_data[:transactions_attempted_last_year], + 'purchasesCompletedLastSixMonths' => shopper_account_risk_data[:purchases_completed_last_six_months], + 'addCardAttemptsLastDay' => shopper_account_risk_data[:add_card_attempts_last_day], + 'previousSuspiciousActivity' => shopper_account_risk_data[:previous_suspicious_activity], + 'shippingNameMatchesAccountName' => shopper_account_risk_data[:shipping_name_matches_account_name], + 'shopperAccountAgeIndicator' => shopper_account_risk_data[:shopper_account_age_indicator], + 'shopperAccountChangeIndicator' => shopper_account_risk_data[:shopper_account_change_indicator], + 'shopperAccountPasswordChangeIndicator' => shopper_account_risk_data[:shopper_account_password_change_indicator], + 'shopperAccountShippingAddressUsageIndicator' => shopper_account_risk_data[:shopper_account_shipping_address_usage_indicator], + 'shopperAccountPaymentAccountIndicator' => shopper_account_risk_data[:shopper_account_payment_account_indicator] + }.reject { |_k, v| v.nil? } + + xml.shopperAccountRiskData(data) do + add_date_element(xml, 'shopperAccountCreationDate', shopper_account_risk_data[:shopper_account_creation_date]) + add_date_element(xml, 'shopperAccountModificationDate', shopper_account_risk_data[:shopper_account_modification_date]) + add_date_element(xml, 'shopperAccountPasswordChangeDate', shopper_account_risk_data[:shopper_account_password_change_date]) + add_date_element(xml, 'shopperAccountShippingAddressFirstUseDate', shopper_account_risk_data[:shopper_account_shipping_address_first_use_date]) + add_date_element(xml, 'shopperAccountPaymentAccountFirstUseDate', shopper_account_risk_data[:shopper_account_payment_account_first_use_date]) + end + end + + def add_transaction_risk_data(xml, transaction_risk_data) + return unless transaction_risk_data + + data = { + 'shippingMethod' => transaction_risk_data[:shipping_method], + 'deliveryTimeframe' => transaction_risk_data[:delivery_timeframe], + 'deliveryEmailAddress' => transaction_risk_data[:delivery_email_address], + 'reorderingPreviousPurchases' => transaction_risk_data[:reordering_previous_purchases], + 'preOrderPurchase' => transaction_risk_data[:pre_order_purchase], + 'giftCardCount' => transaction_risk_data[:gift_card_count] + }.reject { |_k, v| v.nil? } + + xml.transactionRiskData(data) do + xml.transactionRiskDataGiftCardAmount do + amount_hash = { + 'value' => transaction_risk_data.dig(:transaction_risk_data_gift_card_amount, :value), + 'currencyCode' => transaction_risk_data.dig(:transaction_risk_data_gift_card_amount, :currency), + 'exponent' => transaction_risk_data.dig(:transaction_risk_data_gift_card_amount, :exponent) + } + debit_credit_indicator = transaction_risk_data.dig(:transaction_risk_data_gift_card_amount, :debit_credit_indicator) + amount_hash['debitCreditIndicator'] = debit_credit_indicator if debit_credit_indicator + xml.amount(amount_hash) + end + add_date_element(xml, 'transactionRiskDataPreOrderDate', transaction_risk_data[:transaction_risk_data_pre_order_date]) + end + end + + def add_date_element(xml, name, date) + xml.tag! name do + xml.date('dayOfMonth' => date[:day_of_month], 'month' => date[:month], 'year' => date[:year]) + end end def add_amount(xml, money, options) @@ -278,29 +366,27 @@ def add_amount(xml, money, options) 'exponent' => currency_exponent(currency) } - if options[:debit_credit_indicator] - amount_hash['debitCreditIndicator'] = options[:debit_credit_indicator] - end + amount_hash['debitCreditIndicator'] = options[:debit_credit_indicator] if options[:debit_credit_indicator] - xml.tag! 'amount', amount_hash + xml.amount amount_hash end def add_payment_method(xml, amount, payment_method, options) if options[:payment_type] == :pay_as_order if options[:merchant_code] - xml.tag! 'payAsOrder', 'orderCode' => payment_method, 'merchantCode' => options[:merchant_code] do + xml.payAsOrder 'orderCode' => payment_method, 'merchantCode' => options[:merchant_code] do add_amount(xml, amount, options) end else - xml.tag! 'payAsOrder', 'orderCode' => payment_method do + xml.payAsOrder 'orderCode' => payment_method do add_amount(xml, amount, options) end end else - xml.tag! 'paymentDetails', credit_fund_transfer_attribute(options) do + xml.paymentDetails credit_fund_transfer_attribute(options) do if options[:payment_type] == :token xml.tag! 'TOKEN-SSL', 'tokenScope' => options[:token_scope] do - xml.tag! 'paymentTokenID', options[:token_id] + xml.paymentTokenID options[:token_id] end else xml.tag! card_code_for(payment_method) do @@ -309,10 +395,10 @@ def add_payment_method(xml, amount, payment_method, options) end add_stored_credential_options(xml, options) if options[:ip] && options[:session_id] - xml.tag! 'session', 'shopperIPAddress' => options[:ip], 'id' => options[:session_id] + xml.session 'shopperIPAddress' => options[:ip], 'id' => options[:session_id] else - xml.tag! 'session', 'shopperIPAddress' => options[:ip] if options[:ip] - xml.tag! 'session', 'id' => options[:session_id] if options[:session_id] + xml.session 'shopperIPAddress' => options[:ip] if options[:ip] + xml.session 'id' => options[:session_id] if options[:session_id] end if three_d_secure = options[:three_d_secure] @@ -323,31 +409,35 @@ def add_payment_method(xml, amount, payment_method, options) end def add_three_d_secure(three_d_secure, xml) - xml.tag! 'info3DSecure' do - xml.tag! 'threeDSVersion', three_d_secure[:version] - if three_d_secure[:version] =~ /^2/ - xml.tag! 'dsTransactionId', three_d_secure[:ds_transaction_id] + xml.info3DSecure do + xml.threeDSVersion three_d_secure[:version] + if /^2/.match?(three_d_secure[:version]) + xml.dsTransactionId three_d_secure[:ds_transaction_id] else - xml.tag! 'xid', three_d_secure[:xid] + xml.xid three_d_secure[:xid] end - xml.tag! 'cavv', three_d_secure[:cavv] - xml.tag! 'eci', three_d_secure[:eci] + xml.cavv three_d_secure[:cavv] + xml.eci three_d_secure[:eci] end end def add_card(xml, payment_method, options) - xml.tag! 'cardNumber', payment_method.number - xml.tag! 'expiryDate' do - xml.tag! 'date', 'month' => format(payment_method.month, :two_digits), 'year' => format(payment_method.year, :four_digits) + xml.cardNumber payment_method.number + xml.expiryDate do + xml.date( + 'month' => format(payment_method.month, :two_digits), + 'year' => format(payment_method.year, :four_digits) + ) end - xml.tag! 'cardHolderName', options[:execute_threed] && (options[:three_ds_version] =~ /[^2]/).nil? ? '3D' : payment_method.name - xml.tag! 'cvc', payment_method.verification_value + card_holder_name = options[:execute_threed] && !options[:three_ds_version]&.start_with?('2') ? '3D' : payment_method.name + xml.cardHolderName card_holder_name + xml.cvc payment_method.verification_value - add_address(xml, (options[:billing_address] || options[:address])) + add_address(xml, (options[:billing_address] || options[:address]), options) end - def add_stored_credential_options(xml, options={}) + def add_stored_credential_options(xml, options = {}) if options[:stored_credential] add_stored_credential_using_normalized_fields(xml, options) else @@ -357,7 +447,7 @@ def add_stored_credential_options(xml, options={}) def add_stored_credential_using_normalized_fields(xml, options) if options[:stored_credential][:initial_transaction] - xml.tag! 'storedCredentials', 'usage' => 'FIRST' + xml.storedCredentials 'usage' => 'FIRST' else reason = case options[:stored_credential][:reason_type] when 'installment' then 'INSTALMENT' @@ -365,8 +455,8 @@ def add_stored_credential_using_normalized_fields(xml, options) when 'unscheduled' then 'UNSCHEDULED' end - xml.tag! 'storedCredentials', 'usage' => 'USED', 'merchantInitiatedReason' => reason do - xml.tag! 'schemeTransactionIdentifier', options[:stored_credential][:network_transaction_id] if options[:stored_credential][:network_transaction_id] + xml.storedCredentials 'usage' => 'USED', 'merchantInitiatedReason' => reason do + xml.schemeTransactionIdentifier options[:stored_credential][:network_transaction_id] if options[:stored_credential][:network_transaction_id] end end end @@ -375,69 +465,74 @@ def add_stored_credential_using_gateway_specific_fields(xml, options) return unless options[:stored_credential_usage] if options[:stored_credential_initiated_reason] - xml.tag! 'storedCredentials', 'usage' => options[:stored_credential_usage], 'merchantInitiatedReason' => options[:stored_credential_initiated_reason] do - xml.tag! 'schemeTransactionIdentifier', options[:stored_credential_transaction_id] if options[:stored_credential_transaction_id] + xml.storedCredentials 'usage' => options[:stored_credential_usage], 'merchantInitiatedReason' => options[:stored_credential_initiated_reason] do + xml.schemeTransactionIdentifier options[:stored_credential_transaction_id] if options[:stored_credential_transaction_id] end else - xml.tag! 'storedCredentials', 'usage' => options[:stored_credential_usage] + xml.storedCredentials 'usage' => options[:stored_credential_usage] end end def add_shopper(xml, options) return unless options[:execute_threed] || options[:email] || options[:customer] - xml.tag! 'shopper' do - xml.tag! 'shopperEmailAddress', options[:email] if options[:email] + + xml.shopper do + xml.shopperEmailAddress options[:email] if options[:email] add_authenticated_shopper_id(xml, options) - xml.tag! 'browser' do - xml.tag! 'acceptHeader', options[:accept_header] - xml.tag! 'userAgentHeader', options[:user_agent] + xml.browser do + xml.acceptHeader options[:accept_header] + xml.userAgentHeader options[:user_agent] end end end + def add_statement_narrative(xml, options) + xml.statementNarrative truncate(options[:statement_narrative], 50) if options[:statement_narrative] + end + def add_authenticated_shopper_id(xml, options) - xml.tag!('authenticatedShopperID', options[:customer]) if options[:customer] + xml.authenticatedShopperID options[:customer] if options[:customer] end - def add_address(xml, address) + def add_address(xml, address, options) return unless address address = address_with_defaults(address) - xml.tag! 'cardAddress' do - xml.tag! 'address' do + xml.cardAddress do + xml.address do if m = /^\s*([^\s]+)\s+(.+)$/.match(address[:name]) - xml.tag! 'firstName', m[1] - xml.tag! 'lastName', m[2] + xml.firstName m[1] + xml.lastName m[2] end - xml.tag! 'address1', address[:address1] - xml.tag! 'address2', address[:address2] if address[:address2] - xml.tag! 'postalCode', address[:zip] - xml.tag! 'city', address[:city] - xml.tag! 'state', address[:state] - xml.tag! 'countryCode', address[:country] - xml.tag! 'telephoneNumber', address[:phone] if address[:phone] + xml.address1 address[:address1] + xml.address2 address[:address2] if address[:address2] + xml.postalCode address[:zip] + xml.city address[:city] + xml.state address[:state] unless address[:country] != 'US' && options[:execute_threed] + xml.countryCode address[:country] + xml.telephoneNumber address[:phone] if address[:phone] end end end def add_hcg_additional_data(xml, options) - xml.tag! 'hcgAdditionalData' do + xml.hcgAdditionalData do options[:hcg_additional_data].each do |k, v| - xml.tag! 'param', {name: k.to_s}, v + xml.param({ name: k.to_s }, v) end end end def add_instalments_data(xml, options) - xml.tag! 'thirdPartyData' do - xml.tag! 'instalments', options[:instalments] - xml.tag! 'cpf', options[:cpf] if options[:cpf] + xml.thirdPartyData do + xml.instalments options[:instalments] + xml.cpf options[:cpf] if options[:cpf] end end def add_moto_flag(xml, options) - xml.tag! 'dynamicInteractionType', 'type' => 'MOTO' + xml.dynamicInteractionType 'type' => 'MOTO' end def address_with_defaults(address) @@ -448,11 +543,10 @@ def address_with_defaults(address) def default_address { - address1: 'N/A', zip: '0000', + country: 'US', city: 'N/A', - state: 'N/A', - country: 'US' + address1: 'N/A' } end @@ -460,7 +554,7 @@ def parse(action, xml) xml = xml.strip.gsub(/\&/, '&') doc = Nokogiri::XML(xml, &:strict) doc.remove_namespaces! - resp_params = {:action => action} + resp_params = { action: action } parse_elements(doc.root, resp_params) resp_params @@ -482,6 +576,8 @@ def parse_elements(node, response) end def headers(options) + idempotency_key = options[:idempotency_key] + headers = { 'Content-Type' => 'text/xml', 'Authorization' => encoded_credentials @@ -489,6 +585,8 @@ def headers(options) if options[:cookie] headers['Cookie'] = options[:cookie] if options[:cookie] end + + headers['Idempotency-Key'] = idempotency_key if idempotency_key headers end @@ -496,7 +594,7 @@ def commit(action, request, *success_criteria, options) xml = ssl_post(url, request, headers(options)) raw = parse(action, xml) if options[:execute_threed] - raw[:cookie] = @cookie + raw[:cookie] = @cookie if defined?(@cookie) raw[:session_id] = options[:session_id] raw[:is3DSOrder] = true end @@ -507,17 +605,17 @@ def commit(action, request, *success_criteria, options) success, message, raw, - :authorization => authorization_from(action, raw, options), - :error_code => error_code_from(success, raw), - :test => test?, - :avs_result => AVSResult.new(code: AVS_CODE_MAP[raw[:avs_result_code_description]]), - :cvv_result => CVVResult.new(CVC_CODE_MAP[raw[:cvc_result_code_description]]) + authorization: authorization_from(action, raw, options), + error_code: error_code_from(success, raw), + test: test?, + avs_result: AVSResult.new(code: AVS_CODE_MAP[raw[:avs_result_code_description]]), + cvv_result: CVVResult.new(CVC_CODE_MAP[raw[:cvc_result_code_description]]) ) rescue Nokogiri::SyntaxError unparsable_response(xml) rescue ActiveMerchant::ResponseError => e if e.response.code.to_s == '401' - return Response.new(false, 'Invalid credentials', {}, :test => test?) + return Response.new(false, 'Invalid credentials', {}, test: test?) else raise e end @@ -551,6 +649,7 @@ def success_from(action, raw, success_criteria) def message_from(success, raw, success_criteria) return 'SUCCESS' if success + raw[:iso8583_return_code_description] || raw[:error] || required_status_message(raw, success_criteria) end @@ -572,15 +671,11 @@ def action_success?(action, raw) end def error_code_from(success, raw) - unless success == 'SUCCESS' - raw[:iso8583_return_code_code] || raw[:error_code] || nil - end + raw[:iso8583_return_code_code] || raw[:error_code] || nil unless success == 'SUCCESS' end def required_status_message(raw, success_criteria) - if(!success_criteria.include?(raw[:last_event])) - "A transaction status of #{success_criteria.collect { |c| "'#{c}'" }.join(" or ")} is required." - end + "A transaction status of #{success_criteria.collect { |c| "'#{c}'" }.join(' or ')} is required." if !success_criteria.include?(raw[:last_event]) end def authorization_from(action, raw, options) @@ -600,11 +695,11 @@ def authorization_from(action, raw, options) end def order_id_from(raw) - pair = raw.detect { |k, v| k.to_s =~ /_order_code$/ } + pair = raw.detect { |k, _v| k.to_s =~ /_order_code$/ } (pair ? pair.last : nil) end - def authorization_from_token_details(options={}) + def authorization_from_token_details(options = {}) [options[:order_id], options[:token_id], options[:token_scope], options[:customer]].join('|') end @@ -643,7 +738,8 @@ def payment_details_from(payment_method) def credit_fund_transfer_attribute(options) return unless options[:credit] - {'action' => 'REFUND'} + + { 'action' => 'REFUND' } end def encoded_credentials @@ -654,6 +750,7 @@ def encoded_credentials def currency_exponent(currency) return 0 if non_fractional_currency?(currency) return 3 if three_decimal_currency?(currency) + return 2 end diff --git a/lib/active_merchant/billing/gateways/worldpay_online_payments.rb b/lib/active_merchant/billing/gateways/worldpay_online_payments.rb index d3a03ffbeec..2481dce0805 100644 --- a/lib/active_merchant/billing/gateways/worldpay_online_payments.rb +++ b/lib/active_merchant/billing/gateways/worldpay_online_payments.rb @@ -1,27 +1,27 @@ module ActiveMerchant #:nodoc: module Billing #:nodoc: class WorldpayOnlinePaymentsGateway < Gateway - self.live_url = 'https://api.worldpay.com/v1/' + self.live_url = 'https://api.worldpay.com/v1/' self.default_currency = 'GBP' self.money_format = :cents self.supported_countries = %w(HK US GB BE CH CZ DE DK ES FI FR GR HU IE IT LU MT NL NO PL PT SE SG TR) - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :maestro] + self.supported_cardtypes = %i[visa master american_express discover jcb maestro] self.homepage_url = 'http://online.worldpay.com' self.display_name = 'Worldpay Online Payments' - def initialize(options={}) + def initialize(options = {}) requires!(options, :client_key, :service_key) @client_key = options[:client_key] @service_key = options[:service_key] super end - def authorize(money, credit_card, options={}) - response = create_token(true, credit_card.first_name+' '+credit_card.last_name, credit_card.month, credit_card.year, credit_card.number, credit_card.verification_value) + def authorize(money, credit_card, options = {}) + response = create_token(true, credit_card.first_name + ' ' + credit_card.last_name, credit_card.month, credit_card.year, credit_card.number, credit_card.verification_value) if response.success? options[:authorizeOnly] = true post = create_post_for_auth_or_purchase(response.authorization, money, options) @@ -30,24 +30,23 @@ def authorize(money, credit_card, options={}) response end - def capture(money, authorization, options={}) + def capture(money, authorization, options = {}) if authorization - commit(:post, "orders/#{CGI.escape(authorization)}/capture", {'captureAmount'=>money}, options, 'capture') + commit(:post, "orders/#{CGI.escape(authorization)}/capture", { 'captureAmount' => money }, options, 'capture') else Response.new(false, 'FAILED', 'FAILED', - :test => test?, - :authorization => false, - :avs_result => {}, - :cvv_result => {}, - :error_code => false - ) + test: test?, + authorization: false, + avs_result: {}, + cvv_result: {}, + error_code: false) end end - def purchase(money, credit_card, options={}) - response = create_token(true, credit_card.first_name+' '+credit_card.last_name, credit_card.month, credit_card.year, credit_card.number, credit_card.verification_value) + def purchase(money, credit_card, options = {}) + response = create_token(true, credit_card.first_name + ' ' + credit_card.last_name, credit_card.month, credit_card.year, credit_card.number, credit_card.verification_value) if response.success? post = create_post_for_auth_or_purchase(response.authorization, money, options) response = commit(:post, 'orders', post, options, 'purchase') @@ -55,20 +54,18 @@ def purchase(money, credit_card, options={}) response end - def refund(money, orderCode, options={}) - obj = money ? {'refundAmount' => money} : {} + def refund(money, orderCode, options = {}) + obj = money ? { 'refundAmount' => money } : {} commit(:post, "orders/#{CGI.escape(orderCode)}/refund", obj, options, 'refund') end - def void(orderCode, options={}) + def void(orderCode, options = {}) response = commit(:delete, "orders/#{CGI.escape(orderCode)}", nil, options, 'void') - if !response.success? && (response.params && response.params['customCode'] != 'ORDER_NOT_FOUND') - response = refund(nil, orderCode) - end + response = refund(nil, orderCode) if !response.success? && (response.params && response.params['customCode'] != 'ORDER_NOT_FOUND') response end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) authorize(0, credit_card, options) end @@ -76,18 +73,18 @@ def verify(credit_card, options={}) def create_token(reusable, name, exp_month, exp_year, number, cvc) obj = { - 'reusable'=> reusable, - 'paymentMethod'=> { - 'type'=> 'Card', - 'name'=> name, - 'expiryMonth'=> exp_month, - 'expiryYear'=> exp_year, - 'cardNumber'=> number, - 'cvc'=> cvc + 'reusable' => reusable, + 'paymentMethod' => { + 'type' => 'Card', + 'name' => name, + 'expiryMonth' => exp_month, + 'expiryYear' => exp_year, + 'cardNumber' => number, + 'cvc' => cvc }, - 'clientKey'=> @client_key + 'clientKey' => @client_key } - token_response = commit(:post, 'tokens', obj, {'Authorization' => @service_key}, 'token') + token_response = commit(:post, 'tokens', obj, { 'Authorization' => @service_key }, 'token') token_response end @@ -97,16 +94,16 @@ def create_post_for_auth_or_purchase(token, money, options) 'orderDescription' => options[:description] || 'Worldpay Order', 'amount' => money, 'currencyCode' => options[:currency] || default_currency, - 'name' => options[:billing_address]&&options[:billing_address][:name] ? options[:billing_address][:name] : '', + 'name' => options[:billing_address] && options[:billing_address][:name] ? options[:billing_address][:name] : '', 'billingAddress' => { - 'address1'=>options[:billing_address]&&options[:billing_address][:address1] ? options[:billing_address][:address1] : '', - 'address2'=>options[:billing_address]&&options[:billing_address][:address2] ? options[:billing_address][:address2] : '', - 'address3'=>'', - 'postalCode'=>options[:billing_address]&&options[:billing_address][:zip] ? options[:billing_address][:zip] : '', - 'city'=>options[:billing_address]&&options[:billing_address][:city] ? options[:billing_address][:city] : '', - 'state'=>options[:billing_address]&&options[:billing_address][:state] ? options[:billing_address][:state] : '', - 'countryCode'=>options[:billing_address]&&options[:billing_address][:country] ? options[:billing_address][:country] : '' - }, + 'address1' => options[:billing_address] && options[:billing_address][:address1] ? options[:billing_address][:address1] : '', + 'address2' => options[:billing_address] && options[:billing_address][:address2] ? options[:billing_address][:address2] : '', + 'address3' => '', + 'postalCode' => options[:billing_address] && options[:billing_address][:zip] ? options[:billing_address][:zip] : '', + 'city' => options[:billing_address] && options[:billing_address][:city] ? options[:billing_address][:city] : '', + 'state' => options[:billing_address] && options[:billing_address][:state] ? options[:billing_address][:state] : '', + 'countryCode' => options[:billing_address] && options[:billing_address][:country] ? options[:billing_address][:country] : '' + }, 'customerOrderCode' => options[:order_id], 'orderType' => 'ECOM', 'authorizeOnly' => options[:authorizeOnly] ? true : false @@ -123,15 +120,13 @@ def headers(options = {}) 'Content-Type' => 'application/json', 'User-Agent' => "Worldpay/v1 ActiveMerchantBindings/#{ActiveMerchant::VERSION}", 'X-Worldpay-Client-User-Agent' => user_agent, - 'X-Worldpay-Client-User-Metadata' => {:ip => options[:ip]}.to_json + 'X-Worldpay-Client-User-Metadata' => { ip: options[:ip] }.to_json } - if options['Authorization'] - headers['Authorization'] = options['Authorization'] - end + headers['Authorization'] = options['Authorization'] if options['Authorization'] headers end - def commit(method, url, parameters=nil, options = {}, type = false) + def commit(method, url, parameters = nil, options = {}, type = false) raw_response = response = nil success = false begin @@ -151,7 +146,7 @@ def commit(method, url, parameters=nil, options = {}, type = false) success = true elsif type == 'purchase' && response['paymentStatus'] == 'SUCCESS' success = true - elsif type == 'capture' || type=='refund' || type=='void' + elsif type == 'capture' || type == 'refund' || type == 'void' success = true end end @@ -178,12 +173,11 @@ def commit(method, url, parameters=nil, options = {}, type = false) Response.new(success, success ? 'SUCCESS' : response['message'], response, - :test => test?, - :authorization => authorization, - :avs_result => {}, - :cvv_result => {}, - :error_code => success ? nil : response['customCode'] - ) + test: test?, + authorization: authorization, + avs_result: {}, + cvv_result: {}, + error_code: success ? nil : response['customCode']) end def test? @@ -209,7 +203,6 @@ def json_error(raw_response) def handle_response(response) response.body end - end end end diff --git a/lib/active_merchant/billing/gateways/worldpay_us.rb b/lib/active_merchant/billing/gateways/worldpay_us.rb index 303b5b1767e..d0b7844d214 100644 --- a/lib/active_merchant/billing/gateways/worldpay_us.rb +++ b/lib/active_merchant/billing/gateways/worldpay_us.rb @@ -15,14 +15,14 @@ class WorldpayUsGateway < Gateway self.supported_countries = ['US'] self.default_currency = 'USD' self.money_format = :dollars - self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb] + self.supported_cardtypes = %i[visa master american_express discover jcb] - def initialize(options={}) + def initialize(options = {}) requires!(options, :acctid, :subid, :merchantpin) super end - def purchase(money, payment_method, options={}) + def purchase(money, payment_method, options = {}) post = {} add_invoice(post, money, options) add_payment_method(post, payment_method) @@ -31,7 +31,7 @@ def purchase(money, payment_method, options={}) commit('purchase', options, post) end - def authorize(money, payment, options={}) + def authorize(money, payment, options = {}) post = {} add_invoice(post, money, options) add_credit_card(post, payment) @@ -40,7 +40,7 @@ def authorize(money, payment, options={}) commit('authorize', options, post) end - def capture(amount, authorization, options={}) + def capture(amount, authorization, options = {}) post = {} add_invoice(post, amount, options) add_reference(post, authorization) @@ -49,7 +49,7 @@ def capture(amount, authorization, options={}) commit('capture', options, post) end - def refund(amount, authorization, options={}) + def refund(amount, authorization, options = {}) post = {} add_invoice(post, amount, options) add_reference(post, authorization) @@ -58,14 +58,14 @@ def refund(amount, authorization, options={}) commit('refund', options, post) end - def void(authorization, options={}) + def void(authorization, options = {}) post = {} add_reference(post, authorization) commit('void', options, post) end - def verify(credit_card, options={}) + def verify(credit_card, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, credit_card, options) } r.process(:ignore_result) { void(r.authorization, options) } @@ -91,7 +91,7 @@ def url(options) end def add_customer_data(post, options) - if(billing_address = (options[:billing_address] || options[:address])) + if (billing_address = (options[:billing_address] || options[:address])) post[:ci_companyname] = billing_address[:company] post[:ci_billaddr1] = billing_address[:address1] post[:ci_billaddr2] = billing_address[:address2] @@ -105,13 +105,13 @@ def add_customer_data(post, options) post[:ci_ipaddress] = billing_address[:ip] end - if(shipping_address = options[:shipping_address]) + if (shipping_address = options[:shipping_address]) post[:ci_shipaddr1] = shipping_address[:address1] post[:ci_shipaddr2] = shipping_address[:address2] post[:ci_shipcity] = shipping_address[:city] post[:ci_shipstate] = shipping_address[:state] - post[:ci_shipzip] = shipping_address[:zip] - post[:ci_shipcountry] = shipping_address[:country] + post[:ci_shipzip] = shipping_address[:zip] + post[:ci_shipcountry] = shipping_address[:country] end end @@ -139,7 +139,7 @@ def add_credit_card(post, payment_method) ACCOUNT_TYPES = { 'checking' => '1', - 'savings' => '2', + 'savings' => '2' } def add_check(post, payment_method) @@ -178,7 +178,7 @@ def parse(xml) 'refund' => 'ns_credit', 'authorize' => 'ns_quicksale_cc', 'capture' => 'ns_quicksale_cc', - 'void' => 'ns_void', + 'void' => 'ns_void' } def commit(action, options, post) @@ -196,8 +196,8 @@ def commit(action, options, post) succeeded, message_from(succeeded, raw), raw, - :authorization => authorization_from(raw), - :test => test? + authorization: authorization_from(raw), + test: test? ) end diff --git a/lib/active_merchant/billing/network_tokenization_credit_card.rb b/lib/active_merchant/billing/network_tokenization_credit_card.rb index 0f358948ab8..5fe7a1441af 100644 --- a/lib/active_merchant/billing/network_tokenization_credit_card.rb +++ b/lib/active_merchant/billing/network_tokenization_credit_card.rb @@ -17,7 +17,7 @@ class NetworkTokenizationCreditCard < CreditCard attr_accessor :payment_cryptogram, :eci, :transaction_id attr_writer :source - SOURCES = %i(apple_pay android_pay google_pay) + SOURCES = %i(apple_pay android_pay google_pay network_token) def source if defined?(@source) && SOURCES.include?(@source) diff --git a/lib/active_merchant/billing/response.rb b/lib/active_merchant/billing/response.rb index 491bb0cab5b..077042dcb0f 100644 --- a/lib/active_merchant/billing/response.rb +++ b/lib/active_merchant/billing/response.rb @@ -4,7 +4,7 @@ class Error < ActiveMerchantError #:nodoc: end class Response - attr_reader :params, :message, :test, :authorization, :avs_result, :cvv_result, :error_code, :emv_authorization + attr_reader :params, :message, :test, :authorization, :avs_result, :cvv_result, :error_code, :emv_authorization, :network_transaction_id def success? @success @@ -25,18 +25,19 @@ def initialize(success, message, params = {}, options = {}) @fraud_review = options[:fraud_review] @error_code = options[:error_code] @emv_authorization = options[:emv_authorization] + @network_transaction_id = options[:network_transaction_id] @avs_result = if options[:avs_result].kind_of?(AVSResult) options[:avs_result].to_hash else AVSResult.new(options[:avs_result]).to_hash - end + end @cvv_result = if options[:cvv_result].kind_of?(CVVResult) options[:cvv_result].to_hash else CVVResult.new(options[:cvv_result]).to_hash - end + end end end @@ -53,14 +54,14 @@ def initialize(use_first_response = false) @primary_response = nil end - def process(ignore_result=false) + def process(ignore_result = false) return unless success? response = yield self << response unless ignore_result - if(@use_first_response && response.success?) + if @use_first_response && response.success? @primary_response ||= response else @primary_response = response diff --git a/lib/active_merchant/connection.rb b/lib/active_merchant/connection.rb index e6731ed8566..c15ac5bb803 100644 --- a/lib/active_merchant/connection.rb +++ b/lib/active_merchant/connection.rb @@ -62,6 +62,7 @@ def initialize(endpoint) def wiredump_device=(device) raise ArgumentError, "can't wiredump to frozen #{device.class}" if device&.frozen? + @wiredump_device = device end @@ -71,20 +72,21 @@ def request(method, body, headers = {}) headers = headers.dup headers['connection'] ||= 'close' - retry_exceptions(:max_retries => max_retries, :logger => logger, :tag => tag) do - begin - info "connection_http_method=#{method.to_s.upcase} connection_uri=#{endpoint}", tag + retry_exceptions(max_retries: max_retries, logger: logger, tag: tag) do + info "connection_http_method=#{method.to_s.upcase} connection_uri=#{endpoint}", tag - result = nil + result = nil - realtime = Benchmark.realtime do - http.start unless http.started? - @ssl_connection = http.ssl_connection - info "connection_ssl_version=#{ssl_connection[:version]} connection_ssl_cipher=#{ssl_connection[:cipher]}", tag + realtime = Benchmark.realtime do + http.start unless http.started? + @ssl_connection = http.ssl_connection + info "connection_ssl_version=#{ssl_connection[:version]} connection_ssl_cipher=#{ssl_connection[:cipher]}", tag - result = case method + result = + case method when :get raise ArgumentError, 'GET requests do not support a request body' if body + http.get(endpoint.request_uri, headers) when :post debug body @@ -110,12 +112,11 @@ def request(method, body, headers = {}) else raise ArgumentError, "Unsupported request method #{method.to_s.upcase}" end - end - - info '--> %d %s (%d %.4fs)' % [result.code, result.message, result.body ? result.body.length : 0, realtime], tag - debug result.body - result end + + info '--> %d %s (%d %.4fs)' % [result.code, result.message, result.body ? result.body.length : 0, realtime], tag + debug result.body + result end ensure info 'connection_request_total_time=%.4fs' % [Process.clock_gettime(Process::CLOCK_MONOTONIC) - request_start], tag diff --git a/lib/active_merchant/country.rb b/lib/active_merchant/country.rb index eb18ba69665..3070ab65ad3 100644 --- a/lib/active_merchant/country.rb +++ b/lib/active_merchant/country.rb @@ -39,7 +39,7 @@ class Country def initialize(options = {}) @name = options.delete(:name) - @codes = options.collect { |k, v| CountryCode.new(v) } + @codes = options.collect { |_k, v| CountryCode.new(v) } end def code(format) @@ -330,6 +330,7 @@ def self.find(name) country = COUNTRIES.detect { |c| c[:name].casecmp(name).zero? } end raise InvalidCountryCodeError, "No country could be found for the country #{name}" if country.nil? + Country.new(country.dup) end end diff --git a/lib/active_merchant/net_http_ssl_connection.rb b/lib/active_merchant/net_http_ssl_connection.rb index c0ae5ce1080..17babbf0510 100644 --- a/lib/active_merchant/net_http_ssl_connection.rb +++ b/lib/active_merchant/net_http_ssl_connection.rb @@ -4,6 +4,7 @@ module NetHttpSslConnection refine Net::HTTP do def ssl_connection return {} unless use_ssl? && @socket.present? + { version: @socket.io.ssl_version, cipher: @socket.io.cipher[0] } end end diff --git a/lib/active_merchant/network_connection_retries.rb b/lib/active_merchant/network_connection_retries.rb index 09e1b146f30..267524b27cd 100644 --- a/lib/active_merchant/network_connection_retries.rb +++ b/lib/active_merchant/network_connection_retries.rb @@ -17,26 +17,24 @@ def self.included(base) base.send(:attr_accessor, :retry_safe) end - def retry_exceptions(options={}) + def retry_exceptions(options = {}) connection_errors = DEFAULT_CONNECTION_ERRORS.merge(options[:connection_exceptions] || {}) retry_network_exceptions(options) do - begin - yield - rescue Errno::ECONNREFUSED => e - raise ActiveMerchant::RetriableConnectionError.new('The remote server refused the connection', e) - rescue OpenSSL::X509::CertificateError => e - NetworkConnectionRetries.log(options[:logger], :error, e.message, options[:tag]) - raise ActiveMerchant::ClientCertificateError, 'The remote server did not accept the provided SSL certificate' - rescue Zlib::BufError - raise ActiveMerchant::InvalidResponseError, 'The remote server replied with an invalid response' - rescue *connection_errors.keys => e - raise ActiveMerchant::ConnectionError.new(derived_error_message(connection_errors, e.class), e) - end + yield + rescue Errno::ECONNREFUSED => e + raise ActiveMerchant::RetriableConnectionError.new('The remote server refused the connection', e) + rescue OpenSSL::X509::CertificateError => e + NetworkConnectionRetries.log(options[:logger], :error, e.message, options[:tag]) + raise ActiveMerchant::ClientCertificateError, 'The remote server did not accept the provided SSL certificate' + rescue Zlib::BufError + raise ActiveMerchant::InvalidResponseError, 'The remote server replied with an invalid response' + rescue *connection_errors.keys => e + raise ActiveMerchant::ConnectionError.new(derived_error_message(connection_errors, e.class), e) end end - def self.log(logger, level, message, tag=nil) + def self.log(logger, level, message, tag = nil) tag ||= self.class.to_s message = "[#{tag}] #{message}" logger&.send(level, message) @@ -52,17 +50,17 @@ def retry_network_exceptions(options = {}) begin request_start = Process.clock_gettime(Process::CLOCK_MONOTONIC) result = yield - log_with_retry_details(options[:logger], initial_retries-retries + 1, Process.clock_gettime(Process::CLOCK_MONOTONIC) - request_start, 'success', options[:tag]) + log_with_retry_details(options[:logger], initial_retries - retries + 1, Process.clock_gettime(Process::CLOCK_MONOTONIC) - request_start, 'success', options[:tag]) result rescue ActiveMerchant::RetriableConnectionError => e retries -= 1 - log_with_retry_details(options[:logger], initial_retries-retries, Process.clock_gettime(Process::CLOCK_MONOTONIC) - request_start, e.message, options[:tag]) + log_with_retry_details(options[:logger], initial_retries - retries, Process.clock_gettime(Process::CLOCK_MONOTONIC) - request_start, e.message, options[:tag]) retry unless retries.zero? raise ActiveMerchant::ConnectionError.new(e.message, e) rescue ActiveMerchant::ConnectionError, ActiveMerchant::InvalidResponseError => e retries -= 1 - log_with_retry_details(options[:logger], initial_retries-retries, Process.clock_gettime(Process::CLOCK_MONOTONIC) - request_start, e.message, options[:tag]) + log_with_retry_details(options[:logger], initial_retries - retries, Process.clock_gettime(Process::CLOCK_MONOTONIC) - request_start, e.message, options[:tag]) retry if (options[:retry_safe] || retry_safe) && !retries.zero? raise end diff --git a/lib/active_merchant/post_data.rb b/lib/active_merchant/post_data.rb index c95b85244d2..2ad6a15fdb1 100644 --- a/lib/active_merchant/post_data.rb +++ b/lib/active_merchant/post_data.rb @@ -2,11 +2,12 @@ module ActiveMerchant class PostData < Hash - class_attribute :required_fields, :instance_writer => false + class_attribute :required_fields, instance_writer: false self.required_fields = [] def []=(key, value) return if value.blank? && !required?(key) + super end @@ -14,7 +15,7 @@ def to_post_data collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join('&') end - alias_method :to_s, :to_post_data + alias to_s to_post_data private diff --git a/lib/active_merchant/posts_data.rb b/lib/active_merchant/posts_data.rb index 15446c09fd8..ded8a8f3a70 100644 --- a/lib/active_merchant/posts_data.rb +++ b/lib/active_merchant/posts_data.rb @@ -1,5 +1,5 @@ module ActiveMerchant #:nodoc: - module PostsData #:nodoc: + module PostsData #:nodoc: def self.included(base) base.class_attribute :ssl_strict base.ssl_strict = true @@ -32,7 +32,7 @@ def self.included(base) base.class_attribute :proxy_port end - def ssl_get(endpoint, headers={}) + def ssl_get(endpoint, headers = {}) ssl_request(:get, endpoint, nil, headers) end diff --git a/lib/active_merchant/version.rb b/lib/active_merchant/version.rb index ad84d6f0555..1bed9032241 100644 --- a/lib/active_merchant/version.rb +++ b/lib/active_merchant/version.rb @@ -1,3 +1,3 @@ module ActiveMerchant - VERSION = '1.99.0' + VERSION = '1.119.0' end diff --git a/lib/certs/cacert.pem b/lib/certs/cacert.pem index 72bbb947fe5..149e8601e38 100644 --- a/lib/certs/cacert.pem +++ b/lib/certs/cacert.pem @@ -3986,3 +3986,78 @@ QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl 0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB NVOFBkpdn627G190 -----END CERTIFICATE----- + +USERTrust RSA Certification Authority +===================================== +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw +MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV +BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B +3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY +tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ +Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 +VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT +79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 +c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT +Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l +c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee +UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE +Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF +Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO +VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 +ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs +8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR +iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze +Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ +XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ +qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB +VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB +L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG +jjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- + +Sectigo RSA Organization Validation Secure Server CA +==================================================== +-----BEGIN CERTIFICATE----- +MIIGGTCCBAGgAwIBAgIQE31TnKp8MamkM3AZaIR6jTANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgx +MTAyMDAwMDAwWhcNMzAxMjMxMjM1OTU5WjCBlTELMAkGA1UEBhMCR0IxGzAZBgNV +BAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UE +ChMPU2VjdGlnbyBMaW1pdGVkMT0wOwYDVQQDEzRTZWN0aWdvIFJTQSBPcmdhbml6 +YXRpb24gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAnJMCRkVKUkiS/FeN+S3qU76zLNXYqKXsW2kDwB0Q +9lkz3v4HSKjojHpnSvH1jcM3ZtAykffEnQRgxLVK4oOLp64m1F06XvjRFnG7ir1x +on3IzqJgJLBSoDpFUd54k2xiYPHkVpy3O/c8Vdjf1XoxfDV/ElFw4Sy+BKzL+k/h +fGVqwECn2XylY4QZ4ffK76q06Fha2ZnjJt+OErK43DOyNtoUHZZYQkBuCyKFHFEi +rsTIBkVtkuZntxkj5Ng2a4XQf8dS48+wdQHgibSov4o2TqPgbOuEQc6lL0giE5dQ +YkUeCaXMn2xXcEAG2yDoG9bzk4unMp63RBUJ16/9fAEc2wIDAQABo4IBbjCCAWow +HwYDVR0jBBgwFoAUU3m/WqorSs9UgOHYm8Cd8rIDZsswHQYDVR0OBBYEFBfZ1iUn +Z/kxwklD2TA2RIxsqU/rMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/ +AgEAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAbBgNVHSAEFDASMAYG +BFUdIAAwCAYGZ4EMAQICMFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwudXNl +cnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNy +bDB2BggrBgEFBQcBAQRqMGgwPwYIKwYBBQUHMAKGM2h0dHA6Ly9jcnQudXNlcnRy +dXN0LmNvbS9VU0VSVHJ1c3RSU0FBZGRUcnVzdENBLmNydDAlBggrBgEFBQcwAYYZ +aHR0cDovL29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG9w0BAQwFAAOCAgEAThNA +lsnD5m5bwOO69Bfhrgkfyb/LDCUW8nNTs3Yat6tIBtbNAHwgRUNFbBZaGxNh10m6 +pAKkrOjOzi3JKnSj3N6uq9BoNviRrzwB93fVC8+Xq+uH5xWo+jBaYXEgscBDxLmP +bYox6xU2JPti1Qucj+lmveZhUZeTth2HvbC1bP6mESkGYTQxMD0gJ3NR0N6Fg9N3 +OSBGltqnxloWJ4Wyz04PToxcvr44APhL+XJ71PJ616IphdAEutNCLFGIUi7RPSRn +R+xVzBv0yjTqJsHe3cQhifa6ezIejpZehEU4z4CqN2mLYBd0FUiRnG3wTqN3yhsc +SPr5z0noX0+FCuKPkBurcEya67emP7SsXaRfz+bYipaQ908mgWB2XQ8kd5GzKjGf +FlqyXYwcKapInI5v03hAcNt37N3j0VcFcC3mSZiIBYRiBXBWdoY5TtMibx3+bfEO +s2LEPMvAhblhHrrhFYBZlAyuBbuMf1a+HNJav5fyakywxnB2sJCNwQs2uRHY1ihc +6k/+JLcYCpsM0MF8XPtpvcyiTcaQvKZN8rG61ppnW5YCUtCC+cQKXA0o4D/I+pWV +idWkvklsQLI+qGu41SWyxP7x09fn1txDAXYw+zuLXfdKiXyaNb78yvBXAfCNP6CH +MntHWpdLgtJmwsQt6j8k9Kf5qLnjatkYYaA7jBU= +-----END CERTIFICATE----- diff --git a/lib/support/gateway_support.rb b/lib/support/gateway_support.rb index b3bb28e54cf..c1e358db323 100644 --- a/lib/support/gateway_support.rb +++ b/lib/support/gateway_support.rb @@ -3,7 +3,7 @@ require 'active_merchant' class GatewaySupport #:nodoc: - ACTIONS = [:purchase, :authorize, :capture, :void, :credit, :recurring] + ACTIONS = %i[purchase authorize capture void credit recurring] include ActiveMerchant::Billing diff --git a/lib/support/ssl_verify.rb b/lib/support/ssl_verify.rb index 5570e7fde47..9f431a8da48 100644 --- a/lib/support/ssl_verify.rb +++ b/lib/support/ssl_verify.rb @@ -2,7 +2,6 @@ require 'support/gateway_support' class SSLVerify - def initialize @gateways = GatewaySupport.new.gateways end @@ -18,9 +17,7 @@ def test_gateways next end - if !g.ssl_strict - disabled << g - end + disabled << g if !g.ssl_strict uri = URI.parse(g.live_url) result, message = ssl_verify_peer?(uri) @@ -30,10 +27,10 @@ def test_gateways success << g when :fail print 'F' - failed << {:gateway => g, :message => message} + failed << { gateway: g, message: message } when :error print 'E' - errored << {:gateway => g, :message => message} + errored << { gateway: g, message: message } end end @@ -88,5 +85,4 @@ def ssl_verify_peer?(uri) rescue Net::HTTPBadResponse, Errno::ETIMEDOUT, EOFError, SocketError, Errno::ECONNREFUSED, Timeout::Error => ex return :error, ex.inspect end - end diff --git a/lib/support/ssl_version.rb b/lib/support/ssl_version.rb index ed7c716c9c0..3050d09f438 100644 --- a/lib/support/ssl_version.rb +++ b/lib/support/ssl_version.rb @@ -29,10 +29,10 @@ def test_gateways(min_version = :TLS1_1) success << g when :fail print 'F' - failed << {:gateway => g, :message => message} + failed << { gateway: g, message: message } when :error print 'E' - errored << {:gateway => g, :message => message} + errored << { gateway: g, message: message } end end @@ -83,5 +83,4 @@ def test_min_version(uri, min_version) rescue StandardError => ex return :error, ex.inspect end - end diff --git a/test/comm_stub.rb b/test/comm_stub.rb index 9293ef77955..cf7320fd01c 100644 --- a/test/comm_stub.rb +++ b/test/comm_stub.rb @@ -40,7 +40,7 @@ def last_comm_stub @last_comm_stub ||= Stub::Complete.new end - def stub_comms(gateway=@gateway, method_to_stub=:ssl_post, &action) + def stub_comms(gateway = @gateway, method_to_stub = :ssl_post, &action) assert last_comm_stub.complete?, "Tried to stub communications when there's a stub already in progress." @last_comm_stub = Stub.new(gateway, method_to_stub, action) end diff --git a/test/fixtures.yml b/test/fixtures.yml index 2b9a8e14318..bff9570316e 100644 --- a/test/fixtures.yml +++ b/test/fixtures.yml @@ -411,6 +411,9 @@ hdfc: hps: secret_api_key: "skapi_cert_MYl2AQAowiQAbLp5JesGKh7QFkcizOP2jcX9BrEMqQ" +hps_echeck: + secret_api_key: + iats_payments: agent_code: TEST88 password: TEST88 @@ -443,6 +446,12 @@ iveri: cert_id: CB69E68D-C7E7-46B9-9B7A-025DCABAD6EF app_id: d10a603d-4ade-405b-93f1-826dfc0181e8 +ixopay: + username: USERNAME + api_key: API_KEY + password: PASSWORD + secret: SHARED_SECRET + jetpay: login: TESTTERMINAL @@ -551,10 +560,6 @@ moneris: login: store3 password: yesguy -moneris_us: - login: monusqa002 - password: qatoken - money_movers: login: demo password: password @@ -628,8 +633,7 @@ openpay: merchant_id: 'mzdtln0bmtms6o3kck8f' opp: - user_id: '8a8294174b7ecb28014b9699220015cc' - password: 'sy6KJsT8' + access_token: 'OGE4Mjk0MTc0YjdlY2IyODAxNGI5Njk5MjIwMDE1Y2N8c3k2S0pzVDg=' entity_id: '8a8294174d0a8edd014d242337942575' optimal_payment: @@ -685,9 +689,14 @@ pay_secure: password: PASSWORD paybox_direct: - login: 199988863 + login: 1999888 password: 1999888I - rang: 85 + rang: 222 + credit_card_ok_3ds: 4012001037141112 + credit_card_nok_3ds: 4012001037141113 + credit_card_ok_3ds_not_enrolled: 4012001038443335 + credit_card_ok: 1111222233334444 + credit_card_nok: 1111222233334445 # Working credentials, no need to replace payeezy: @@ -790,6 +799,12 @@ payway: password: pem: +# Working credentials, no need to replace +payway_dot_com: + login: "sprerestwsdev" + password: "sprerestwsdev1!" + company_id: "3" + pin: api_key: "I_mo9BUUUXIwXF-avcs3LA" @@ -875,8 +890,17 @@ quantum: password: Y # You will need to create a developer sandbox at https://developer.intuit.com/ and -# successfully generate an OAuth 1.0a access token and token secret. +# successfully generate an OAuth 2.0 access token and refresh_token. Access token +# expires every 60 minutes quickbooks: + client_id: + client_secret: + refresh_token: + access_token: + +# You will need to create a developer sandbox at https://developer.intuit.com/ and +# successfully generate an OAuth 1.0a access token and token secret. +quickbooks_oauth_1: consumer_key: consumer_secret: access_token: diff --git a/test/remote/gateways/remote_adyen_test.rb b/test/remote/gateways/remote_adyen_test.rb index 87671971635..e0d651c183f 100644 --- a/test/remote/gateways/remote_adyen_test.rb +++ b/test/remote/gateways/remote_adyen_test.rb @@ -7,51 +7,66 @@ def setup @amount = 100 @credit_card = credit_card('4111111111111111', - :month => 10, - :year => 2020, - :first_name => 'John', - :last_name => 'Smith', - :verification_value => '737', - :brand => 'visa' - ) + month: 3, + year: 2030, + first_name: 'John', + last_name: 'Smith', + verification_value: '737', + brand: 'visa') @avs_credit_card = credit_card('4400000000000008', - :month => 10, - :year => 2020, - :first_name => 'John', - :last_name => 'Smith', - :verification_value => '737', - :brand => 'visa' - ) + month: 3, + year: 2030, + first_name: 'John', + last_name: 'Smith', + verification_value: '737', + brand: 'visa') @elo_credit_card = credit_card('5066 9911 1111 1118', - :month => 10, - :year => 2020, - :first_name => 'John', - :last_name => 'Smith', - :verification_value => '737', - :brand => 'elo' - ) + month: 3, + year: 2030, + first_name: 'John', + last_name: 'Smith', + verification_value: '737', + brand: 'elo') - @three_ds_enrolled_card = credit_card('4917610000000000', month: 10, year: 2020, verification_value: '737', brand: :visa) + @three_ds_enrolled_card = credit_card('4917610000000000', + month: 3, + year: 2030, + verification_value: '737', + brand: :visa) @cabal_credit_card = credit_card('6035 2277 1642 7021', - :month => 10, - :year => 2020, - :first_name => 'John', - :last_name => 'Smith', - :verification_value => '737', - :brand => 'cabal' - ) + month: 3, + year: 2030, + first_name: 'John', + last_name: 'Smith', + verification_value: '737', + brand: 'cabal') @invalid_cabal_credit_card = credit_card('6035 2200 0000 0006', - :month => 10, - :year => 2020, - :first_name => 'John', - :last_name => 'Smith', - :verification_value => '737', - :brand => 'cabal' - ) + month: 3, + year: 2030, + first_name: 'John', + last_name: 'Smith', + verification_value: '737', + brand: 'cabal') + + @unionpay_credit_card = credit_card('8171 9999 0000 0000 021', + month: 10, + year: 2030, + first_name: 'John', + last_name: 'Smith', + verification_value: '737', + brand: 'unionpay') + + @invalid_unionpay_credit_card = credit_card('8171 9999 1234 0000 921', + month: 10, + year: 2030, + first_name: 'John', + last_name: 'Smith', + verification_value: '737', + brand: 'unionpay') @declined_card = credit_card('4000300011112220') @@ -65,40 +80,42 @@ def setup brand: 'mastercard' ) - @apple_pay_card = network_tokenization_credit_card('4111111111111111', - :payment_cryptogram => 'YwAAAAAABaYcCMX/OhNRQAAAAAA=', - :month => '08', - :year => '2018', - :source => :apple_pay, - :verification_value => nil + @apple_pay_card = network_tokenization_credit_card( + '4761209980011439', + payment_cryptogram: 'YwAAAAAABaYcCMX/OhNRQAAAAAA=', + month: '11', + year: '2022', + source: :apple_pay, + verification_value: 569 ) - @google_pay_card = network_tokenization_credit_card('4111111111111111', - :payment_cryptogram => 'YwAAAAAABaYcCMX/OhNRQAAAAAA=', - :month => '08', - :year => '2018', - :source => :google_pay, - :verification_value => nil + @google_pay_card = network_tokenization_credit_card( + '4761209980011439', + payment_cryptogram: 'YwAAAAAABaYcCMX/OhNRQAAAAAA=', + month: '11', + year: '2022', + source: :google_pay, + verification_value: nil ) @options = { reference: '345123', - shopper_email: 'john.smith@test.com', - shopper_ip: '77.110.174.153', + email: 'john.smith@test.com', + ip: '77.110.174.153', shopper_reference: 'John Smith', billing_address: address(), order_id: '123', - stored_credential: {reason_type: 'unscheduled'}, + stored_credential: { reason_type: 'unscheduled' } } @normalized_3ds_2_options = { reference: '345123', - shopper_email: 'john.smith@test.com', - shopper_ip: '77.110.174.153', + email: 'john.smith@test.com', + ip: '77.110.174.153', shopper_reference: 'John Smith', billing_address: address(), order_id: '123', - stored_credential: {reason_type: 'unscheduled'}, + stored_credential: { reason_type: 'unscheduled' }, three_ds_2: { channel: 'browser', notification_url: 'https://example.com/notification', @@ -114,6 +131,44 @@ def setup } } } + + @sub_seller_options = { + "subMerchant.numberOfSubSellers": '2', + "subMerchant.subSeller1.id": '111111111', + "subMerchant.subSeller1.name": 'testSub1', + "subMerchant.subSeller1.street": 'Street1', + "subMerchant.subSeller1.postalCode": '12242840', + "subMerchant.subSeller1.city": 'Sao jose dos campos', + "subMerchant.subSeller1.state": 'SP', + "subMerchant.subSeller1.country": 'BRA', + "subMerchant.subSeller1.taxId": '12312312340', + "subMerchant.subSeller1.mcc": '5691', + "subMerchant.subSeller1.debitSettlementBank": '1', + "subMerchant.subSeller1.debitSettlementAgency": '1', + "subMerchant.subSeller1.debitSettlementAccountType": '1', + "subMerchant.subSeller1.debitSettlementAccount": '1', + "subMerchant.subSeller1.creditSettlementBank": '1', + "subMerchant.subSeller1.creditSettlementAgency": '1', + "subMerchant.subSeller1.creditSettlementAccountType": '1', + "subMerchant.subSeller1.creditSettlementAccount": '1', + "subMerchant.subSeller2.id": '22222222', + "subMerchant.subSeller2.name": 'testSub2', + "subMerchant.subSeller2.street": 'Street2', + "subMerchant.subSeller2.postalCode": '12300000', + "subMerchant.subSeller2.city": 'Jacarei', + "subMerchant.subSeller2.state": 'SP', + "subMerchant.subSeller2.country": 'BRA', + "subMerchant.subSeller2.taxId": '12312312340', + "subMerchant.subSeller2.mcc": '5691', + "subMerchant.subSeller2.debitSettlementBank": '1', + "subMerchant.subSeller2.debitSettlementAgency": '1', + "subMerchant.subSeller2.debitSettlementAccountType": '1', + "subMerchant.subSeller2.debitSettlementAccount": '1', + "subMerchant.subSeller2.creditSettlementBank": '1', + "subMerchant.subSeller2.creditSettlementAgency": '1', + "subMerchant.subSeller2.creditSettlementAccountType": '1', + "subMerchant.subSeller2.creditSettlementAccount": '1' + } end def test_successful_authorize @@ -162,6 +217,33 @@ def test_successful_authorize_with_3ds refute response.params['paRequest'].blank? end + def test_successful_authorize_with_execute_threed_false + assert response = @gateway.authorize(@amount, @three_ds_enrolled_card, @options.merge(execute_threed: false, sca_exemption: 'lowValue')) + assert response.test? + refute response.authorization.blank? + assert_equal response.params['resultCode'], 'Authorised' + end + + def test_successful_authorize_with_3ds_with_idempotency_key + options = @options.merge(idempotency_key: SecureRandom.hex, execute_threed: true) + assert response = @gateway.authorize(@amount, @three_ds_enrolled_card, options) + assert response.test? + refute response.authorization.blank? + assert_equal response.params['resultCode'], 'RedirectShopper' + refute response.params['issuerUrl'].blank? + refute response.params['md'].blank? + refute response.params['paRequest'].blank? + + assert response2 = @gateway.authorize(@amount, @three_ds_enrolled_card, options) + assert_success response2 + refute response2.authorization.blank? + assert_equal response2.params['resultCode'], 'RedirectShopper' + refute response2.params['issuerUrl'].blank? + refute response2.params['md'].blank? + refute response2.params['paRequest'].blank? + assert_equal response.authorization, response2.authorization + end + def test_successful_authorize_with_3ds_dynamic assert response = @gateway.authorize(@amount, @three_ds_enrolled_card, @options.merge(threed_dynamic: true)) assert response.test? @@ -208,14 +290,14 @@ def test_successful_purchase_with_3ds2_exemption_requested_and_execute_threed_tr def test_successful_authorize_with_3ds2_app_based_request three_ds_app_based_options = { reference: '345123', - shopper_email: 'john.smith@test.com', - shopper_ip: '77.110.174.153', + email: 'john.smith@test.com', + ip: '77.110.174.153', shopper_reference: 'John Smith', billing_address: address(), order_id: '123', - stored_credential: {reason_type: 'unscheduled'}, + stored_credential: { reason_type: 'unscheduled' }, three_ds_2: { - channel: 'app', + channel: 'app' } } @@ -233,25 +315,34 @@ def test_successful_authorize_with_3ds2_app_based_request # with rule set in merchant account to skip 3DS for cards of this brand def test_successful_authorize_with_3ds_dynamic_rule_broken mastercard_threed = credit_card('5212345678901234', - :month => 10, - :year => 2020, - :first_name => 'John', - :last_name => 'Smith', - :verification_value => '737', - :brand => 'mastercard' - ) + month: 3, + year: 2030, + first_name: 'John', + last_name: 'Smith', + verification_value: '737', + brand: 'mastercard') assert response = @gateway.authorize(@amount, mastercard_threed, @options.merge(threed_dynamic: true)) assert response.test? refute response.authorization.blank? assert_equal response.params['resultCode'], 'Authorised' end + # Fail in situations where neither execute_threed nor dynamic_threed is + # present, but the account is set to dynamic 3ds and it is triggered. This + # test assumes a Dynamic 3DS rule set for the Adyen test account to always + # perform 3ds auth for an amount of 8484 + def test_purchase_fails_on_unexpected_3ds_initiation + response = @gateway.purchase(8484, @three_ds_enrolled_card, @options) + assert_failure response + assert_match 'Received unexpected 3DS authentication response', response.message + end + def test_successful_purchase_with_auth_data_via_threeds1_standalone eci = '05' cavv = '3q2+78r+ur7erb7vyv66vv\/\/\/\/8=' cavv_algorithm = '1' xid = 'ODUzNTYzOTcwODU5NzY3Qw==' - directory_response_status = 'Y' + enrolled = 'Y' authentication_response_status = 'Y' options = @options.merge( three_d_secure: { @@ -259,7 +350,7 @@ def test_successful_purchase_with_auth_data_via_threeds1_standalone cavv: cavv, cavv_algorithm: cavv_algorithm, xid: xid, - directory_response_status: directory_response_status, + enrolled: enrolled, authentication_response_status: authentication_response_status } ) @@ -267,6 +358,7 @@ def test_successful_purchase_with_auth_data_via_threeds1_standalone auth = @gateway.authorize(@amount, @credit_card, options) assert_success auth assert_equal 'Authorised', auth.message + # The assertion below requires the "3D Secure Result" data activated for the test account assert_equal 'true', auth.params['additionalData']['liabilityShift'] response = @gateway.purchase(@amount, @credit_card, options) @@ -296,6 +388,7 @@ def test_successful_purchase_with_auth_data_via_threeds2_standalone auth = @gateway.authorize(@amount, @credit_card, options) assert_success auth assert_equal 'Authorised', auth.message + # The assertion below requires the "3D Secure Result" data activated for the test account assert_equal 'true', auth.params['additionalData']['liabilityShift'] response = @gateway.purchase(@amount, @credit_card, options) @@ -305,8 +398,8 @@ def test_successful_purchase_with_auth_data_via_threeds2_standalone def test_successful_authorize_with_no_address options = { reference: '345123', - shopper_email: 'john.smith@test.com', - shopper_ip: '77.110.174.153', + email: 'john.smith@test.com', + ip: '77.110.174.153', shopper_reference: 'John Smith', order_id: '123', recurring_processing_model: 'CardOnFile' @@ -319,7 +412,7 @@ def test_successful_authorize_with_no_address def test_failed_authorize response = @gateway.authorize(@amount, @declined_card, @options) assert_failure response - assert_equal 'CVC Declined', response.message + assert_equal 'Refused', response.message end def test_successful_purchase @@ -342,7 +435,8 @@ def test_successful_purchase_with_more_options installments: 2, shopper_statement: 'statement note', device_fingerprint: 'm7Cmrf++0cW4P6XfF7m/rA', - capture_delay_hours: 4) + capture_delay_hours: 4 + ) response = @gateway.purchase(@amount, @credit_card, options) assert_success response assert_equal '[capture-received]', response.message @@ -382,7 +476,13 @@ def test_successful_purchase_with_apple_pay end def test_succesful_purchase_with_brand_override - response = @gateway.purchase(@amount, @improperly_branded_maestro, @options.merge({overwrite_brand: true, selected_brand: 'maestro'})) + response = @gateway.purchase(@amount, @improperly_branded_maestro, @options.merge({ overwrite_brand: true, selected_brand: 'maestro' })) + assert_success response + assert_equal '[capture-received]', response.message + end + + def test_succesful_purchase_with_brand_override_with_execute_threed_false + response = @gateway.purchase(@amount, @improperly_branded_maestro, @options.merge({ execute_threed: false, overwrite_brand: true, selected_brand: 'maestro' })) assert_success response assert_equal '[capture-received]', response.message end @@ -405,10 +505,16 @@ def test_successful_purchase_with_cabal_card assert_equal '[capture-received]', response.message end + def test_successful_purchase_with_unionpay_card + response = @gateway.purchase(@amount, @unionpay_credit_card, @options.merge(currency: 'CNY')) + assert_success response + assert_equal '[capture-received]', response.message + end + def test_failed_purchase response = @gateway.purchase(@amount, @declined_card, @options) assert_failure response - assert_equal 'CVC Declined', response.message + assert_equal 'Refused', response.message end def test_failed_purchase_with_invalid_cabal_card @@ -417,6 +523,12 @@ def test_failed_purchase_with_invalid_cabal_card assert_equal 'Invalid card number', response.message end + def test_failed_purchase_with_invalid_unionpay_card + response = @gateway.purchase(@amount, @invalid_unionpay_credit_card, @options) + assert_failure response + assert_equal 'Invalid card number', response.message + end + def test_successful_authorize_and_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth @@ -444,11 +556,20 @@ def test_successful_authorize_and_capture_with_cabal_card assert_equal '[capture-received]', capture.message end + def test_successful_authorize_and_capture_with_unionpay_card + auth = @gateway.authorize(@amount, @unionpay_credit_card, @options) + assert_success auth + + assert capture = @gateway.capture(@amount, auth.authorization) + assert_success capture + assert_equal '[capture-received]', capture.message + end + def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -467,6 +588,16 @@ def test_successful_refund assert_equal '[refund-received]', refund.message end + def test_successful_refund_with_auth_original_reference + auth_response = @gateway.authorize(@amount, @credit_card, @options) + assert_success auth_response + assert_equal 'Authorised', auth_response.message + + refund_resp = @gateway.refund(@amount, auth_response.authorization) + assert_success refund_resp + assert_equal '[refund-received]', refund_resp.message + end + def test_successful_refund_with_elo_card purchase = @gateway.purchase(@amount, @elo_credit_card, @options) assert_success purchase @@ -485,11 +616,20 @@ def test_successful_refund_with_cabal_card assert_equal '[refund-received]', refund.message end + def test_successful_refund_with_unionpay_card + purchase = @gateway.purchase(@amount, @unionpay_credit_card, @options) + assert_success purchase + + assert refund = @gateway.refund(@amount, purchase.authorization) + assert_success refund + assert_equal '[refund-received]', refund.message + end + def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund end @@ -499,6 +639,18 @@ def test_failed_refund assert_equal 'Original pspReference required for this operation', response.message end + def test_successful_credit + response = @gateway.credit(@amount, @credit_card, @options) + assert_success response + assert_equal 'Received', response.message + end + + def test_failed_credit + response = @gateway.credit(@amount, '') + assert_failure response + assert_equal 'Reference Missing', response.message + end + def test_successful_void auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth @@ -526,6 +678,43 @@ def test_successful_void_with_cabal_card assert_equal '[cancel-received]', void.message end + def test_successful_void_with_unionpay_card + auth = @gateway.authorize(@amount, @unionpay_credit_card, @options) + assert_success auth + + assert void = @gateway.void(auth.authorization) + assert_success void + assert_equal '[cancel-received]', void.message + end + + def test_successul_void_of_pending_3ds_authorization + assert auth = @gateway.authorize(@amount, @three_ds_enrolled_card, @options.merge(execute_threed: true)) + assert auth.test? + refute auth.authorization.blank? + assert_equal auth.params['resultCode'], 'RedirectShopper' + refute auth.params['issuerUrl'].blank? + refute auth.params['md'].blank? + refute auth.params['paRequest'].blank? + + assert void = @gateway.void(auth.authorization) + assert_success void + assert_equal '[cancel-received]', void.message + end + + def test_successful_void_requires_unique_idempotency_key + idempotency_key = SecureRandom.hex + options = @options.merge(idempotency_key: idempotency_key) + auth = @gateway.authorize(@amount, @credit_card, options) + assert_success auth + + assert void = @gateway.void(auth.authorization, idempotency_key: idempotency_key) + assert_failure void + + assert void = @gateway.void(auth.authorization, idempotency_key: "#{idempotency_key}-auto-void") + assert_success void + assert_equal '[cancel-received]', void.message + end + def test_failed_void response = @gateway.void('') assert_failure response @@ -607,6 +796,52 @@ def test_successful_store assert_equal 'Authorised', response.message end + def test_successful_unstore + assert response = @gateway.store(@credit_card, @options) + + assert !response.authorization.split('#')[2].nil? + assert_equal 'Authorised', response.message + + shopper_reference = response.params['additionalData']['recurring.shopperReference'] + recurring_detail_reference = response.params['additionalData']['recurring.recurringDetailReference'] + + assert response = @gateway.unstore(shopper_reference: shopper_reference, + recurring_detail_reference: recurring_detail_reference) + + assert_success response + assert_equal '[detail-successfully-disabled]', response.message + end + + def test_failed_unstore + assert response = @gateway.store(@credit_card, @options) + + assert !response.authorization.split('#')[2].nil? + assert_equal 'Authorised', response.message + + shopper_reference = response.params['additionalData']['recurring.shopperReference'] + recurring_detail_reference = response.params['additionalData']['recurring.recurringDetailReference'] + + assert response = @gateway.unstore(shopper_reference: 'random_reference', + recurring_detail_reference: recurring_detail_reference) + + assert_failure response + assert_equal 'Contract not found', response.message + + assert response = @gateway.unstore(shopper_reference: shopper_reference, + recurring_detail_reference: 'random_reference') + + assert_failure response + assert_equal 'PaymentDetail not found', response.message + end + + def test_successful_tokenize_only_store + assert response = @gateway.store(@credit_card, @options.merge({ tokenize_only: true })) + + assert_success response + assert !response.authorization.split('#')[2].nil? + assert_equal 'Success', response.message + end + def test_successful_store_with_elo_card assert response = @gateway.store(@elo_credit_card, @options) @@ -622,11 +857,19 @@ def test_failed_store_with_cabal_card assert_equal 'Recurring transactions are not supported for this card type.', response.message end + def test_successful_store_with_unionpay_card + assert response = @gateway.store(@unionpay_credit_card, @options) + + assert_success response + assert !response.authorization.split('#')[2].nil? + assert_equal 'Authorised', response.message + end + def test_failed_store assert response = @gateway.store(@declined_card, @options) assert_failure response - assert_equal 'CVC Declined', response.message + assert_equal 'Refused', response.message end def test_successful_purchase_using_stored_card @@ -665,7 +908,7 @@ def test_successful_verify def test_failed_verify response = @gateway.verify(@declined_card, @options) assert_failure response - assert_match 'CVC Declined', response.message + assert_match 'Refused', response.message end def test_verify_with_idempotency_key @@ -796,4 +1039,107 @@ def test_missing_phone_for_purchase response = @gateway.authorize(@amount, @credit_card, @options) assert_success response end + + def test_purchase_using_stored_credential_recurring_cit + initial_options = stored_credential_options(:cardholder, :recurring, :initial) + assert auth = @gateway.authorize(@amount, @credit_card, initial_options) + assert_success auth + assert_equal 'Subscription', auth.params['additionalData']['recurringProcessingModel'] + assert capture = @gateway.capture(@amount, auth.authorization) + assert_success capture + assert_equal '[capture-received]', capture.message + assert network_transaction_id = 'none' + + used_options = stored_credential_options(:recurring, :cardholder, id: network_transaction_id) + assert purchase = @gateway.purchase(@amount, @credit_card, used_options) + assert_success purchase + end + + def test_purchase_using_stored_credential_recurring_mit + initial_options = stored_credential_options(:merchant, :recurring, :initial) + assert auth = @gateway.authorize(@amount, @credit_card, initial_options) + assert_success auth + assert_equal 'Subscription', auth.params['additionalData']['recurringProcessingModel'] + assert capture = @gateway.capture(@amount, auth.authorization) + assert_success capture + assert_equal '[capture-received]', capture.message + assert network_transaction_id = 'none' + + used_options = stored_credential_options(:recurring, :cardholder, id: network_transaction_id) + assert purchase = @gateway.purchase(@amount, @credit_card, used_options) + assert_success purchase + end + + def test_purchase_using_stored_credential_unscheduled_cit + initial_options = stored_credential_options(:cardholder, :unscheduled, :initial) + assert auth = @gateway.authorize(@amount, @credit_card, initial_options) + assert_success auth + assert_equal 'CardOnFile', auth.params['additionalData']['recurringProcessingModel'] + assert capture = @gateway.capture(@amount, auth.authorization) + assert_success capture + assert_equal '[capture-received]', capture.message + assert network_transaction_id = 'none' + + used_options = stored_credential_options(:unscheduled, :cardholder, id: network_transaction_id) + assert purchase = @gateway.purchase(@amount, @credit_card, used_options) + assert_success purchase + end + + def test_purchase_using_stored_credential_unscheduled_mit + initial_options = stored_credential_options(:merchant, :unscheduled, :initial) + assert auth = @gateway.authorize(@amount, @credit_card, initial_options) + assert_success auth + assert_equal 'UnscheduledCardOnFile', auth.params['additionalData']['recurringProcessingModel'] + assert capture = @gateway.capture(@amount, auth.authorization) + assert_success capture + assert_equal '[capture-received]', capture.message + assert network_transaction_id = 'none' + + used_options = stored_credential_options(:unscheduled, :cardholder, id: network_transaction_id) + assert purchase = @gateway.purchase(@amount, @credit_card, used_options) + assert_success purchase + end + + def test_successful_authorize_with_sub_merchant_data + sub_merchant_data = { + sub_merchant_id: '123451234512345', + sub_merchant_name: 'Wildsea', + sub_merchant_street: '1234 Street St', + sub_merchant_city: 'Night City', + sub_merchant_state: 'East Block', + sub_merchant_postal_code: '112233', + sub_merchant_country: 'EUR', + sub_merchant_tax_id: '12345abcde67', + sub_merchant_mcc: '1234' + } + options = @options.update({ + installments: 2, + billing_address: { + address1: 'Infinite Loop', + address2: 1, + country: 'US', + city: 'Cupertino', + state: 'CA', + zip: '95014' + } + }) + assert response = @gateway.authorize(@amount, @avs_credit_card, options.merge(sub_merchant_data)) + assert response.test? + refute response.authorization.blank? + assert_success response + end + + def test_successful_authorize_with_sub_merchant_sub_seller_data + assert response = @gateway.authorize(@amount, @avs_credit_card, @options.merge(sub_merchant_data: @sub_seller_options)) + assert response.test? + refute response.authorization.blank? + assert_success response + end + + private + + def stored_credential_options(*args, id: nil) + @options.merge(order_id: generate_unique_id, + stored_credential: stored_credential(*args, id: id)) + end end diff --git a/test/remote/gateways/remote_allied_wallet_test.rb b/test/remote/gateways/remote_allied_wallet_test.rb index 8ab761e508b..7511b5f9644 100644 --- a/test/remote/gateways/remote_allied_wallet_test.rb +++ b/test/remote/gateways/remote_allied_wallet_test.rb @@ -9,7 +9,7 @@ def setup @declined_card = credit_card('4242424242424242', verification_value: '555') @options = { - billing_address: address, + billing_address: address } end @@ -32,11 +32,12 @@ def test_failed_purchase_no_address end def test_successful_purchase_with_more_options - response = @gateway.purchase(@amount, @credit_card, @options.merge( + options = @options.merge( order_id: generate_unique_id, ip: '127.0.0.1', email: 'jim_smith@example.com' - )) + ) + response = @gateway.purchase(@amount, @credit_card, options) assert_success response assert_equal 'Succeeded', response.message end diff --git a/test/remote/gateways/remote_authorize_net_apple_pay_test.rb b/test/remote/gateways/remote_authorize_net_apple_pay_test.rb index cf430b4a975..0cd7a16fe8f 100644 --- a/test/remote/gateways/remote_authorize_net_apple_pay_test.rb +++ b/test/remote/gateways/remote_authorize_net_apple_pay_test.rb @@ -47,14 +47,14 @@ def test_successful_apple_pay_authorization_and_void end def test_failed_apple_pay_authorization - response = @gateway.authorize(@amount, apple_pay_payment_token(payment_data: {data: 'garbage'}), @options) + response = @gateway.authorize(@amount, apple_pay_payment_token(payment_data: { data: 'garbage' }), @options) assert_failure response assert_equal 'There was an error processing the payment data', response.message assert_equal 'processing_error', response.error_code end def test_failed_apple_pay_purchase - response = @gateway.purchase(@amount, apple_pay_payment_token(payment_data: {data: 'garbage'}), @options) + response = @gateway.purchase(@amount, apple_pay_payment_token(payment_data: { data: 'garbage' }), @options) assert_failure response assert_equal 'There was an error processing the payment data', response.message assert_equal 'processing_error', response.error_code @@ -85,8 +85,6 @@ def apple_pay_payment_token(options = {}) ActiveMerchant::Billing::ApplePayPaymentToken.new(defaults[:payment_data], payment_instrument_name: defaults[:payment_instrument_name], payment_network: defaults[:payment_network], - transaction_identifier: defaults[:transaction_identifier] - ) + transaction_identifier: defaults[:transaction_identifier]) end - end diff --git a/test/remote/gateways/remote_authorize_net_arb_test.rb b/test/remote/gateways/remote_authorize_net_arb_test.rb index 5a04f9de419..77ba6ae7c8f 100644 --- a/test/remote/gateways/remote_authorize_net_arb_test.rb +++ b/test/remote/gateways/remote_authorize_net_arb_test.rb @@ -8,17 +8,17 @@ def setup @check = check @options = { - :amount => 100, - :subscription_name => 'Test Subscription 1', - :credit_card => @credit_card, - :billing_address => address.merge(:first_name => 'Jim', :last_name => 'Smith'), - :interval => { - :length => 1, - :unit => :months + amount: 100, + subscription_name: 'Test Subscription 1', + credit_card: @credit_card, + billing_address: address.merge(first_name: 'Jim', last_name: 'Smith'), + interval: { + length: 1, + unit: :months }, - :duration => { - :start_date => Date.today, - :occurrences => 1 + duration: { + start_date: Date.today, + occurrences: 1 } } end @@ -30,7 +30,7 @@ def test_successful_recurring subscription_id = response.authorization - assert response = @gateway.update_recurring(:subscription_id => subscription_id, :amount => @amount * 2) + assert response = @gateway.update_recurring(subscription_id: subscription_id, amount: @amount * 2) assert_success response assert response = @gateway.status_recurring(subscription_id) @@ -50,8 +50,8 @@ def test_recurring_should_fail_expired_credit_card def test_bad_login gateway = AuthorizeNetArbGateway.new( - :login => 'X', - :password => 'Y' + login: 'X', + password: 'Y' ) assert response = gateway.recurring(@amount, @credit_card, @options) diff --git a/test/remote/gateways/remote_authorize_net_cim_test.rb b/test/remote/gateways/remote_authorize_net_cim_test.rb index 124b81c7753..e0655dfcf9c 100644 --- a/test/remote/gateways/remote_authorize_net_cim_test.rb +++ b/test/remote/gateways/remote_authorize_net_cim_test.rb @@ -9,39 +9,39 @@ def setup @amount = 100 @credit_card = credit_card('4242424242424242') @payment = { - :credit_card => @credit_card + credit_card: @credit_card } @profile = { - :merchant_customer_id => 'Up to 20 chars', # Optional - :description => 'Up to 255 Characters', # Optional - :email => 'Up to 255 Characters', # Optional - :payment_profiles => { # Optional - :customer_type => 'individual', # Optional - :bill_to => address, - :payment => @payment + merchant_customer_id: 'Up to 20 chars', # Optional + description: 'Up to 255 Characters', # Optional + email: 'Up to 255 Characters', # Optional + payment_profiles: { # Optional + customer_type: 'individual', # Optional + bill_to: address, + payment: @payment }, - :ship_to_list => { - :first_name => 'John', - :last_name => 'Doe', - :company => 'Widgets, Inc', - :address1 => '1234 Fake Street', - :city => 'Anytown', - :state => 'MD', - :zip => '12345', - :country => 'USA', - :phone_number => '(123)123-1234', # Optional - Up to 25 digits (no letters) - :fax_number => '(123)123-1234' # Optional - Up to 25 digits (no letters) + ship_to_list: { + first_name: 'John', + last_name: 'Doe', + company: 'Widgets, Inc', + address1: '1234 Fake Street', + city: 'Anytown', + state: 'MD', + zip: '12345', + country: 'USA', + phone_number: '(123)123-1234', # Optional - Up to 25 digits (no letters) + fax_number: '(123)123-1234' # Optional - Up to 25 digits (no letters) } } @options = { - :ref_id => '1234', # Optional - :profile => @profile + ref_id: '1234', # Optional + profile: @profile } end def teardown if @customer_profile_id - assert response = @gateway.delete_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.delete_customer_profile(customer_profile_id: @customer_profile_id) assert_success response @customer_profile_id = nil end @@ -54,7 +54,7 @@ def test_successful_profile_create_get_update_and_delete assert_success response assert response.test? - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert response.test? assert_success response assert_equal @customer_profile_id, response.authorization @@ -68,11 +68,11 @@ def test_successful_profile_create_get_update_and_delete assert_equal @profile[:ship_to_list][:phone_number], response.params['profile']['ship_to_list']['phone_number'] assert_equal @profile[:ship_to_list][:company], response.params['profile']['ship_to_list']['company'] - assert response = @gateway.update_customer_profile(:profile => {:customer_profile_id => @customer_profile_id, :email => 'new email address'}) + assert response = @gateway.update_customer_profile(profile: { customer_profile_id: @customer_profile_id, email: 'new email address' }) assert response.test? assert_success response assert_nil response.authorization - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert_nil response.params['profile']['merchant_customer_id'] assert_nil response.params['profile']['description'] assert_equal 'new email address', response.params['profile']['email'] @@ -85,15 +85,15 @@ def test_successful_create_customer_profile_transaction_auth_only_and_then_captu assert response = @gateway.create_customer_profile(@options) @customer_profile_id = response.authorization - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) @customer_payment_profile_id = response.params['profile']['payment_profiles']['customer_payment_profile_id'] assert response = @gateway.create_customer_profile_transaction( - :transaction => { - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :type => :auth_only, - :amount => @amount + transaction: { + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + type: :auth_only, + amount: @amount } ) @@ -111,12 +111,12 @@ def test_successful_create_customer_profile_transaction_auth_only_and_then_captu # Capture the previously authorized funds assert response = @gateway.create_customer_profile_transaction( - :transaction => { - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :type => :capture_only, - :amount => @amount, - :approval_code => approval_code + transaction: { + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + type: :capture_only, + amount: @amount, + approval_code: approval_code } ) @@ -133,22 +133,22 @@ def test_successful_create_customer_profile_transaction_auth_capture_request assert response = @gateway.create_customer_profile(@options) @customer_profile_id = response.authorization - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) @customer_payment_profile_id = response.params['profile']['payment_profiles']['customer_payment_profile_id'] assert response = @gateway.create_customer_profile_transaction( - :transaction => { - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :type => :auth_capture, - :order => { - :invoice_number => '1234', - :description => 'Test Order Description', - :purchase_order_number => '4321' + transaction: { + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + type: :auth_capture, + order: { + invoice_number: '1234', + description: 'Test Order Description', + purchase_order_number: '4321' }, - :recurring_billing => true, - :card_code => '900', # authorize.net says this is a matching CVV - :amount => @amount + recurring_billing: true, + card_code: '900', # authorize.net says this is a matching CVV + amount: @amount } ) @@ -169,12 +169,12 @@ def test_successful_create_customer_payment_profile_request assert response = @gateway.create_customer_profile(@options) @customer_profile_id = response.authorization - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert_nil response.params['profile']['payment_profiles'] assert response = @gateway.create_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :payment_profile => payment_profile + customer_profile_id: @customer_profile_id, + payment_profile: payment_profile ) assert response.test? @@ -189,30 +189,30 @@ def test_successful_create_customer_payment_profile_request_with_bank_account assert response = @gateway.create_customer_profile(@options) @customer_profile_id = response.authorization - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert_nil response.params['profile']['payment_profiles'] assert response = @gateway.create_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :payment_profile => { - :customer_type => 'individual', # Optional - :bill_to => @address, - :payment => { - :bank_account => { - :account_type => :checking, - :name_on_account => 'John Doe', - :echeck_type => :ccd, - :bank_name => 'Bank of America', - :routing_number => '123456789', - :account_number => '12345' + customer_profile_id: @customer_profile_id, + payment_profile: { + customer_type: 'individual', # Optional + bill_to: @address, + payment: { + bank_account: { + account_type: :checking, + name_on_account: 'John Doe', + echeck_type: :ccd, + bank_name: 'Bank of America', + routing_number: '123456789', + account_number: '12345' } }, - :drivers_license => { - :state => 'MD', - :number => '12345', - :date_of_birth => '1981-3-31' + drivers_license: { + state: 'MD', + number: '12345', + date_of_birth: '1981-3-31' }, - :tax_id => '123456789' + tax_id: '123456789' } ) @@ -228,12 +228,12 @@ def test_successful_create_customer_shipping_address_request assert response = @gateway.create_customer_profile(@options) @customer_profile_id = response.authorization - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert_nil response.params['profile']['ship_to_list'] assert response = @gateway.create_customer_shipping_address( - :customer_profile_id => @customer_profile_id, - :address => shipping_address + customer_profile_id: @customer_profile_id, + address: shipping_address ) assert response.test? @@ -245,20 +245,20 @@ def test_successful_create_customer_shipping_address_request def test_successful_get_customer_profile_with_multiple_payment_profiles second_payment_profile = { - :customer_type => 'individual', - :bill_to => @address, - :payment => { - :credit_card => credit_card('1234123412341234') + customer_type: 'individual', + bill_to: @address, + payment: { + credit_card: credit_card('1234123412341234') } } assert response = @gateway.create_customer_profile(@options) @customer_profile_id = response.authorization - assert @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert response = @gateway.create_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :payment_profile => second_payment_profile + customer_profile_id: @customer_profile_id, + payment_profile: second_payment_profile ) assert response.test? @@ -267,7 +267,7 @@ def test_successful_get_customer_profile_with_multiple_payment_profiles assert customer_payment_profile_id = response.params['customer_payment_profile_id'] assert customer_payment_profile_id =~ /\d+/, "The customerPaymentProfileId should be numeric. It was #{customer_payment_profile_id}" - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert_equal 2, response.params['profile']['payment_profiles'].size assert_equal 'XXXX4242', response.params['profile']['payment_profiles'][0]['payment']['credit_card']['card_number'] assert_equal 'XXXX1234', response.params['profile']['payment_profiles'][1]['payment']['credit_card']['card_number'] @@ -277,19 +277,19 @@ def test_successful_delete_customer_payment_profile_request assert response = @gateway.create_customer_profile(@options) @customer_profile_id = response.authorization - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert customer_payment_profile_id = response.params['profile']['payment_profiles']['customer_payment_profile_id'] assert response = @gateway.delete_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => customer_payment_profile_id + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: customer_payment_profile_id ) assert response.test? assert_success response assert_nil response.authorization - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert_nil response.params['profile']['payment_profiles'] end @@ -297,19 +297,19 @@ def test_successful_delete_customer_shipping_address_request assert response = @gateway.create_customer_profile(@options) @customer_profile_id = response.authorization - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert customer_address_id = response.params['profile']['ship_to_list']['customer_address_id'] assert response = @gateway.delete_customer_shipping_address( - :customer_profile_id => @customer_profile_id, - :customer_address_id => customer_address_id + customer_profile_id: @customer_profile_id, + customer_address_id: customer_address_id ) assert response.test? assert_success response assert_nil response.authorization - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert_nil response.params['profile']['ship_to_list'] end @@ -317,12 +317,12 @@ def test_successful_get_customer_payment_profile_request assert response = @gateway.create_customer_profile(@options) @customer_profile_id = response.authorization - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert customer_payment_profile_id = response.params['profile']['payment_profiles']['customer_payment_profile_id'] assert response = @gateway.get_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => customer_payment_profile_id + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: customer_payment_profile_id ) assert response.test? @@ -338,13 +338,13 @@ def test_successful_get_customer_payment_profile_unmasked_request assert response = @gateway.create_customer_profile(@options) @customer_profile_id = response.authorization - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert customer_payment_profile_id = response.params['profile']['payment_profiles']['customer_payment_profile_id'] assert response = @gateway.get_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => customer_payment_profile_id, - :unmask_expiration_date => true + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: customer_payment_profile_id, + unmask_expiration_date: true ) assert response.test? @@ -360,12 +360,12 @@ def test_successful_get_customer_shipping_address_request assert response = @gateway.create_customer_profile(@options) @customer_profile_id = response.authorization - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert customer_address_id = response.params['profile']['ship_to_list']['customer_address_id'] assert response = @gateway.get_customer_shipping_address( - :customer_profile_id => @customer_profile_id, - :customer_address_id => customer_address_id + customer_profile_id: @customer_profile_id, + customer_address_id: customer_address_id ) assert response.test? @@ -381,13 +381,13 @@ def test_successful_update_customer_payment_profile_request @customer_profile_id = response.authorization # Get the customerPaymentProfileId - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert customer_payment_profile_id = response.params['profile']['payment_profiles']['customer_payment_profile_id'] # Get the customerPaymentProfile assert response = @gateway.get_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => customer_payment_profile_id + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: customer_payment_profile_id ) # The value before updating @@ -395,11 +395,11 @@ def test_successful_update_customer_payment_profile_request # Update the payment profile assert response = @gateway.update_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :payment_profile => { - :customer_payment_profile_id => customer_payment_profile_id, - :payment => { - :credit_card => credit_card('1234123412341234') + customer_profile_id: @customer_profile_id, + payment_profile: { + customer_payment_profile_id: customer_payment_profile_id, + payment: { + credit_card: credit_card('1234123412341234') } } ) @@ -409,8 +409,8 @@ def test_successful_update_customer_payment_profile_request # Get the updated payment profile assert response = @gateway.get_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => customer_payment_profile_id + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: customer_payment_profile_id ) # Show that the payment profile was updated @@ -419,25 +419,25 @@ def test_successful_update_customer_payment_profile_request assert_nil response.params['payment_profile']['customer_type'] new_billing_address = response.params['payment_profile']['bill_to'] - new_billing_address.update(:first_name => 'Frank', :last_name => 'Brown') - masked_credit_card = ActiveMerchant::Billing::CreditCard.new(:number => response.params['payment_profile']['payment']['credit_card']['card_number']) + new_billing_address.update(first_name: 'Frank', last_name: 'Brown') + masked_credit_card = ActiveMerchant::Billing::CreditCard.new(number: response.params['payment_profile']['payment']['credit_card']['card_number']) # Update only the billing address with a masked card and expiration date assert @gateway.update_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :payment_profile => { - :customer_payment_profile_id => customer_payment_profile_id, - :bill_to => new_billing_address, - :payment => { - :credit_card => masked_credit_card + customer_profile_id: @customer_profile_id, + payment_profile: { + customer_payment_profile_id: customer_payment_profile_id, + bill_to: new_billing_address, + payment: { + credit_card: masked_credit_card } } ) # Get the updated payment profile assert response = @gateway.get_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => customer_payment_profile_id + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: customer_payment_profile_id ) # Show that the billing address on the payment profile was updated @@ -450,40 +450,40 @@ def test_successful_update_customer_payment_profile_request_with_credit_card_las @customer_profile_id = response.authorization # Get the customerPaymentProfileId - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert customer_payment_profile_id = response.params['profile']['payment_profiles']['customer_payment_profile_id'] # Get the customerPaymentProfile assert response = @gateway.get_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => customer_payment_profile_id + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: customer_payment_profile_id ) # Card number last 4 digits is 4242 assert_equal 'XXXX4242', response.params['payment_profile']['payment']['credit_card']['card_number'], 'The card number should contain the last 4 digits of the card we passed in 4242' new_billing_address = response.params['payment_profile']['bill_to'] - new_billing_address.update(:first_name => 'Frank', :last_name => 'Brown') + new_billing_address.update(first_name: 'Frank', last_name: 'Brown') # Initialize credit card with only last 4 digits as the number - last_four_credit_card = ActiveMerchant::Billing::CreditCard.new(:number => '4242') # Credit card with only last four digits + last_four_credit_card = ActiveMerchant::Billing::CreditCard.new(number: '4242') # Credit card with only last four digits # Update only the billing address with a card with the last 4 digits and expiration date assert @gateway.update_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :payment_profile => { - :customer_payment_profile_id => customer_payment_profile_id, - :bill_to => new_billing_address, - :payment => { - :credit_card => last_four_credit_card + customer_profile_id: @customer_profile_id, + payment_profile: { + customer_payment_profile_id: customer_payment_profile_id, + bill_to: new_billing_address, + payment: { + credit_card: last_four_credit_card } } ) # Get the updated payment profile assert response = @gateway.get_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => customer_payment_profile_id + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: customer_payment_profile_id ) # Show that the billing address on the payment profile was updated @@ -496,13 +496,13 @@ def test_successful_update_customer_shipping_address_request @customer_profile_id = response.authorization # Get the customerAddressId - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert customer_address_id = response.params['profile']['ship_to_list']['customer_address_id'] # Get the customerShippingAddress assert response = @gateway.get_customer_shipping_address( - :customer_profile_id => @customer_profile_id, - :customer_address_id => customer_address_id + customer_profile_id: @customer_profile_id, + customer_address_id: customer_address_id ) assert address = response.params['address'] @@ -511,14 +511,14 @@ def test_successful_update_customer_shipping_address_request # Update the address and remove the phone_number new_address = address.symbolize_keys.merge!( - :address => '5678 Fake Street' + address: '5678 Fake Street' ) new_address.delete(:phone_number) # Update the shipping address assert response = @gateway.update_customer_shipping_address( - :customer_profile_id => @customer_profile_id, - :address => new_address + customer_profile_id: @customer_profile_id, + address: new_address ) assert response.test? assert_success response @@ -526,8 +526,8 @@ def test_successful_update_customer_shipping_address_request # Get the updated shipping address assert response = @gateway.get_customer_shipping_address( - :customer_profile_id => @customer_profile_id, - :customer_address_id => customer_address_id + customer_profile_id: @customer_profile_id, + customer_address_id: customer_address_id ) # Show that the shipping address was updated @@ -540,15 +540,15 @@ def test_successful_validate_customer_payment_profile_request_live assert response = @gateway.create_customer_profile(@options) @customer_profile_id = response.authorization - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert @customer_payment_profile_id = response.params['profile']['payment_profiles']['customer_payment_profile_id'] assert @customer_address_id = response.params['profile']['ship_to_list']['customer_address_id'] assert response = @gateway.validate_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :customer_address_id => @customer_address_id, - :validation_mode => :live + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + customer_address_id: @customer_address_id, + validation_mode: :live ) assert response.test? @@ -562,15 +562,15 @@ def test_validate_customer_payment_profile_request_live_requires_billing_address assert response = @gateway.create_customer_profile(@options) @customer_profile_id = response.authorization - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert @customer_payment_profile_id = response.params['profile']['payment_profiles']['customer_payment_profile_id'] assert @customer_address_id = response.params['profile']['ship_to_list']['customer_address_id'] assert response = @gateway.validate_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :customer_address_id => @customer_address_id, - :validation_mode => :live + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + customer_address_id: @customer_address_id, + validation_mode: :live ) assert response.test? @@ -583,15 +583,15 @@ def test_validate_customer_payment_profile_request_old_does_not_require_billing_ assert response = @gateway.create_customer_profile(@options) @customer_profile_id = response.authorization - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert @customer_payment_profile_id = response.params['profile']['payment_profiles']['customer_payment_profile_id'] assert @customer_address_id = response.params['profile']['ship_to_list']['customer_address_id'] assert response = @gateway.validate_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :customer_address_id => @customer_address_id, - :validation_mode => :old + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + customer_address_id: @customer_address_id, + validation_mode: :old ) assert response.test? @@ -603,24 +603,24 @@ def test_should_create_duplicate_customer_profile_transactions_with_duplicate_wi assert response = @gateway.create_customer_profile(@options) @customer_profile_id = response.authorization - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert @customer_payment_profile_id = response.params['profile']['payment_profiles']['customer_payment_profile_id'] key = (Time.now.to_f * 1000000).to_i.to_s customer_profile_transaction = { - :transaction => { - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :type => :auth_capture, - :order => { - :invoice_number => key.to_s, - :description => "Test Order Description #{key}", - :purchase_order_number => key.to_s + transaction: { + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + type: :auth_capture, + order: { + invoice_number: key.to_s, + description: "Test Order Description #{key}", + purchase_order_number: key.to_s }, - :amount => @amount + amount: @amount }, - :extra_options => { 'x_duplicate_window' => 1 } + extra_options: { 'x_duplicate_window' => 1 } } assert response = @gateway.create_customer_profile_transaction(customer_profile_transaction) @@ -639,22 +639,22 @@ def test_should_not_create_duplicate_customer_profile_transactions_without_dupli assert response = @gateway.create_customer_profile(@options) @customer_profile_id = response.authorization - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert @customer_payment_profile_id = response.params['profile']['payment_profiles']['customer_payment_profile_id'] key = (Time.now.to_f * 1000000).to_i.to_s customer_profile_transaction = { - :transaction => { - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :type => :auth_capture, - :order => { - :invoice_number => key.to_s, - :description => "Test Order Description #{key}", - :purchase_order_number => key.to_s + transaction: { + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + type: :auth_capture, + order: { + invoice_number: key.to_s, + description: "Test Order Description #{key}", + purchase_order_number: key.to_s }, - :amount => @amount + amount: @amount } } @@ -674,9 +674,9 @@ def test_should_create_customer_profile_transaction_auth_capture_and_then_void_r response = get_and_validate_auth_capture_response assert response = @gateway.create_customer_profile_transaction_for_void( - :transaction => { - :type => :void, - :trans_id => response.params['direct_response']['transaction_id'] + transaction: { + type: :void, + trans_id: response.params['direct_response']['transaction_id'] } ) assert_instance_of Response, response @@ -689,12 +689,12 @@ def test_should_create_customer_profile_transaction_auth_capture_and_then_refund response = get_and_validate_auth_capture_response assert response = @gateway.create_customer_profile_transaction( - :transaction => { - :type => :refund, - :amount => 1, - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :trans_id => response.params['direct_response']['transaction_id'] + transaction: { + type: :refund, + amount: 1, + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + trans_id: response.params['direct_response']['transaction_id'] } ) assert_instance_of Response, response @@ -710,13 +710,13 @@ def test_should_create_customer_profile_transaction_auth_capture_and_then_refund response = get_and_validate_auth_capture_response assert response = @gateway.create_customer_profile_transaction( - :transaction => { - :type => :refund, - :amount => 1, - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :trans_id => response.params['direct_response']['transaction_id'], - :order => {} + transaction: { + type: :refund, + amount: 1, + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + trans_id: response.params['direct_response']['transaction_id'], + order: {} } ) assert_instance_of Response, response @@ -732,11 +732,11 @@ def test_should_create_customer_profile_transaction_auth_capture_and_then_refund response = get_and_validate_auth_capture_response assert response = @gateway.create_customer_profile_transaction( - :transaction => { - :type => :refund, - :amount => 1, - :credit_card_number_masked => 'XXXX4242', - :trans_id => response.params['direct_response']['transaction_id'] + transaction: { + type: :refund, + amount: 1, + credit_card_number_masked: 'XXXX4242', + trans_id: response.params['direct_response']['transaction_id'] } ) assert_instance_of Response, response @@ -752,10 +752,10 @@ def test_should_create_customer_profile_transaction_auth_only_and_then_prior_aut response = get_and_validate_auth_only_response assert response = @gateway.create_customer_profile_transaction( - :transaction => { - :type => :prior_auth_capture, - :trans_id => response.params['direct_response']['transaction_id'], - :amount => response.params['direct_response']['amount'] + transaction: { + type: :prior_auth_capture, + trans_id: response.params['direct_response']['transaction_id'], + amount: response.params['direct_response']['amount'] } ) assert_instance_of Response, response @@ -770,30 +770,30 @@ def get_and_validate_customer_payment_profile_request_with_bank_account_response assert response = @gateway.create_customer_profile(@options) @customer_profile_id = response.authorization - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert_nil response.params['profile']['payment_profiles'] assert response = @gateway.create_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :payment_profile => { - :customer_type => 'individual', # Optional - :bill_to => @address, - :payment => { - :bank_account => { - :account_type => :checking, - :name_on_account => 'John Doe', - :echeck_type => :ccd, - :bank_name => 'Bank of America', - :routing_number => '123456789', - :account_number => '12345678' + customer_profile_id: @customer_profile_id, + payment_profile: { + customer_type: 'individual', # Optional + bill_to: @address, + payment: { + bank_account: { + account_type: :checking, + name_on_account: 'John Doe', + echeck_type: :ccd, + bank_name: 'Bank of America', + routing_number: '123456789', + account_number: '12345678' } }, - :drivers_license => { - :state => 'MD', - :number => '12345', - :date_of_birth => '1981-3-31' + drivers_license: { + state: 'MD', + number: '12345', + date_of_birth: '1981-3-31' }, - :tax_id => '123456789' + tax_id: '123456789' } ) @@ -809,22 +809,22 @@ def get_and_validate_auth_capture_response assert response = @gateway.create_customer_profile(@options) @customer_profile_id = response.authorization - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) @customer_payment_profile_id = response.params['profile']['payment_profiles']['customer_payment_profile_id'] key = (Time.now.to_f * 1000000).to_i.to_s assert response = @gateway.create_customer_profile_transaction( - :transaction => { - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :type => :auth_capture, - :order => { - :invoice_number => key.to_s, - :description => "Test Order Description #{key}", - :purchase_order_number => key.to_s + transaction: { + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + type: :auth_capture, + order: { + invoice_number: key.to_s, + description: "Test Order Description #{key}", + purchase_order_number: key.to_s }, - :amount => @amount + amount: @amount } ) @@ -847,19 +847,19 @@ def get_and_validate_auth_only_response key = (Time.now.to_f * 1000000).to_i.to_s - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) @customer_payment_profile_id = response.params['profile']['payment_profiles']['customer_payment_profile_id'] assert response = @gateway.create_customer_profile_transaction( - :transaction => { - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :type => :auth_only, - :order => { - :invoice_number => key.to_s, - :description => "Test Order Description #{key}", - :purchase_order_number => key.to_s + transaction: { + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + type: :auth_only, + order: { + invoice_number: key.to_s, + description: "Test Order Description #{key}", + purchase_order_number: key.to_s }, - :amount => @amount + amount: @amount } ) @@ -872,5 +872,4 @@ def get_and_validate_auth_only_response return response end - end diff --git a/test/remote/gateways/remote_authorize_net_test.rb b/test/remote/gateways/remote_authorize_net_test.rb index 2b239ad18bb..3fa59c7d76b 100644 --- a/test/remote/gateways/remote_authorize_net_test.rb +++ b/test/remote/gateways/remote_authorize_net_test.rb @@ -19,19 +19,19 @@ def setup @level_2_options = { tax: { - amount: '100', - name: 'tax name', - description: 'tax description' - }, + amount: '100', + name: 'tax name', + description: 'tax description' + }, duty: { - amount: '200', - name: 'duty name', - description: 'duty description' - }, + amount: '200', + name: 'duty name', + description: 'duty description' + }, shipping: { amount: '300', name: 'shipping name', - description: 'shipping description', + description: 'shipping description' }, tax_exempt: 'false', po_number: '123' @@ -164,7 +164,7 @@ def test_successful_purchase_with_utf_character assert_match %r{This transaction has been approved}, response.message end - def test_successful_echeck_purchase + def test_successful_echeck_purchase_with_checking_account_type response = @gateway.purchase(@amount, @check, @options) assert_success response assert response.test? @@ -172,6 +172,15 @@ def test_successful_echeck_purchase assert response.authorization end + def test_successful_echeck_purchase_with_savings_account_type + savings_account = check(account_type: 'savings') + response = @gateway.purchase(@amount, savings_account, @options) + assert_success response + assert response.test? + assert_equal 'This transaction has been approved', response.message + assert response.authorization + end + def test_card_present_purchase_with_no_data no_data_credit_card = ActiveMerchant::Billing::CreditCard.new response = @gateway.purchase(@amount, no_data_credit_card, @options) @@ -202,8 +211,92 @@ def test_successful_purchase_with_disable_partial_authorize assert_success purchase end + def test_successful_auth_and_capture_with_recurring_stored_credential + stored_credential_params = { + initial_transaction: true, + reason_type: 'recurring', + initiator: 'merchant', + network_transaction_id: nil + } + assert auth = @gateway.authorize(@amount, @credit_card, @options.merge({ stored_credential: stored_credential_params })) + assert_success auth + assert auth.authorization + + assert capture = @gateway.capture(@amount, auth.authorization, authorization_validated: true) + assert_success capture + + @options[:stored_credential] = { + initial_transaction: false, + reason_type: 'recurring', + initiator: 'merchant', + network_transaction_id: auth.params['transaction_identifier'] + } + + assert next_auth = @gateway.authorize(@amount, @credit_card, @options) + assert next_auth.authorization + + assert capture = @gateway.capture(@amount, next_auth.authorization, authorization_validated: true) + assert_success capture + end + + def test_successful_auth_and_capture_with_unscheduled_stored_credential + stored_credential_params = { + initial_transaction: true, + reason_type: 'unscheduled', + initiator: 'merchant', + network_transaction_id: nil + } + assert auth = @gateway.authorize(@amount, @credit_card, @options.merge({ stored_credential: stored_credential_params })) + assert_success auth + assert auth.authorization + + assert capture = @gateway.capture(@amount, auth.authorization, authorization_validated: true) + assert_success capture + + @options[:stored_credential] = { + initial_transaction: false, + reason_type: 'unscheduled', + initiator: 'merchant', + network_transaction_id: auth.params['transaction_identifier'] + } + + assert next_auth = @gateway.authorize(@amount, @credit_card, @options) + assert next_auth.authorization + + assert capture = @gateway.capture(@amount, next_auth.authorization, authorization_validated: true) + assert_success capture + end + + def test_successful_auth_and_capture_with_installment_stored_credential + stored_credential_params = { + initial_transaction: true, + reason_type: 'installment', + initiator: 'merchant', + network_transaction_id: nil + } + assert auth = @gateway.authorize(@amount, @credit_card, @options.merge({ stored_credential: stored_credential_params })) + assert_success auth + assert auth.authorization + + assert capture = @gateway.capture(@amount, auth.authorization, authorization_validated: true) + assert_success capture + + @options[:stored_credential] = { + initial_transaction: false, + reason_type: 'installment', + initiator: 'merchant', + network_transaction_id: auth.params['transaction_identifier'] + } + + assert next_auth = @gateway.authorize(@amount, @credit_card, @options) + assert next_auth.authorization + + assert capture = @gateway.capture(@amount, next_auth.authorization, authorization_validated: true) + assert_success capture + end + def test_successful_authorize_with_email_and_ip - options = @options.merge({email: 'hello@example.com', ip: '127.0.0.1'}) + options = @options.merge({ email: 'hello@example.com', ip: '127.0.0.1' }) auth = @gateway.authorize(@amount, @credit_card, options) assert_success auth @@ -220,7 +313,7 @@ def test_failed_authorize end def test_card_present_authorize_and_capture_with_track_data_only - track_credit_card = ActiveMerchant::Billing::CreditCard.new(:track_data => '%B378282246310005^LONGSON/LONGBOB^1705101130504392?') + track_credit_card = ActiveMerchant::Billing::CreditCard.new(track_data: '%B378282246310005^LONGSON/LONGBOB^1705101130504392?') assert authorization = @gateway.authorize(@amount, track_credit_card, @options) assert_success authorization @@ -245,7 +338,7 @@ def test_failed_echeck_authorization end def test_card_present_purchase_with_track_data_only - track_credit_card = ActiveMerchant::Billing::CreditCard.new(:track_data => '%B378282246310005^LONGSON/LONGBOB^1705101130504392?') + track_credit_card = ActiveMerchant::Billing::CreditCard.new(track_data: '%B378282246310005^LONGSON/LONGBOB^1705101130504392?') response = @gateway.purchase(@amount, track_credit_card, @options) assert response.test? assert_equal 'This transaction has been approved', response.message @@ -318,7 +411,7 @@ def test_successful_store_new_payment_profile assert store.authorization new_card = credit_card('4424222222222222') - customer_profile_id, _, _ = store.authorization.split('#') + customer_profile_id, = store.authorization.split('#') assert response = @gateway.store(new_card, customer_profile_id: customer_profile_id) assert_success response @@ -332,7 +425,7 @@ def test_failed_store_new_payment_profile assert store.authorization new_card = credit_card('141241') - customer_profile_id, _, _ = store.authorization.split('#') + customer_profile_id, = store.authorization.split('#') assert response = @gateway.store(new_card, customer_profile_id: customer_profile_id) assert_failure response @@ -384,7 +477,7 @@ def test_successful_purchase_using_stored_card_new_payment_profile assert store.authorization new_card = credit_card('4007000000027') - customer_profile_id, _, _ = store.authorization.split('#') + customer_profile_id, = store.authorization.split('#') assert response = @gateway.store(new_card, customer_profile_id: customer_profile_id, email: 'anet@example.com', billing_address: address) assert_success response @@ -554,8 +647,8 @@ def test_failed_void_using_stored_card def test_bad_login gateway = AuthorizeNetGateway.new( - :login => 'X', - :password => 'Y' + login: 'X', + password: 'Y' ) response = gateway.purchase(@amount, @credit_card) @@ -583,7 +676,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - capture = @gateway.capture(@amount-1, auth.authorization) + capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -638,7 +731,7 @@ def test_successful_echeck_refund purchase = @gateway.purchase(@amount, @check, @options) assert_success purchase - @options.update(transaction_id: purchase.params['transaction_id'], test_request: true) + @options.update(transaction_id: purchase.params['transaction_id'], test_request: true) refund = @gateway.credit(@amount, @check, @options) assert_failure refund assert_match %r{The transaction cannot be found}, refund.message, 'Only allowed to refund transactions that have settled. This is the best we can do for now testing wise.' @@ -671,8 +764,7 @@ def test_dump_transcript def test_successful_authorize_and_capture_with_network_tokenization credit_card = network_tokenization_credit_card('4000100011112224', payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', - verification_value: nil - ) + verification_value: nil) auth = @gateway.authorize(@amount, credit_card, @options) assert_success auth assert_equal 'This transaction has been approved', auth.message @@ -684,8 +776,7 @@ def test_successful_authorize_and_capture_with_network_tokenization def test_successful_refund_with_network_tokenization credit_card = network_tokenization_credit_card('4000100011112224', payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', - verification_value: nil - ) + verification_value: nil) purchase = @gateway.purchase(@amount, credit_card, @options) assert_success purchase @@ -700,8 +791,7 @@ def test_successful_refund_with_network_tokenization def test_successful_credit_with_network_tokenization credit_card = network_tokenization_credit_card('4000100011112224', payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', - verification_value: nil - ) + verification_value: nil) response = @gateway.credit(@amount, credit_card, @options) assert_success response @@ -711,10 +801,9 @@ def test_successful_credit_with_network_tokenization def test_network_tokenization_transcript_scrubbing credit_card = network_tokenization_credit_card('4111111111111111', - :brand => 'visa', - :eci => '05', - :payment_cryptogram => 'EHuWW9PiBkWvqE5juRwDzAUFBAk=' - ) + brand: 'visa', + eci: '05', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=') transcript = capture_transcript(@gateway) do @gateway.authorize(@amount, credit_card, @options) @@ -743,5 +832,4 @@ def test_verify_credentials gateway = AuthorizeNetGateway.new(login: 'unknown_login', password: 'not_right') assert !gateway.verify_credentials end - end diff --git a/test/remote/gateways/remote_axcessms_test.rb b/test/remote/gateways/remote_axcessms_test.rb index 54b1c82213a..225064740f9 100644 --- a/test/remote/gateways/remote_axcessms_test.rb +++ b/test/remote/gateways/remote_axcessms_test.rb @@ -30,7 +30,7 @@ def test_successful_authorize_and_capture assert_success auth, 'Authorize failed' assert_match %r{Successful Processing - Request successfully processed}, auth.message - assert capture = @gateway.capture(@amount, auth.authorization, {mode: @mode}) + assert capture = @gateway.capture(@amount, auth.authorization, { mode: @mode }) assert_success capture, 'Capture failed' assert_match %r{Successful Processing - Request successfully processed}, capture.message end @@ -40,7 +40,7 @@ def test_successful_authorize_and_partial_capture assert_success auth, 'Authorize failed' assert_match %r{Successful Processing - Request successfully processed}, auth.message - assert capture = @gateway.capture(@amount-30, auth.authorization, {mode: @mode}) + assert capture = @gateway.capture(@amount - 30, auth.authorization, { mode: @mode }) assert_success capture, 'Capture failed' assert_match %r{Successful Processing - Request successfully processed}, capture.message end @@ -50,7 +50,7 @@ def test_successful_authorize_and_void assert_success auth, 'Authorize failed' assert_match %r{Successful Processing - Request successfully processed}, auth.message - assert void = @gateway.void(auth.authorization, {mode: @mode}) + assert void = @gateway.void(auth.authorization, { mode: @mode }) assert_success void, 'Void failed' assert_match %r{Successful Processing - Request successfully processed}, void.message end @@ -82,7 +82,7 @@ def test_successful_purchase_and_refund assert_success purchase, 'Purchase failed' assert_match %r{Successful Processing - Request successfully processed}, purchase.message - assert refund = @gateway.refund(@amount, purchase.authorization, {mode: @mode}) + assert refund = @gateway.refund(@amount, purchase.authorization, { mode: @mode }) assert_success refund, 'Refund failed' assert_match %r{Successful Processing - Request successfully processed}, refund.message end @@ -92,7 +92,7 @@ def test_successful_purchase_and_partial_refund assert_success purchase, 'Purchase failed' assert_match %r{Successful Processing - Request successfully processed}, purchase.message - assert refund = @gateway.refund(@amount-50, purchase.authorization, {mode: @mode}) + assert refund = @gateway.refund(@amount - 50, purchase.authorization, { mode: @mode }) assert_success refund, 'Refund failed' assert_match %r{Successful Processing - Request successfully processed}, refund.message end @@ -115,7 +115,7 @@ def test_failed_bigger_capture_then_authorised auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth, 'Authorize failed' - assert capture = @gateway.capture(@amount+30, auth.authorization, {mode: @mode}) + assert capture = @gateway.capture(@amount + 30, auth.authorization, { mode: @mode }) assert_failure capture, 'Capture failed' assert_match %r{PA value exceeded}, capture.message end @@ -127,13 +127,13 @@ def test_failed_authorize end def test_failed_refund - assert refund = @gateway.refund(@amount, 'invalid authorization', {mode: @mode}) + assert refund = @gateway.refund(@amount, 'invalid authorization', { mode: @mode }) assert_failure refund assert_match %r{Configuration Validation - Invalid payment data}, refund.message end def test_failed_void - void = @gateway.void('invalid authorization', {mode: @mode}) + void = @gateway.void('invalid authorization', { mode: @mode }) assert_failure void assert_match %r{Reference Error - reversal}, void.message end diff --git a/test/remote/gateways/remote_balanced_test.rb b/test/remote/gateways/remote_balanced_test.rb index d5930116419..9613e557f06 100644 --- a/test/remote/gateways/remote_balanced_test.rb +++ b/test/remote/gateways/remote_balanced_test.rb @@ -144,7 +144,7 @@ def test_refund_partial_purchase def test_store new_email_address = '%d@example.org' % Time.now store = @gateway.store(@credit_card, { - email: new_email_address + email: new_email_address }) assert_instance_of String, store.authorization end diff --git a/test/remote/gateways/remote_bambora_apac_test.rb b/test/remote/gateways/remote_bambora_apac_test.rb index 896f0d17865..43f92c7be3b 100644 --- a/test/remote/gateways/remote_bambora_apac_test.rb +++ b/test/remote/gateways/remote_bambora_apac_test.rb @@ -9,7 +9,7 @@ def setup @options = { order_id: '1', billing_address: address, - description: 'Store Purchase', + description: 'Store Purchase' } end @@ -69,14 +69,14 @@ def test_failed_refund def test_successful_void response = @gateway.purchase(200, @credit_card, @options) assert_success response - response = @gateway.void(200, response.authorization) + response = @gateway.void(response.authorization, amount: 200) assert_success response end def test_failed_void response = @gateway.purchase(200, @credit_card, @options) assert_success response - response = @gateway.void(200, 123) + response = @gateway.void(123, amount: 200) assert_failure response assert_equal 'Cannot find matching transaction to VOID', response.message end diff --git a/test/remote/gateways/remote_bank_frick_test.rb b/test/remote/gateways/remote_bank_frick_test.rb index d1bb6447d4e..e817b7c0aff 100644 --- a/test/remote/gateways/remote_bank_frick_test.rb +++ b/test/remote/gateways/remote_bank_frick_test.rb @@ -24,7 +24,7 @@ def test_successful_purchase end def test_successful_purchase_with_minimal_options - assert response = @gateway.purchase(@amount, @credit_card, {address: address}) + assert response = @gateway.purchase(@amount, @credit_card, { address: address }) assert_success response assert response.test? assert_match %r{Transaction succeeded}, response.message @@ -63,7 +63,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -84,7 +84,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund end diff --git a/test/remote/gateways/remote_banwire_test.rb b/test/remote/gateways/remote_banwire_test.rb index 0af462e9a7b..37004591279 100644 --- a/test/remote/gateways/remote_banwire_test.rb +++ b/test/remote/gateways/remote_banwire_test.rb @@ -7,12 +7,12 @@ def setup @gateway = BanwireGateway.new(fixtures(:banwire)) @amount = 100 - @credit_card = credit_card('5204164299999999', :verification_value => '999', :brand => 'mastercard') - @visa_credit_card = credit_card('4485814063899108', :verification_value => '434') + @credit_card = credit_card('5204164299999999', verification_value: '999', brand: 'mastercard') + @visa_credit_card = credit_card('4485814063899108', verification_value: '434') @declined_card = credit_card('4000300011112220') @options = { - billing_address: address, + billing_address: address } end @@ -45,9 +45,9 @@ def test_unsuccessful_purchase def test_invalid_login gateway = BanwireGateway.new( - :login => 'fakeuser', - :currency => 'MXN' - ) + login: 'fakeuser', + currency: 'MXN' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'ID de cuenta invalido', response.message @@ -62,5 +62,4 @@ def test_transcript_scrubbing assert_scrubbed(@credit_card.number, clean_transcript) assert_scrubbed(@credit_card.verification_value.to_s, clean_transcript) end - end diff --git a/test/remote/gateways/remote_barclaycard_smartpay_test.rb b/test/remote/gateways/remote_barclaycard_smartpay_test.rb index 0cd7a6ab001..ac59135ddba 100644 --- a/test/remote/gateways/remote_barclaycard_smartpay_test.rb +++ b/test/remote/gateways/remote_barclaycard_smartpay_test.rb @@ -7,84 +7,86 @@ def setup @amount = 100 @error_amount = 1_000_000_000_000_000_000_000 - @credit_card = credit_card('4111111111111111', :month => 10, :year => 2020, :verification_value => 737) - @declined_card = credit_card('4000300011112220', :month => 3, :year => 2030, :verification_value => 737) + @credit_card = credit_card('4111111111111111', month: 10, year: 2020, verification_value: 737) + @declined_card = credit_card('4000300011112220', month: 3, year: 2030, verification_value: 737) @three_ds_enrolled_card = credit_card('4212345678901237', brand: :visa) - @three_ds_2_enrolled_card = credit_card('4917610000000000', brand: :visa) + @three_ds_2_enrolled_card = credit_card('4917610000000000', month: 10, year: 2020, verification_value: '737', brand: :visa) @options = { 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' } @options_with_alternate_address = { - order_id: '1', - billing_address: { - name: 'PU JOI SO', - address1: '新北市店溪路3579號139樓', - company: 'Widgets Inc', - city: '新北市', - zip: '231509', - country: 'TW', - phone: '(555)555-5555', - fax: '(555)555-6666' - }, - email: 'pujoi@so.com', - customer: 'PU JOI SO', - description: 'Store Purchase' + order_id: '1', + billing_address: { + name: 'PU JOI SO', + address1: '新北市店溪路3579號139樓', + company: 'Widgets Inc', + city: '新北市', + zip: '231509', + country: 'TW', + phone: '(555)555-5555', + fax: '(555)555-6666' + }, + email: 'pujoi@so.com', + customer: 'PU JOI SO', + description: 'Store Purchase' } @options_with_house_number_and_street = { - order_id: '1', - house_number: '100', - street: 'Top Level Drive', - billing_address: { - name: 'Jim Smith', - address1: '100 Top Level Dr', - company: 'Widgets Inc', - city: 'Ottawa', - state: 'ON', - zip: 'K1C2N6', - country: 'CA', - phone: '(555)555-5555', - fax: '(555)555-6666' - }, - email: 'long@deb.com', - customer: 'Longdeb Longsen', - description: 'Store Purchase' + order_id: '1', + house_number: '100', + street: 'Top Level Drive', + billing_address: { + name: 'Jim Smith', + address1: '100 Top Level Dr', + company: 'Widgets Inc', + city: 'Ottawa', + state: 'ON', + zip: 'K1C2N6', + country: 'CA', + phone: '(555)555-5555', + fax: '(555)555-6666' + }, + email: 'long@deb.com', + customer: 'Longdeb Longsen', + description: 'Store Purchase' } @options_with_no_address = { - order_id: '1', - email: 'long@bob.com', - customer: 'Longbob Longsen', - description: 'Store Purchase' + order_id: '1', + email: 'long@bob.com', + customer: 'Longbob Longsen', + 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', @@ -99,20 +101,20 @@ def setup } @avs_credit_card = credit_card('4400000000000008', - :month => 8, - :year => 2018, - :verification_value => 737) + month: 8, + year: 2018, + verification_value: 737) @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', @@ -121,7 +123,7 @@ def setup shopper_reference: 'John Smith', billing_address: address(), order_id: '123', - stored_credential: {reason_type: 'unscheduled'}, + stored_credential: { reason_type: 'unscheduled' }, three_ds_2: { channel: 'browser', browser_info: { @@ -222,6 +224,28 @@ def test_successful_authorize_with_3ds2_browser_client_data refute response.params['additionalData']['threeds2.threeDSMethodURL'].blank? end + def test_successful_purchase_with_3ds2_exemption_requested_and_execute_threed_false + assert response = @gateway.authorize(@amount, @three_ds_2_enrolled_card, @normalized_3ds_2_options.merge(execute_threed: false, sca_exemption: 'lowValue')) + assert response.test? + refute response.authorization.blank? + + assert_equal response.params['resultCode'], 'Authorised' + end + + # According to Adyen documentation, if execute_threed is set to true and an exemption provided + # the gateway will apply and request for the specified exemption in the authentication request, + # after the device fingerprint is submitted to the issuer. + def test_successful_purchase_with_3ds2_exemption_requested_and_execute_threed_true + assert response = @gateway.authorize(@amount, @three_ds_2_enrolled_card, @normalized_3ds_2_options.merge(execute_threed: true, sca_exemption: 'lowValue')) + assert response.test? + refute response.authorization.blank? + + 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_successful_authorize_with_3ds2_app_based_request three_ds_app_based_options = { reference: '345123', @@ -230,9 +254,9 @@ def test_successful_authorize_with_3ds2_app_based_request shopper_reference: 'John Smith', billing_address: address(), order_id: '123', - stored_credential: {reason_type: 'unscheduled'}, + stored_credential: { reason_type: 'unscheduled' }, three_ds_2: { - channel: 'app', + channel: 'app' } } @@ -318,7 +342,7 @@ def test_failed_credit_insufficient_validation end def test_successful_third_party_payout - response = @gateway.credit(@amount, @credit_card, @options_with_credit_fields.merge({third_party_payout: true})) + response = @gateway.credit(@amount, @credit_card, @options_with_credit_fields.merge({ third_party_payout: true })) assert_success response end @@ -366,7 +390,7 @@ def test_successful_store end def test_failed_store - response = @gateway.store(credit_card('4111111111111111', :month => '', :year => '', :verification_value => ''), @options) + response = @gateway.store(credit_card('4111111111111111', month: '', year: '', verification_value: ''), @options) assert_failure response assert_equal '129: Expiry Date Invalid', response.message end @@ -385,17 +409,17 @@ def test_avs_no_with_house_number end def test_nonfractional_currency - response = @gateway.authorize(1234, @credit_card, @options.merge(:currency => 'JPY')) + response = @gateway.authorize(1234, @credit_card, @options.merge(currency: 'JPY')) assert_success response - response = @gateway.purchase(1234, @credit_card, @options.merge(:currency => 'JPY')) + response = @gateway.purchase(1234, @credit_card, @options.merge(currency: 'JPY')) assert_success response end def test_three_decimal_currency - response = @gateway.authorize(1234, @credit_card, @options.merge(:currency => 'OMR')) + response = @gateway.authorize(1234, @credit_card, @options.merge(currency: 'OMR')) assert_success response - response = @gateway.purchase(1234, @credit_card, @options.merge(:currency => 'OMR')) + response = @gateway.purchase(1234, @credit_card, @options.merge(currency: 'OMR')) assert_success response end diff --git a/test/remote/gateways/remote_barclays_epdq_extra_plus_test.rb b/test/remote/gateways/remote_barclays_epdq_extra_plus_test.rb index dd06e16d724..60ccd0eb6d0 100644 --- a/test/remote/gateways/remote_barclays_epdq_extra_plus_test.rb +++ b/test/remote/gateways/remote_barclays_epdq_extra_plus_test.rb @@ -6,15 +6,15 @@ class RemoteBarclaysEpdqExtraPlusTest < Test::Unit::TestCase def setup @gateway = BarclaysEpdqExtraPlusGateway.new(fixtures(:barclays_epdq_extra_plus)) @amount = 100 - @credit_card = credit_card('4000100011112224', :verification_value => '987') - @mastercard = credit_card('5399999999999999', :brand => 'mastercard') + @credit_card = credit_card('4000100011112224', verification_value: '987') + @mastercard = credit_card('5399999999999999', brand: 'mastercard') @declined_card = credit_card('1111111111111111') - @credit_card_d3d = credit_card('4000000000000002', :verification_value => '111') + @credit_card_d3d = credit_card('4000000000000002', verification_value: '111') @options = { - :order_id => generate_unique_id[0...30], - :billing_address => address, - :description => 'Store Purchase', - :currency => fixtures(:barclays_epdq_extra_plus)[:currency] || 'GBP' + order_id: generate_unique_id[0...30], + billing_address: address, + description: 'Store Purchase', + currency: fixtures(:barclays_epdq_extra_plus)[:currency] || 'GBP' } end @@ -37,13 +37,13 @@ def test_successful_purchase_with_minimal_info end def test_successful_purchase_with_utf8_encoding_1 - assert response = @gateway.purchase(@amount, credit_card('4000100011112224', :first_name => 'Rémy', :last_name => 'Fröåïør'), @options) + assert response = @gateway.purchase(@amount, credit_card('4000100011112224', first_name: 'Rémy', last_name: 'Fröåïør'), @options) assert_success response assert_equal BarclaysEpdqExtraPlusGateway::SUCCESS_MESSAGE, response.message end def test_successful_purchase_with_utf8_encoding_2 - assert response = @gateway.purchase(@amount, credit_card('4000100011112224', :first_name => 'ワタシ', :last_name => 'ёжзийклмнопрсуфхцч'), @options) + assert response = @gateway.purchase(@amount, credit_card('4000100011112224', first_name: 'ワタシ', last_name: 'ёжзийклмнопрсуфхцч'), @options) assert_success response assert_equal BarclaysEpdqExtraPlusGateway::SUCCESS_MESSAGE, response.message end @@ -51,7 +51,7 @@ def test_successful_purchase_with_utf8_encoding_2 # NOTE: You have to set the "Hash algorithm" to "SHA-1" in the "Technical information"->"Global security parameters" # section of your account admin before running this test def test_successful_purchase_with_signature_encryptor_to_sha1 - gateway = BarclaysEpdqExtraPlusGateway.new(fixtures(:barclays_epdq_extra_plus).merge(:signature_encryptor => 'sha1')) + gateway = BarclaysEpdqExtraPlusGateway.new(fixtures(:barclays_epdq_extra_plus).merge(signature_encryptor: 'sha1')) assert response = gateway.purchase(@amount, @credit_card, @options) assert_success response assert_equal BarclaysEpdqExtraPlusGateway::SUCCESS_MESSAGE, response.message @@ -60,7 +60,7 @@ def test_successful_purchase_with_signature_encryptor_to_sha1 # NOTE: You have to set the "Hash algorithm" to "SHA-256" in the "Technical information"->"Global security parameters" # section of your account admin before running this test def test_successful_purchase_with_signature_encryptor_to_sha256 - gateway = BarclaysEpdqExtraPlusGateway.new(fixtures(:barclays_epdq_extra_plus).merge(:signature_encryptor => 'sha256')) + gateway = BarclaysEpdqExtraPlusGateway.new(fixtures(:barclays_epdq_extra_plus).merge(signature_encryptor: 'sha256')) assert response = gateway.purchase(@amount, @credit_card, @options) assert_success response assert_equal BarclaysEpdqExtraPlusGateway::SUCCESS_MESSAGE, response.message @@ -69,7 +69,7 @@ def test_successful_purchase_with_signature_encryptor_to_sha256 # NOTE: You have to set the "Hash algorithm" to "SHA-512" in the "Technical information"->"Global security parameters" # section of your account admin before running this test def test_successful_purchase_with_signature_encryptor_to_sha512 - gateway = BarclaysEpdqExtraPlusGateway.new(fixtures(:barclays_epdq_extra_plus).merge(:signature_encryptor => 'sha512')) + gateway = BarclaysEpdqExtraPlusGateway.new(fixtures(:barclays_epdq_extra_plus).merge(signature_encryptor: 'sha512')) assert response = gateway.purchase(@amount, @credit_card, @options) assert_success response assert_equal BarclaysEpdqExtraPlusGateway::SUCCESS_MESSAGE, response.message @@ -125,76 +125,75 @@ def test_successful_void assert_success void end -=begin Enable if/when fully enabled account is available to test - def test_reference_transactions - # Setting an alias - assert response = @gateway.purchase(@amount, credit_card('4000100011112224'), @options.merge(:billing_id => "awesomeman", :order_id=>Time.now.to_i.to_s+"1")) - assert_success response - # Updating an alias - assert response = @gateway.purchase(@amount, credit_card('4111111111111111'), @options.merge(:billing_id => "awesomeman", :order_id=>Time.now.to_i.to_s+"2")) - assert_success response - # Using an alias (i.e. don't provide the credit card) - assert response = @gateway.purchase(@amount, "awesomeman", @options.merge(:order_id => Time.now.to_i.to_s + "3")) - assert_success response - end - - def test_successful_store - assert response = @gateway.store(@credit_card, :billing_id => 'test_alias') - assert_success response - assert purchase = @gateway.purchase(@amount, 'test_alias') - assert_success purchase - end - - def test_successful_store_generated_alias - assert response = @gateway.store(@credit_card) - assert_success response - assert purchase = @gateway.purchase(@amount, response.billing_id) - assert_success purchase - end - - def test_successful_store - assert response = @gateway.store(@credit_card, :billing_id => 'test_alias') - assert_success response - assert purchase = @gateway.purchase(@amount, 'test_alias') - assert_success purchase - end - - def test_successful_unreferenced_credit - assert credit = @gateway.credit(@amount, @credit_card, @options) - assert_success credit - assert credit.authorization - assert_equal BarclaysEpdqExtraPlusGateway::SUCCESS_MESSAGE, credit.message - end - - # NOTE: You have to allow USD as a supported currency in the "Account"->"Currencies" - # section of your account admin before running this test - def test_successful_purchase_with_custom_currency_at_the_gateway_level - gateway = BarclaysEpdqExtraPlusGateway.new(fixtures(:barclays_epdq_extra_plus).merge(:currency => 'USD')) - assert response = gateway.purchase(@amount, @credit_card) - assert_success response - assert_equal BarclaysEpdqExtraPlusGateway::SUCCESS_MESSAGE, response.message - assert_equal "USD", response.params["currency"] - end - - # NOTE: You have to allow USD as a supported currency in the "Account"->"Currencies" - # section of your account admin before running this test - def test_successful_purchase_with_custom_currency - gateway = BarclaysEpdqExtraPlusGateway.new(fixtures(:barclays_epdq_extra_plus).merge(:currency => 'EUR')) - assert response = gateway.purchase(@amount, @credit_card, @options.merge(:currency => 'USD')) - assert_success response - assert_equal BarclaysEpdqExtraPlusGateway::SUCCESS_MESSAGE, response.message - assert_equal "USD", response.params["currency"] - end - - # NOTE: You have to contact Barclays to make sure your test account allow 3D Secure transactions before running this test - def test_successful_purchase_with_3d_secure - assert response = @gateway.purchase(@amount, @credit_card_d3d, @options.merge(:d3d => true)) - assert_success response - assert_equal '46', response.params["STATUS"] - assert_equal BarclaysEpdqExtraPlusGateway::SUCCESS_MESSAGE, response.message - assert response.params["HTML_ANSWER"] - end -=end + # Enable if/when fully enabled account is available to test + # def test_reference_transactions + # # Setting an alias + # assert response = @gateway.purchase(@amount, credit_card('4000100011112224'), @options.merge(:billing_id => "awesomeman", :order_id=>Time.now.to_i.to_s+"1")) + # assert_success response + # # Updating an alias + # assert response = @gateway.purchase(@amount, credit_card('4111111111111111'), @options.merge(:billing_id => "awesomeman", :order_id=>Time.now.to_i.to_s+"2")) + # assert_success response + # # Using an alias (i.e. don't provide the credit card) + # assert response = @gateway.purchase(@amount, "awesomeman", @options.merge(:order_id => Time.now.to_i.to_s + "3")) + # assert_success response + # end + # + # def test_successful_store + # assert response = @gateway.store(@credit_card, :billing_id => 'test_alias') + # assert_success response + # assert purchase = @gateway.purchase(@amount, 'test_alias') + # assert_success purchase + # end + # + # def test_successful_store_generated_alias + # assert response = @gateway.store(@credit_card) + # assert_success response + # assert purchase = @gateway.purchase(@amount, response.billing_id) + # assert_success purchase + # end + # + # def test_successful_store + # assert response = @gateway.store(@credit_card, :billing_id => 'test_alias') + # assert_success response + # assert purchase = @gateway.purchase(@amount, 'test_alias') + # assert_success purchase + # end + # + # def test_successful_unreferenced_credit + # assert credit = @gateway.credit(@amount, @credit_card, @options) + # assert_success credit + # assert credit.authorization + # assert_equal BarclaysEpdqExtraPlusGateway::SUCCESS_MESSAGE, credit.message + # end + # + # # NOTE: You have to allow USD as a supported currency in the "Account"->"Currencies" + # # section of your account admin before running this test + # def test_successful_purchase_with_custom_currency_at_the_gateway_level + # gateway = BarclaysEpdqExtraPlusGateway.new(fixtures(:barclays_epdq_extra_plus).merge(:currency => 'USD')) + # assert response = gateway.purchase(@amount, @credit_card) + # assert_success response + # assert_equal BarclaysEpdqExtraPlusGateway::SUCCESS_MESSAGE, response.message + # assert_equal "USD", response.params["currency"] + # end + # + # # NOTE: You have to allow USD as a supported currency in the "Account"->"Currencies" + # # section of your account admin before running this test + # def test_successful_purchase_with_custom_currency + # gateway = BarclaysEpdqExtraPlusGateway.new(fixtures(:barclays_epdq_extra_plus).merge(:currency => 'EUR')) + # assert response = gateway.purchase(@amount, @credit_card, @options.merge(:currency => 'USD')) + # assert_success response + # assert_equal BarclaysEpdqExtraPlusGateway::SUCCESS_MESSAGE, response.message + # assert_equal "USD", response.params["currency"] + # end + # + # # NOTE: You have to contact Barclays to make sure your test account allow 3D Secure transactions before running this test + # def test_successful_purchase_with_3d_secure + # assert response = @gateway.purchase(@amount, @credit_card_d3d, @options.merge(:d3d => true)) + # assert_success response + # assert_equal '46', response.params["STATUS"] + # assert_equal BarclaysEpdqExtraPlusGateway::SUCCESS_MESSAGE, response.message + # assert response.params["HTML_ANSWER"] + # end def test_successful_refund assert purchase = @gateway.purchase(@amount, @credit_card, @options) @@ -208,7 +207,7 @@ def test_successful_refund def test_unsuccessful_refund assert purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount+1, purchase.authorization, @options) # too much refund requested + assert refund = @gateway.refund(@amount + 1, purchase.authorization, @options) # too much refund requested assert_failure refund assert refund.authorization assert_equal 'Overflow in refunds requests', refund.message @@ -216,11 +215,11 @@ def test_unsuccessful_refund def test_invalid_login gateway = BarclaysEpdqExtraPlusGateway.new( - :login => '', - :user => '', - :password => '', - :signature_encryptor => 'none' - ) + login: '', + user: '', + password: '', + signature_encryptor: 'none' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'Some of the data entered is incorrect. please retry.', response.message diff --git a/test/remote/gateways/remote_be2bill_test.rb b/test/remote/gateways/remote_be2bill_test.rb index 6e48bdcba5e..0c0b1da2761 100644 --- a/test/remote/gateways/remote_be2bill_test.rb +++ b/test/remote/gateways/remote_be2bill_test.rb @@ -9,13 +9,13 @@ def setup @declined_card = credit_card('5555557376384001') @options = { - :order_id => '1', - :description => 'Store Purchase', - :client_id => '1', - :referrer => 'google.com', - :user_agent => 'Firefox 25', - :ip => '127.0.0.1', - :email => 'customer@yopmail.com' + order_id: '1', + description: 'Store Purchase', + client_id: '1', + referrer: 'google.com', + user_agent: 'Firefox 25', + ip: '127.0.0.1', + email: 'customer@yopmail.com' } end @@ -49,8 +49,8 @@ def test_failed_capture def test_invalid_login gateway = Be2billGateway.new( - :login => '', - :password => '' + login: '', + password: '' ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response diff --git a/test/remote/gateways/remote_beanstream_interac_test.rb b/test/remote/gateways/remote_beanstream_interac_test.rb index 4f4d1b9b79e..4b716d8be38 100644 --- a/test/remote/gateways/remote_beanstream_interac_test.rb +++ b/test/remote/gateways/remote_beanstream_interac_test.rb @@ -1,30 +1,29 @@ require 'test_helper' class RemoteBeanstreamInteracTest < Test::Unit::TestCase - def setup @gateway = BeanstreamInteracGateway.new(fixtures(:beanstream_interac)) @amount = 100 @options = { - :order_id => generate_unique_id, - :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: generate_unique_id, + 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' } end @@ -42,10 +41,10 @@ def test_failed_confirmation def test_invalid_login gateway = BeanstreamInteracGateway.new( - :merchant_id => '', - :login => '', - :password => '' - ) + merchant_id: '', + login: '', + password: '' + ) assert response = gateway.purchase(@amount, @options) assert_failure response assert_equal 'Invalid merchant id (merchant_id = 0)', response.message diff --git a/test/remote/gateways/remote_beanstream_test.rb b/test/remote/gateways/remote_beanstream_test.rb index 972e9c599aa..93b799e4ac5 100644 --- a/test/remote/gateways/remote_beanstream_test.rb +++ b/test/remote/gateways/remote_beanstream_test.rb @@ -6,7 +6,6 @@ # only work the first time you run them since the profile, if created again, becomes a duplicate. There is a setting in order settings which, when unchecked will allow the tests to be run any number # of times without needing the manual deletion step between test runs. The setting is: Do not allow profile to be created with card data duplicated from an existing profile. class RemoteBeanstreamTest < Test::Unit::TestCase - def setup @gateway = BeanstreamGateway.new(fixtures(:beanstream)) @@ -18,50 +17,51 @@ def setup @mastercard = credit_card('5100000010001004') @declined_mastercard = credit_card('5100000020002000') - @amex = credit_card('371100001000131', {:verification_value => 1234}) - @declined_amex = credit_card('342400001000180', {:verification_value => 1234}) + @amex = credit_card('371100001000131', { verification_value: 1234 }) + @declined_amex = credit_card('342400001000180', { verification_value: 1234 }) # Canadian EFT - @check = check( - :institution_number => '001', - :transit_number => '26729' - ) + @check = check( + institution_number: '001', + transit_number: '26729' + ) @amount = 1500 @options = { - :order_id => generate_unique_id, - :billing_address => { - :name => 'xiaobo zzz', - :phone => '555-555-5555', - :address1 => '4444 Levesque St.', - :address2 => 'Apt B', - :city => 'Montreal', - :state => 'Quebec', - :country => 'CA', - :zip => 'H2C1X8' + order_id: generate_unique_id, + billing_address: { + name: 'xiaobo zzz', + phone: '555-555-5555', + address1: '4444 Levesque St.', + address2: 'Apt B', + city: 'Montreal', + state: 'Quebec', + country: 'CA', + zip: 'H2C1X8' }, - :shipping_address => { - :name => 'shippy', - :phone => '888-888-8888', - :address1 => '777 Foster Street', - :address2 => 'Ste #100', - :city => 'Durham', - :state => 'North Carolina', - :country => 'US', - :zip => '27701' + shipping_address: { + name: 'shippy', + phone: '888-888-8888', + address1: '777 Foster Street', + address2: 'Ste #100', + city: 'Durham', + state: 'North Carolina', + country: 'US', + zip: '27701' }, - :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 }, - :occurences => 5) + interval: { unit: :months, length: 1 }, + occurences: 5 + ) end def test_successful_visa_purchase @@ -146,9 +146,9 @@ def test_successful_purchase_with_state_in_iso_format def test_successful_purchase_with_only_email options = { - :order_id => generate_unique_id, - :email => 'xiaobozzz@example.com', - :shipping_email => 'ship@mail.com' + order_id: generate_unique_id, + email: 'xiaobozzz@example.com', + shipping_email: 'ship@mail.com' } assert response = @gateway.purchase(@amount, @visa, options) @@ -293,7 +293,7 @@ def test_successful_update_recurring assert response.test? assert_false response.authorization.blank? - assert response = @gateway.update_recurring(@amount + 500, @visa, @recurring_options.merge(:account_id => response.params['rbAccountId'])) + assert response = @gateway.update_recurring(@amount + 500, @visa, @recurring_options.merge(account_id: response.params['rbAccountId'])) assert_success response end @@ -303,16 +303,16 @@ def test_successful_cancel_recurring assert response.test? assert_false response.authorization.blank? - assert response = @gateway.cancel_recurring(:account_id => response.params['rbAccountId']) + assert response = @gateway.cancel_recurring(account_id: response.params['rbAccountId']) assert_success response end def test_invalid_login gateway = BeanstreamGateway.new( - :merchant_id => '', - :login => '', - :password => '' - ) + merchant_id: '', + login: '', + password: '' + ) assert response = gateway.purchase(@amount, @visa, @options) assert_failure response assert_equal 'merchantid=Invalid merchant id (merchant_id = )', response.message @@ -370,7 +370,7 @@ def test_delete_from_vault_with_unstore_method def test_successful_add_to_vault_and_use test_add_to_vault_with_custom_vault_id_with_store_method - assert second_response = @gateway.purchase(@amount*2, @options[:vault_id], @options) + assert second_response = @gateway.purchase(@amount * 2, @options[:vault_id], @options) assert_equal 'Approved', second_response.message assert second_response.success? end @@ -380,13 +380,13 @@ def test_unsuccessful_visa_with_vault assert response = @gateway.update(@options[:vault_id], @declined_visa) assert_success response - assert second_response = @gateway.purchase(@amount*2, @options[:vault_id], @options) + assert second_response = @gateway.purchase(@amount * 2, @options[:vault_id], @options) assert_equal 'DECLINE', second_response.message end def test_unsuccessful_closed_profile_charge test_delete_from_vault - assert second_response = @gateway.purchase(@amount*2, @options[:vault_id], @options) + assert second_response = @gateway.purchase(@amount * 2, @options[:vault_id], @options) assert_failure second_response assert_match %r{Invalid customer code\.}, second_response.message end @@ -417,7 +417,7 @@ def generate_single_use_token(credit_card) 'number' => credit_card.number, 'expiry_month' => '01', 'expiry_year' => (Time.now.year + 1) % 100, - 'cvd' => credit_card.verification_value, + 'cvd' => credit_card.verification_value }.to_json response = http.request(request) diff --git a/test/remote/gateways/remote_blue_pay_test.rb b/test/remote/gateways/remote_blue_pay_test.rb index 4faf2277846..e368f1b1b6d 100644 --- a/test/remote/gateways/remote_blue_pay_test.rb +++ b/test/remote/gateways/remote_blue_pay_test.rb @@ -8,19 +8,19 @@ def setup @amount = 100 @credit_card = credit_card('4242424242424242') @options = { - :order_id => generate_unique_id, - :billing_address => address, - :description => 'Store purchase', - :ip => '192.168.0.1' + order_id: generate_unique_id, + billing_address: address, + description: 'Store purchase', + ip: '192.168.0.1' } @recurring_options = { - :rebill_amount => 100, - :rebill_start_date => Date.today, - :rebill_expression => '1 DAY', - :rebill_cycles => '4', - :billing_address => address.merge(:first_name => 'Jim', :last_name => 'Smith'), - :duplicate_override => 1 + rebill_amount: 100, + rebill_start_date: Date.today, + rebill_expression: '1 DAY', + rebill_cycles: '4', + billing_address: address.merge(first_name: 'Jim', last_name: 'Smith'), + duplicate_override: 1 } end @@ -34,7 +34,7 @@ def test_successful_purchase # The included test account credentials do not support ACH processor. def test_successful_purchase_with_check - assert response = @gateway.purchase(@amount, check, @options.merge(:email=>'foo@example.com')) + assert response = @gateway.purchase(@amount, check, @options.merge(email: 'foo@example.com')) assert_success response assert response.test? assert_equal 'App ACH Sale', response.message @@ -50,7 +50,7 @@ def test_expired_credit_card end def test_forced_test_mode_purchase - gateway = BluePayGateway.new(fixtures(:blue_pay).update(:test => true)) + gateway = BluePayGateway.new(fixtures(:blue_pay).update(test: true)) assert response = gateway.purchase(@amount, @credit_card, @options) assert_success response assert response.test? @@ -81,7 +81,7 @@ def test_that_we_understand_and_parse_all_keys_in_rebilling_response assert response = @gateway.recurring(@amount, @credit_card, @recurring_options) assert_success response rebill_id = response.params['rebid'] - assert response = @gateway.update_recurring(:rebill_id => rebill_id, :rebill_amount => @amount * 2) + assert response = @gateway.update_recurring(rebill_id: rebill_id, rebill_amount: @amount * 2) assert_success response response_keys = response.params.keys.map(&:to_sym) @@ -111,8 +111,8 @@ def test_authorization_and_void def test_bad_login gateway = BluePayGateway.new( - :login => 'X', - :password => 'Y' + login: 'X', + password: 'Y' ) assert response = gateway.purchase(@amount, @credit_card) @@ -123,8 +123,8 @@ def test_bad_login def test_using_test_request gateway = BluePayGateway.new( - :login => 'X', - :password => 'Y' + login: 'X', + password: 'Y' ) assert response = gateway.purchase(@amount, @credit_card) assert_equal Response, response.class @@ -140,7 +140,7 @@ def test_successful_recurring rebill_id = response.params['rebid'] - assert response = @gateway.update_recurring(:rebill_id => rebill_id, :rebill_amount => @amount * 2) + assert response = @gateway.update_recurring(rebill_id: rebill_id, rebill_amount: @amount * 2) assert_success response assert response = @gateway.status_recurring(rebill_id) @@ -172,19 +172,19 @@ def test_successful_purchase_with_solution_id end def test_successful_refund_with_check - assert response = @gateway.purchase(@amount, check, @options.merge(:email=>'foo@example.com')) + assert response = @gateway.purchase(@amount, check, @options.merge(email: 'foo@example.com')) assert_success response assert response.test? assert_equal 'App ACH Sale', response.message assert response.authorization - assert refund = @gateway.refund(@amount, response.authorization, @options.merge(:doc_type=>'PPD')) + assert refund = @gateway.refund(@amount, response.authorization, @options.merge(doc_type: 'PPD')) assert_success refund assert_equal 'App ACH Void', refund.message end def test_successful_credit_with_check - assert credit = @gateway.credit(@amount, check, @options.merge(:doc_type=>'PPD')) + assert credit = @gateway.credit(@amount, check, @options.merge(doc_type: 'PPD')) assert_success credit assert_equal 'App ACH Credit', credit.message end diff --git a/test/remote/gateways/remote_blue_snap_test.rb b/test/remote/gateways/remote_blue_snap_test.rb index f04f0aba6eb..a9164cc1d6c 100644 --- a/test/remote/gateways/remote_blue_snap_test.rb +++ b/test/remote/gateways/remote_blue_snap_test.rb @@ -6,14 +6,21 @@ def setup @amount = 100 @credit_card = credit_card('4263982640269299') - @cabal_card = credit_card('6271701225979642', month: 3, year: 2020) - @naranja_card = credit_card('5895626746595650', month: 11, year: 2020) + @cabal_card = credit_card('6271701225979642', month: 3, year: 2024) + @naranja_card = credit_card('5895626746595650', month: 11, year: 2024) @declined_card = credit_card('4917484589897107', month: 1, year: 2023) @invalid_card = credit_card('4917484589897106', month: 1, year: 2023) @three_ds_visa_card = credit_card('4000000000001091', month: 1) @three_ds_master_card = credit_card('5200000000001096', month: 1) @invalid_cabal_card = credit_card('5896 5700 0000 0000', month: 1, year: 2023) + # BlueSnap may require support contact to activate fraud checking on sandbox accounts. + # Specific merchant-configurable thresholds can be set as follows: + # Order Total Amount Decline Threshold = 3728 + # Payment Country Decline List = Brazil + @fraudulent_amount = 3729 + @fraudulent_card = credit_card('4007702835532454') + @options = { billing_address: address } @options_3ds2 = @options.merge( three_d_secure: { @@ -26,7 +33,7 @@ def setup ) @check = check - @invalid_check = check(:routing_number => '123456', :account_number => '123456789') + @invalid_check = check(routing_number: '123456', account_number: '123456789') @valid_check_options = { billing_address: { address1: '123 Street', @@ -45,6 +52,20 @@ def test_successful_purchase assert_equal 'Success', response.message end + def test_successful_fractionless_currency_purchase + options = @options.merge(currency: 'JPY') + response = @gateway.purchase(12300, @credit_card, options) + assert_success response + assert_equal 'Success', response.message + end + + def test_successful_three_decimal_currency_purchase + options = @options.merge(currency: 'BHD') + response = @gateway.purchase(1234, @credit_card, options) + assert_success response + assert_equal 'Success', response.message + end + def test_successful_purchase_with_cabal_card options = @options.merge({ email: 'joe@example.com' @@ -82,6 +103,125 @@ def test_successful_purchase_with_more_options response = @gateway.purchase(@amount, @credit_card, more_options) assert_success response assert_equal 'Success', response.message + + # description SHOULD BE set as a meta-data field + assert_not_empty response.params['transaction-meta-data'] + meta = response.params['transaction-meta-data'] + + assert_equal 1, meta.length + assert_equal 'description', meta[0]['meta-key'] + assert_equal 'Product Description', meta[0]['meta-value'] + assert_equal 'Description', meta[0]['meta-description'] + end + + def test_successful_purchase_with_meta_data + 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: 'description', + meta_value: 'Product ABC', + meta_description: 'Product Description' + } + ], + soft_descriptor: 'OnCardStatement', + personal_identification_number: 'CNPJ' + }) + + response = @gateway.purchase(@amount, @credit_card, more_options) + assert_success response + assert_equal 'Success', response.message + + # description SHOULD BE set as a meta-data field + assert_not_empty response.params['transaction-meta-data'] + meta = response.params['transaction-meta-data'] + + assert_equal 3, meta.length + + meta.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', + soft_descriptor: 'OnCardStatement', + personal_identification_number: 'CNPJ' + }) + + response = @gateway.purchase(@amount, @credit_card, more_options) + assert_success response + assert_equal 'Success', response.message + + assert_nil response.params['transaction-meta-data'] + end + + def test_successful_purchase_with_card_holder_info + more_options = @options.merge({ + order_id: '1', + ip: '127.0.0.1', + email: 'joe@example.com', + soft_descriptor: 'OnCardStatement', + personal_identification_number: 'CNPJ', + billing_address: { + address1: '123 Street', + address2: 'Apt 1', + city: 'Happy City', + state: 'CA', + zip: '94901' + }, + phone_number: '555 888 0000' + }) + + response = @gateway.purchase(@amount, @credit_card, more_options) + assert_success response + assert_equal 'Success', response.message + end + + def test_successful_purchase_with_shipping_contact_info + more_options = @options.merge({ + shipping_address: { + address1: '123 Main St', + address2: 'Apt B', + city: 'Springfield', + state: 'NC', + country: 'US', + zip: '27701' + } + }) + + response = @gateway.purchase(@amount, @credit_card, more_options) + assert_success response + assert_equal 'Success', response.message end def test_successful_purchase_with_3ds2_auth @@ -165,12 +305,35 @@ def test_successful_purchase_with_unused_state_code assert_equal 'Success', response.message end + def test_successful_purchase_with_transaction_fraud_info + fraud_info_options = @options.merge({ + ip: '123.12.134.1', + transaction_fraud_info: { + fraud_session_id: 'fbcc094208f54c0e974d56875c73af7a' + } + }) + + response = @gateway.purchase(@amount, @credit_card, fraud_info_options) + assert_success response + assert_equal 'Success', response.message + end + def test_successful_echeck_purchase response = @gateway.purchase(@amount, @check, @options.merge(@valid_check_options)) assert_success response assert_equal 'Success', response.message end + def test_fraudulent_purchase + # Reflects specific settings on Bluesnap sandbox account. + response = @gateway.purchase(@fraudulent_amount, @fraudulent_card, @options) + assert_failure response + assert_match(/fraud-reference-id/, response.message) + assert_match(/fraud-event/, response.message) + assert_match(/blacklistPaymentCountryDecline/, response.message) + assert_match(/orderTotalDecline/, response.message) + end + def test_failed_purchase response = @gateway.purchase(@amount, @declined_card, @options) assert_failure response @@ -207,7 +370,7 @@ def test_failed_echeck_purchase end def test_failed_unauthorized_echeck_purchase - response = @gateway.purchase(@amount, @check, @options.merge({authorized_by_shopper: false})) + response = @gateway.purchase(@amount, @check, @options.merge({ authorized_by_shopper: false })) assert_failure response assert_match(/The payment was not authorized by shopper/, response.message) assert_equal '16004', response.error_code @@ -250,7 +413,7 @@ def test_partial_capture_succeeds_even_though_amount_is_ignored_by_gateway auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -273,7 +436,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund end @@ -360,7 +523,7 @@ def test_successful_purchase_using_stored_echeck assert_success store_response assert_match(/check/, store_response.authorization) - response = @gateway.purchase(@amount, store_response.authorization, @options.merge({authorized_by_shopper: true})) + response = @gateway.purchase(@amount, store_response.authorization, @options.merge({ authorized_by_shopper: true })) assert_success response assert_equal 'Success', response.message end @@ -410,5 +573,4 @@ def test_transcript_scrubbing_with_echeck assert_scrubbed(@check.routing_number, transcript) assert_scrubbed(@gateway.options[:api_password], transcript) end - end diff --git a/test/remote/gateways/remote_borgun_test.rb b/test/remote/gateways/remote_borgun_test.rb index 32f7b1b6fc7..eddde1d769a 100644 --- a/test/remote/gateways/remote_borgun_test.rb +++ b/test/remote/gateways/remote_borgun_test.rb @@ -8,7 +8,7 @@ def setup @gateway = BorgunGateway.new(fixtures(:borgun)) @amount = 100 - @credit_card = credit_card('5587402000012011', year: 2018, month: 9, verification_value: 415) + @credit_card = credit_card('5587402000012011', year: 2022, month: 9, verification_value: 415) @declined_card = credit_card('4155520000000002') @options = { @@ -54,6 +54,27 @@ def test_successful_authorize_and_capture assert_success capture end + def test_successful_authorize_airline_data + passenger_itinerary_data = { + 'MessageNumber' => '1111111', + 'TrDate' => '20120222', + 'TrTime' => '151515', + 'PassengerName' => 'Jane Doe', + 'ServiceClassCode_1' => '100', + 'FlightNumber_1' => '111111', + 'TravelDate_1' => '20120222', + 'DepartureAirport_1' => 'KEF', + 'CarrierCode_1' => 'CC', + 'TravelAgencyCode' => 'A7654321', + 'TravelAgencyName' => 'Spreedly Inc', + 'TicketNumber' => '900.123.222' + } + + options = @options.merge(passenger_itinerary_data: passenger_itinerary_data) + auth = @gateway.authorize(@amount, @credit_card, options) + assert_success auth + end + def test_successful_authorize_and_capture_usd auth = @gateway.authorize(@amount, @credit_card, @options.merge(currency: 'USD')) assert_success auth @@ -71,7 +92,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -100,7 +121,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund end diff --git a/test/remote/gateways/remote_bpoint_test.rb b/test/remote/gateways/remote_bpoint_test.rb index c2ba913c86c..e176bc4c648 100644 --- a/test/remote/gateways/remote_bpoint_test.rb +++ b/test/remote/gateways/remote_bpoint_test.rb @@ -41,7 +41,7 @@ def test_successful_purchase end def test_successful_purchase_with_more_options - response = @gateway.purchase(@amount, @credit_card, @options.merge({ crn1: 'ref'})) + response = @gateway.purchase(@amount, @credit_card, @options.merge({ crn1: 'ref' })) assert_success response assert_equal 'Approved', response.message end @@ -69,7 +69,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -90,7 +90,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund end @@ -103,12 +103,12 @@ def test_successful_void auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert void = @gateway.void(@amount, auth.authorization) + assert void = @gateway.void(auth.authorization, amount: @amount) assert_success void end def test_failed_void - response = @gateway.void(@amount, '') + response = @gateway.void('', amount: @amount) assert_failure response end diff --git a/test/remote/gateways/remote_braintree_blue_test.rb b/test/remote/gateways/remote_braintree_blue_test.rb index d1031516fab..6c3b44cd2dc 100644 --- a/test/remote/gateways/remote_braintree_blue_test.rb +++ b/test/remote/gateways/remote_braintree_blue_test.rb @@ -11,9 +11,9 @@ def setup @declined_card = credit_card('4000300011112220') @options = { - :order_id => '1', - :billing_address => address(:country_name => 'Canada'), - :description => 'Store Purchase' + order_id: '1', + billing_address: address(country_name: 'Canada'), + description: 'Store Purchase' } end @@ -41,16 +41,16 @@ def test_successful_authorize def test_successful_authorize_with_nil_and_empty_billing_address_options credit_card = credit_card('5105105105105100') options = { - :billing_address => { - :name => 'John Smith', - :phone => '123-456-7890', - :company => nil, - :address1 => nil, - :address2 => '', - :city => nil, - :state => nil, - :zip => nil, - :country => '' + billing_address: { + name: 'John Smith', + phone: '123-456-7890', + company: nil, + address1: nil, + address2: '', + city: nil, + state: nil, + zip: nil, + country: '' } } assert response = @gateway.authorize(@amount, credit_card, options) @@ -68,14 +68,14 @@ def test_masked_card_number end def test_successful_authorize_with_order_id - assert response = @gateway.authorize(@amount, @credit_card, :order_id => '123') + assert response = @gateway.authorize(@amount, @credit_card, order_id: '123') assert_success response assert_equal '1000 Approved', response.message assert_equal '123', response.params['braintree_transaction']['order_id'] end def test_successful_purchase_with_hold_in_escrow - @options.merge({:merchant_account_id => fixtures(:braintree_blue)[:merchant_account_id], :hold_in_escrow => true}) + @options.merge({ merchant_account_id: fixtures(:braintree_blue)[:merchant_account_id], hold_in_escrow: true }) assert response = @gateway.authorize(@amount, @credit_card, @options) assert_success response assert_equal '1000 Approved', response.message @@ -116,49 +116,49 @@ def test_successful_purchase_using_card_token credit_card_token = response.params['credit_card_token'] assert_match %r{^\w+$}, credit_card_token - assert response = @gateway.purchase(@amount, credit_card_token, :payment_method_token => true) + assert response = @gateway.purchase(@amount, credit_card_token, payment_method_token: true) assert_success response assert_equal '1000 Approved', response.message assert_equal 'submitted_for_settlement', response.params['braintree_transaction']['status'] end def test_successful_purchase_with_level_2_data - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:tax_amount => '20', :purchase_order_number => '6789')) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(tax_amount: '20', purchase_order_number: '6789')) assert_success response assert_equal '1000 Approved', response.message end def test_successful_purchase_with_level_2_and_3_data options = { - :tax_amount => '20', - :purchase_order_number => '6789', - :shipping_amount => '300', - :discount_amount => '150', - :ships_from_postal_code => '90210', - :line_items => [ + tax_amount: '20', + purchase_order_number: '6789', + shipping_amount: '300', + discount_amount: '150', + ships_from_postal_code: '90210', + line_items: [ { - :name => 'Product Name', - :kind => 'debit', - :quantity => '10.0000', - :unit_amount => '9.5000', - :unit_of_measure => 'unit', - :total_amount => '95.00', - :tax_amount => '5.00', - :discount_amount => '0.00', - :product_code => '54321', - :commodity_code => '98765' + name: 'Product Name', + kind: 'debit', + quantity: '10.0000', + unit_amount: '9.5000', + unit_of_measure: 'unit', + total_amount: '95.00', + tax_amount: '5.00', + discount_amount: '0.00', + product_code: '54321', + commodity_code: '98765' }, { - :name => 'Other Product Name', - :kind => 'debit', - :quantity => '1.0000', - :unit_amount => '2.5000', - :unit_of_measure => 'unit', - :total_amount => '90.00', - :tax_amount => '2.00', - :discount_amount => '1.00', - :product_code => '54322', - :commodity_code => '98766' + name: 'Other Product Name', + kind: 'debit', + quantity: '1.0000', + unit_amount: '2.5000', + unit_of_measure: 'unit', + total_amount: '90.00', + tax_amount: '2.00', + discount_amount: '1.00', + product_code: '54322', + commodity_code: '98766' } ] } @@ -181,7 +181,7 @@ def test_failed_verify def test_successful_verify_with_device_data # Requires Advanced Fraud Tools to be enabled - assert response = @gateway.verify(@credit_card, @options.merge({device_data: 'device data for verify'})) + assert response = @gateway.verify(@credit_card, @options.merge({ device_data: 'device data for verify' })) assert_success response assert_equal '1000 Approved', response.message @@ -194,22 +194,22 @@ def test_successful_verify_with_device_data end def test_successful_validate_on_store - card = credit_card('4111111111111111', :verification_value => '101') - assert response = @gateway.store(card, :verify_card => true) + card = credit_card('4111111111111111', verification_value: '101') + assert response = @gateway.store(card, verify_card: true) assert_success response assert_equal 'OK', response.message end def test_failed_validate_on_store - card = credit_card('4000111111111115', :verification_value => '200') - assert response = @gateway.store(card, :verify_card => true) + card = credit_card('4000111111111115', verification_value: '200') + assert response = @gateway.store(card, verify_card: true) assert_failure response assert_equal 'Processor declined: Do Not Honor (2000)', response.message end def test_successful_store_with_no_validate - card = credit_card('4000111111111115', :verification_value => '200') - assert response = @gateway.store(card, :verify_card => false) + card = credit_card('4000111111111115', verification_value: '200') + assert response = @gateway.store(card, verify_card: false) assert_success response assert_equal 'OK', response.message end @@ -222,46 +222,46 @@ def test_successful_store_with_invalid_card def test_successful_store_with_billing_address billing_address = { - :address1 => '1 E Main St', - :address2 => 'Suite 403', - :city => 'Chicago', - :state => 'Illinois', - :zip => '60622', - :country_name => 'United States of America' + address1: '1 E Main St', + address2: 'Suite 403', + city: 'Chicago', + state: 'Illinois', + zip: '60622', + country_name: 'United States of America' } credit_card = credit_card('5105105105105100') - assert response = @gateway.store(credit_card, :billing_address => billing_address) + assert response = @gateway.store(credit_card, billing_address: billing_address) assert_success response assert_equal 'OK', response.message vault_id = response.params['customer_vault_id'] purchase_response = @gateway.purchase(@amount, vault_id) response_billing_details = { - 'country_name'=>'United States of America', - 'region'=>'Illinois', - 'company'=>nil, - 'postal_code'=>'60622', - 'extended_address'=>'Suite 403', - 'street_address'=>'1 E Main St', - 'locality'=>'Chicago' + 'country_name' => 'United States of America', + 'region' => 'Illinois', + 'company' => nil, + 'postal_code' => '60622', + 'extended_address' => 'Suite 403', + 'street_address' => '1 E Main St', + 'locality' => 'Chicago' } assert_equal purchase_response.params['braintree_transaction']['billing_details'], response_billing_details end def test_successful_store_with_nil_billing_address_options billing_address = { - :name => 'John Smith', - :phone => '123-456-7890', - :company => nil, - :address1 => nil, - :address2 => nil, - :city => nil, - :state => nil, - :zip => nil, - :country_name => nil + name: 'John Smith', + phone: '123-456-7890', + company: nil, + address1: nil, + address2: nil, + city: nil, + state: nil, + zip: nil, + country_name: nil } credit_card = credit_card('5105105105105100') - assert response = @gateway.store(credit_card, :billing_address => billing_address) + assert response = @gateway.store(credit_card, billing_address: billing_address) assert_success response assert_equal 'OK', response.message @@ -292,11 +292,12 @@ def test_successful_store_with_new_customer_id def test_successful_store_with_existing_customer_id credit_card = credit_card('5105105105105100') customer_id = generate_unique_id - assert response = @gateway.store(credit_card, customer: customer_id) + assert response = @gateway.store(credit_card, @options.merge(customer: customer_id)) assert_success response assert_equal 1, @braintree_backend.customer.find(customer_id).credit_cards.size - assert response = @gateway.store(credit_card, customer: customer_id) + credit_card = credit_card('4111111111111111') + assert response = @gateway.store(credit_card, @options.merge(customer: customer_id)) assert_success response assert_equal 2, @braintree_backend.customer.find(customer_id).credit_cards.size assert_equal customer_id, response.params['customer_vault_id'] @@ -308,17 +309,17 @@ def test_successful_store_with_existing_customer_id_and_nil_billing_address_opti credit_card = credit_card('5105105105105100') customer_id = generate_unique_id options = { - :customer => customer_id, - :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: customer_id, + billing_address: { + name: 'John Smith', + phone: '123-456-7890', + company: nil, + address1: nil, + address2: nil, + city: nil, + state: nil, + zip: nil, + country_name: nil } } assert response = @gateway.store(credit_card, options) @@ -376,28 +377,27 @@ def test_avs end def test_cvv_match - assert response = @gateway.purchase(@amount, credit_card('5105105105105100', :verification_value => '400')) + assert response = @gateway.purchase(@amount, credit_card('5105105105105100', verification_value: '400')) assert_success response - assert_equal({'code' => 'M', 'message' => ''}, response.cvv_result) + assert_equal({ 'code' => 'M', 'message' => '' }, response.cvv_result) end def test_cvv_no_match - assert response = @gateway.purchase(@amount, credit_card('5105105105105100', :verification_value => '200')) + assert response = @gateway.purchase(@amount, credit_card('5105105105105100', verification_value: '200')) assert_success response - assert_equal({'code' => 'N', 'message' => ''}, response.cvv_result) + assert_equal({ 'code' => 'N', 'message' => '' }, response.cvv_result) end def test_successful_purchase_with_email assert response = @gateway.purchase(@amount, @credit_card, - :email => 'customer@example.com' - ) + email: 'customer@example.com') assert_success response transaction = response.params['braintree_transaction'] assert_equal 'customer@example.com', transaction['customer_details']['email'] end def test_successful_purchase_with_phone - assert response = @gateway.purchase(@amount, @credit_card, :phone => '123-345-5678') + assert response = @gateway.purchase(@amount, @credit_card, phone: '123-345-5678') assert_success response transaction = response.params['braintree_transaction'] assert_equal '123-345-5678', transaction['customer_details']['phone'] @@ -447,7 +447,7 @@ def test_successful_purchase_with_device_data def test_purchase_with_store_using_random_customer_id assert response = @gateway.purchase( - @amount, credit_card('5105105105105100'), @options.merge(:store => true) + @amount, credit_card('5105105105105100'), @options.merge(store: true) ) assert_success response assert_equal '1000 Approved', response.message @@ -459,7 +459,7 @@ def test_purchase_with_store_using_random_customer_id def test_purchase_with_store_using_specified_customer_id customer_id = rand(1_000_000_000).to_s assert response = @gateway.purchase( - @amount, credit_card('5105105105105100'), @options.merge(:store => customer_id) + @amount, credit_card('5105105105105100'), @options.merge(store: customer_id) ) assert_success response assert_equal '1000 Approved', response.message @@ -473,7 +473,7 @@ def test_purchase_with_transaction_source assert_success response customer_vault_id = response.params['customer_vault_id'] - assert response = @gateway.purchase(@amount, customer_vault_id, @options.merge(:transaction_source => 'unscheduled')) + assert response = @gateway.purchase(@amount, customer_vault_id, @options.merge(transaction_source: 'unscheduled')) assert_success response assert_equal '1000 Approved', response.message end @@ -481,11 +481,10 @@ def test_purchase_with_transaction_source def test_purchase_using_specified_payment_method_token assert response = @gateway.store( credit_card('4111111111111111', - :first_name => 'Old First', :last_name => 'Old Last', - :month => 9, :year => 2012 - ), - :email => 'old@example.com', - :phone => '321-654-0987' + first_name: 'Old First', last_name: 'Old Last', + month: 9, year: 2012), + email: 'old@example.com', + phone: '321-654-0987' ) payment_method_token = response.params['braintree_customer']['credit_cards'][0]['token'] assert response = @gateway.purchase( @@ -498,27 +497,26 @@ def test_purchase_using_specified_payment_method_token def test_successful_purchase_with_addresses billing_address = { - :address1 => '1 E Main St', - :address2 => 'Suite 101', - :company => 'Widgets Co', - :city => 'Chicago', - :state => 'IL', - :zip => '60622', - :country_name => 'United States of America' + address1: '1 E Main St', + address2: 'Suite 101', + company: 'Widgets Co', + city: 'Chicago', + state: 'IL', + zip: '60622', + country_name: 'United States of America' } shipping_address = { - :address1 => '1 W Main St', - :address2 => 'Suite 102', - :company => 'Widgets Company', - :city => 'Bartlett', - :state => 'Illinois', - :zip => '60103', - :country_name => 'Mexico' + address1: '1 W Main St', + address2: 'Suite 102', + company: 'Widgets Company', + city: 'Bartlett', + state: 'Illinois', + zip: '60103', + country_name: 'Mexico' } assert response = @gateway.purchase(@amount, @credit_card, - :billing_address => billing_address, - :shipping_address => shipping_address - ) + billing_address: billing_address, + shipping_address: shipping_address) assert_success response transaction = response.params['braintree_transaction'] assert_equal '1 E Main St', transaction['billing_details']['street_address'] @@ -540,16 +538,14 @@ def test_successful_purchase_with_addresses def test_successful_purchase_with_three_d_secure_pass_thru three_d_secure_params = { version: '2.0', cavv: 'cavv', eci: '02', ds_transaction_id: 'trans_id', cavv_algorithm: 'algorithm', directory_response_status: 'directory', authentication_response_status: 'auth' } response = @gateway.purchase(@amount, @credit_card, - three_d_secure: three_d_secure_params - ) + three_d_secure: three_d_secure_params) assert_success response end def test_successful_purchase_with_some_three_d_secure_pass_thru_fields three_d_secure_params = { version: '2.0', cavv: 'cavv', eci: '02', ds_transaction_id: 'trans_id' } response = @gateway.purchase(@amount, @credit_card, - three_d_secure: three_d_secure_params - ) + three_d_secure: three_d_secure_params) assert_success response end @@ -564,7 +560,7 @@ def test_unsuccessful_purchase_validation_error assert response = @gateway.purchase(@amount, credit_card('51051051051051000')) assert_failure response assert_match %r{Credit card number is invalid\. \(81715\)}, response.message - assert_equal({'processor_response_code'=>'91577'}, response.params['braintree_transaction']) + assert_equal({ 'processor_response_code' => '91577' }, response.params['braintree_transaction']) end def test_authorize_and_capture @@ -578,10 +574,9 @@ def test_authorize_and_capture def test_authorize_and_capture_with_apple_pay_card credit_card = network_tokenization_credit_card('4111111111111111', - :brand => 'visa', - :eci => '05', - :payment_cryptogram => 'EHuWW9PiBkWvqE5juRwDzAUFBAk=' - ) + brand: 'visa', + eci: '05', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=') assert auth = @gateway.authorize(@amount, credit_card, @options) assert_success auth @@ -593,13 +588,12 @@ def test_authorize_and_capture_with_apple_pay_card def test_authorize_and_capture_with_android_pay_card credit_card = network_tokenization_credit_card('4111111111111111', - :payment_cryptogram => 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', - :month => '01', - :year => '2024', - :source => :android_pay, - :transaction_id => '123456789', - :eci => '05' - ) + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + month: '01', + year: '2024', + source: :android_pay, + transaction_id: '123456789', + eci: '05') assert auth = @gateway.authorize(@amount, credit_card, @options) assert_success auth @@ -611,13 +605,12 @@ def test_authorize_and_capture_with_android_pay_card def test_authorize_and_capture_with_google_pay_card credit_card = network_tokenization_credit_card('4111111111111111', - :payment_cryptogram => 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', - :month => '01', - :year => '2024', - :source => :google_pay, - :transaction_id => '123456789', - :eci => '05' - ) + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + month: '01', + year: '2024', + source: :google_pay, + transaction_id: '123456789', + eci: '05') assert auth = @gateway.authorize(@amount, credit_card, @options) assert_success auth @@ -668,7 +661,7 @@ def test_failed_void assert failed_void = @gateway.void(auth.authorization) assert_failure failed_void assert_match('Transaction can only be voided if status is authorized', failed_void.message) - assert_equal({'processor_response_code'=>'91504'}, failed_void.params['braintree_transaction']) + assert_equal({ 'processor_response_code' => '91504' }, failed_void.params['braintree_transaction']) end def test_failed_capture_with_invalid_transaction_id @@ -678,7 +671,7 @@ def test_failed_capture_with_invalid_transaction_id end def test_invalid_login - gateway = BraintreeBlueGateway.new(:merchant_id => 'invalid', :public_key => 'invalid', :private_key => 'invalid') + gateway = BraintreeBlueGateway.new(merchant_id: 'invalid', public_key: 'invalid', private_key: 'invalid') assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'Braintree::AuthenticationError', response.message @@ -729,11 +722,10 @@ def test_unstore_with_delete_method def test_successful_update assert response = @gateway.store( credit_card('4111111111111111', - :first_name => 'Old First', :last_name => 'Old Last', - :month => 9, :year => 2012 - ), - :email => 'old@example.com', - :phone => '321-654-0987' + first_name: 'Old First', last_name: 'Old Last', + month: 9, year: 2012), + email: 'old@example.com', + phone: '321-654-0987' ) assert_success response assert_equal 'OK', response.message @@ -751,11 +743,10 @@ def test_successful_update assert response = @gateway.update( customer_vault_id, credit_card('5105105105105100', - :first_name => 'New First', :last_name => 'New Last', - :month => 10, :year => 2014 - ), - :email => 'new@example.com', - :phone => '987-765-5432' + first_name: 'New First', last_name: 'New Last', + month: 10, year: 2014), + email: 'new@example.com', + phone: '987-765-5432' ) assert_success response assert_equal 'new@example.com', response.params['braintree_customer']['email'] @@ -769,7 +760,7 @@ def test_successful_update end def test_failed_customer_update - assert response = @gateway.store(credit_card('4111111111111111'), :email => 'email@example.com', :phone => '321-654-0987') + assert response = @gateway.store(credit_card('4111111111111111'), email: 'email@example.com', phone: '321-654-0987') assert_success response assert_equal 'OK', response.message assert customer_vault_id = response.params['customer_vault_id'] @@ -813,7 +804,7 @@ def test_failed_credit_card_update_on_verify assert response = @gateway.update( customer_vault_id, credit_card('4000111111111115'), - {:verify_card => true} + { verify_card: true } ) assert_failure response assert_equal 'Processor declined: Do Not Honor (2000)', response.message @@ -840,14 +831,14 @@ def test_failed_credit end def test_successful_credit_with_merchant_account_id - assert response = @gateway.credit(@amount, @credit_card, :merchant_account_id => fixtures(:braintree_blue)[:merchant_account_id]) + assert response = @gateway.credit(@amount, @credit_card, merchant_account_id: fixtures(:braintree_blue)[:merchant_account_id]) assert_success response, 'You must specify a valid :merchant_account_id key in your fixtures.yml AND get credits enabled in your Sandbox account for this to pass.' assert_equal '1002 Processed', response.message assert_equal 'submitted_for_settlement', response.params['braintree_transaction']['status'] end def test_successful_authorize_with_merchant_account_id - assert response = @gateway.authorize(@amount, @credit_card, :merchant_account_id => fixtures(:braintree_blue)[:merchant_account_id]) + assert response = @gateway.authorize(@amount, @credit_card, merchant_account_id: fixtures(:braintree_blue)[:merchant_account_id]) assert_success response, 'You must specify a valid :merchant_account_id key in your fixtures.yml for this to pass.' assert_equal '1000 Approved', response.message assert_equal 'authorized', response.params['braintree_transaction']['status'] @@ -858,9 +849,32 @@ def test_authorize_with_descriptor assert_success auth end + def test_authorize_with_travel_data + assert auth = @gateway.authorize(@amount, @credit_card, + 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' + }) + assert_success auth + end + + def test_authorize_with_lodging_data + assert auth = @gateway.authorize(@amount, @credit_card, + lodging_data: { + folio_number: 'ABC123', + check_in_date: '2050-12-22', + check_out_date: '2050-12-25', + room_rate: '80.00' + }) + assert_success auth + end + def test_successful_validate_on_store_with_verification_merchant_account - card = credit_card('4111111111111111', :verification_value => '101') - assert response = @gateway.store(card, :verify_card => true, :verification_merchant_account_id => fixtures(:braintree_blue)[:merchant_account_id]) + card = credit_card('4111111111111111', verification_value: '101') + assert response = @gateway.store(card, verify_card: true, verification_merchant_account_id: fixtures(:braintree_blue)[:merchant_account_id]) assert_success response, 'You must specify a valid :merchant_account_id key in your fixtures.yml for this to pass.' assert_equal 'OK', response.message end @@ -940,7 +954,7 @@ def stored_credential_options(*args, id: nil) end def assert_avs(address1, zip, expected_avs_code) - response = @gateway.purchase(@amount, @credit_card, billing_address: {address1: address1, zip: zip}) + response = @gateway.purchase(@amount, @credit_card, billing_address: { address1: address1, zip: zip }) assert_success response assert_equal expected_avs_code, response.avs_result['code'] diff --git a/test/remote/gateways/remote_braintree_orange_test.rb b/test/remote/gateways/remote_braintree_orange_test.rb index 0816eb1821b..6f69e221f56 100644 --- a/test/remote/gateways/remote_braintree_orange_test.rb +++ b/test/remote/gateways/remote_braintree_orange_test.rb @@ -8,9 +8,8 @@ def setup @credit_card = credit_card('4111111111111111') @check = check() @declined_amount = rand(99) - @options = { :order_id => generate_unique_id, - :billing_address => address - } + @options = { order_id: generate_unique_id, + billing_address: address } end def test_successful_purchase @@ -21,12 +20,12 @@ def test_successful_purchase def test_successful_purchase_with_echeck check = ActiveMerchant::Billing::Check.new( - :name => 'Fredd Bloggs', - :routing_number => '111000025', # Valid ABA # - Bank of America, TX - :account_number => '999999999999', - :account_holder_type => 'personal', - :account_type => 'checking' - ) + name: 'Fredd Bloggs', + routing_number: '111000025', # Valid ABA # - Bank of America, TX + account_number: '999999999999', + account_holder_type: 'personal', + account_type: 'checking' + ) assert response = @gateway.purchase(@amount, check, @options) assert_equal 'This transaction has been approved', response.message assert_success response @@ -61,7 +60,7 @@ def test_successful_add_to_vault_and_use assert_success response assert_not_nil customer_id = response.params['customer_vault_id'] - assert second_response = @gateway.purchase(@amount*2, customer_id, @options) + assert second_response = @gateway.purchase(@amount * 2, customer_id, @options) assert_equal 'This transaction has been approved', second_response.message assert second_response.success? end @@ -90,7 +89,7 @@ def test_add_to_vault_with_store_and_check def test_update_vault test_add_to_vault_with_custom_vault_id - @credit_card = credit_card('4111111111111111', :month => 10) + @credit_card = credit_card('4111111111111111', month: 10) assert response = @gateway.update(@options[:store], @credit_card) assert_success response assert_equal 'Customer Update Successful', response.message @@ -163,9 +162,9 @@ def test_failed_verify def test_invalid_login gateway = BraintreeOrangeGateway.new( - :login => '', - :password => '' - ) + login: '', + password: '' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_equal 'Invalid Username', response.message assert_failure response diff --git a/test/remote/gateways/remote_bridge_pay_test.rb b/test/remote/gateways/remote_bridge_pay_test.rb index 88f91a8212c..9fa4ff781a7 100644 --- a/test/remote/gateways/remote_bridge_pay_test.rb +++ b/test/remote/gateways/remote_bridge_pay_test.rb @@ -9,10 +9,10 @@ def setup @declined_card = credit_card('4000300011100000') @check = check( - :name => 'John Doe', - :routing_number => '490000018', - :account_number => '1234567890', - :number => '1001' + name: 'John Doe', + routing_number: '490000018', + account_number: '1234567890', + number: '1001' ) @options = { @@ -57,7 +57,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -78,7 +78,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund end diff --git a/test/remote/gateways/remote_cams_test.rb b/test/remote/gateways/remote_cams_test.rb index e193a39ce7e..b1e6a61ed75 100644 --- a/test/remote/gateways/remote_cams_test.rb +++ b/test/remote/gateways/remote_cams_test.rb @@ -73,7 +73,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -94,7 +94,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund end diff --git a/test/remote/gateways/remote_card_connect_test.rb b/test/remote/gateways/remote_card_connect_test.rb index 4ec9496c19d..7f9e5b026e2 100644 --- a/test/remote/gateways/remote_card_connect_test.rb +++ b/test/remote/gateways/remote_card_connect_test.rb @@ -65,6 +65,75 @@ def test_successful_purchase_with_more_options assert_equal 'Approval Queued for Capture', response.message end + def test_successful_purchase_with_more_options_but_no_PO + options = { + order_id: '1', + ip: '127.0.0.1', + email: 'joe@example.com', + tax_amount: '50', + freight_amount: '29', + duty_amount: '67', + order_date: '20170507', + ship_from_date: '20877', + items: [ + { + lineno: '1', + material: 'MATERIAL-1', + description: 'DESCRIPTION-1', + upc: 'UPC-1', + quantity: '1000', + uom: 'CS', + unitcost: '900', + netamnt: '150', + taxamnt: '117', + discamnt: '0' + }, + { + lineno: '2', + material: 'MATERIAL-2', + description: 'DESCRIPTION-2', + upc: 'UPC-1', + quantity: '2000', + uom: 'CS', + unitcost: '450', + netamnt: '300', + taxamnt: '117', + discamnt: '0' + } + ] + } + + response = @gateway.purchase(@amount, @credit_card, options) + assert_success response + assert_equal 'Approval', response.message + end + + def test_successful_purchase_with_user_fields + # `response` does not contain userfields, but the transaction may be checked after + # running the test suite via an authorized call to the inquireByOrderid endpoint: + # /cardconnect/rest/inquireByOrderid// + options = { + order_id: '138510', + ip: '127.0.0.1', + email: 'joe@example.com', + po_number: '5FSD4', + tax_amount: '50', + freight_amount: '29', + duty_amount: '67', + order_date: '20170507', + ship_from_date: '20877', + user_fields: [ + { 'udf0': 'value0' }, + { 'udf1': 'value1' }, + { 'udf2': 'value2' } + ] + } + + response = @gateway.purchase(@amount, @credit_card, options) + assert_success response + assert_equal 'Approval Queued for Capture', response.message + end + def test_successful_purchase_3DS three_ds_options = @options.merge( secure_flag: 'se3453', diff --git a/test/remote/gateways/remote_card_save_test.rb b/test/remote/gateways/remote_card_save_test.rb index 06ee56d1053..a3c34c19f3c 100644 --- a/test/remote/gateways/remote_card_save_test.rb +++ b/test/remote/gateways/remote_card_save_test.rb @@ -1,20 +1,19 @@ require 'test_helper' class RemoteCardSaveTest < Test::Unit::TestCase - def setup @gateway = CardSaveGateway.new(fixtures(:card_save)) @amount = 100 - @credit_card = credit_card('4976000000003436', :verification_value => '452') - @declined_card = credit_card('4221690000004963', :verification_value => '125') - @addresses = {'4976000000003436' => { :name => 'John Watson', :address1 => '32 Edward Street', :city => 'Camborne,', :state => 'Cornwall', :country => 'GB', :zip => 'TR14 8PA' }, - '4221690000004963' => { :name => 'Ian Lee', :address1 => '274 Lymington Avenue', :city => 'London', :state => 'London', :country => 'GB', :zip => 'N22 6JN' }} + @credit_card = credit_card('4976000000003436', verification_value: '452') + @declined_card = credit_card('4221690000004963', verification_value: '125') + @addresses = { '4976000000003436' => { name: 'John Watson', address1: '32 Edward Street', city: 'Camborne,', state: 'Cornwall', country: 'GB', zip: 'TR14 8PA' }, + '4221690000004963' => { name: 'Ian Lee', address1: '274 Lymington Avenue', city: 'London', state: 'London', country: 'GB', zip: 'N22 6JN' } } @options = { - :order_id => '1', - :billing_address => @addresses[@credit_card.number], - :description => 'Store Purchase' + order_id: '1', + billing_address: @addresses[@credit_card.number], + description: 'Store Purchase' } end @@ -32,7 +31,7 @@ def test_unsuccessful_purchase end def test_authorize_and_capture - amount = @amount+10 + amount = @amount + 10 assert auth = @gateway.authorize(amount, @credit_card, @options) assert_success auth assert auth.message =~ /AuthCode: ([0-9]+)/ @@ -49,8 +48,8 @@ def test_failed_capture def test_invalid_login gateway = CardSaveGateway.new( - :login => '', - :password => '' + login: '', + password: '' ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response diff --git a/test/remote/gateways/remote_card_stream_test.rb b/test/remote/gateways/remote_card_stream_test.rb index fd6d3e8e3ef..b37ecdf90d2 100644 --- a/test/remote/gateways/remote_card_stream_test.rb +++ b/test/remote/gateways/remote_card_stream_test.rb @@ -7,117 +7,112 @@ def setup @gateway = CardStreamGateway.new(fixtures(:card_stream)) @amex = credit_card('374245455400001', - :month => '12', - :year => '2014', - :verification_value => '4887', - :brand => :american_express - ) + month: '12', + year: Time.now.year + 1, + verification_value: '4887', + brand: :american_express) @mastercard = credit_card('5301250070000191', - :month => '12', - :year => '2014', - :verification_value => '419', - :brand => :master - ) + month: '12', + year: Time.now.year + 1, + verification_value: '419', + brand: :master) @visacreditcard = credit_card('4929421234600821', - :month => '12', - :year => '2014', - :verification_value => '356', - :brand => :visa - ) + month: '12', + year: Time.now.year + 1, + verification_value: '356', + brand: :visa) @visadebitcard = credit_card('4539791001730106', - :month => '12', - :year => '2014', - :verification_value => '289', - :brand => :visa - ) + month: '12', + year: Time.now.year + 1, + verification_value: '289', + brand: :visa) @declined_card = credit_card('4000300011112220', - :month => '9', - :year => '2014' - ) + month: '9', + year: Time.now.year + 1) @amex_options = { - :billing_address => { - :address1 => 'The Hunts Way', - :city => '', - :state => 'Leicester', - :zip => 'SO18 1GW', - :country => 'GB' + billing_address: { + address1: 'The Hunts Way', + city: '', + state: 'Leicester', + zip: 'SO18 1GW', + country: 'GB' }, - :order_id => generate_unique_id, - :description => 'AM test purchase', - :ip => '1.1.1.1' + order_id: generate_unique_id, + description: 'AM test purchase', + ip: '1.1.1.1' } @visacredit_options = { - :billing_address => { - :address1 => 'Flat 6, Primrose Rise', - :address2 => '347 Lavender Road', - :city => '', - :state => 'Northampton', - :zip => 'NN17 8YG', - :country => 'GB' + billing_address: { + address1: 'Flat 6, Primrose Rise', + address2: '347 Lavender Road', + city: '', + state: 'Northampton', + zip: 'NN17 8YG', + country: 'GB' }, - :order_id => generate_unique_id, - :description => 'AM test purchase', - :ip => '1.1.1.1' + order_id: generate_unique_id, + description: 'AM test purchase', + ip: '1.1.1.1' } @visacredit_descriptor_options = { - :billing_address => { - :address1 => 'Flat 6, Primrose Rise', - :address2 => '347 Lavender Road', - :city => '', - :state => 'Northampton', - :zip => 'NN17 8YG', - :country => 'GB' + billing_address: { + address1: 'Flat 6, Primrose Rise', + address2: '347 Lavender Road', + city: '', + state: 'Northampton', + zip: 'NN17 8YG', + country: 'GB' }, - :merchant_name => 'merchant', - :dynamic_descriptor => 'product', - :ip => '1.1.1.1', + order_id: generate_unique_id, + merchant_name: 'merchant', + dynamic_descriptor: 'product', + ip: '1.1.1.1' } @visacredit_reference_options = { - :order_id => generate_unique_id, - :description => 'AM test purchase', - :ip => '1.1.1.1' + order_id: generate_unique_id, + description: 'AM test purchase', + ip: '1.1.1.1' } @visadebit_options = { - :billing_address => { - :address1 => 'Unit 5, Pickwick Walk', - :address2 => '120 Uxbridge Road', - :city => 'Hatch End', - :state => 'Middlesex', - :zip => 'HA6 7HJ', - :country => 'GB' + billing_address: { + address1: 'Unit 5, Pickwick Walk', + address2: '120 Uxbridge Road', + city: 'Hatch End', + state: 'Middlesex', + zip: 'HA6 7HJ', + country: 'GB' }, - :order_id => generate_unique_id, - :description => 'AM test purchase', - :ip => '1.1.1.1' + order_id: generate_unique_id, + description: 'AM test purchase', + ip: '1.1.1.1' } @mastercard_options = { - :billing_address => { - :address1 => '25 The Larches', - :city => 'Narborough', - :state => 'Leicester', - :zip => 'LE10 2RT', - :country => 'GB' + billing_address: { + address1: '25 The Larches', + city: 'Narborough', + state: 'Leicester', + zip: 'LE10 2RT', + country: 'GB' }, - :order_id => generate_unique_id, - :description => 'AM test purchase', - :ip => '1.1.1.1' + order_id: generate_unique_id, + description: 'AM test purchase', + ip: '1.1.1.1' } @three_ds_enrolled_card = credit_card('4012001037141112', - :month => '12', - :year => '2020', - :brand => :visa - ) + month: '12', + year: '2020', + brand: :visa) end def test_successful_visacreditcard_authorization_and_capture @@ -166,7 +161,7 @@ def test_failed_visacreditcard_purchase_and_refund assert responseRefund = @gateway.refund(142, responsePurchase.authorization, @visacredit_options) assert_failure responseRefund - assert_equal 'Can not REFUND this SALE transaction', responseRefund.message + assert_equal 'Cannot REFUND this SALE transaction', responseRefund.message assert responseRefund.test? end @@ -223,7 +218,7 @@ def test_failed_visadebitcard_purchase_and_refund assert !responsePurchase.authorization.blank? assert responseRefund = @gateway.refund(142, responsePurchase.authorization, @visadebit_options) - assert_equal 'Can not REFUND this SALE transaction', responseRefund.message + assert_equal 'Cannot REFUND this SALE transaction', responseRefund.message assert_failure responseRefund assert responseRefund.test? end @@ -261,7 +256,7 @@ def test_failed_amex_purchase_and_refund assert !responsePurchase.authorization.blank? assert responseRefund = @gateway.refund(142, responsePurchase.authorization, @amex_options) - assert_equal 'Can not REFUND this SALE transaction', responseRefund.message + assert_equal 'Cannot REFUND this SALE transaction', responseRefund.message assert_failure responseRefund assert responseRefund.test? end @@ -299,7 +294,7 @@ def test_failed_mastercard_purchase_and_refund assert !responsePurchase.authorization.blank? assert responseRefund = @gateway.refund(142, responsePurchase.authorization, @mastercard_options) - assert_equal 'Can not REFUND this SALE transaction', responseRefund.message + assert_equal 'Cannot REFUND this SALE transaction', responseRefund.message assert_failure responseRefund assert responseRefund.test? end @@ -313,7 +308,7 @@ def test_successful_visacreditcard_purchase end def test_successful_visacreditcard_purchase_via_reference - assert response = @gateway.purchase(142, @visacreditcard, @visacredit_options.merge({:type => '9'})) + assert response = @gateway.purchase(142, @visacreditcard, @visacredit_options.merge({ type: '9' })) assert_equal 'APPROVED', response.message assert_success response assert response.test? @@ -343,6 +338,13 @@ def test_failed_purchase_non_existent_currency assert_match %r{MISSING_CURRENCYCODE}, response.message end + def test_successful_purchase_and_amount_for_non_decimal_currency + assert response = @gateway.purchase(14200, @visacreditcard, @visacredit_options.merge(currency: 'JPY')) + assert_success response + assert_equal '392', response.params['currencyCode'] + assert_equal '142', response.params['amount'] + end + def test_successful_visadebitcard_purchase assert response = @gateway.purchase(142, @visadebitcard, @visadebit_options) assert_equal 'APPROVED', response.message @@ -376,8 +378,8 @@ def test_successful_amex_purchase def test_invalid_login gateway = CardStreamGateway.new( - :login => '', - :shared_secret => '' + login: '', + shared_secret: '' ) assert response = gateway.purchase(142, @mastercard, @mastercard_options) assert_match %r{MISSING_MERCHANTID}, response.message @@ -393,7 +395,7 @@ def test_successful_verify def test_failed_verify response = @gateway.verify(@declined_card, @mastercard_options) assert_failure response - assert_match %r{INVALID_CARDNUMBER}, response.message + assert_match %r{Disallowed cardnumber}, response.message end def test_successful_3dsecure_purchase diff --git a/test/remote/gateways/remote_cardknox_test.rb b/test/remote/gateways/remote_cardknox_test.rb index 211e1e9afcb..ca7b0aef440 100644 --- a/test/remote/gateways/remote_cardknox_test.rb +++ b/test/remote/gateways/remote_cardknox_test.rb @@ -33,7 +33,7 @@ def setup zip: '46112', country: 'US', phone: '(555)555-5555', - fax: '(555)555-6666', + fax: '(555)555-6666' } } @@ -124,7 +124,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -138,7 +138,7 @@ def test_credit_card_purchase_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund end @@ -146,7 +146,7 @@ def test_failed_credit_card_authorize_partial_refund auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert refund = @gateway.refund(@amount-1, auth.authorization) + assert refund = @gateway.refund(@amount - 1, auth.authorization) assert_failure refund assert_equal 'Refund not allowed on non-captured auth.', refund.message end @@ -155,7 +155,7 @@ def test_failed_partial_check_refund # the gate way does not support this transa purchase = @gateway.purchase(@amount, @check, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_failure refund assert_equal "Transaction is in a state that cannot be refunded\nParameter name: originalReferenceNumber", refund.message # "Only allowed to refund transactions that have settled. This is the best we can do for now testing wise." end @@ -167,7 +167,7 @@ def test_credit_card_capture_partial_refund assert capture = @gateway.capture(@amount, auth.authorization) assert_success capture - assert refund = @gateway.refund(@amount-1, capture.authorization) + assert refund = @gateway.refund(@amount - 1, capture.authorization) assert_success refund end @@ -190,7 +190,7 @@ def test_successful_credit_card_capture_void auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture assert void = @gateway.void(capture.authorization, @options) @@ -214,7 +214,7 @@ def test_successful_credit_card_refund_void assert capture = @gateway.capture(@amount, auth.authorization) assert_success capture - assert refund = @gateway.refund(@amount-1, capture.authorization) + assert refund = @gateway.refund(@amount - 1, capture.authorization) assert_success refund assert void = @gateway.void(refund.authorization, @options) diff --git a/test/remote/gateways/remote_cardprocess_test.rb b/test/remote/gateways/remote_cardprocess_test.rb index 951c07e0ab3..c1763f9bd0e 100644 --- a/test/remote/gateways/remote_cardprocess_test.rb +++ b/test/remote/gateways/remote_cardprocess_test.rb @@ -50,7 +50,7 @@ def test_successful_authorize_and_capture end def test_failed_authorize - @gateway.instance_variable_set(:@test_options, {'customParameters[forceResultCode]' => '800.100.151'}) + @gateway.instance_variable_set(:@test_options, { 'customParameters[forceResultCode]' => '800.100.151' }) response = @gateway.authorize(@amount, @credit_card, @options) assert_failure response assert_equal 'transaction declined (invalid card)', response.message @@ -60,7 +60,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -89,7 +89,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund end @@ -121,7 +121,7 @@ def test_successful_verify end def test_failed_verify - @gateway.instance_variable_set(:@test_options, {'customParameters[forceResultCode]' => '600.200.100'}) + @gateway.instance_variable_set(:@test_options, { 'customParameters[forceResultCode]' => '600.200.100' }) response = @gateway.verify(@credit_card, @options) assert_failure response assert_match %r{invalid Payment Method}, response.message diff --git a/test/remote/gateways/remote_cecabank_test.rb b/test/remote/gateways/remote_cecabank_test.rb index b44ff568ead..d0389ba26fc 100644 --- a/test/remote/gateways/remote_cecabank_test.rb +++ b/test/remote/gateways/remote_cecabank_test.rb @@ -5,12 +5,12 @@ def setup @gateway = CecabankGateway.new(fixtures(:cecabank)) @amount = 100 - @credit_card = credit_card('5540500001000004', {:month => 12, :year => Time.now.year, :verification_value => 989}) - @declined_card = credit_card('5540500001000004', {:month => 11, :year => Time.now.year + 1, :verification_value => 001}) + @credit_card = credit_card('5540500001000004', { month: 12, year: Time.now.year, verification_value: 989 }) + @declined_card = credit_card('5540500001000004', { month: 11, year: Time.now.year + 1, verification_value: 001 }) @options = { - :order_id => generate_unique_id, - :description => 'Active Merchant Test Purchase' + order_id: generate_unique_id, + description: 'Active Merchant Test Purchase' } end diff --git a/test/remote/gateways/remote_cenpos_test.rb b/test/remote/gateways/remote_cenpos_test.rb index a3474658bbc..0edde763895 100644 --- a/test/remote/gateways/remote_cenpos_test.rb +++ b/test/remote/gateways/remote_cenpos_test.rb @@ -5,13 +5,19 @@ def setup @gateway = CenposGateway.new(fixtures(:cenpos)) @amount = SecureRandom.random_number(10000) - @credit_card = credit_card('4111111111111111', month: 02, year: 18, verification_value: 999) + @declined_amount = 100 + @credit_card = credit_card('4003440008007566', month: 12, year: 2025, verification_value: 999) + @declined_card = credit_card('4000300011112220') @invalid_card = credit_card('9999999999999999') @options = { order_id: SecureRandom.random_number(1000000), - billing_address: address + billing_address: { + name: 'Jim Smith', + address1: 'D8320', + zip: 'D5284' + } } end @@ -61,21 +67,21 @@ def test_successful_purchase_with_currency end def test_failed_purchase - response = @gateway.purchase(@amount, @declined_card, @options) + response = @gateway.purchase(@declined_amount, @declined_card, @options) assert_failure response assert_equal 'Decline transaction', response.message assert_equal Gateway::STANDARD_ERROR_CODE[:card_declined], response.error_code end def test_failed_purchase_cvv_result - response = @gateway.purchase(@amount, @declined_card, @options) + response = @gateway.purchase(@declined_amount, @declined_card, @options) %w(code message).each do |key| assert_equal nil, response.cvv_result[key] end end def test_failed_purchase_avs_result - response = @gateway.purchase(@amount, @declined_card, @options) + response = @gateway.purchase(@declined_amount, @declined_card, @options) %w(code message).each do |key| assert_equal nil, response.avs_result[key] end @@ -93,7 +99,7 @@ def test_successful_authorize_and_capture end def test_failed_authorize - response = @gateway.authorize(@amount, @declined_card, @options) + response = @gateway.authorize(@declined_amount, @declined_card, @options) assert_failure response assert_equal 'Decline transaction', response.message assert_equal Gateway::STANDARD_ERROR_CODE[:card_declined], response.error_code @@ -107,7 +113,7 @@ def test_failed_capture @gateway.capture(@amount, response.authorization) capture = @gateway.capture(@amount, response.authorization) assert_failure capture - assert_equal 'Duplicated force transaction.', capture.message + assert_match(/Duplicated.*transaction/, capture.message) end def test_successful_void @@ -166,11 +172,13 @@ def test_failed_credit assert_equal Gateway::STANDARD_ERROR_CODE[:invalid_number], response.error_code end - def test_successful_verify - response = @gateway.verify(@credit_card, @options) - assert_success response - assert_match %r{Succeeded}, response.message - end + # This test appears to fail due to the amount of 100 being set in verify + # That amount is automatically triggering a decline message in tests + # def test_successful_verify + # response = @gateway.verify(@credit_card, @options) + # assert_success response + # assert_match %r{Succeeded}, response.message + # end def test_failed_verify response = @gateway.verify(@declined_card, @options) diff --git a/test/remote/gateways/remote_checkout_test.rb b/test/remote/gateways/remote_checkout_test.rb index 206442a70fa..4977d1889f4 100644 --- a/test/remote/gateways/remote_checkout_test.rb +++ b/test/remote/gateways/remote_checkout_test.rb @@ -9,7 +9,7 @@ def setup year: '2017', verification_value: '956' ) - @declined_card = credit_card( + @declined_card = credit_card( '4543474002249996', month: '06', year: '2018', @@ -27,13 +27,14 @@ def test_successful_purchase end def test_successful_purchase_with_extra_options - response = @gateway.purchase(100, @credit_card, @options.merge( + options = @options.merge( currency: 'EUR', email: 'bob@example.com', order_id: generate_unique_id, customer: generate_unique_id, ip: '127.0.0.1' - )) + ) + response = @gateway.purchase(100, @credit_card, options) assert_success response assert_equal 'Successful', response.message end @@ -60,7 +61,7 @@ def test_successful_authorize_and_capture auth = @gateway.authorize(100, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(100, auth.authorization, {currency: 'CAD'}) + assert capture = @gateway.capture(100, auth.authorization, { currency: 'CAD' }) assert_success capture assert_equal 'Successful', capture.message end @@ -101,7 +102,7 @@ def test_successful_refund assert response = @gateway.purchase(100, @credit_card, @options) assert_success response - assert refund = @gateway.refund(100, response.authorization, {currency: 'CAD'}) + assert refund = @gateway.refund(100, response.authorization, { currency: 'CAD' }) assert_success refund assert_equal 'Successful', refund.message end @@ -110,7 +111,7 @@ def test_failed_refund assert response = @gateway.purchase(100, @credit_card, @options) assert_success response - assert refund = @gateway.refund(100, '||||', {currency: 'CAD'}) + assert refund = @gateway.refund(100, '||||', { currency: 'CAD' }) assert_failure refund end diff --git a/test/remote/gateways/remote_checkout_v2_test.rb b/test/remote/gateways/remote_checkout_v2_test.rb index fa02c0c3371..3afb7ddb76c 100644 --- a/test/remote/gateways/remote_checkout_v2_test.rb +++ b/test/remote/gateways/remote_checkout_v2_test.rb @@ -8,6 +8,14 @@ def setup @credit_card = credit_card('4242424242424242', verification_value: '100', month: '6', year: '2025') @expired_card = credit_card('4242424242424242', verification_value: '100', month: '6', year: '2010') @declined_card = credit_card('42424242424242424', verification_value: '234', month: '6', year: '2025') + @threeds_card = credit_card('4485040371536584', verification_value: '100', month: '12', year: '2020') + + @network_token = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'AgAAAAAAAIR8CQrXcIhbQAAAAAA', + month: '10', + year: '2025', + source: :network_token, + verification_value: nil) @options = { order_id: '1', @@ -31,6 +39,7 @@ def setup ) @additional_options_3ds2 = @options.merge( execute_threed: true, + attempt_n3d: true, three_d_secure: { version: '2.0.0', eci: '06', @@ -57,6 +66,13 @@ def test_successful_purchase assert_equal 'Succeeded', response.message end + def test_successful_purchase_with_network_token + response = @gateway.purchase(100, @network_token, @options) + assert_success response + assert_equal 'Succeeded', response.message + assert_not_nil response.params['source']['payment_account_reference'] + end + def test_successful_purchase_with_additional_options response = @gateway.purchase(@amount, @credit_card, @additional_options) assert_success response @@ -71,7 +87,7 @@ def test_successful_purchase_with_moto_flag end def test_successful_purchase_with_manual_entry_flag - response = @gateway.authorize(@amount, @credit_card, @options.merge(metadata: { manual_entry: true})) + response = @gateway.authorize(@amount, @credit_card, @options.merge(metadata: { manual_entry: true })) assert_success response assert_equal 'Succeeded', response.message @@ -133,9 +149,9 @@ def test_successful_purchase_with_ip end def test_failed_purchase - response = @gateway.purchase(@amount, @declined_card, @options) + response = @gateway.purchase(12305, @credit_card, @options) assert_failure response - assert_equal 'request_invalid: card_number_invalid', response.message + assert_equal 'Declined - Do Not Honour', response.message end def test_avs_failed_purchase @@ -182,16 +198,25 @@ def test_successful_authorize_and_capture_with_3ds2 assert_success capture end + def test_direct_3ds_authorize + auth = @gateway.authorize(@amount, @threeds_card, @options.merge(execute_threed: true)) + + assert_equal 'Pending', auth.message + assert_equal 'Y', auth.params['3ds']['enrolled'] + assert auth.params['_links']['redirect'] + end + def test_failed_authorize - response = @gateway.authorize(@amount, @declined_card, @options) + response = @gateway.authorize(12314, @credit_card, @options) assert_failure response + assert_equal 'Invalid Card Number', response.message end def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -204,6 +229,8 @@ def test_successful_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase + sleep 1 + assert refund = @gateway.refund(@amount, purchase.authorization) assert_success refund end @@ -212,7 +239,9 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + sleep 1 + + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund end @@ -236,6 +265,11 @@ def test_failed_void def test_successful_verify response = @gateway.verify(@credit_card, @options) + # this should only be a Response and not a MultiResponse + # as we are passing in a 0 amount and there should be + # no void call + assert_instance_of(Response, response) + refute_instance_of(MultiResponse, response) assert_success response assert_match %r{Succeeded}, response.message end diff --git a/test/remote/gateways/remote_citrus_pay_test.rb b/test/remote/gateways/remote_citrus_pay_test.rb index cf7d131b942..cfb4711d02a 100644 --- a/test/remote/gateways/remote_citrus_pay_test.rb +++ b/test/remote/gateways/remote_citrus_pay_test.rb @@ -34,7 +34,7 @@ def test_successful_purchase_sans_options def test_successful_purchase_with_more_options more_options = @options.merge({ ip: '127.0.0.1', - email: 'joe@example.com', + email: 'joe@example.com' }) assert response = @gateway.purchase(@amount, @credit_card, @options.merge(more_options)) @@ -104,9 +104,9 @@ def test_successful_verify def test_invalid_login gateway = CitrusPayGateway.new( - :userid => 'nosuch', - :password => 'thing' - ) + userid: 'nosuch', + password: 'thing' + ) response = gateway.authorize(@amount, @credit_card, @options) assert_failure response assert_equal 'ERROR - INVALID_REQUEST - Invalid credentials.', response.message @@ -130,5 +130,4 @@ def test_verify_credentials gateway = CitrusPayGateway.new(userid: 'unknown', password: 'unknown') assert !gateway.verify_credentials end - end diff --git a/test/remote/gateways/remote_clearhaus_test.rb b/test/remote/gateways/remote_clearhaus_test.rb index 9a716294dcb..844b748aee4 100644 --- a/test/remote/gateways/remote_clearhaus_test.rb +++ b/test/remote/gateways/remote_clearhaus_test.rb @@ -74,10 +74,17 @@ def test_successful_purchase_with_text_on_statement assert_equal 'Approved', response.message end + def test_successful_purchase_and_amount_for_non_decimal_currency + response = @gateway.purchase(14200, @credit_card, @options.merge(currency: 'JPY')) + assert_success response + assert_equal 142, response.params['amount'] + assert_equal 'Approved', response.message + end + def test_successful_purchase_with_more_options options = { order_id: '1', - ip: '127.0.0.1', + ip: '127.0.0.1' } response = @gateway.purchase(@amount, @credit_card, @options.merge(options)) @@ -113,7 +120,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -136,7 +143,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund end @@ -184,7 +191,7 @@ def test_failed_verify end def test_successful_authorize_with_nonfractional_currency - assert response = @gateway.authorize(100, @credit_card, @options.merge(:currency => 'KRW')) + assert response = @gateway.authorize(100, @credit_card, @options.merge(currency: 'KRW')) assert_equal 1, response.params['amount'] assert_success response end diff --git a/test/remote/gateways/remote_commercegate_test.rb b/test/remote/gateways/remote_commercegate_test.rb index 3ca37b555c2..4f9c0be7cf8 100644 --- a/test/remote/gateways/remote_commercegate_test.rb +++ b/test/remote/gateways/remote_commercegate_test.rb @@ -11,7 +11,7 @@ def setup } @credit_card = credit_card(fixtures(:commercegate)[:card_number]) - @expired_credit_card = credit_card(fixtures(:commercegate)[:card_number], year: Time.now.year-1) + @expired_credit_card = credit_card(fixtures(:commercegate)[:card_number], year: Time.now.year - 1) end def test_successful_authorize diff --git a/test/remote/gateways/remote_conekta_test.rb b/test/remote/gateways/remote_conekta_test.rb index c466b8ad74c..bda8473700c 100644 --- a/test/remote/gateways/remote_conekta_test.rb +++ b/test/remote/gateways/remote_conekta_test.rb @@ -25,7 +25,7 @@ def setup ) @options = { - :device_fingerprint => '41l9l92hjco6cuekf0c7dq68v4', + device_fingerprint: '41l9l92hjco6cuekf0c7dq68v4', description: 'Blue clip', billing_address: { address1: 'Rio Missisipi #123', @@ -34,18 +34,18 @@ def setup country: 'Mexico', zip: '5555', name: 'Mario Reyes', - phone: '12345678', + phone: '12345678' }, carrier: 'Estafeta', email: 'bob@something.com', line_items: [{ - name: 'Box of Cohiba S1s', - description: 'Imported From Mex.', - unit_price: 20000, - quantity: 1, - sku: '7500244909', - type: 'food' - }] + name: 'Box of Cohiba S1s', + description: 'Imported From Mex.', + unit_price: 20000, + quantity: 1, + sku: '7500244909', + type: 'food' + }] } end @@ -56,7 +56,7 @@ def test_successful_purchase end def test_successful_purchase_with_installments - assert response = @gateway.purchase(@amount * 300, @credit_card, @options.merge({monthly_installments: 3})) + assert response = @gateway.purchase(@amount * 300, @credit_card, @options.merge({ monthly_installments: 3 })) assert_success response assert_equal nil, response.message end @@ -143,7 +143,7 @@ def test_successful_purchase_passing_more_details city: 'Wanaque', state: 'NJ', country: 'USA', - zip: '01085', + zip: '01085' }, line_items: [ { diff --git a/test/remote/gateways/remote_creditcall_test.rb b/test/remote/gateways/remote_creditcall_test.rb index 527d60979a6..d7ed5a7d2fa 100644 --- a/test/remote/gateways/remote_creditcall_test.rb +++ b/test/remote/gateways/remote_creditcall_test.rb @@ -89,7 +89,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -112,7 +112,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund end diff --git a/test/remote/gateways/remote_credorax_test.rb b/test/remote/gateways/remote_credorax_test.rb index fc4c3506ad9..c20c8b4d3df 100644 --- a/test/remote/gateways/remote_credorax_test.rb +++ b/test/remote/gateways/remote_credorax_test.rb @@ -5,10 +5,11 @@ def setup @gateway = CredoraxGateway.new(fixtures(:credorax)) @amount = 100 + @adviser_amount = 1000001 @credit_card = credit_card('4176661000001015', verification_value: '281', month: '12', year: '2022') @fully_auth_card = credit_card('5223450000000007', brand: 'mastercard', verification_value: '090', month: '12', year: '2025') @declined_card = credit_card('4176661000001111', verification_value: '681', month: '12', year: '2022') - @three_ds_card = credit_card('5185520050000010', verification_value: '737', month: '12', year: '2022') + @three_ds_card = credit_card('4761739000060016', verification_value: '212', month: '12', year: '2027') @options = { order_id: '1', currency: 'EUR', @@ -26,7 +27,7 @@ def setup execute_threed: true, three_ds_version: '2', three_ds_challenge_window_size: '01', - stored_credential: {reason_type: 'unscheduled'}, + stored_credential: { reason_type: 'unscheduled' }, three_ds_2: { channel: 'browser', notification_url: 'www.example.com', @@ -57,6 +58,13 @@ def test_successful_purchase assert_equal 'Succeeded', response.message end + def test_successful_purchase_and_amount_for_non_decimal_currency + response = @gateway.purchase(14200, @credit_card, @options.merge(currency: 'JPY')) + assert_success response + assert_equal '142', response.params['A4'] + assert_equal 'Succeeded', response.message + end + def test_successful_purchase_with_extra_options response = @gateway.purchase(@amount, @credit_card, @options.merge(transaction_type: '10')) assert_success response @@ -68,7 +76,48 @@ def test_successful_purchase_with_auth_data_via_3ds1_fields options = @options.merge( eci: '02', cavv: 'jJ81HADVRtXfCBATEp01CJUAAAA=', - xid: '00000000000000000501' + xid: '00000000000000000501', + # Having processor-specification enabled in Credorax test account causes 3DS tests to fail without a r1 (processor) parameter. + processor: 'CREDORAX' + ) + + response = @gateway.purchase(@amount, @fully_auth_card, options) + assert_success response + assert_equal '1', response.params['H9'] + assert_equal 'Succeeded', response.message + end + + def test_successful_purchase_with_auth_data_via_3ds1_fields_passing_3ds_version + options = @options.merge( + eci: '02', + cavv: 'jJ81HADVRtXfCBATEp01CJUAAAA=', + xid: '00000000000000000501', + # Having processor-specification enabled in Credorax test account causes 3DS tests to fail without a r1 (processor) parameter. + processor: 'CREDORAX', + three_ds_version: '1.0.2' + ) + + response = @gateway.purchase(@amount, @fully_auth_card, options) + assert_success response + assert_equal '1', response.params['H9'] + assert_equal 'Succeeded', response.message + end + + def test_successful_purchase_with_auth_data_via_normalized_3ds1_options + version = '1.0.2' + eci = '02' + cavv = 'jJ81HADVRtXfCBATEp01CJUAAAA=' + xid = '00000000000000000501' + + options = @options.merge( + three_d_secure: { + version: version, + eci: eci, + cavv: cavv, + xid: xid + }, + # Having processor-specification enabled in Credorax test account causes 3DS tests to fail without a r1 (processor) parameter. + processor: 'CREDORAX' ) response = @gateway.purchase(@amount, @fully_auth_card, options) @@ -84,6 +133,15 @@ def test_successful_purchase_with_3ds2_fields assert_equal 'Succeeded', response.message end + def test_successful_purchase_with_3ds_adviser + threeds_options = @options.merge(@normalized_3ds_2_options) + options = threeds_options.merge(three_ds_initiate: '03', f23: '1') + response = @gateway.purchase(@adviser_amount, @three_ds_card, options) + assert_success response + assert_equal 'Succeeded', response.message + assert_equal '01', response.params['SMART_3DS_RESULT'] + end + def test_successful_moto_purchase response = @gateway.purchase(@amount, @three_ds_card, @options.merge(metadata: { manual_entry: true })) assert_success response @@ -93,7 +151,7 @@ def test_successful_moto_purchase end def test_successful_purchase_with_auth_data_via_normalized_3ds2_options - version = '2.0' + version = '2.2.0' eci = '02' cavv = 'jJ81HADVRtXfCBATEp01CJUAAAA=' ds_transaction_id = '97267598-FAE6-48F2-8083-C23433990FBC' @@ -103,7 +161,9 @@ def test_successful_purchase_with_auth_data_via_normalized_3ds2_options eci: eci, cavv: cavv, ds_transaction_id: ds_transaction_id - } + }, + # Having processor-specification enabled in Credorax test account causes 3DS tests to fail without a r1 (processor) parameter. + processor: 'CREDORAX' ) response = @gateway.purchase(@amount, @fully_auth_card, options) @@ -162,11 +222,21 @@ def test_successful_authorize_and_capture assert_equal 'Succeeded', capture.message end + def test_successful_authorize_with_authorization_details + options_with_auth_details = @options.merge({ authorization_type: '2', multiple_capture_count: '5' }) + response = @gateway.authorize(@amount, @credit_card, options_with_auth_details) + assert_success response + assert_equal 'Succeeded', response.message + assert response.authorization + end + def test_successful_authorize_with_auth_data_via_3ds1_fields options = @options.merge( eci: '02', cavv: 'jJ81HADVRtXfCBATEp01CJUAAAA=', - xid: '00000000000000000501' + xid: '00000000000000000501', + # Having processor-specification enabled in Credorax test account causes 3DS tests to fail without a r1 (processor) parameter. + processor: 'CREDORAX' ) response = @gateway.authorize(@amount, @fully_auth_card, options) @@ -186,7 +256,9 @@ def test_successful_authorize_with_auth_data_via_normalized_3ds2_options eci: eci, cavv: cavv, ds_transaction_id: ds_transaction_id - } + }, + # Having processor-specification enabled in Credorax test account causes 3DS tests to fail without a r1 (processor) parameter. + processor: 'CREDORAX' ) response = @gateway.authorize(@amount, @fully_auth_card, options) @@ -277,6 +349,45 @@ def test_failed_refund assert_equal 'Referred to transaction has not been found.', response.message end + def test_successful_referral_cft + options = @options.merge(@normalized_3ds_2_options) + response = @gateway.purchase(@amount, @three_ds_card, options) + assert_success response + assert_equal 'Succeeded', response.message + + cft_options = { referral_cft: true, email: 'john.smith@test.com' } + referral_cft = @gateway.refund(@amount, response.authorization, cft_options) + assert_success referral_cft + assert_equal 'Succeeded', referral_cft.message + # Confirm that the operation code was `referral_cft` + assert_equal '34', referral_cft.params['O'] + end + + def test_successful_referral_cft_with_first_and_last_name + response = @gateway.purchase(@amount, @credit_card, @options) + assert_success response + assert_equal 'Succeeded', response.message + + cft_options = { referral_cft: true, email: 'john.smith@test.com', first_name: 'John', last_name: 'Smith' } + referral_cft = @gateway.refund(@amount, response.authorization, cft_options) + assert_success referral_cft + assert_equal 'Succeeded', referral_cft.message + # Confirm that the operation code was `referral_cft` + assert_equal '34', referral_cft.params['O'] + end + + def test_failed_referral_cft + options = @options.merge(@normalized_3ds_2_options) + response = @gateway.purchase(@amount, @three_ds_card, options) + assert_success response + assert_equal 'Succeeded', response.message + + cft_options = { referral_cft: true, email: 'john.smith@test.com' } + referral_cft = @gateway.refund(@amount, '123;123;123', cft_options) + assert_failure referral_cft + assert_equal 'Referred to transaction has not been found.', referral_cft.message + end + def test_successful_credit response = @gateway.credit(@amount, @credit_card, @options) assert_success response @@ -401,11 +512,12 @@ def test_transcript_scrubbing def test_purchase_passes_processor # returns a successful response when a valid processor parameter is sent - assert good_response = @gateway.purchase(@amount, @credit_card, @options.merge(fixtures(:credorax_with_processor))) + assert good_response = @gateway.purchase(@amount, @credit_card, @options.merge(processor: 'CREDORAX')) assert_success good_response assert_equal 'Succeeded', good_response.message + assert_equal 'CREDORAX', good_response.params['Z33'] - # returns a failed response when an invalid tx_source parameter is sent + # returns a failed response when an invalid processor parameter is sent assert bad_response = @gateway.purchase(@amount, @credit_card, @options.merge(processor: 'invalid')) assert_failure bad_response end diff --git a/test/remote/gateways/remote_ct_payment_certification_test.rb b/test/remote/gateways/remote_ct_payment_certification_test.rb index 7a4ef3988f4..2bc5d80aa16 100644 --- a/test/remote/gateways/remote_ct_payment_certification_test.rb +++ b/test/remote/gateways/remote_ct_payment_certification_test.rb @@ -239,5 +239,4 @@ def print_result(test_number, response) puts "Test #{test_number} | transaction number: #{response.params['transactionNumber']}, invoice number #{response.params['invoiceNumber']}, timestamp: #{response.params['timeStamp']}, result: #{response.params['returnCode']}" puts response.inspect end - end diff --git a/test/remote/gateways/remote_ct_payment_test.rb b/test/remote/gateways/remote_ct_payment_test.rb index 4fd0ba8738a..87c793de4be 100644 --- a/test/remote/gateways/remote_ct_payment_test.rb +++ b/test/remote/gateways/remote_ct_payment_test.rb @@ -47,7 +47,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization, @options.merge(order_id: generate_unique_id[0, 11])) + assert capture = @gateway.capture(@amount - 1, auth.authorization, @options.merge(order_id: generate_unique_id[0, 11])) assert_success capture end @@ -70,7 +70,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization, @options.merge(order_id: generate_unique_id[0, 11])) + assert refund = @gateway.refund(@amount - 1, purchase.authorization, @options.merge(order_id: generate_unique_id[0, 11])) assert_success refund end @@ -169,5 +169,4 @@ def test_transcript_scrubbing_store assert_scrubbed(Base64.strict_encode64(@credit_card.number), transcript) assert_scrubbed(@gateway.options[:api_key], transcript) end - end diff --git a/test/remote/gateways/remote_culqi_test.rb b/test/remote/gateways/remote_culqi_test.rb index d8241b2aef3..c4c1fb7131a 100644 --- a/test/remote/gateways/remote_culqi_test.rb +++ b/test/remote/gateways/remote_culqi_test.rb @@ -58,7 +58,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture assert_match %r{Transaction has been successfully captured}, capture.message end @@ -97,7 +97,7 @@ def test_partial_refund auth = @gateway.authorize(@amount, @credit_card, @options) capture = @gateway.capture(@amount, auth.authorization) - refund = @gateway.refund(@amount-1, capture.authorization) + refund = @gateway.refund(@amount - 1, capture.authorization) assert_success refund assert_match %r{reversed}, refund.message end diff --git a/test/remote/gateways/remote_cyber_source_test.rb b/test/remote/gateways/remote_cyber_source_test.rb index e72a734592b..a01eef5f1ed 100644 --- a/test/remote/gateways/remote_cyber_source_test.rb +++ b/test/remote/gateways/remote_cyber_source_test.rb @@ -1,79 +1,75 @@ require 'test_helper' class RemoteCyberSourceTest < Test::Unit::TestCase + # Reduce code duplication: use `assert_successful_response` when feasible! def setup Base.mode = :test - @gateway = CyberSourceGateway.new({nexus: 'NC'}.merge(fixtures(:cyber_source))) + @gateway = CyberSourceGateway.new({ nexus: 'NC' }.merge(fixtures(:cyber_source))) - @credit_card = credit_card('4111111111111111', verification_value: '321') + @credit_card = credit_card('4111111111111111', verification_value: '987') @declined_card = credit_card('801111111111111') @pinless_debit_card = credit_card('4002269999999999') @elo_credit_card = credit_card('5067310000000010', verification_value: '321', month: '12', year: (Time.now.year + 2).to_s, - brand: :elo - ) + brand: :elo) @three_ds_unenrolled_card = credit_card('4000000000000051', verification_value: '321', month: '12', year: (Time.now.year + 2).to_s, - brand: :visa - ) + brand: :visa) @three_ds_enrolled_card = credit_card('4000000000000002', verification_value: '321', month: '12', year: (Time.now.year + 2).to_s, - brand: :visa - ) + brand: :visa) @three_ds_invalid_card = credit_card('4000000000000010', verification_value: '321', month: '12', year: (Time.now.year + 2).to_s, - brand: :visa - ) + brand: :visa) @three_ds_enrolled_mastercard = credit_card('5200000000001005', verification_value: '321', month: '12', year: (Time.now.year + 2).to_s, - brand: :master - ) + brand: :master) @amount = 100 @options = { - :order_id => generate_unique_id, - :line_items => [ + order_id: generate_unique_id, + line_items: [ { - :declared_value => 100, - :quantity => 2, - :code => 'default', - :description => 'Giant Walrus', - :sku => 'WA323232323232323' + declared_value: 100, + quantity: 2, + code: 'default', + description: 'Giant Walrus', + sku: 'WA323232323232323' }, { - :declared_value => 100, - :quantity => 2, - :description => 'Marble Snowcone', - :sku => 'FAKE1232132113123' + declared_value: 100, + quantity: 2, + description: 'Marble Snowcone', + sku: 'FAKE1232132113123' } ], - :currency => 'USD', - :ignore_avs => 'true', - :ignore_cvv => 'true', - :commerce_indicator => 'internet' + currency: 'USD', + ignore_avs: 'true', + ignore_cvv: 'true', + commerce_indicator: 'internet' } @subscription_options = { - :order_id => generate_unique_id, - :credit_card => @credit_card, - :subscription => { - :frequency => 'weekly', - :start_date => Date.today.next_week, - :occurrences => 4, - :auto_renew => true, - :amount => 100 + order_id: generate_unique_id, + credit_card: @credit_card, + subscription: { + frequency: 'weekly', + start_date: Date.today.next_week, + occurrences: 4, + auto_renew: true, + amount: 100 } } @@ -94,10 +90,9 @@ def test_transcript_scrubbing def test_network_tokenization_transcript_scrubbing credit_card = network_tokenization_credit_card('4111111111111111', - :brand => 'visa', - :eci => '05', - :payment_cryptogram => 'EHuWW9PiBkWvqE5juRwDzAUFBAk=' - ) + brand: 'visa', + eci: '05', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=') transcript = capture_transcript(@gateway) do @gateway.authorize(@amount, credit_card, @options) @@ -115,6 +110,39 @@ def test_successful_authorization assert !response.authorization.blank? end + def test_successful_authorization_with_reconciliation_id + options = @options.merge(reconciliation_id: '1936831') + assert response = @gateway.authorize(@amount, @credit_card, options) + assert_successful_response(response) + assert !response.authorization.blank? + end + + def test_successful_authorize_with_solution_id + ActiveMerchant::Billing::CyberSourceGateway.application_id = 'A1000000' + assert response = @gateway.authorize(@amount, @credit_card, @options) + assert_successful_response(response) + assert !response.authorization.blank? + ensure + ActiveMerchant::Billing::CyberSourceGateway.application_id = nil + end + + def test_successful_authorize_with_solution_id_and_stored_creds + ActiveMerchant::Billing::CyberSourceGateway.application_id = 'A1000000' + @options[:stored_credential] = { + initiator: 'cardholder', + reason_type: '', + initial_transaction: true, + network_transaction_id: '' + } + @options[:commerce_indicator] = 'internet' + + assert response = @gateway.authorize(@amount, @credit_card, @options) + assert_successful_response(response) + assert !response.authorization.blank? + ensure + ActiveMerchant::Billing::CyberSourceGateway.application_id = nil + end + def test_successful_authorization_with_issuer_additional_data @options[:issuer_additional_data] = @issuer_additional_data @@ -123,56 +151,139 @@ def test_successful_authorization_with_issuer_additional_data assert !response.authorization.blank? end + def test_successful_authorization_with_issuer_additional_data_and_partner_solution_id + @options[:issuer_additional_data] = @issuer_additional_data + + ActiveMerchant::Billing::CyberSourceGateway.application_id = 'A1000000' + + assert auth = @gateway.authorize(@amount, @credit_card, @options) + assert_successful_response(auth) + + assert void = @gateway.void(auth.authorization, @options) + assert_successful_response(void) + ensure + ActiveMerchant::Billing::CyberSourceGateway.application_id = nil + end + + def test_successful_authorize_with_merchant_descriptor_and_partner_solution_id + @options[:merchant_descriptor] = 'Spreedly' + + ActiveMerchant::Billing::CyberSourceGateway.application_id = 'A1000000' + + assert auth = @gateway.authorize(@amount, @credit_card, @options) + assert_successful_response(auth) + + assert void = @gateway.void(auth.authorization, @options) + assert_successful_response(void) + ensure + ActiveMerchant::Billing::CyberSourceGateway.application_id = nil + end + + def test_successful_authorize_with_issuer_additional_data_stored_creds_merchant_desc_and_partner_solution_id + @options[:issuer_additional_data] = @issuer_additional_data + @options[:stored_credential] = { + initiator: 'cardholder', + reason_type: '', + initial_transaction: true, + network_transaction_id: '' + } + @options[:commerce_indicator] = 'internet' + @options[:merchant_descriptor] = 'Spreedly' + + ActiveMerchant::Billing::CyberSourceGateway.application_id = 'A1000000' + + assert auth = @gateway.authorize(@amount, @credit_card, @options) + assert_successful_response(auth) + ensure + ActiveMerchant::Billing::CyberSourceGateway.application_id = nil + end + def test_successful_authorization_with_elo assert response = @gateway.authorize(@amount, @elo_credit_card, @options) assert_successful_response(response) assert !response.authorization.blank? end + def test_successful_authorization_with_installment_total_count + assert response = @gateway.authorize(@amount, @credit_card, installment_total_count: 5) + assert_successful_response(response) + assert !response.authorization.blank? + end + def test_unsuccessful_authorization assert response = @gateway.authorize(@amount, @declined_card, @options) assert response.test? assert_equal 'Invalid account number', response.message - assert_equal false, response.success? + assert_equal false, response.success? + end + + def test_purchase_and_void + assert purchase = @gateway.purchase(@amount, @credit_card, @options) + assert_successful_response(purchase) + assert void = @gateway.void(purchase.authorization, @options) + assert_successful_response(void) end def test_authorize_and_void assert auth = @gateway.authorize(@amount, @credit_card, @options) - assert_success auth + assert_successful_response(auth) assert void = @gateway.void(auth.authorization, @options) - assert_equal 'Successful transaction', void.message - assert_success void - assert void.test? + assert_successful_response(void) end def test_capture_and_void assert auth = @gateway.authorize(@amount, @credit_card, @options) - assert_success auth + assert_successful_response(auth) assert capture = @gateway.capture(@amount, auth.authorization, @options) - assert_success capture + assert_successful_response(capture) assert void = @gateway.void(capture.authorization, @options) - assert_equal 'Successful transaction', void.message - assert_success void - assert void.test? + assert_successful_response(void) end def test_capture_and_void_with_elo assert auth = @gateway.authorize(@amount, @elo_credit_card, @options) - assert_success auth + assert_successful_response(auth) assert capture = @gateway.capture(@amount, auth.authorization, @options) - assert_success capture + assert_successful_response(capture) assert void = @gateway.void(capture.authorization, @options) - assert_equal 'Successful transaction', void.message - assert_success void - assert void.test? + assert_successful_response(void) + end + + def test_void_with_issuer_additional_data + @options[:issuer_additional_data] = @issuer_additional_data + + assert auth = @gateway.authorize(@amount, @credit_card, @options) + assert_successful_response(auth) + assert void = @gateway.void(auth.authorization, @options) + assert_successful_response(void) + end + + def test_void_with_mdd_fields + (1..20).each { |e| @options["mdd_field_#{e}".to_sym] = "value #{e}" } + + assert auth = @gateway.authorize(@amount, @credit_card, @options) + assert_successful_response(auth) + assert void = @gateway.void(auth.authorization, @options) + assert_successful_response(void) + end + + def test_successful_void_with_solution_id + ActiveMerchant::Billing::CyberSourceGateway.application_id = 'A1000000' + + assert auth = @gateway.authorize(@amount, @credit_card, @options) + assert_successful_response(auth) + + assert void = @gateway.void(auth.authorization, @options) + assert_successful_response(void) + ensure + ActiveMerchant::Billing::CyberSourceGateway.application_id = nil end def test_successful_tax_calculation assert response = @gateway.calculate_tax(@credit_card, @options) - assert_equal 'Successful transaction', response.message assert response.params['totalTaxAmount'] assert_not_equal '0', response.params['totalTaxAmount'] - assert_success response + assert_successful_response(response) end def test_successful_purchase @@ -187,6 +298,60 @@ def test_successful_purchase_with_issuer_additional_data assert_successful_response(response) end + def test_successful_purchase_with_merchant_descriptor + @options[:merchant_descriptor] = 'Spreedly' + + assert response = @gateway.purchase(@amount, @credit_card, @options) + assert_successful_response(response) + end + + def test_successful_purchase_with_issuer_additional_data_and_partner_solution_id + @options[:issuer_additional_data] = @issuer_additional_data + + ActiveMerchant::Billing::CyberSourceGateway.application_id = 'A1000000' + + assert purchase = @gateway.purchase(@amount, @credit_card, @options) + assert_successful_response(purchase) + ensure + ActiveMerchant::Billing::CyberSourceGateway.application_id = nil + end + + def test_successful_purchase_with_merchant_descriptor_and_partner_solution_id + @options[:merchant_descriptor] = 'Spreedly' + + ActiveMerchant::Billing::CyberSourceGateway.application_id = 'A1000000' + + assert purchase = @gateway.purchase(@amount, @credit_card, @options) + assert_successful_response(purchase) + ensure + ActiveMerchant::Billing::CyberSourceGateway.application_id = nil + end + + def test_successful_purchase_with_issuer_additional_data_stored_creds_merchant_desc_and_partner_solution_id + @options[:issuer_additional_data] = @issuer_additional_data + @options[:stored_credential] = { + initiator: 'cardholder', + reason_type: '', + initial_transaction: true, + network_transaction_id: '' + } + @options[:commerce_indicator] = 'internet' + @options[:merchant_descriptor] = 'Spreedly' + + ActiveMerchant::Billing::CyberSourceGateway.application_id = 'A1000000' + + assert purchase = @gateway.purchase(@amount, @credit_card, @options) + assert_successful_response(purchase) + ensure + ActiveMerchant::Billing::CyberSourceGateway.application_id = nil + end + + def test_successful_purchase_with_reconciliation_id + options = @options.merge(reconciliation_id: '1936831') + assert response = @gateway.purchase(@amount, @credit_card, options) + assert_successful_response(response) + end + def test_successful_purchase_with_elo assert response = @gateway.purchase(@amount, @elo_credit_card, @options) assert_successful_response(response) @@ -195,22 +360,27 @@ def test_successful_purchase_with_elo def test_successful_purchase_sans_options assert response = @gateway.purchase(@amount, @credit_card) assert_equal 'Successful transaction', response.message - assert_success response + assert_successful_response(response) end def test_successful_purchase_with_billing_address_override - @options[:billing_address] = address + billing_address = { + address1: '111 North Pole Lane', + city: 'Santaland', + state: '', + phone: nil + } + @options[:billing_address] = billing_address @options[:email] = 'override@example.com' assert response = @gateway.purchase(@amount, @credit_card, @options) - assert_equal 'Successful transaction', response.message - assert_success response + assert_equal true, response.success? + assert_successful_response(response) end def test_successful_purchase_with_long_country_name @options[:billing_address] = address(country: 'united states', state: 'NC') assert response = @gateway.purchase(@amount, @credit_card, @options) - assert_equal 'Successful transaction', response.message - assert_success response + assert_successful_response(response) end def test_successful_purchase_without_decision_manager @@ -227,9 +397,40 @@ def test_successful_purchase_with_decision_manager_profile end def test_successful_pinless_debit_card_puchase - assert response = @gateway.purchase(@amount, @pinless_debit_card, @options.merge(:pinless_debit_card => true)) - assert_equal 'Successful transaction', response.message - assert_success response + assert response = @gateway.purchase(@amount, @pinless_debit_card, @options.merge(pinless_debit_card: true)) + assert_successful_response(response) + end + + def test_successful_purchase_with_solution_id + ActiveMerchant::Billing::CyberSourceGateway.application_id = 'A1000000' + assert response = @gateway.purchase(@amount, @credit_card, @options) + assert_successful_response(response) + assert !response.authorization.blank? + ensure + ActiveMerchant::Billing::CyberSourceGateway.application_id = nil + end + + def test_successful_purchase_with_solution_id_and_stored_creds + ActiveMerchant::Billing::CyberSourceGateway.application_id = 'A1000000' + @options[:stored_credential] = { + initiator: 'cardholder', + reason_type: '', + initial_transaction: true, + network_transaction_id: '' + } + @options[:commerce_indicator] = 'internet' + + assert response = @gateway.purchase(@amount, @credit_card, @options) + assert_successful_response(response) + assert !response.authorization.blank? + ensure + ActiveMerchant::Billing::CyberSourceGateway.application_id = nil + end + + def test_successful_purchase_with_country_submitted_as_empty_string + @options[:billing_address] = { country: '' } + assert response = @gateway.purchase(@amount, @credit_card, @options) + assert_successful_response(response) end def test_unsuccessful_purchase @@ -240,30 +441,49 @@ def test_unsuccessful_purchase def test_authorize_and_capture assert auth = @gateway.authorize(@amount, @credit_card, @options) - assert_success auth - assert_equal 'Successful transaction', auth.message + assert_successful_response(auth) assert capture = @gateway.capture(@amount, auth.authorization) - assert_success capture + assert_successful_response(capture) end def test_authorize_and_capture_with_elo assert auth = @gateway.authorize(@amount, @elo_credit_card, @options) - assert_success auth - assert_equal 'Successful transaction', auth.message + assert_successful_response(auth) assert capture = @gateway.capture(@amount, auth.authorization) - assert_success capture + assert_successful_response(capture) + end + + def test_successful_capture_with_issuer_additional_data + @options[:issuer_additional_data] = @issuer_additional_data + assert auth = @gateway.authorize(@amount, @credit_card, @options) + assert_successful_response(auth) + + assert response = @gateway.capture(@amount, auth.authorization) + assert_successful_response(response) + assert !response.authorization.blank? + end + + def test_successful_capture_with_solution_id + ActiveMerchant::Billing::CyberSourceGateway.application_id = 'A1000000' + assert auth = @gateway.authorize(@amount, @credit_card, @options) + assert_successful_response(auth) + + assert response = @gateway.capture(@amount, auth.authorization, @options) + assert_successful_response(response) + assert !response.authorization.blank? + ensure + ActiveMerchant::Billing::CyberSourceGateway.application_id = nil end def test_successful_authorization_and_failed_capture assert auth = @gateway.authorize(@amount, @credit_card, @options) - assert_success auth - assert_equal 'Successful transaction', auth.message + assert_successful_response(auth) assert capture = @gateway.capture(@amount + 10, auth.authorization, @options) assert_failure capture - assert_equal 'The requested amount exceeds the originally authorized amount', capture.message + assert_equal 'The requested amount exceeds the originally authorized amount', capture.message end def test_failed_capture_bad_auth_info @@ -273,7 +493,7 @@ def test_failed_capture_bad_auth_info end def test_invalid_login - gateway = CyberSourceGateway.new(:login => 'asdf', :password => 'qwer') + gateway = CyberSourceGateway.new(login: 'asdf', password: 'qwer') assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal "wsse:FailedCheck: \nSecurity Data : UsernameToken authentication failed.\n", response.message @@ -288,56 +508,98 @@ def test_successful_refund assert_successful_response(response) assert response = @gateway.refund(@amount, response.authorization) - assert_equal 'Successful transaction', response.message - assert_success response + assert_successful_response(response) + end + + def test_successful_refund_with_solution_id + ActiveMerchant::Billing::CyberSourceGateway.application_id = 'A1000000' + + assert purchase = @gateway.purchase(@amount, @credit_card, @options) + assert_successful_response(purchase) + + assert refund = @gateway.refund(@amount, purchase.authorization, @options) + assert_successful_response(refund) + ensure + ActiveMerchant::Billing::CyberSourceGateway.application_id = nil end def test_successful_validate_pinless_debit_card assert response = @gateway.validate_pinless_debit_card(@pinless_debit_card, @options) assert response.test? assert_equal 'Y', response.params['status'] - assert_equal true, response.success? + assert_equal true, response.success? end def test_network_tokenization_authorize_and_capture credit_card = network_tokenization_credit_card('4111111111111111', - :brand => 'visa', - :eci => '05', - :payment_cryptogram => 'EHuWW9PiBkWvqE5juRwDzAUFBAk=' - ) + brand: 'visa', + eci: '05', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=') assert auth = @gateway.authorize(@amount, credit_card, @options) - assert_success auth - assert_equal 'Successful transaction', auth.message + assert_successful_response(auth) assert capture = @gateway.capture(@amount, auth.authorization) - assert_success capture + assert_successful_response(capture) end def test_successful_authorize_with_mdd_fields (1..20).each { |e| @options["mdd_field_#{e}".to_sym] = "value #{e}" } assert response = @gateway.authorize(@amount, @credit_card, @options) - assert_success response + assert_successful_response(response) end def test_successful_purchase_with_mdd_fields (1..20).each { |e| @options["mdd_field_#{e}".to_sym] = "value #{e}" } assert response = @gateway.purchase(@amount, @credit_card, @options) - assert_success response + assert_successful_response(response) + end + + def test_successful_capture_with_mdd_fields + assert auth = @gateway.authorize(@amount, @credit_card, @options) + assert_successful_response(auth) + + (1..20).each { |e| @options["mdd_field_#{e}".to_sym] = "value #{e}" } + assert capture = @gateway.capture(@amount, auth.authorization, @options) + assert_successful_response(capture) + end + + def test_merchant_description + merchant_options = { + merchantInformation: { + merchantDescriptor: { + name: 'Test Name', + address1: '123 Main Dr', + locality: 'Durham' + } + } + } + + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(merchant_options)) + assert_successful_response(response) + end + + def test_successful_capture_with_tax + assert auth = @gateway.authorize(@amount, @credit_card, @options) + assert_successful_response(auth) + + capture_options = @options.merge(local_tax_amount: '0.17', national_tax_amount: '0.05') + assert capture = @gateway.capture(@amount, auth.authorization, capture_options) + assert_successful_response(capture) end def test_successful_authorize_with_nonfractional_currency - assert response = @gateway.authorize(100, @credit_card, @options.merge(:currency => 'JPY')) + assert response = @gateway.authorize(100, @credit_card, @options.merge(currency: 'JPY')) assert_equal '1', response.params['amount'] - assert_success response + assert_successful_response(response) end def test_successful_subscription_authorization assert response = @gateway.store(@credit_card, @subscription_options) assert_successful_response(response) - assert response = @gateway.authorize(@amount, response.authorization, :order_id => generate_unique_id) + assert response = @gateway.authorize(@amount, response.authorization, order_id: generate_unique_id) assert_successful_response(response) assert !response.authorization.blank? end @@ -346,7 +608,7 @@ def test_successful_subscription_purchase assert response = @gateway.store(@credit_card, @subscription_options) assert_successful_response(response) - assert response = @gateway.purchase(@amount, response.authorization, :order_id => generate_unique_id) + assert response = @gateway.purchase(@amount, response.authorization, order_id: generate_unique_id) assert_successful_response(response) end @@ -354,7 +616,7 @@ def test_successful_subscription_purchase_with_elo assert response = @gateway.store(@elo_credit_card, @subscription_options) assert_successful_response(response) - assert response = @gateway.purchase(@amount, response.authorization, :order_id => generate_unique_id) + assert response = @gateway.purchase(@amount, response.authorization, order_id: generate_unique_id) assert_successful_response(response) end @@ -363,6 +625,24 @@ def test_successful_standalone_credit_to_card assert_successful_response(response) end + def test_successful_standalone_credit_to_card_with_merchant_descriptor + @options[:merchant_descriptor] = 'Spreedly' + assert response = @gateway.credit(@amount, @credit_card, @options) + assert_successful_response(response) + end + + def test_successful_standalone_credit_to_card_with_issuer_additional_data + @options[:issuer_additional_data] = @issuer_additional_data + assert response = @gateway.credit(@amount, @credit_card, @options) + assert_successful_response(response) + end + + def test_successful_standalone_credit_to_card_with_mdd_fields + (1..20).each { |e| @options["mdd_field_#{e}".to_sym] = "value #{e}" } + assert response = @gateway.credit(@amount, @credit_card, @options) + assert_successful_response(response) + end + def test_failed_standalone_credit_to_card assert response = @gateway.credit(@amount, @declined_card, @options) @@ -375,7 +655,16 @@ def test_successful_standalone_credit_to_subscription assert response = @gateway.store(@credit_card, @subscription_options) assert_successful_response(response) - assert response = @gateway.credit(@amount, response.authorization, :order_id => generate_unique_id) + assert response = @gateway.credit(@amount, response.authorization, order_id: generate_unique_id) + assert_successful_response(response) + end + + def test_successful_standalone_credit_to_subscription_with_merchant_descriptor + @subscription_options[:merchant_descriptor] = 'Spreedly' + assert response = @gateway.store(@credit_card, @subscription_options) + assert_successful_response(response) + + assert response = @gateway.credit(@amount, response.authorization, order_id: generate_unique_id) assert_successful_response(response) end @@ -390,12 +679,12 @@ def test_successful_create_subscription_with_elo end def test_successful_create_subscription_with_setup_fee - assert response = @gateway.store(@credit_card, @subscription_options.merge(:setup_fee => 100)) + assert response = @gateway.store(@credit_card, @subscription_options.merge(setup_fee: 100)) assert_successful_response(response) end def test_successful_create_subscription_with_monthly_options - response = @gateway.store(@credit_card, @subscription_options.merge(:setup_fee => 99.0, :subscription => {:amount => 49.0, :automatic_renew => false, frequency: 'monthly'})) + response = @gateway.store(@credit_card, @subscription_options.merge(setup_fee: 99.0, subscription: { amount: 49.0, automatic_renew: false, frequency: 'monthly' })) assert_equal 'Successful transaction', response.message response = @gateway.retrieve(response.authorization, order_id: @subscription_options[:order_id]) assert_equal '0.49', response.params['recurringAmount'] @@ -406,7 +695,7 @@ def test_successful_update_subscription_creditcard assert response = @gateway.store(@credit_card, @subscription_options) assert_successful_response(response) - assert response = @gateway.update(response.authorization, @credit_card, {:order_id => generate_unique_id, :setup_fee => 100}) + assert response = @gateway.update(response.authorization, @credit_card, { order_id: generate_unique_id, setup_fee: 100 }) assert_successful_response(response) end @@ -415,7 +704,7 @@ def test_successful_update_subscription_billing_address assert_successful_response(response) assert response = @gateway.update(response.authorization, nil, - {:order_id => generate_unique_id, :setup_fee => 100, billing_address: address, email: 'someguy1232@fakeemail.net'}) + { order_id: generate_unique_id, setup_fee: 100, billing_address: address, email: 'someguy1232@fakeemail.net' }) assert_successful_response(response) end @@ -425,7 +714,7 @@ def test_successful_delete_subscription assert response.success? assert response.test? - assert response = @gateway.unstore(response.authorization, :order_id => generate_unique_id) + assert response = @gateway.unstore(response.authorization, order_id: generate_unique_id) assert response.success? assert response.test? end @@ -435,7 +724,7 @@ def test_successful_delete_subscription_with_elo assert response.success? assert response.test? - assert response = @gateway.unstore(response.authorization, :order_id => generate_unique_id) + assert response = @gateway.unstore(response.authorization, order_id: generate_unique_id) assert response.success? assert response.test? end @@ -445,7 +734,7 @@ def test_successful_retrieve_subscription 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 @@ -518,8 +807,7 @@ def test_successful_authorize_via_normalized_3ds2_fields ) response = @gateway.authorize(@amount, @three_ds_enrolled_card, options) - assert_success response - assert_equal 'Successful transaction', response.message + assert_successful_response(response) end def test_successful_mastercard_authorize_via_normalized_3ds2_fields @@ -536,8 +824,7 @@ def test_successful_mastercard_authorize_via_normalized_3ds2_fields ) response = @gateway.authorize(@amount, @three_ds_enrolled_mastercard, options) - assert_success response - assert_equal 'Successful transaction', response.message + assert_successful_response(response) end def test_successful_purchase_via_normalized_3ds2_fields @@ -552,8 +839,7 @@ def test_successful_purchase_via_normalized_3ds2_fields ) response = @gateway.purchase(@amount, @three_ds_enrolled_card, options) - assert_success response - assert_equal 'Successful transaction', response.message + assert_successful_response(response) end def test_successful_mastercard_purchase_via_normalized_3ds2_fields @@ -570,68 +856,101 @@ def test_successful_mastercard_purchase_via_normalized_3ds2_fields ) response = @gateway.purchase(@amount, @three_ds_enrolled_mastercard, options) - assert_success response - assert_equal 'Successful transaction', response.message + assert_successful_response(response) end - def test_successful_first_unscheduled_cof_transaction + def test_successful_first_cof_authorize @options[:stored_credential] = { - :initiator => 'cardholder', - :reason_type => 'unscheduled', - :initial_transaction => true, - :network_transaction_id => '' + initiator: 'cardholder', + reason_type: '', + initial_transaction: true, + network_transaction_id: '' } + @options[:commerce_indicator] = 'internet' assert response = @gateway.authorize(@amount, @credit_card, @options) - assert_equal 'Successful transaction', response.message - assert_success response + assert_successful_response(response) end - def test_successful_subsequent_unscheduled_cof_transaction + def test_successful_subsequent_unscheduled_cof_authorize @options[:stored_credential] = { - :initiator => 'merchant', - :reason_type => 'unscheduled', - :initial_transaction => false, - :network_transaction_id => '016150703802094' + initiator: 'merchant', + reason_type: 'unscheduled', + initial_transaction: false, + network_transaction_id: '016150703802094' } assert response = @gateway.authorize(@amount, @credit_card, @options) - assert_equal 'Successful transaction', response.message - assert_success response + assert_successful_response(response) end - def test_successful_first_recurring_cof_transaction + def test_successful_recurring_cof_authorize @options[:stored_credential] = { - :initiator => 'cardholder', - :reason_type => 'recurring', - :initial_transaction => true, - :network_transaction_id => '' + initiator: 'merchant', + reason_type: 'recurring', + initial_transaction: false, + network_transaction_id: '' } assert response = @gateway.authorize(@amount, @credit_card, @options) - assert_equal 'Successful transaction', response.message - assert_success response + assert_successful_response(response) end - def test_successful_subsequent_recurring_cof_transaction + def test_successful_subsequent_recurring_cof_authorize @options[:stored_credential] = { - :initiator => 'merchant', - :reason_type => 'recurring', - :initial_transaction => false, - :network_transaction_id => '016150703802094' + initiator: 'merchant', + reason_type: 'recurring', + initial_transaction: false, + network_transaction_id: '016150703802094' } assert response = @gateway.authorize(@amount, @credit_card, @options) - assert_equal 'Successful transaction', response.message - assert_success response + assert_successful_response(response) + end + + def test_successful_subsequent_installment_cof_authorize + @options[:stored_credential] = { + initiator: 'merchant', + reason_type: 'installment', + initial_transaction: false, + network_transaction_id: '016150703802094' + } + assert response = @gateway.authorize(@amount, @credit_card, @options) + assert_successful_response(response) + end + + def test_successful_subsequent_unscheduled_cof_purchase + @options[:stored_credential] = { + initiator: 'merchant', + reason_type: 'unscheduled', + initial_transaction: false, + network_transaction_id: '016150703802094' + } + assert response = @gateway.purchase(@amount, @credit_card, @options) + assert_successful_response(response) + end + + def test_invalid_field + @options = @options.merge({ + address: { + address1: 'Unspecified', + city: 'Unspecified', + state: 'NC', + zip: '1234567890', + country: 'US' + } + }) + + assert response = @gateway.purchase(@amount, @credit_card, @options) + assert_failure response + assert_equal 'One or more fields contains invalid data: c:billTo/c:postalCode', response.message end def pares - <<-PARES -eNqdmFuTqkgSgN+N8D90zD46M4B3J+yOKO6goNyFN25yEUHkUsiv31K7T/ec6dg9u75YlWRlZVVmflWw1uNrGNJa6DfX8G0thVXlRuFLErz+tgm67sRlbJr3ky4G9LWn8N/e1nughtVD4dFawFAodT8OqbBx4NLdj/o8y3JqKlavSLsNr1VS5G/En/if4zX20UUTXf3Yzeu3teuXpCC/TeerMTFfY+/d9Tm8CvRbEB7dJqvX2LO7xj7H7Zt7q0JOd0nwpo3VacjVvMc4pZcXfcjFpMqLc6UHr2vsrrEO3Dp8G+P4Ap+PZy/E9C+c+AtfrrGHfH25mwPnokG2CRxfY18Fa7Q71zD3b2/LKXr0o7cOu0uRh0gDre1He419+nZx8zf87z+kepeu9cPbuk7OX31a3X0iFmvsIV9XtVs31Zu9xt5ba99t2zcAAAksNjsr4N5MVctyGIaN2H6E1vpQWYd+8obPkFPo/zEKZFFxTer4fHf174I1dncFe4Tzba0lUY4mu4Yv3TnLURDjur78hWEQwj/h5M/iGmHIYRzDVxhSCKok+tdvz1FhIOTH4n8aRrl5kSe+myW9W6PEkMI6LoKXH759Z0ZX75YITGWoP5CpP3ximv9xl+ATYoZsYt8b/bKyX5nlZ2evlftHFbvEfYKfDL2t1fAY3jMifDFU4fW3f/1KZdBJFFb1/+PKhxtfLXzYM92sCd8qN5U5lrrNDZOFzkiecUIszvyCVJjXj3FPzTX2w/f3hT2j+GW3noobXm8xXJ3KK2aZztNbVdsLWbbOASZgzSY45eYqFNiK5ReRNLKbzvZSIDJj+zqBzIEkIx1L9ZTabYeDJa/MV51fF9A0dxDvxzf5CiPmttuVVBLHxmZSNp53lnBcJzh+IS3YpejKebycHjQlvMggwkvHdZjhYBHf8M1R4ikKjHxMGxlCfuCv+IqmxjTRk9GMnO2ynnXsWMvZSYdlk+Vmvpz1pVns4v05ugRWIGZNMhxUGLzoqs+VDe14Jtzli63TT06WBvpJg2+2UVLie+5mgGDlEVjip+7EmZhCvRdndtQHmKm0vaUDejhYTRgglbR5qysx6I1gf+vTyWJ3ahaXNOWBUrXRYnwasbKlbi3XsJLNuA3g6+uXrHqPzCa8PSNxmKElubX7bGmNl4Z+LbuIEJT8SrnXIMnd7IUOz8XLI4DX3192xucDQGlI8NmnijOiqR/+/rJ9lRCvCqSv6a+7OCl+f6FeDW2N/TzPY2IqvNbJEdUVwqUkCLTVo32vtAhAgQSRQAFNgLRii5vCEeLWl4HCsKQCoJMyWwmcOEAYDBlLlGlKHa2DLRnJ5nCAhkoksypca9nxKfDvUhIUEmvIsX9WL96ZrZTxqvYs82aPjQi1bz7NaBIJHhYpCEXplJ2GA8ea4a7lXCRVgUxk06ai0DSoDecg4wIvE3ZC0ooOQhbinUQzNyn1OzkFM5kWXSS7PWVKNxx8SCV+2VE9EJ8+2TrITF1ScEjBh3WBgere5bJWUpb3ld9lPAMd+e6JNxGQJS4F9vuKdObLigRGbj2LyPyznEmqAZmnxS0DO9o+iCfXmsUeRZIKIXW8Djy0Tw8rks4yX62omWctI2Oc5d7ZvKGokEIKZDI6lfEp4VYQJ+9RAGBHAWUJ7s+HAyraoB4DSmYSEIl4LuOMDMYCIZJ71pj7U99OwbapLHXFMLI66s7eKosO9qmWU56LwmJCul2tccin+XTKE4tV7EatfZaSNCQFH9bYXMNCetuoK2kl0SN6An3f3xmIMwGIT8KlZZS5pV/wpTIz8FzIF9fhIK6EhVLuzEDAg4MI+sybxjVzA/TGuEmsEHDZbZFBtjKxdKfgilSRZDLRoGjQmpWlzUEZGeJ+7CK6jCNPPgQe2ZInYsxH5YEWZoId7i5G2RJNax3USyCJo1OXS/jNLKdCtZiMSaCR4jKPaXvXqjl/6Et+OMBDRoth7MfSnLa3o7ItpxyV8CZcmjrVbJtyWykIypti158qotvx1VkJTm48GzeYBAUaKIAsJhUcDkL9mUO8KjEgBUCiIEdZFKcBjhsxAkpL5cjGxN7nzMYgZElgguweT/ugZg5F0s5BfGT2cGCPWdzRQfCwpkzRoa8YasSpRuIhBMUdRVxBGyn1FouIkytA/p5XKp4iAEO2AMZRSKQkIPDhgLC0ZSKTIV5IsXXC55ue+a566chmgKyLBwZfHlr7igWzo4Dn4m63WjXm3kMV3G7GNc3KJz9Ur5pt1AxBnafhdFf03bi2pnQlT8pZhWNWN7Mu+6RtWe/I6AbUz1wcFd6puR7FdrSYDwcYP5lcIsJ0ZNh7zOxcqcSFOjoUhaui645OzZ5qHGeazOnrqlxJ1+2eSJtTNOo7bBrgyvIanQyHuh9xP/PqO4BROI0Alp6/AOzbLYAh/asAo/t78d0L1ZdQ/mVerrZ+yoQSCZ+wiqCpjNmbw2WNbXW0NyZqFNzU0Uh0dHgTEUqqABnwhAENTjfNUu9WLs751LE60N8xINGsmvkTJTLOqzag/g624UDS72hjelmXP9GmKz9kEmf/R7DR4Ak2ZEmdQv7pz4YmzU84fQHYHWZ+DjomBcrTYiVRuig6KJ1R5Z5dhD5kiRQeewAg3Jqc2SOv+8ASIgVnYOQsf9558pl8OIIWJ4KCQ4u+QWKmIqgK7g5MOZ+0XJ4jemPuucVRUPf5rma5LL6U7RxuXQ4ax+NodrIvC4k53wRDanhGdkGrnhJRq2/UajccHM67ebQItvRyk3PEnFrl1y5dFuT0PEFYMqbn0dG2dlx+js/7Yt7HZFuSVXvsV5OYiTYHec4EG7kxo+GgKfvamoPtDhry3CPLjaJN7okBAJeGPTl7z5+AgQolAQC3wBZtwRGA7U2ViJFJcmnxxgo+jjHdwGGkjs0G5UYccOYJ7XDmP7IgS+9QkEj8YY2OFIsk1WUi3MTJQTed7U3A2YUW3Vh3OND14irp4PiAhSYxHA2siFSZKN1jhOVFme2MOa7LKcst80SEKId+OjqM+9GBjoxIIZfNxsBWkyVmbmYUa4iJghm7gzu+8jeiAxMvJwhiR80zcl4FSr2Q01jx442ebHWlimZHrNQymRgOto7dtFMgbPTdxmG4ayKWQJ+Lp3K0OcQ1rU2jtLyw+XKXOqWoLo7ulVFHgTebYaLWXho+Sr1OPy7AcHCGCar/njbEqWk2ib1Z6iWb3cbm1eTZ6PVXIdCmCAJJ+AEBEYh0tx8xmanGGwngHKWVnCZ4E/qRkgaQ+OgfpYOS+5vi+XoroMHnreA/3XIQBP7LPefzlvPj1oBuOd3zlsOKrYegcC+p4YCPfRmFv5NSZiLpNpR1cLPusvQhw3/IUnIqKRWknr5yDBRNo2dkCVSPmdGNAUBGH8cXr2f29z15gBBCTrfuBb66/SokhoP/gglTIqUPSEjvkNC88QpHo0kEguNHRIaDj5igJAWIBjKgKTJRNmSkUNPwevRaVWGow9Vezev9QtlZJaWDcZpjs3SywiKsxD0p8RVKHQ6u49ExWZz6zY28KaVz4ntbnC0nGDi0G9GFeM2id5cJkwbRKezMS2ZrYcnsZzuDlqaRqx0XJS9F5h6VycYt8nF7TfnOCimzY5NpNyWLIBPzY4ZhNZdu8FKm+3pxwqZyqLHWzSsT5f2mQACop8+THcXu42wXhB5bmeepaHFBHFcOzM7lZZr4DPOPs/073eHgQ5sGD22dBAZE4SSx/vtijxSQsEuSy0gWSqEshkxiw9xVEJhqg78mbmrU3nxGzJe1fLxwDDO59rxHzgrpzPiHrvK8WlDJpo33y3MdhU7GZ81W6fFSHfnjYpbBcDjo4CLNjoAvSxRlLaU2W76plphc5At/tEhKra8VXiLN0FuM59Ddt5zgHZitL1vFyttHamkZ44sToxvD5ubwK/BtsWOfr03Yj1epz5esx7ekx8eu+/ePrx/B/g0UAjN8 + <<~PARES + eNqdmFuTqkgSgN+N8D90zD46M4B3J+yOKO6goNyFN25yEUHkUsiv31K7T/ec6dg9u75YlWRlZVVmflWw1uNrGNJa6DfX8G0thVXlRuFLErz+tgm67sRlbJr3ky4G9LWn8N/e1nughtVD4dFawFAodT8OqbBx4NLdj/o8y3JqKlavSLsNr1VS5G/En/if4zX20UUTXf3Yzeu3teuXpCC/TeerMTFfY+/d9Tm8CvRbEB7dJqvX2LO7xj7H7Zt7q0JOd0nwpo3VacjVvMc4pZcXfcjFpMqLc6UHr2vsrrEO3Dp8G+P4Ap+PZy/E9C+c+AtfrrGHfH25mwPnokG2CRxfY18Fa7Q71zD3b2/LKXr0o7cOu0uRh0gDre1He419+nZx8zf87z+kepeu9cPbuk7OX31a3X0iFmvsIV9XtVs31Zu9xt5ba99t2zcAAAksNjsr4N5MVctyGIaN2H6E1vpQWYd+8obPkFPo/zEKZFFxTer4fHf174I1dncFe4Tzba0lUY4mu4Yv3TnLURDjur78hWEQwj/h5M/iGmHIYRzDVxhSCKok+tdvz1FhIOTH4n8aRrl5kSe+myW9W6PEkMI6LoKXH759Z0ZX75YITGWoP5CpP3ximv9xl+ATYoZsYt8b/bKyX5nlZ2evlftHFbvEfYKfDL2t1fAY3jMifDFU4fW3f/1KZdBJFFb1/+PKhxtfLXzYM92sCd8qN5U5lrrNDZOFzkiecUIszvyCVJjXj3FPzTX2w/f3hT2j+GW3noobXm8xXJ3KK2aZztNbVdsLWbbOASZgzSY45eYqFNiK5ReRNLKbzvZSIDJj+zqBzIEkIx1L9ZTabYeDJa/MV51fF9A0dxDvxzf5CiPmttuVVBLHxmZSNp53lnBcJzh+IS3YpejKebycHjQlvMggwkvHdZjhYBHf8M1R4ikKjHxMGxlCfuCv+IqmxjTRk9GMnO2ynnXsWMvZSYdlk+Vmvpz1pVns4v05ugRWIGZNMhxUGLzoqs+VDe14Jtzli63TT06WBvpJg2+2UVLie+5mgGDlEVjip+7EmZhCvRdndtQHmKm0vaUDejhYTRgglbR5qysx6I1gf+vTyWJ3ahaXNOWBUrXRYnwasbKlbi3XsJLNuA3g6+uXrHqPzCa8PSNxmKElubX7bGmNl4Z+LbuIEJT8SrnXIMnd7IUOz8XLI4DX3192xucDQGlI8NmnijOiqR/+/rJ9lRCvCqSv6a+7OCl+f6FeDW2N/TzPY2IqvNbJEdUVwqUkCLTVo32vtAhAgQSRQAFNgLRii5vCEeLWl4HCsKQCoJMyWwmcOEAYDBlLlGlKHa2DLRnJ5nCAhkoksypca9nxKfDvUhIUEmvIsX9WL96ZrZTxqvYs82aPjQi1bz7NaBIJHhYpCEXplJ2GA8ea4a7lXCRVgUxk06ai0DSoDecg4wIvE3ZC0ooOQhbinUQzNyn1OzkFM5kWXSS7PWVKNxx8SCV+2VE9EJ8+2TrITF1ScEjBh3WBgere5bJWUpb3ld9lPAMd+e6JNxGQJS4F9vuKdObLigRGbj2LyPyznEmqAZmnxS0DO9o+iCfXmsUeRZIKIXW8Djy0Tw8rks4yX62omWctI2Oc5d7ZvKGokEIKZDI6lfEp4VYQJ+9RAGBHAWUJ7s+HAyraoB4DSmYSEIl4LuOMDMYCIZJ71pj7U99OwbapLHXFMLI66s7eKosO9qmWU56LwmJCul2tccin+XTKE4tV7EatfZaSNCQFH9bYXMNCetuoK2kl0SN6An3f3xmIMwGIT8KlZZS5pV/wpTIz8FzIF9fhIK6EhVLuzEDAg4MI+sybxjVzA/TGuEmsEHDZbZFBtjKxdKfgilSRZDLRoGjQmpWlzUEZGeJ+7CK6jCNPPgQe2ZInYsxH5YEWZoId7i5G2RJNax3USyCJo1OXS/jNLKdCtZiMSaCR4jKPaXvXqjl/6Et+OMBDRoth7MfSnLa3o7ItpxyV8CZcmjrVbJtyWykIypti158qotvx1VkJTm48GzeYBAUaKIAsJhUcDkL9mUO8KjEgBUCiIEdZFKcBjhsxAkpL5cjGxN7nzMYgZElgguweT/ugZg5F0s5BfGT2cGCPWdzRQfCwpkzRoa8YasSpRuIhBMUdRVxBGyn1FouIkytA/p5XKp4iAEO2AMZRSKQkIPDhgLC0ZSKTIV5IsXXC55ue+a566chmgKyLBwZfHlr7igWzo4Dn4m63WjXm3kMV3G7GNc3KJz9Ur5pt1AxBnafhdFf03bi2pnQlT8pZhWNWN7Mu+6RtWe/I6AbUz1wcFd6puR7FdrSYDwcYP5lcIsJ0ZNh7zOxcqcSFOjoUhaui645OzZ5qHGeazOnrqlxJ1+2eSJtTNOo7bBrgyvIanQyHuh9xP/PqO4BROI0Alp6/AOzbLYAh/asAo/t78d0L1ZdQ/mVerrZ+yoQSCZ+wiqCpjNmbw2WNbXW0NyZqFNzU0Uh0dHgTEUqqABnwhAENTjfNUu9WLs751LE60N8xINGsmvkTJTLOqzag/g624UDS72hjelmXP9GmKz9kEmf/R7DR4Ak2ZEmdQv7pz4YmzU84fQHYHWZ+DjomBcrTYiVRuig6KJ1R5Z5dhD5kiRQeewAg3Jqc2SOv+8ASIgVnYOQsf9558pl8OIIWJ4KCQ4u+QWKmIqgK7g5MOZ+0XJ4jemPuucVRUPf5rma5LL6U7RxuXQ4ax+NodrIvC4k53wRDanhGdkGrnhJRq2/UajccHM67ebQItvRyk3PEnFrl1y5dFuT0PEFYMqbn0dG2dlx+js/7Yt7HZFuSVXvsV5OYiTYHec4EG7kxo+GgKfvamoPtDhry3CPLjaJN7okBAJeGPTl7z5+AgQolAQC3wBZtwRGA7U2ViJFJcmnxxgo+jjHdwGGkjs0G5UYccOYJ7XDmP7IgS+9QkEj8YY2OFIsk1WUi3MTJQTed7U3A2YUW3Vh3OND14irp4PiAhSYxHA2siFSZKN1jhOVFme2MOa7LKcst80SEKId+OjqM+9GBjoxIIZfNxsBWkyVmbmYUa4iJghm7gzu+8jeiAxMvJwhiR80zcl4FSr2Q01jx442ebHWlimZHrNQymRgOto7dtFMgbPTdxmG4ayKWQJ+Lp3K0OcQ1rU2jtLyw+XKXOqWoLo7ulVFHgTebYaLWXho+Sr1OPy7AcHCGCar/njbEqWk2ib1Z6iWb3cbm1eTZ6PVXIdCmCAJJ+AEBEYh0tx8xmanGGwngHKWVnCZ4E/qRkgaQ+OgfpYOS+5vi+XoroMHnreA/3XIQBP7LPefzlvPj1oBuOd3zlsOKrYegcC+p4YCPfRmFv5NSZiLpNpR1cLPusvQhw3/IUnIqKRWknr5yDBRNo2dkCVSPmdGNAUBGH8cXr2f29z15gBBCTrfuBb66/SokhoP/gglTIqUPSEjvkNC88QpHo0kEguNHRIaDj5igJAWIBjKgKTJRNmSkUNPwevRaVWGow9Vezev9QtlZJaWDcZpjs3SywiKsxD0p8RVKHQ6u49ExWZz6zY28KaVz4ntbnC0nGDi0G9GFeM2id5cJkwbRKezMS2ZrYcnsZzuDlqaRqx0XJS9F5h6VycYt8nF7TfnOCimzY5NpNyWLIBPzY4ZhNZdu8FKm+3pxwqZyqLHWzSsT5f2mQACop8+THcXu42wXhB5bmeepaHFBHFcOzM7lZZr4DPOPs/073eHgQ5sGD22dBAZE4SSx/vtijxSQsEuSy0gWSqEshkxiw9xVEJhqg78mbmrU3nxGzJe1fLxwDDO59rxHzgrpzPiHrvK8WlDJpo33y3MdhU7GZ81W6fFSHfnjYpbBcDjo4CLNjoAvSxRlLaU2W76plphc5At/tEhKra8VXiLN0FuM59Ddt5zgHZitL1vFyttHamkZ44sToxvD5ubwK/BtsWOfr03Yj1epz5esx7ekx8eu+/ePrx/B/g0UAjN8 PARES end def test_successful_verify_with_elo response = @gateway.verify(@elo_credit_card, @options) - assert_equal 'Successful transaction', response.message - assert_success response + assert_successful_response(response) end def test_verify_credentials diff --git a/test/remote/gateways/remote_d_local_test.rb b/test/remote/gateways/remote_d_local_test.rb index 2dc9708d940..14db177cc8b 100644 --- a/test/remote/gateways/remote_d_local_test.rb +++ b/test/remote/gateways/remote_d_local_test.rb @@ -26,6 +26,13 @@ def setup document: '10563145', currency: 'ARS' } + @options_argentina_installments = { + billing_address: address(country: 'Argentina'), + document: '10563145', + currency: 'ARS', + installments: '3', + installments_id: 'INS54434' + } @options_mexico = { billing_address: address(country: 'Mexico'), document: '128475869794933', @@ -44,6 +51,12 @@ def test_successful_purchase assert_match 'The payment was paid', response.message end + def test_successful_purchase_with_installments + response = @gateway.purchase(@amount, @credit_card, @options_argentina_installments) + assert_success response + assert_match 'The payment was paid', response.message + end + def test_successful_purchase_naranja response = @gateway.purchase(@amount, @credit_card_naranja, @options) assert_success response @@ -97,6 +110,12 @@ def test_successful_purchase_peru assert_match 'The payment was paid', response.message end + def test_successful_purchase_partial_address + response = @gateway.purchase(@amount, @credit_card, @options.merge(billing_address: address(address1: 'My Street', country: 'Brazil'))) + assert_success response + assert_match 'The payment was paid', response.message + end + def test_failed_purchase response = @gateway.purchase(@amount, @credit_card, @options.merge(description: '300')) assert_failure response @@ -146,7 +165,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization, @options) + assert capture = @gateway.capture(@amount - 1, auth.authorization, @options) assert_success capture end @@ -171,7 +190,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization, @options.merge(notification_url: 'http://example.com')) + assert refund = @gateway.refund(@amount - 1, purchase.authorization, @options.merge(notification_url: 'http://example.com')) assert_success refund end @@ -179,7 +198,7 @@ def test_failed_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - response = @gateway.refund(@amount+1, purchase.authorization, @options.merge(notification_url: 'http://example.com')) + response = @gateway.refund(@amount + 1, purchase.authorization, @options.merge(notification_url: 'http://example.com')) assert_failure response assert_match 'Amount exceeded', response.message end @@ -194,15 +213,9 @@ def test_successful_void end def test_failed_void - auth = @gateway.authorize(@amount, @credit_card, @options) - assert_success auth - - assert capture = @gateway.capture(@amount, auth.authorization, @options) - assert_success capture - - response = @gateway.void(auth.authorization) + response = @gateway.void('') assert_failure response - assert_match 'Invalid transaction status', response.message + assert_match 'Invalid request', response.message end def test_successful_verify @@ -242,5 +255,4 @@ def test_transcript_scrubbing assert_scrubbed(@credit_card.verification_value, transcript) assert_scrubbed(@gateway.options[:trans_key], transcript) end - end diff --git a/test/remote/gateways/remote_data_cash_test.rb b/test/remote/gateways/remote_data_cash_test.rb index 9fb77b19a6f..c1297dca20b 100644 --- a/test/remote/gateways/remote_data_cash_test.rb +++ b/test/remote/gateways/remote_data_cash_test.rb @@ -1,64 +1,62 @@ require 'test_helper' class RemoteDataCashTest < Test::Unit::TestCase - def setup # gateway to connect to Datacash @gateway = DataCashGateway.new(fixtures(:data_cash)) @mastercard = CreditCard.new( - :number => '5120790000000034', - :month => 3, - :year => Date.today.year + 2, - :first_name => 'Mark', - :last_name => 'McBride', - :brand => :master + number: '5120790000000034', + month: 3, + year: Date.today.year + 2, + first_name: 'Mark', + last_name: 'McBride', + brand: :master ) @mastercard_declined = CreditCard.new( - :number => '5473000000000106', - :month => 3, - :year => Date.today.year + 2, - :first_name => 'Mark', - :last_name => 'McBride', - :brand => :master, - :verification_value => '547' + number: '5473000000000106', + month: 3, + year: Date.today.year + 2, + first_name: 'Mark', + last_name: 'McBride', + brand: :master, + verification_value: '547' ) @visa_delta = CreditCard.new( - :number => '4539792100000003', - :month => 3, - :year => Date.today.year + 2, - :first_name => 'Mark', - :last_name => 'McBride', - :brand => :visa, - :verification_value => '444' + number: '4539792100000003', + month: 3, + year: Date.today.year + 2, + first_name: 'Mark', + last_name: 'McBride', + brand: :visa, + verification_value: '444' ) @solo = CreditCard.new( - :first_name => 'Cody', - :last_name => 'Fauser', - :number => '633499100000000004', - :month => 3, - :year => Date.today.year + 2, - :brand => :solo, - :issue_number => 5, - :start_month => 12, - :start_year => 2006 + first_name: 'Cody', + last_name: 'Fauser', + number: '633499100000000004', + month: 3, + year: Date.today.year + 2, + brand: :solo, + start_month: 12, + start_year: 2006 ) @address = { - :name => 'Mark McBride', - :address1 => 'Flat 12/3', - :address2 => '45 Main Road', - :city => 'Sometown', - :state => 'Somecounty', - :zip => 'A987AA', - :phone => '(555)555-5555' + name: 'Mark McBride', + address1: 'Flat 12/3', + address2: '45 Main Road', + city: 'Sometown', + state: 'Somecounty', + zip: 'A987AA', + phone: '(555)555-5555' } @params = { - :order_id => generate_unique_id + order_id: generate_unique_id } @amount = 198 @@ -110,7 +108,7 @@ def test_successful_purchase_with_account_set_up_and_repeat_payments assert response.test? # Make second payment on the continuous authorization that was set up in the first purchase - second_order_params = { :order_id => generate_unique_id } + second_order_params = { order_id: generate_unique_id } purchase = @gateway.purchase(201, response.authorization, second_order_params) assert_success purchase end @@ -122,7 +120,7 @@ def test_successful_purchase_with_account_set_up_and_repeat_payments_with_visa_d assert !response.authorization.to_s.split(';')[2].blank? # Make second payment on the continuous authorization that was set up in the first purchase - second_order_params = { :order_id => generate_unique_id } + second_order_params = { order_id: generate_unique_id } purchase = @gateway.purchase(201, response.authorization, second_order_params) assert_success purchase end @@ -148,7 +146,7 @@ def test_successful_authorization_and_capture_with_account_set_up_and_second_pur assert capture.test? # Collect second purchase - second_order_params = { :order_id => generate_unique_id } + second_order_params = { order_id: generate_unique_id } purchase = @gateway.purchase(201, first_authorization.authorization, second_order_params) assert_success purchase assert purchase.test? @@ -165,6 +163,7 @@ def test_duplicate_order_id end def test_invalid_verification_number + @mastercard.number = 1000350000000007 @mastercard.verification_value = 123 response = @gateway.purchase(@amount, @mastercard, @params) assert_failure response @@ -310,7 +309,7 @@ def test_successful_refund_of_a_repeat_payment assert response.test? # Make second payment on the continuous authorization that was set up in the first purchase - second_order_params = { :order_id => generate_unique_id } + second_order_params = { order_id: generate_unique_id } purchase = @gateway.purchase(201, response.authorization, second_order_params) assert_success purchase @@ -326,7 +325,7 @@ def test_order_id_that_is_too_short end def test_order_id_that_is_too_long - @params[:order_id] = "#{@params[:order_id]}1234356" + @params[:order_id] = "#{@params[:order_id]}1234356" response = @gateway.purchase(@amount, @mastercard, @params) assert_success response assert response.test? diff --git a/test/remote/gateways/remote_decidir_test.rb b/test/remote/gateways/remote_decidir_test.rb index 604d95ea3c3..6ff34d2a887 100644 --- a/test/remote/gateways/remote_decidir_test.rb +++ b/test/remote/gateways/remote_decidir_test.rb @@ -7,6 +7,9 @@ def setup @amount = 100 @credit_card = credit_card('4507990000004905') + @master_card_credit_card = credit_card('5299910010000015') + @amex_credit_card = credit_card('373953192351004') + @diners_club_credit_card = credit_card('36463664750005') @cabal_credit_card = credit_card('5896570000000008') @naranja_credit_card = credit_card('5895627823453005') @declined_card = credit_card('4000300011112220') @@ -24,6 +27,30 @@ def test_successful_purchase assert response.authorization end + def test_successful_purchase_with_master_card + response = @gateway_for_purchase.purchase(@amount, @master_card_credit_card, @options) + assert_success response + assert_equal 'approved', response.message + assert response.authorization + end + + def test_successful_purchase_with_amex + response = @gateway_for_purchase.purchase(@amount, @amex_credit_card, @options) + assert_success response + assert_equal 'approved', response.message + assert response.authorization + end + + # This test is currently failing. + # Decidir hasn't been able to provide a valid Diners Club test card number. + # + # def test_successful_purchase_with_diners_club + # response = @gateway_for_purchase.purchase(@amount, @diners_club_credit_card, @options) + # assert_success response + # assert_equal 'approved', response.message + # assert response.authorization + # end + def test_successful_purchase_with_cabal response = @gateway_for_purchase.purchase(@amount, @cabal_credit_card, @options) assert_success response @@ -46,27 +73,92 @@ def test_successful_purchase_with_more_options card_holder_birthday: '01011980', card_holder_identification_type: 'dni', card_holder_identification_number: '123456', - installments: '12' + establishment_name: 'Heavenly Buffaloes', + device_unique_identifier: '1', + fraud_detection: { + send_to_cs: false, + channel: 'Web', + dispatch_method: 'Store Pick Up', + csmdds: [ + { + code: 17, + description: 'Campo MDD17' + } + ], + device_unique_id: '1', + bill_to: { + postal_code: '12345', + last_name: 'Smith', + country: 'US', + street1: '123 Mockingbird Lane', + state: 'TN', + email: 'dootdoot@hotmail.com', + customer_id: '111111', + phone_number: '555-5555', + first_name: 'Joe', + city: 'Pantsville' + }, + customer_in_site: { + password: '', + is_guest: false, + street: '123 Mockingbird Lane', + cellphone_number: '555-1212', + num_of_transactions: 48, + date_of_birth: '8-4-80', + days_in_site: 105 + }, + purchase_totals: { + currency: 'USD', + amount: 100 + } + }, + installments: '12', + site_id: '99999999' } response = @gateway_for_purchase.purchase(@amount, credit_card('4509790112684851'), @options.merge(options)) assert_success response assert_equal 'approved', response.message + assert_equal 'Heavenly Buffaloes', response.params['establishment_name'] + assert_equal '99999999', response.params['site_id'] + assert_equal({ 'status' => nil }, response.params['fraud_detection']) assert response.authorization end + def test_failed_purchase_with_bad_csmdds + options = { + fraud_detection: { + send_to_cs: false, + channel: 'Web', + dispatch_method: 'Store Pick Up', + csmdds: [ + { + codee: 17, + descriptione: 'Campo MDD17' + } + ] + } + } + + response = @gateway_for_purchase.purchase(@amount, credit_card('4509790112684851'), @options.merge(options)) + assert_failure response + assert_equal 'param_required: fraud_detection.csmdds.[0].code, param_required: fraud_detection.csmdds.[0].description', response.message + assert_equal(nil, response.params['fraud_detection']) + end + def test_failed_purchase response = @gateway_for_purchase.purchase(@amount, @declined_card, @options) assert_failure response - assert_equal 'TARJETA INVALIDA', response.message - assert_match Gateway::STANDARD_ERROR_CODE[:invalid_number], response.error_code + assert_equal 'COMERCIO INVALIDO | invalid_card', response.message + assert_equal '3, config_error', response.error_code + assert_match Gateway::STANDARD_ERROR_CODE[:config_error], response.error_code end def test_failed_purchase_with_invalid_field response = @gateway_for_purchase.purchase(@amount, @declined_card, @options.merge(installments: -1)) assert_failure response assert_equal 'invalid_param: installments', response.message - assert_match 'invalid_request_error', response.error_code + assert_equal 'invalid_request_error', response.error_code end def test_successful_authorize_and_capture @@ -84,8 +176,8 @@ def test_successful_authorize_and_capture def test_failed_authorize response = @gateway_for_auth.authorize(@amount, @declined_card, @options) assert_failure response - assert_equal 'TARJETA INVALIDA', response.message - assert_match Gateway::STANDARD_ERROR_CODE[:invalid_number], response.error_code + assert_equal 'PEDIR AUTORIZACION | request_authorization_card', response.message + assert_match 'call_issuer', response.error_code end def test_failed_partial_capture @@ -120,7 +212,7 @@ def test_partial_refund purchase = @gateway_for_purchase.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway_for_purchase.refund(@amount-1, purchase.authorization) + assert refund = @gateway_for_purchase.refund(@amount - 1, purchase.authorization) assert_success refund assert_equal 'approved', refund.message assert refund.authorization @@ -159,12 +251,20 @@ def test_successful_verify def test_failed_verify response = @gateway_for_auth.verify(@declined_card, @options) assert_failure response - assert_match %r{TARJETA INVALIDA}, response.message + assert_match %r{PEDIR AUTORIZACION | request_authorization_card}, response.message end - def test_invalid_login + def test_invalid_login_without_api_key gateway = DecidirGateway.new(api_key: '') + response = gateway.purchase(@amount, @credit_card, @options) + assert_failure response + assert_match %r{No API key found in request}, response.message + end + + def test_invalid_login + gateway = DecidirGateway.new(api_key: 'xxxxxxx') + response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_match %r{Invalid authentication credentials}, response.message @@ -180,5 +280,4 @@ def test_transcript_scrubbing assert_scrubbed(@credit_card.verification_value, transcript) assert_scrubbed(@gateway_for_purchase.options[:api_key], transcript) end - end diff --git a/test/remote/gateways/remote_dibs_test.rb b/test/remote/gateways/remote_dibs_test.rb index 1e6b16e36b1..daf302ac6df 100644 --- a/test/remote/gateways/remote_dibs_test.rb +++ b/test/remote/gateways/remote_dibs_test.rb @@ -5,11 +5,11 @@ def setup @gateway = DibsGateway.new(fixtures(:dibs)) cc_options = { - :month => 6, - :year => 24, - :verification_value => '684', - :brand => 'visa' - } + month: 6, + year: 24, + verification_value: '684', + brand: 'visa' + } @amount = 100 @credit_card = credit_card('4711100000000000', cc_options) diff --git a/test/remote/gateways/remote_digitzs_test.rb b/test/remote/gateways/remote_digitzs_test.rb index 285dd840f9d..271aa7f5f62 100644 --- a/test/remote/gateways/remote_digitzs_test.rb +++ b/test/remote/gateways/remote_digitzs_test.rb @@ -83,7 +83,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization, @options) + assert refund = @gateway.refund(@amount - 1, purchase.authorization, @options) assert_success refund end @@ -99,17 +99,17 @@ def test_successful_store end def test_successful_store_without_billing_address - assert response = @gateway.store(@credit_card, {merchant_id: 'spreedly-susanswidg-32268973-2091076-148408385'}) + assert response = @gateway.store(@credit_card, { merchant_id: 'spreedly-susanswidg-32268973-2091076-148408385' }) assert_success response end def test_store_adds_card_to_existing_customer - assert response = @gateway.store(@credit_card, @options.merge({customer_id: 'spreedly-susanswidg-32268973-2091076-148408385-5980208887457495-148700575'})) + assert response = @gateway.store(@credit_card, @options.merge({ customer_id: 'spreedly-susanswidg-32268973-2091076-148408385-5980208887457495-148700575' })) assert_success response end def test_store_creates_new_customer_and_adds_card - assert response = @gateway.store(@credit_card, @options.merge({customer_id: 'nonexistant'})) + assert response = @gateway.store(@credit_card, @options.merge({ customer_id: 'nonexistant' })) assert_success response end @@ -132,5 +132,4 @@ def test_transcript_scrubbing assert_scrubbed(@gateway.options[:api_key], transcript) assert_scrubbed(@gateway.options[:app_key], transcript) end - end diff --git a/test/remote/gateways/remote_ebanx_test.rb b/test/remote/gateways/remote_ebanx_test.rb index d1035d9b62b..070cf935eb1 100644 --- a/test/remote/gateways/remote_ebanx_test.rb +++ b/test/remote/gateways/remote_ebanx_test.rb @@ -17,7 +17,12 @@ def setup phone_number: '8522847035' }), order_id: generate_unique_id, - document: '853.513.468-93' + document: '853.513.468-93', + device_id: '34c376b2767', + metadata: { + metadata_1: 'test', + metadata_2: 'test2' + } } end @@ -71,13 +76,13 @@ def test_successful_purchase_as_colombian response = @gateway.purchase(500, @credit_card, options) assert_success response - assert_equal 'Sandbox - Test credit card, transaction captured', response.message + assert_equal 'Accepted', response.message end def test_failed_purchase response = @gateway.purchase(@amount, @declined_card, @options) assert_failure response - assert_equal 'Sandbox - Test credit card, transaction declined reason insufficientFunds', response.message + assert_equal 'Invalid card or card type', response.message assert_equal 'NOK', response.error_code end @@ -86,7 +91,7 @@ def test_successful_authorize_and_capture assert_success auth assert_equal 'Accepted', auth.message - assert capture = @gateway.capture(@amount, auth.authorization) + assert capture = @gateway.capture(@amount, auth.authorization, @options) assert_success capture assert_equal 'Accepted', capture.message end @@ -94,18 +99,28 @@ def test_successful_authorize_and_capture def test_failed_authorize response = @gateway.authorize(@amount, @declined_card, @options) assert_failure response - assert_equal 'Sandbox - Test credit card, transaction declined reason insufficientFunds', response.message + assert_equal 'Invalid card or card type', response.message assert_equal 'NOK', response.error_code end - def test_partial_capture + def test_successful_partial_capture_when_include_capture_amount_is_not_passed auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end + # Partial capture is only available in Brazil and the EBANX Integration Team must be contacted to enable + def test_failed_partial_capture_when_include_capture_amount_is_passed + auth = @gateway.authorize(@amount, @credit_card, @options) + assert_success auth + + assert capture = @gateway.capture(@amount - 1, auth.authorization, @options.merge(include_capture_amount: true)) + assert_failure capture + assert_equal 'Partial capture not available', capture.message + end + def test_failed_capture response = @gateway.capture(@amount, '') assert_failure response @@ -116,7 +131,7 @@ def test_successful_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - refund_options = @options.merge({description: 'full refund'}) + refund_options = @options.merge({ description: 'full refund' }) assert refund = @gateway.refund(@amount, purchase.authorization, refund_options) assert_success refund assert_equal 'Accepted', refund.message @@ -127,7 +142,7 @@ def test_partial_refund assert_success purchase refund_options = @options.merge(description: 'refund due to returned item') - assert refund = @gateway.refund(@amount-1, purchase.authorization, refund_options) + assert refund = @gateway.refund(@amount - 1, purchase.authorization, refund_options) assert_success refund end @@ -149,7 +164,7 @@ def test_successful_void def test_failed_void response = @gateway.void('') assert_failure response - assert_equal 'Parameter hash not informed', response.message + assert_equal 'Parameters hash or merchant_payment_code not informed', response.message end def test_successful_store_and_purchase @@ -190,10 +205,31 @@ def test_successful_verify assert_match %r{Accepted}, response.message end + def test_successful_verify_for_chile + options = @options.merge({ + order_id: generate_unique_id, + ip: '127.0.0.1', + email: 'jose@example.com.cl', + birth_date: '10/11/1980', + billing_address: address({ + address1: '1040 Rua E', + city: 'Medellín', + state: 'AN', + zip: '29269', + country: 'CL', + phone_number: '8522847035' + }) + }) + + response = @gateway.verify(@credit_card, options) + assert_success response + assert_match %r{Accepted}, response.message + end + def test_failed_verify response = @gateway.verify(@declined_card, @options) assert_failure response - assert_match %r{Accepted}, response.message + assert_match %r{Invalid card or card type}, response.message end def test_invalid_login @@ -215,4 +251,11 @@ def test_transcript_scrubbing assert_scrubbed(@gateway.options[:integration_key], transcript) end + def test_successful_purchase_with_long_order_id + options = @options.update(order_id: SecureRandom.hex(50)) + + response = @gateway.purchase(@amount, @credit_card, options) + assert_success response + assert_equal 'Accepted', response.message + end end diff --git a/test/remote/gateways/remote_efsnet_test.rb b/test/remote/gateways/remote_efsnet_test.rb index 4e6f22499b7..c2745e2551f 100644 --- a/test/remote/gateways/remote_efsnet_test.rb +++ b/test/remote/gateways/remote_efsnet_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class RemoteEfsnetTest < Test::Unit::TestCase - def setup Base.mode = :test @@ -12,9 +11,8 @@ def setup @amount = 100 @declined_amount = 156 - @options = { :order_id => generate_unique_id, - :billing_address => address - } + @options = { order_id: generate_unique_id, + billing_address: address } end def test_successful_purchase @@ -71,8 +69,8 @@ def test_failed_capture def test_invalid_login gateway = EfsnetGateway.new( - :login => '', - :password => '' + login: '', + password: '' ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_equal 'Invalid credentials', response.message diff --git a/test/remote/gateways/remote_elavon_test.rb b/test/remote/gateways/remote_elavon_test.rb index 1f89405e99a..4b8f711887b 100644 --- a/test/remote/gateways/remote_elavon_test.rb +++ b/test/remote/gateways/remote_elavon_test.rb @@ -3,16 +3,87 @@ class RemoteElavonTest < Test::Unit::TestCase def setup @gateway = ElavonGateway.new(fixtures(:elavon)) + @tokenization_gateway = fixtures(:elavon_tokenization) ? ElavonGateway.new(fixtures(:elavon_tokenization)) : ElavonGateway.new(fixtures(:elavon)) + @bad_creds_gateway = ElavonGateway.new(login: 'foo', password: 'bar', user: 'me') @multi_currency_gateway = ElavonGateway.new(fixtures(:elavon_multi_currency)) - @credit_card = credit_card('4124939999999990') + @credit_card = credit_card('4000000000000002') @bad_credit_card = credit_card('invalid') @options = { - :email => 'paul@domain.com', - :description => 'Test Transaction', - :billing_address => address, - :ip => '203.0.113.0' + email: 'paul@domain.com', + description: 'Test Transaction', + billing_address: address, + ip: '203.0.113.0', + merchant_initiated_unscheduled: 'N' + } + @shipping_address = { + address1: '733 Foster St.', + city: 'Durham', + state: 'NC', + phone: '8887277750', + country: 'USA', + zip: '27701' + } + @level_3_data = { + customer_code: 'bob', + salestax: '3.45', + salestax_indicator: 'Y', + level3_indicator: 'Y', + ship_to_zip: '12345', + ship_to_country: 'US', + shipping_amount: '1234', + ship_from_postal_code: '54321', + discount_amount: '5', + duty_amount: '2', + national_tax_indicator: '0', + national_tax_amount: '10', + order_date: '280810', + other_tax: '3', + summary_commodity_code: '123', + merchant_vat_number: '222', + customer_vat_number: '333', + freight_tax_amount: '4', + vat_invoice_number: '26', + tracking_number: '45', + shipping_company: 'UFedzon', + other_fees: '2', + line_items: [ + { + description: 'thing', + product_code: '23', + commodity_code: '444', + quantity: '15', + unit_of_measure: 'kropogs', + unit_cost: '4.5', + discount_indicator: 'Y', + tax_indicator: 'Y', + discount_amount: '1', + tax_rate: '8.25', + tax_amount: '12', + tax_type: '000', + extended_total: '500', + total: '525', + alternative_tax: '111' + }, + { + description: 'thing2', + product_code: '23', + commodity_code: '444', + quantity: '15', + unit_of_measure: 'kropogs', + unit_cost: '4.5', + discount_indicator: 'Y', + tax_indicator: 'Y', + discount_amount: '1', + tax_rate: '8.25', + tax_amount: '12', + tax_type: '000', + extended_total: '500', + total: '525', + alternative_tax: '111' + } + ] } @amount = 100 end @@ -40,7 +111,7 @@ def test_authorize_and_capture assert_equal 'APPROVAL', auth.message assert auth.authorization - assert capture = @gateway.capture(@amount, auth.authorization, :credit_card => @credit_card) + assert capture = @gateway.capture(@amount, auth.authorization, @options.merge(credit_card: @credit_card)) assert_success capture end @@ -55,7 +126,7 @@ def test_authorize_and_capture_with_auth_code end def test_unsuccessful_capture - assert response = @gateway.capture(@amount, '', :credit_card => @credit_card) + assert response = @gateway.capture(@amount, '', credit_card: @credit_card) assert_failure response assert_equal 'The FORCE Approval Code supplied in the authorization request appears to be invalid or blank. The FORCE Approval Code must be 6 or less alphanumeric characters.', response.message end @@ -70,7 +141,6 @@ def test_successful_verify assert response = @gateway.verify(@credit_card, @options) assert_success response assert_equal 'APPROVAL', response.message - assert_success response.responses.last, 'The void should succeed' end def test_failed_verify @@ -137,72 +207,157 @@ def test_authorize_and_successful_void assert response.authorization end + def test_successful_auth_and_capture_with_recurring_stored_credential + stored_credential_params = { + initial_transaction: true, + reason_type: 'recurring', + initiator: 'merchant', + network_transaction_id: nil + } + assert auth = @gateway.authorize(@amount, @credit_card, @options.merge({ stored_credential: stored_credential_params })) + assert_success auth + assert auth.authorization + + assert capture = @gateway.capture(@amount, auth.authorization, authorization_validated: true) + assert_success capture + + @options[:stored_credential] = { + initial_transaction: false, + reason_type: 'recurring', + initiator: 'merchant', + network_transaction_id: auth.network_transaction_id + } + + assert next_auth = @gateway.authorize(@amount, @credit_card, @options) + assert next_auth.authorization + + assert capture = @gateway.capture(@amount, next_auth.authorization, authorization_validated: true) + assert_success capture + end + + def test_successful_auth_and_capture_with_unscheduled_stored_credential + stored_credential_params = { + initial_transaction: true, + reason_type: 'unscheduled', + initiator: 'merchant', + network_transaction_id: nil + } + assert auth = @gateway.authorize(@amount, @credit_card, @options.merge({ stored_credential: stored_credential_params })) + assert_success auth + assert auth.authorization + + assert capture = @gateway.capture(@amount, auth.authorization, authorization_validated: true) + assert_success capture + + @options[:stored_credential] = { + initial_transaction: false, + reason_type: 'unscheduled', + initiator: 'merchant', + network_transaction_id: auth.network_transaction_id + } + + assert next_auth = @gateway.authorize(@amount, @credit_card, @options) + assert next_auth.authorization + + assert capture = @gateway.capture(@amount, next_auth.authorization, authorization_validated: true) + assert_success capture + end + + def test_successful_auth_and_capture_with_installment_stored_credential + stored_credential_params = { + initial_transaction: true, + reason_type: 'installment', + initiator: 'merchant', + network_transaction_id: nil + } + assert auth = @gateway.authorize(@amount, @credit_card, @options.merge({ stored_credential: stored_credential_params })) + assert_success auth + assert auth.authorization + + assert capture = @gateway.capture(@amount, auth.authorization, authorization_validated: true) + assert_success capture + + @options[:stored_credential] = { + initial_transaction: false, + reason_type: 'installment', + initiator: 'merchant', + network_transaction_id: auth.network_transaction_id + } + + assert next_auth = @gateway.authorize(@amount, @credit_card, @options) + assert next_auth.authorization + + assert capture = @gateway.capture(@amount, next_auth.authorization, authorization_validated: true) + assert_success capture + end + def test_successful_store_without_verify - assert response = @gateway.store(@credit_card, @options) + assert response = @tokenization_gateway.store(@credit_card, @options) assert_success response assert_nil response.message assert response.test? end def test_successful_store_with_verify_false - assert response = @gateway.store(@credit_card, @options.merge(verify: false)) + assert response = @tokenization_gateway.store(@credit_card, @options.merge(verify: false)) assert_success response assert_nil response.message assert response.test? end def test_successful_store_with_verify_true - assert response = @gateway.store(@credit_card, @options.merge(verify: true)) + assert response = @tokenization_gateway.store(@credit_card, @options.merge(verify: true)) assert_success response assert_equal 'APPROVAL', response.message assert response.test? end def test_unsuccessful_store - assert response = @gateway.store(@bad_credit_card, @options) + assert response = @tokenization_gateway.store(@bad_credit_card, @options) assert_failure response assert_equal 'The Credit Card Number supplied in the authorization request appears to be invalid.', response.message assert response.test? end def test_successful_update - store_response = @gateway.store(@credit_card, @options) + store_response = @tokenization_gateway.store(@credit_card, @options) token = store_response.params['token'] - credit_card = credit_card('4124939999999990', :month => 10) - assert response = @gateway.update(token, credit_card, @options) + credit_card = credit_card('4000000000000002', month: 10) + assert response = @tokenization_gateway.update(token, credit_card, @options) assert_success response assert response.test? end def test_unsuccessful_update - assert response = @gateway.update('ABC123', @credit_card, @options) + assert response = @tokenization_gateway.update('ABC123', @credit_card, @options) assert_failure response assert_match %r{invalid}i, response.message assert response.test? end def test_successful_purchase_with_token - store_response = @gateway.store(@credit_card, @options) + store_response = @tokenization_gateway.store(@credit_card, @options) token = store_response.params['token'] - assert response = @gateway.purchase(@amount, token, @options) + assert response = @tokenization_gateway.purchase(@amount, token, @options) assert_success response assert response.test? assert_equal 'APPROVAL', response.message end def test_failed_purchase_with_token - assert response = @gateway.purchase(@amount, 'ABC123', @options) + assert response = @tokenization_gateway.purchase(@amount, 'ABC123', @options) assert_failure response assert response.test? assert_match %r{invalid}i, response.message end def test_successful_purchase_with_custom_fields - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(custom_fields: {a_key: 'a value'})) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(custom_fields: { my_field: 'a value' })) assert_success response - assert response.test? + assert_match response.params['my_field'], 'a value' assert_equal 'APPROVAL', response.message + assert response.test? assert response.authorization end @@ -234,6 +389,41 @@ def test_successful_purchase_with_multi_currency_transaction_setting assert response.authorization end + def test_successful_purchase_with_level_3_fields + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(level_3_data: @level_3_data)) + + assert_success response + assert_equal 'APPROVAL', response.message + assert response.authorization + end + + def test_successful_purchase_with_shipping_address + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(shipping_address: @shipping_address)) + + assert_success response + assert_equal 'APPROVAL', response.message + assert response.authorization + end + + def test_successful_purchase_with_shipping_address_and_l3 + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(shipping_address: @shipping_address).merge(level_3_data: @level_3_data)) + + assert_success response + assert_equal 'APPROVAL', response.message + assert response.authorization + end + + def test_successful_purchase_with_truncated_data + credit_card = @credit_card + credit_card.first_name = 'Rick & ™ \" < > Martínez įncogníto' + credit_card.last_name = 'Lesly Andrea Mart™nez estrada the last name' + @options[:billing_address][:city] = 'Saint-François-Xavier-de-Brompton' + @options[:billing_address][:address1] = 'Bats & Cats' + + assert response = @gateway.purchase(@amount, @credit_card, @options) + assert_success response + end + def test_transcript_scrubbing transcript = capture_transcript(@gateway) do @gateway.purchase(@amount, @credit_card, @options) @@ -241,8 +431,15 @@ def test_transcript_scrubbing transcript = @gateway.scrub(transcript) assert_scrubbed(@credit_card.number, transcript) - assert_scrubbed(@credit_card.verification_value, transcript) + assert_scrubbed("#{@credit_card.verification_value}", transcript) assert_scrubbed(@gateway.options[:password], transcript) end + def test_invalid_login + assert response = @bad_creds_gateway.purchase(@amount, @credit_card, @options) + + assert_failure response + assert response.test? + assert_equal 'The credentials supplied in the authorization request are invalid.', response.message + end end diff --git a/test/remote/gateways/remote_element_test.rb b/test/remote/gateways/remote_element_test.rb index 4cc1b565471..5e1218778f6 100644 --- a/test/remote/gateways/remote_element_test.rb +++ b/test/remote/gateways/remote_element_test.rb @@ -50,6 +50,48 @@ def test_successful_purchase_with_shipping_address assert_equal 'Approved', response.message end + def test_successful_purchase_with_card_present_code + response = @gateway.purchase(@amount, @credit_card, @options.merge(card_present_code: 'Present')) + assert_success response + assert_equal 'Approved', response.message + end + + def test_successful_purchase_with_payment_type + response = @gateway.purchase(@amount, @credit_card, @options.merge(payment_type: 'NotUsed')) + assert_success response + assert_equal 'Approved', response.message + end + + def test_successful_purchase_with_submission_type + response = @gateway.purchase(@amount, @credit_card, @options.merge(submission_type: 'NotUsed')) + assert_success response + assert_equal 'Approved', response.message + end + + def test_successful_purchase_with_duplicate_check_disable_flag + response = @gateway.purchase(@amount, @credit_card, @options.merge(duplicate_check_disable_flag: true)) + assert_success response + assert_equal 'Approved', response.message + + response = @gateway.purchase(@amount, @credit_card, @options.merge(duplicate_check_disable_flag: false)) + assert_success response + assert_equal 'Approved', response.message + + response = @gateway.purchase(@amount, @credit_card, @options.merge(duplicate_check_disable_flag: 'true')) + assert_success response + assert_equal 'Approved', response.message + + response = @gateway.purchase(@amount, @credit_card, @options.merge(duplicate_check_disable_flag: 'xxx')) + assert_success response + assert_equal 'Approved', response.message + end + + def test_successful_purchase_with_terminal_id + response = @gateway.purchase(@amount, @credit_card, @options.merge(terminal_id: '02')) + assert_success response + assert_equal 'Approved', response.message + end + def test_successful_authorize_and_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth @@ -70,7 +112,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -93,7 +135,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund end @@ -121,7 +163,7 @@ def test_failed_void def test_successful_verify response = @gateway.verify(@credit_card, @options) assert_success response - assert_match %r{Approved}, response.message + assert_equal 'Success', response.message end def test_successful_store diff --git a/test/remote/gateways/remote_epay_test.rb b/test/remote/gateways/remote_epay_test.rb index 9c900098697..226f4d2132c 100644 --- a/test/remote/gateways/remote_epay_test.rb +++ b/test/remote/gateways/remote_epay_test.rb @@ -8,8 +8,8 @@ def setup @credit_card = credit_card('3333333333333000') @credit_card_declined = credit_card('3333333333333102') @amount = 100 - @options_xid = {order_id: '1', three_d_secure: { eci: '7', xid: '123', cavv: '456', version: '2', ds_transaction_id: nil }} - @options_ds_transaction_id = {order_id: '1', three_d_secure: { eci: '7', xid: nil, cavv: '456', version: '2', ds_transaction_id: '798' }} + @options_xid = { order_id: generate_unique_id, three_d_secure: { eci: '7', xid: '123', cavv: '456', version: '2', ds_transaction_id: nil } } + @options_ds_transaction_id = { order_id: generate_unique_id, three_d_secure: { eci: '7', xid: nil, cavv: '456', version: '2', ds_transaction_id: '798' } } end def test_successful_purchase_xid @@ -110,5 +110,4 @@ def test_failed_void response = @gateway.void(0) assert_failure response end - end diff --git a/test/remote/gateways/remote_evo_ca_test.rb b/test/remote/gateways/remote_evo_ca_test.rb index 9bc99560d4a..f1b6cb32ebe 100644 --- a/test/remote/gateways/remote_evo_ca_test.rb +++ b/test/remote/gateways/remote_evo_ca_test.rb @@ -7,12 +7,12 @@ def setup @amount = 100 @credit_card = credit_card('4111111111111111') @options = { - :order_id => '1', - :billing_address => address, - :description => 'Store Purchase', - :invoice => 'AB-1234', - :email => 'evo@example.com', - :ip => '127.0.0.1' + order_id: '1', + billing_address: address, + description: 'Store Purchase', + invoice: 'AB-1234', + email: 'evo@example.com', + ip: '127.0.0.1' } end @@ -72,7 +72,7 @@ def test_purchase_and_void def test_purchase_and_update assert response = @gateway.purchase(@amount, @credit_card, @options) assert_success response - assert response = @gateway.update(response.authorization, :shipping_carrier => 'fedex', :tracking_number => '12345') + assert response = @gateway.update(response.authorization, shipping_carrier: 'fedex', tracking_number: '12345') assert_success response assert_equal EvoCaGateway::MESSAGES[100], response.message end @@ -102,7 +102,7 @@ def test_successful_credit def test_avs_match # To simulate an AVS Match, pass 888 in the address1 field, 77777 for zip. - opts = @options.merge(:billing_address => address({:address1 => '888', :zip => '77777'})) + opts = @options.merge(billing_address: address({ address1: '888', zip: '77777' })) assert response = @gateway.purchase(@amount, @credit_card, opts) assert_success response assert_equal 'Y', response.avs_result['code'] @@ -112,7 +112,7 @@ def test_avs_match def test_cvv_match # To simulate a CVV Match, pass 999 in the cvv field. - assert response = @gateway.purchase(@amount, credit_card('4111111111111111', :verification_value => 999), @options) + assert response = @gateway.purchase(@amount, credit_card('4111111111111111', verification_value: 999), @options) assert_success response assert_equal 'M', response.cvv_result['code'] end diff --git a/test/remote/gateways/remote_eway_managed_test.rb b/test/remote/gateways/remote_eway_managed_test.rb index 1322e32676c..c36eca3c21a 100644 --- a/test/remote/gateways/remote_eway_managed_test.rb +++ b/test/remote/gateways/remote_eway_managed_test.rb @@ -2,17 +2,17 @@ class RemoteEwayManagedTest < Test::Unit::TestCase def setup - @gateway = EwayManagedGateway.new(fixtures(:eway_managed).merge({ :test => true })) + @gateway = EwayManagedGateway.new(fixtures(:eway_managed).merge({ test: true })) - @valid_card='4444333322221111' - @valid_customer_id='9876543211000' + @valid_card = '4444333322221111' + @valid_customer_id = '9876543211000' @credit_card = credit_card(@valid_card) @options = { - :billing_address => { - :country => 'au', - :title => 'Mr.' + billing_address: { + country: 'au', + title: 'Mr.' } } @@ -29,9 +29,9 @@ def test_successful_purchase def test_invalid_login gateway = EwayManagedGateway.new( - :login => '', - :password => '', - :username => '' + login: '', + password: '', + username: '' ) assert response = gateway.purchase(@amount, @valid_customer_id, @options) assert_equal 'Login failed. ', response.message diff --git a/test/remote/gateways/remote_eway_rapid_test.rb b/test/remote/gateways/remote_eway_rapid_test.rb index 4feec8d4e6b..2778f1d5c4e 100644 --- a/test/remote/gateways/remote_eway_rapid_test.rb +++ b/test/remote/gateways/remote_eway_rapid_test.rb @@ -60,6 +60,45 @@ def test_successful_purchase_without_address assert_equal customer['Email'], email end + def test_successful_purchase_with_3ds1 + eci = '05' + cavv = 'AgAAAAAA4n1uzQPRaATeQAAAAAA=' + xid = 'AAAAAAAA4n1uzQPRaATeQAAAAAA=' + authentication_response_status = 'Y' + @options[:three_d_secure] = { + eci: eci, + cavv: cavv, + xid: xid, + authentication_response_status: authentication_response_status + } + + response = @gateway.purchase(@amount, @credit_card, @options) + + assert_success response + assert_equal 'Transaction Approved Successful', response.message + end + + def test_successful_purchase_with_3ds2 + eci = '05' + cavv = 'AgAAAAAA4n1uzQPRaATeQAAAAAA=' + authentication_response_status = 'Y' + version = '2.1.0' + ds_transaction_id = '8fe2e850-a028-407e-9a18-c8cf7598ca10' + + @options[:three_d_secure] = { + version: version, + eci: eci, + cavv: cavv, + ds_transaction_id: ds_transaction_id, + authentication_response_status: authentication_response_status + } + + response = @gateway.purchase(@amount, @credit_card, @options) + + assert_success response + assert_equal 'Transaction Approved Successful', response.message + end + def test_successful_purchase_with_shipping_address @options[:shipping_address] = address @@ -109,8 +148,7 @@ def test_fully_loaded_purchase country: 'US', phone: '1115555555', fax: '1115556666' - } - ) + }) assert_success response end @@ -122,12 +160,12 @@ def test_successful_purchase_with_overly_long_fields billing_address: { address1: 'The Billing Address 1 Cannot Be More Than Fifty Characters.', address2: 'The Billing Address 2 Cannot Be More Than Fifty Characters.', - city: 'TheCityCannotBeMoreThanFiftyCharactersOrItAllFallsApart', + city: 'TheCityCannotBeMoreThanFiftyCharactersOrItAllFallsApart' }, shipping_address: { address1: 'The Shipping Address 1 Cannot Be More Than Fifty Characters.', address2: 'The Shipping Address 2 Cannot Be More Than Fifty Characters.', - city: 'TheCityCannotBeMoreThanFiftyCharactersOrItAllFallsApart', + city: 'TheCityCannotBeMoreThanFiftyCharactersOrItAllFallsApart' } } @credit_card.first_name = 'FullNameOnACardMustBeLessThanFiftyCharacters' diff --git a/test/remote/gateways/remote_eway_test.rb b/test/remote/gateways/remote_eway_test.rb index a8d7d583874..64f536d176f 100644 --- a/test/remote/gateways/remote_eway_test.rb +++ b/test/remote/gateways/remote_eway_test.rb @@ -5,20 +5,18 @@ def setup @gateway = EwayGateway.new(fixtures(:eway)) @credit_card_success = credit_card('4444333322221111') @credit_card_fail = credit_card('1234567812345678', - :month => Time.now.month, - :year => Time.now.year-1 - ) + month: Time.now.month, + year: Time.now.year - 1) @params = { - :order_id => '1230123', - :email => 'bob@testbob.com', - :billing_address => { :address1 => '47 Bobway', - :city => 'Bobville', - :state => 'WA', - :country => 'AU', - :zip => '2000' - }, - :description => 'purchased items' + order_id: '1230123', + email: 'bob@testbob.com', + billing_address: { address1: '47 Bobway', + city: 'Bobville', + state: 'WA', + country: 'AU', + zip: '2000' }, + description: 'purchased items' } end @@ -72,7 +70,7 @@ def test_failed_refund end def test_transcript_scrubbing - @credit_card_success.verification_value = '431' + @credit_card_success.verification_value = '431' transcript = capture_transcript(@gateway) do @gateway.purchase(100, @credit_card_success, @params) end diff --git a/test/remote/gateways/remote_exact_test.rb b/test/remote/gateways/remote_exact_test.rb index 8843e170d74..c3a46234636 100644 --- a/test/remote/gateways/remote_exact_test.rb +++ b/test/remote/gateways/remote_exact_test.rb @@ -6,9 +6,9 @@ def setup @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 @@ -49,8 +49,8 @@ def test_failed_capture end def test_invalid_login - gateway = ExactGateway.new(:login => 'NotARealUser', - :password => 'NotARealPassword') + gateway = ExactGateway.new(login: 'NotARealUser', + password: 'NotARealPassword') assert response = gateway.purchase(@amount, @credit_card, @options) assert_match %r{^Invalid Login}, response.message assert_failure response diff --git a/test/remote/gateways/remote_ezic_test.rb b/test/remote/gateways/remote_ezic_test.rb index 7aacb3f3a74..85ec4c441d3 100644 --- a/test/remote/gateways/remote_ezic_test.rb +++ b/test/remote/gateways/remote_ezic_test.rb @@ -46,7 +46,7 @@ def test_failed_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount+30, auth.authorization) + assert capture = @gateway.capture(@amount + 30, auth.authorization) assert_failure capture assert_match(/Settlement amount cannot exceed authorized amount/, capture.message) end @@ -64,7 +64,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund assert_equal 'TEST RETURNED', refund.message assert_equal '-0.99', refund.params['settle_amount'] diff --git a/test/remote/gateways/remote_fat_zebra_test.rb b/test/remote/gateways/remote_fat_zebra_test.rb index 28943103a33..ff8afe7c584 100644 --- a/test/remote/gateways/remote_fat_zebra_test.rb +++ b/test/remote/gateways/remote_fat_zebra_test.rb @@ -9,8 +9,8 @@ def setup @declined_card = credit_card('4557012345678902') @options = { - :order_id => rand(100000).to_s, - :ip => '1.2.3.4' + order_id: generate_unique_id, + ip: '1.2.3.4' } end @@ -21,14 +21,14 @@ def test_successful_purchase end def test_successful_multi_currency_purchase - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:currency => 'USD')) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(currency: 'USD')) assert_success response assert_equal 'Approved', response.message assert_equal 'USD', response.params['response']['currency'] end def test_unsuccessful_multi_currency_purchase - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:currency => 'XYZ')) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(currency: 'XYZ')) assert_failure response assert_match(/Currency XYZ is not valid for this merchant/, response.message) end @@ -64,12 +64,12 @@ def test_successful_authorize_and_capture end def test_multi_currency_authorize_and_capture - assert auth_response = @gateway.authorize(@amount, @credit_card, @options.merge(:currency => 'USD')) + assert auth_response = @gateway.authorize(@amount, @credit_card, @options.merge(currency: 'USD')) assert_success auth_response assert_equal 'Approved', auth_response.message assert_equal 'USD', auth_response.params['response']['currency'] - assert capture_response = @gateway.capture(@amount, auth_response.authorization, @options.merge(:currency => 'USD')) + assert capture_response = @gateway.capture(@amount, auth_response.authorization, @options.merge(currency: 'USD')) assert_success capture_response assert_equal 'Approved', capture_response.message assert_equal 'USD', capture_response.params['response']['currency'] @@ -118,8 +118,10 @@ def test_successful_void def test_successful_void_refund purchase = @gateway.purchase(@amount, @credit_card, @options) - puts purchase.inspect + assert_success purchase + refund = @gateway.refund(@amount, purchase.authorization, @options) + assert_success refund assert response = @gateway.void(refund.authorization, @options) assert_success response @@ -139,42 +141,78 @@ def test_store assert_not_nil card.authorization end + def test_successful_store_without_cvv + credit_card = @credit_card + credit_card.verification_value = nil + assert card = @gateway.store(credit_card, recurring: true) + + assert_success card + assert_not_nil card.authorization + end + + def test_failed_store_without_cvv + credit_card = @credit_card + credit_card.verification_value = nil + assert card = @gateway.store(credit_card) + + assert_failure card + assert_match %r{CVV is required}, card.message + end + def test_purchase_with_token assert card = @gateway.store(@credit_card) - assert purchase = @gateway.purchase(@amount, card.authorization, @options.merge(:cvv => 123)) + assert purchase = @gateway.purchase(@amount, card.authorization, @options.merge(cvv: 123)) assert_success purchase end def test_successful_purchase_with_descriptor - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:merchant => 'Merchant', :merchant_location => 'Location')) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(merchant: 'Merchant', merchant_location: 'Location')) assert_success response assert_equal 'Approved', response.message end def test_successful_purchase_with_metadata - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:metadata => { :description => 'Invoice #1234356' })) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(metadata: { description: 'Invoice #1234356' })) assert_success response assert_equal 'Approved', response.message assert_equal 'Invoice #1234356', response.params['response']['metadata']['description'] end def test_successful_purchase_with_3DS_information - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:cavv => 'MDRjN2MxZTAxYjllNTBkNmM2MTA=', :xid => 'MGVmMmNlMzI4NjAyOWU2ZDgwNTQ=', :sli => '05')) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(cavv: 'MDRjN2MxZTAxYjllNTBkNmM2MTA=', xid: 'MGVmMmNlMzI4NjAyOWU2ZDgwNTQ=', sli: '05')) assert_success response assert_equal 'Approved', response.message end def test_failed_purchase_with_incomplete_3DS_information - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:cavv => 'MDRjN2MxZTAxYjllNTBkNmM2MTA=', :sli => '05')) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(xid: 'MGVmMmNlMzI4NjAyOWU2ZDgwNTZ=', sli: '05')) assert_failure response - assert_match %r{Extra/xid is required for SLI 05}, response.message + assert_match %r{Extra/cavv is required for SLI 05}, response.message + end + + def test_successful_purchase_with_3DS_information_using_standard_fields + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(three_d_secure: { cavv: 'MDRjN2MxZTAxYjllNTBkNmM2MTA=', xid: 'MGVmMmNlMzI4NjAyOWU2ZDgwNTQ=', eci: '05' })) + assert_success response + assert_equal 'Approved', response.message + end + + def test_failed_purchase_with_incomplete_3DS_information_using_standard_fields + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(three_d_secure: { xid: 'MGVmMmNlMzI4NjAyOWU2ZDgwNTQ=', eci: '05' })) + assert_failure response + assert_match %r{Extra/cavv is required for SLI 05}, response.message + end + + def test_successful_purchase_with_card_on_file_information + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(recurring: true, extra: { card_on_file: true, auth_reason: 'U' })) + assert_success response + assert_equal 'Approved', response.message end def test_invalid_login gateway = FatZebraGateway.new( - :username => 'invalid', - :token => 'wrongtoken' - ) + username: 'invalid', + token: 'wrongtoken' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'Invalid Login', response.message diff --git a/test/remote/gateways/remote_federated_canada_test.rb b/test/remote/gateways/remote_federated_canada_test.rb index 3b48d1795af..94eb40e86c9 100644 --- a/test/remote/gateways/remote_federated_canada_test.rb +++ b/test/remote/gateways/remote_federated_canada_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class RemoteFederatedCanadaTest < Test::Unit::TestCase - def setup @gateway = FederatedCanadaGateway.new(fixtures(:federated_canada)) @@ -11,9 +10,9 @@ def setup @credit_card = credit_card('4111111111111111') # Visa @options = { - :order_id => generate_unique_id, - :billing_address => address, - :description => 'Active Merchant Remote Test Purchase' + order_id: generate_unique_id, + billing_address: address, + description: 'Active Merchant Remote Test Purchase' } end @@ -77,9 +76,9 @@ def test_authorize_and_capture def test_invalid_login gateway = FederatedCanadaGateway.new( - :login => '', - :password => '' - ) + login: '', + password: '' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'Error in transaction data or system error', response.message diff --git a/test/remote/gateways/remote_finansbank_test.rb b/test/remote/gateways/remote_finansbank_test.rb index 753df513fe9..df5da0c203b 100644 --- a/test/remote/gateways/remote_finansbank_test.rb +++ b/test/remote/gateways/remote_finansbank_test.rb @@ -12,10 +12,10 @@ def setup @declined_card = credit_card('4000300011112220') @options = { - :order_id => '#' + generate_unique_id, - :billing_address => address, - :description => 'Store Purchase', - :email => 'xyz@gmail.com' + order_id: '#' + generate_unique_id, + billing_address: address, + description: 'Store Purchase', + email: 'xyz@gmail.com' } end @@ -89,9 +89,9 @@ def test_void def test_invalid_login gateway = FinansbankGateway.new( - :login => '', - :password => '', - :client_id => '' + login: '', + password: '', + client_id: '' ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response diff --git a/test/remote/gateways/remote_first_giving_test.rb b/test/remote/gateways/remote_first_giving_test.rb index aa37014c925..e3a291058b8 100644 --- a/test/remote/gateways/remote_first_giving_test.rb +++ b/test/remote/gateways/remote_first_giving_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class RemoteFirstGivingTest < Test::Unit::TestCase - def setup @gateway = FirstGivingGateway.new(fixtures(:first_giving)) @@ -47,10 +46,10 @@ def test_failed_refund def test_invalid_login gateway = FirstGivingGateway.new( - application_key: '25151616', - security_token: '63131jnkj', - charity_id: '1234' - ) + application_key: '25151616', + security_token: '63131jnkj', + charity_id: '1234' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'An error occurred. Please check your input and try again.', response.message diff --git a/test/remote/gateways/remote_first_pay_test.rb b/test/remote/gateways/remote_first_pay_test.rb index 6e174f76976..3aa090b7869 100644 --- a/test/remote/gateways/remote_first_pay_test.rb +++ b/test/remote/gateways/remote_first_pay_test.rb @@ -112,7 +112,7 @@ def test_invalid_login end def test_recurring_payment - @options.merge!({recurring: 1, recurring_start_date: DateTime.now.strftime('%m/%d/%Y'), recurring_end_date: DateTime.now.strftime('%m/%d/%Y'), recurring_type: 'monthly'}) + @options.merge!({ recurring: 1, recurring_start_date: DateTime.now.strftime('%m/%d/%Y'), recurring_end_date: DateTime.now.strftime('%m/%d/%Y'), recurring_type: 'monthly' }) response = @gateway.purchase(@amount, @credit_card, @options) assert_success response assert_equal 'Approved', response.message diff --git a/test/remote/gateways/remote_firstdata_e4_test.rb b/test/remote/gateways/remote_firstdata_e4_test.rb index f7d88e60197..9666a8637d7 100755 --- a/test/remote/gateways/remote_firstdata_e4_test.rb +++ b/test/remote/gateways/remote_firstdata_e4_test.rb @@ -8,9 +8,9 @@ def setup @credit_card_with_track_data = credit_card_with_track_data('4003000123456781') @amount = 100 @options = { - :order_id => '1', - :billing_address => address, - :description => 'Store Purchase' + order_id: '1', + billing_address: address, + description: 'Store Purchase' } @options_with_authentication_data = @options.merge({ eci: '5', @@ -28,8 +28,7 @@ def test_successful_purchase def test_successful_purchase_with_network_tokenization @credit_card = network_tokenization_credit_card('4242424242424242', payment_cryptogram: 'BwABB4JRdgAAAAAAiFF2AAAAAAA=', - verification_value: nil - ) + verification_value: nil) assert response = @gateway.purchase(@amount, @credit_card, @options) assert_success response assert_equal 'Transaction Normal - Approved', response.message @@ -37,7 +36,7 @@ def test_successful_purchase_with_network_tokenization end def test_successful_purchase_with_specified_currency - options_with_specified_currency = @options.merge({currency: 'GBP'}) + options_with_specified_currency = @options.merge({ currency: 'GBP' }) assert response = @gateway.purchase(@amount, @credit_card, options_with_specified_currency) assert_match(/Transaction Normal/, response.message) assert_success response @@ -119,7 +118,7 @@ def test_purchase_and_credit end def test_purchase_and_credit_with_specified_currency - options_with_specified_currency = @options.merge({currency: 'GBP'}) + options_with_specified_currency = @options.merge({ currency: 'GBP' }) assert purchase = @gateway.purchase(@amount, @credit_card, options_with_specified_currency) assert_success purchase assert purchase.authorization @@ -178,8 +177,8 @@ def test_failed_verify end def test_invalid_login - gateway = FirstdataE4Gateway.new(:login => 'NotARealUser', - :password => 'NotARealPassword') + gateway = FirstdataE4Gateway.new(login: 'NotARealUser', + password: 'NotARealPassword') assert response = gateway.purchase(@amount, @credit_card, @options) assert_match %r{Unauthorized Request}, response.message assert_failure response @@ -204,7 +203,7 @@ def test_refund end def test_refund_with_specified_currency - options_with_specified_currency = @options.merge({currency: 'GBP'}) + options_with_specified_currency = @options.merge({ currency: 'GBP' }) assert purchase = @gateway.purchase(@amount, @credit_card, options_with_specified_currency) assert_match(/Transaction Normal/, purchase.message) assert_success purchase @@ -248,5 +247,4 @@ def test_transcript_scrubbing assert_scrubbed(cc_with_different_cvc.verification_value, transcript) assert_scrubbed(@gateway.options[:password], transcript) end - end diff --git a/test/remote/gateways/remote_firstdata_e4_v27_test.rb b/test/remote/gateways/remote_firstdata_e4_v27_test.rb index 0bf4fc8c79c..8b41dc9013a 100644 --- a/test/remote/gateways/remote_firstdata_e4_v27_test.rb +++ b/test/remote/gateways/remote_firstdata_e4_v27_test.rb @@ -4,14 +4,14 @@ class RemoteFirstdataE4V27Test < Test::Unit::TestCase def setup @gateway = FirstdataE4V27Gateway.new(fixtures(:firstdata_e4_v27)) @credit_card = credit_card - @credit_card_master = credit_card('5500000000000004', :brand => 'master') + @credit_card_master = credit_card('5500000000000004', brand: 'master') @bad_credit_card = credit_card('4111111111111113') @credit_card_with_track_data = credit_card_with_track_data('4003000123456781') @amount = 100 @options = { - :order_id => '1', - :billing_address => address, - :description => 'Store Purchase' + order_id: '1', + billing_address: address, + description: 'Store Purchase' } @options_with_authentication_data = @options.merge({ eci: '5', @@ -29,8 +29,7 @@ def test_successful_purchase def test_successful_purchase_with_network_tokenization @credit_card = network_tokenization_credit_card('4242424242424242', payment_cryptogram: 'BwABB4JRdgAAAAAAiFF2AAAAAAA=', - verification_value: nil - ) + verification_value: nil) assert response = @gateway.purchase(@amount, @credit_card, @options) assert_success response assert_equal 'Transaction Normal - Approved', response.message @@ -91,6 +90,7 @@ def test_successful_purchase_with_stored_credentials_initial assert_match(/Transaction Normal/, response.message) assert_success response assert_equal '1', response.params['stored_credentials_indicator'] + assert_equal 'C', response.params['stored_credentials_initiation'] assert_equal 'U', response.params['stored_credentials_schedule'] assert_not_nil response.params['stored_credentials_transaction_id'] end @@ -208,10 +208,10 @@ def test_failed_verify end def test_invalid_login - gateway = FirstdataE4V27Gateway.new(:login => 'NotARealUser', - :password => 'NotARealPassword', - :key_id => 'NotARealKey', - :hmac_key => 'NotARealHMAC') + gateway = FirstdataE4V27Gateway.new(login: 'NotARealUser', + password: 'NotARealPassword', + key_id: 'NotARealKey', + hmac_key: 'NotARealHMAC') assert response = gateway.purchase(@amount, @credit_card, @options) assert_match %r{Unauthorized Request}, response.message assert_failure response @@ -267,5 +267,4 @@ def test_transcript_scrubbing assert_scrubbed(@gateway.options[:password], transcript) assert_scrubbed(@gateway.options[:hmac_key], transcript) end - end diff --git a/test/remote/gateways/remote_forte_test.rb b/test/remote/gateways/remote_forte_test.rb index 8a2df5bccc8..c39656f4b1f 100644 --- a/test/remote/gateways/remote_forte_test.rb +++ b/test/remote/gateways/remote_forte_test.rb @@ -10,13 +10,13 @@ def setup @check = check @bad_check = check({ - :name => 'Jim Smith', - :bank_name => 'Bank of Elbonia', - :routing_number => '1234567890', - :account_number => '0987654321', - :account_holder_type => '', - :account_type => 'checking', - :number => '0' + name: 'Jim Smith', + bank_name: 'Bank of Elbonia', + routing_number: '1234567890', + account_number: '0987654321', + account_holder_type: '', + account_type: 'checking', + number: '0' }) @options = { @@ -43,6 +43,38 @@ def test_successful_purchase_with_echeck response = @gateway.purchase(@amount, @check, @options) assert_success response assert_equal 'APPROVED', response.message + assert_equal 'PPD', response.params['echeck']['sec_code'] + end + + def test_successful_purchase_with_xdata + @options = @options.merge({ + xdata: { + xdata_1: 'some customer metadata', + xdata_2: 'some customer metadata', + xdata_3: 'some customer metadata', + xdata_4: 'some customer metadata', + xdata_5: 'some customer metadata', + xdata_6: 'some customer metadata', + xdata_7: 'some customer metadata', + xdata_8: 'some customer metadata', + xdata_9: 'some customer metadata' + } + }) + + response = @gateway.purchase(@amount, @credit_card, @options) + assert_success response + (1..9).each { |n| assert_equal 'some customer metadata', response.params['xdata']["xdata_#{n}"] } + end + + def test_successful_purchase_with_echeck_with_more_options + options = { + sec_code: 'WEB' + } + + response = @gateway.purchase(@amount, @check, options) + assert_success response + assert_equal 'APPROVED', response.message + assert_equal 'WEB', response.params['echeck']['sec_code'] end def test_failed_purchase_with_echeck @@ -111,7 +143,7 @@ def test_partial_capture wait_for_authorization_to_clear - assert capture = @gateway.capture(@amount-1, auth.authorization, @options) + assert capture = @gateway.capture(@amount - 1, auth.authorization, @options) assert_success capture end @@ -134,7 +166,7 @@ def test_partial_credit purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.credit(@amount-1, @credit_card, @options) + assert refund = @gateway.credit(@amount - 1, @credit_card, @options) assert_success refund end @@ -207,5 +239,4 @@ def test_transcript_scrubbing def wait_for_authorization_to_clear sleep(10) end - end diff --git a/test/remote/gateways/remote_garanti_test.rb b/test/remote/gateways/remote_garanti_test.rb index 189fba6ddd0..df6922f6c73 100644 --- a/test/remote/gateways/remote_garanti_test.rb +++ b/test/remote/gateways/remote_garanti_test.rb @@ -2,7 +2,6 @@ # NOTE: tests may fail randomly because Garanti returns random(!) responses for their test server class RemoteGarantiTest < Test::Unit::TestCase - def setup @gateway = GarantiGateway.new(fixtures(:garanti)) @@ -11,9 +10,9 @@ def setup @credit_card = credit_card('4282209027132016', month: 5, year: 2018, verification_value: 358) @options = { - :order_id => generate_unique_id, - :billing_address => address, - :description => 'Store Purchase' + order_id: generate_unique_id, + billing_address: address, + description: 'Store Purchase' } end @@ -51,11 +50,11 @@ def test_failed_capture def test_invalid_login gateway = GarantiGateway.new( - :login => 'PROVAUT', - :terminal_id => '30691300', - :merchant_id => '', - :password => '' - ) + login: 'PROVAUT', + terminal_id: '30691300', + merchant_id: '', + password: '' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal '0651', response.params['reason_code'] diff --git a/test/remote/gateways/remote_global_collect_test.rb b/test/remote/gateways/remote_global_collect_test.rb index 19eab0296fa..01b4674e9dd 100644 --- a/test/remote/gateways/remote_global_collect_test.rb +++ b/test/remote/gateways/remote_global_collect_test.rb @@ -14,18 +14,27 @@ def setup billing_address: address, description: 'Store Purchase' } + @long_address = { + billing_address: { + address1: '1234 Supercalifragilisticexpialidociousthiscantbemorethanfiftycharacters', + city: '‎Portland', + state: 'ME', + zip: '09901', + country: 'US' + } + } end def test_successful_purchase response = @gateway.purchase(@accepted_amount, @credit_card, @options) assert_success response assert_equal 'Succeeded', response.message + assert_equal 'CAPTURE_REQUESTED', response.params['payment']['status'] end def test_successful_purchase_with_fraud_fields options = @options.merge( - fraud_fields: - { + fraud_fields: { 'website' => 'www.example.com', 'giftMessage' => 'Happy Day!' } @@ -55,8 +64,102 @@ def test_successful_purchase_with_more_options assert_equal 'Succeeded', response.message end + def test_successful_purchase_with_installments + options = @options.merge(number_of_installments: 2) + response = @gateway.purchase(@amount, @credit_card, options) + assert_success response + assert_equal 'Succeeded', response.message + end + + # When requires_approval is true (or not present), + # `purchase` will make both an `auth` and a `capture` call + def test_successful_purchase_with_requires_approval_true + options = @options.merge(requires_approval: true) + + response = @gateway.purchase(@amount, @credit_card, options) + assert_success response + assert_equal 'Succeeded', response.message + assert_equal 'CAPTURE_REQUESTED', response.params['payment']['status'] + end + + # When requires_approval is false, `purchase` will only make an `auth` call + # to request capture (and no subsequent `capture` call). + def test_successful_purchase_with_requires_approval_false + options = @options.merge(requires_approval: false) + + response = @gateway.purchase(@amount, @credit_card, options) + assert_success response + assert_equal 'Succeeded', response.message + assert_equal 'CAPTURE_REQUESTED', response.params['payment']['status'] + end + + def test_successful_authorize_via_normalized_3ds2_fields + options = @options.merge( + three_d_secure: { + version: '2.1.0', + eci: '05', + cavv: 'jJ81HADVRtXfCBATEp01CJUAAAA=', + xid: 'BwABBJQ1AgAAAAAgJDUCAAAAAAA=', + ds_transaction_id: '97267598-FAE6-48F2-8083-C23433990FBC', + acs_transaction_id: '13c701a3-5a88-4c45-89e9-ef65e50a8bf9', + cavv_algorithm: 1, + authentication_response_status: 'Y' + } + ) + + response = @gateway.authorize(@amount, @credit_card, options) + assert_success response + assert_match 'jJ81HADVRtXfCBATEp01CJUAAAA=', response.params['payment']['paymentOutput']['cardPaymentMethodSpecificOutput']['threeDSecureResults']['cavv'] + assert_equal 'Succeeded', response.message + end + + def test_successful_purchase_with_airline_data + options = @options.merge( + airline_data: { + code: 111, + name: 'Spreedly Airlines', + flight_date: '20190810', + passenger_name: 'Randi Smith', + flight_legs: [ + { arrival_airport: 'BDL', + origin_airport: 'RDU', + date: '20190810', + carrier_code: 'SA', + number: 596, + airline_class: 'ZZ' }, + { arrival_airport: 'RDU', + origin_airport: 'BDL', + date: '20190817', + carrier_code: 'SA', + number: 597, + airline_class: 'ZZ' } + ] + } + ) + + response = @gateway.purchase(@amount, @credit_card, options) + assert_success response + assert_equal 'Succeeded', response.message + end + + def test_failed_purchase_with_insufficient_airline_data + options = @options.merge( + airline_data: { + flight_date: '20190810', + passenger_name: 'Randi Smith' + } + ) + + response = @gateway.purchase(@amount, @credit_card, options) + assert_failure response + assert_equal 'PARAMETER_NOT_FOUND_IN_REQUEST', response.message + property_names = response.params['errors'].collect { |e| e['propertyName'] } + assert property_names.include? 'order.additionalInput.airlineData.code' + assert property_names.include? 'order.additionalInput.airlineData.name' + end + def test_successful_purchase_with_very_long_name - credit_card = credit_card('4567350000427977', { first_name: 'thisisaverylongfirstname'}) + credit_card = credit_card('4567350000427977', { first_name: 'thisisaverylongfirstname' }) response = @gateway.purchase(@amount, credit_card, @options) assert_success response @@ -64,13 +167,19 @@ def test_successful_purchase_with_very_long_name end def test_successful_purchase_with_blank_name - credit_card = credit_card('4567350000427977', { first_name: nil, last_name: nil}) + credit_card = credit_card('4567350000427977', { first_name: nil, last_name: nil }) response = @gateway.purchase(@amount, credit_card, @options) assert_success response assert_equal 'Succeeded', response.message end + def test_successful_purchase_with_truncated_address + response = @gateway.purchase(@amount, @credit_card, @long_address) + assert_success response + assert_equal 'Succeeded', response.message + end + def test_failed_purchase response = @gateway.purchase(@rejected_amount, @declined_card, @options) assert_failure response @@ -160,7 +269,6 @@ def test_failed_verify def test_invalid_login gateway = GlobalCollectGateway.new(merchant_id: '', api_key_id: '', secret_api_key: '') - response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_match %r{MISSING_OR_INVALID_AUTHORIZATION}, response.message @@ -175,5 +283,4 @@ def test_transcript_scrubbing assert_scrubbed(@credit_card.number, transcript) assert_scrubbed(@gateway.options[:secret_api_key], transcript) end - end diff --git a/test/remote/gateways/remote_global_transport_test.rb b/test/remote/gateways/remote_global_transport_test.rb index eac5264fe9c..22ca103956f 100644 --- a/test/remote/gateways/remote_global_transport_test.rb +++ b/test/remote/gateways/remote_global_transport_test.rb @@ -9,7 +9,7 @@ def setup @options = { email: 'john@example.com', order_id: '1', - billing_address: address, + billing_address: address } end @@ -137,5 +137,4 @@ def test_transcript_scrubbing assert_scrubbed(@credit_card.verification_value, transcript) assert_scrubbed(@gateway.options[:global_password], transcript) end - end diff --git a/test/remote/gateways/remote_hdfc_test.rb b/test/remote/gateways/remote_hdfc_test.rb index e3f2ed395d5..2b92b92fea6 100644 --- a/test/remote/gateways/remote_hdfc_test.rb +++ b/test/remote/gateways/remote_hdfc_test.rb @@ -11,12 +11,12 @@ def setup # Use an American Express card to simulate a failure since HDFC does not # support any proper decline cards outside of 3D secure failures. - @declined_card = credit_card('377182068239368', :brand => :american_express) + @declined_card = credit_card('377182068239368', brand: :american_express) @options = { - :order_id => generate_unique_id, - :billing_address => address, - :description => 'Store Purchase' + order_id: generate_unique_id, + billing_address: address, + description: 'Store Purchase' } end @@ -61,15 +61,15 @@ def test_successful_refund end def test_passing_billing_address - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:billing_address => address)) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(billing_address: address)) assert_success response end def test_invalid_login gateway = HdfcGateway.new( - :login => '', - :password => '' - ) + login: '', + password: '' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'TranPortal ID required.', response.message diff --git a/test/remote/gateways/remote_hps_test.rb b/test/remote/gateways/remote_hps_test.rb index 832d73703a9..485a0c82fdd 100644 --- a/test/remote/gateways/remote_hps_test.rb +++ b/test/remote/gateways/remote_hps_test.rb @@ -3,10 +3,13 @@ class RemoteHpsTest < Test::Unit::TestCase def setup @gateway = HpsGateway.new(fixtures(:hps)) + @check_gateway = HpsGateway.new(fixtures(:hps_echeck)) @amount = 100 + @check_amount = 2000 @declined_amount = 1034 @credit_card = credit_card('4000100011112224') + @check = check(account_number: '1357902468', routing_number: '122000030', number: '1234', account_type: 'SAVINGS') @options = { order_id: '1', @@ -21,6 +24,13 @@ def test_successful_purchase assert_equal 'Success', response.message end + def test_successful_check_purchase + options = @options.merge(company_name: 'Hot Buttered Toast Incorporated') + response = @check_gateway.purchase(@check_amount, @check, options) + assert_success response + assert_equal 'Success', response.message + end + def test_successful_purchase_without_cardholder response = @gateway.purchase(@amount, @credit_card) assert_success response @@ -97,7 +107,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -106,7 +116,7 @@ def test_failed_capture assert_failure response end - def test_successful_refund + def test_successful_purchase_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase @@ -116,11 +126,37 @@ def test_successful_refund assert_equal '0', refund.params['GatewayRspCode'] end - def test_partial_refund + def test_successful_capture_refund + auth = @gateway.authorize(@amount, @credit_card, @options) + assert_success auth + + assert capture = @gateway.capture(nil, auth.authorization) + assert_success capture + + assert refund = @gateway.refund(@amount, capture.authorization) + assert_success refund + assert_equal 'Success', refund.params['GatewayRspMsg'] + assert_equal '0', refund.params['GatewayRspCode'] + end + + def test_partial_purchase_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) + assert_success refund + assert_equal 'Success', refund.params['GatewayRspMsg'] + assert_equal '0', refund.params['GatewayRspCode'] + end + + def test_partial_capture_refund + auth = @gateway.authorize(@amount, @credit_card, @options) + assert_success auth + + assert capture = @gateway.capture(nil, auth.authorization) + assert_success capture + + assert refund = @gateway.refund(@amount - 1, capture.authorization) assert_success refund assert_equal 'Success', refund.params['GatewayRspMsg'] assert_equal '0', refund.params['GatewayRspCode'] @@ -131,6 +167,17 @@ def test_failed_refund assert_failure response end + def test_successful_credit + credit = @gateway.credit(@amount, @credit_card, @options) + assert_success credit + assert_equal 'Success', credit.params['GatewayRspMsg'] + end + + def test_failed_credit + credit = @gateway.credit(nil, @credit_card) + assert_failure credit + end + def test_successful_void auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth @@ -140,6 +187,16 @@ def test_successful_void assert_equal 'Success', void.params['GatewayRspMsg'] end + def test_successful_check_void + options = @options.merge(company_name: 'Hot Buttered Toast Incorporated') + purchase = @check_gateway.purchase(@check_amount, @check, options) + assert_success purchase + + assert void = @check_gateway.void(purchase.authorization, @options.merge(check_void: true)) + assert_success void + assert_equal 'Success', void.params['GatewayRspMsg'] + end + def test_failed_void response = @gateway.void('123') assert_failure response @@ -207,6 +264,31 @@ def test_successful_purchase_with_swipe_no_encryption assert_equal 'Success', response.message end + def test_successful_purchase_with_stored_credentials + initial_options = @options.merge( + stored_credential: { + initial_transaction: true, + reason_type: 'recurring' + } + ) + initial_response = @gateway.purchase(@amount, @credit_card, initial_options) + assert_success initial_response + assert_equal 'Success', initial_response.message + assert_not_nil initial_response.params['CardBrandTxnId'] + network_transaction_id = initial_response.params['CardBrandTxnId'] + + used_options = @options.merge( + stored_credential: { + initial_transaction: false, + reason_type: 'unscheduled', + network_transaction_id: network_transaction_id + } + ) + response = @gateway.purchase(@amount, @credit_card, used_options) + assert_success response + assert_equal 'Success', response.message + end + def test_failed_purchase_with_swipe_bad_track_data @credit_card.track_data = '%B547888879888877776?;?' response = @gateway.purchase(@amount, @credit_card, @options) @@ -235,6 +317,13 @@ def test_successful_purchase_with_swipe_encryption_type_02 assert_equal 'Success', response.message end + def test_successful_purchase_with_truncated_invoicenbr + response = @gateway.purchase(@amount, @credit_card, @options.merge(order_id: '04863692e6b56aaed85760b3d0879afd18b980da0521f6454c007a838435e561')) + + assert_success response + assert_equal 'Success', response.message + end + def tests_successful_verify response = @gateway.verify(@credit_card, @options) @@ -267,8 +356,7 @@ def test_transcript_scrubbing_with_cryptogram payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', verification_value: nil, eci: '05', - source: :apple_pay - ) + source: :apple_pay) transcript = capture_transcript(@gateway) do @gateway.purchase(@amount, credit_card, @options) end @@ -284,8 +372,7 @@ def test_successful_purchase_with_apple_pay_raw_cryptogram_with_eci payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', verification_value: nil, eci: '05', - source: :apple_pay - ) + source: :apple_pay) assert response = @gateway.purchase(@amount, credit_card, @options) assert_success response assert_equal 'Success', response.message @@ -295,8 +382,7 @@ def test_successful_purchase_with_apple_pay_raw_cryptogram_without_eci credit_card = network_tokenization_credit_card('4242424242424242', payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', verification_value: nil, - source: :apple_pay - ) + source: :apple_pay) assert response = @gateway.purchase(@amount, credit_card, @options) assert_success response assert_equal 'Success', response.message @@ -307,8 +393,7 @@ def test_successful_auth_with_apple_pay_raw_cryptogram_with_eci payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', verification_value: nil, eci: '05', - source: :apple_pay - ) + source: :apple_pay) assert response = @gateway.authorize(@amount, credit_card, @options) assert_success response assert_equal 'Success', response.message @@ -318,8 +403,91 @@ def test_successful_auth_with_apple_pay_raw_cryptogram_without_eci credit_card = network_tokenization_credit_card('4242424242424242', payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', verification_value: nil, - source: :apple_pay - ) + source: :apple_pay) + assert response = @gateway.authorize(@amount, credit_card, @options) + assert_success response + assert_equal 'Success', response.message + end + + def test_successful_purchase_with_android_pay_raw_cryptogram_with_eci + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + eci: '05', + source: :android_pay) + assert response = @gateway.purchase(@amount, credit_card, @options) + assert_success response + assert_equal 'Success', response.message + end + + def test_successful_purchase_with_android_pay_raw_cryptogram_without_eci + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + source: :android_pay) + assert response = @gateway.purchase(@amount, credit_card, @options) + assert_success response + assert_equal 'Success', response.message + end + + def test_successful_auth_with_android_pay_raw_cryptogram_with_eci + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + eci: '05', + source: :android_pay) + assert response = @gateway.authorize(@amount, credit_card, @options) + assert_success response + assert_equal 'Success', response.message + end + + def test_successful_auth_with_android_pay_raw_cryptogram_without_eci + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + source: :android_pay) + assert response = @gateway.authorize(@amount, credit_card, @options) + assert_success response + assert_equal 'Success', response.message + end + + def test_successful_purchase_with_google_pay_raw_cryptogram_with_eci + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + eci: '05', + source: :google_pay) + assert response = @gateway.purchase(@amount, credit_card, @options) + assert_success response + assert_equal 'Success', response.message + end + + def test_successful_purchase_with_google_pay_raw_cryptogram_without_eci + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + source: :google_pay) + assert response = @gateway.purchase(@amount, credit_card, @options) + assert_success response + assert_equal 'Success', response.message + end + + def test_successful_auth_with_google_pay_raw_cryptogram_with_eci + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + eci: '05', + source: :google_pay) + assert response = @gateway.authorize(@amount, credit_card, @options) + assert_success response + assert_equal 'Success', response.message + end + + def test_successful_auth_with_google_pay_raw_cryptogram_without_eci + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + source: :google_pay) assert response = @gateway.authorize(@amount, credit_card, @options) assert_success response assert_equal 'Success', response.message @@ -330,10 +498,10 @@ def test_three_d_secure_visa @credit_card.brand = 'visa' options = { - :three_d_secure => { - :cavv => 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', - :eci => '05', - :xid => 'TTBCSkVTa1ZpbDI1bjRxbGk5ODE=' + three_d_secure: { + cavv: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + eci: '05', + xid: 'TTBCSkVTa1ZpbDI1bjRxbGk5ODE=' } } @@ -347,10 +515,10 @@ def test_three_d_secure_mastercard @credit_card.brand = 'master' options = { - :three_d_secure => { - :cavv => 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', - :eci => '05', - :xid => 'TTBCSkVTa1ZpbDI1bjRxbGk5ODE=' + three_d_secure: { + cavv: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + eci: '05', + xid: 'TTBCSkVTa1ZpbDI1bjRxbGk5ODE=' } } @@ -364,10 +532,10 @@ def test_three_d_secure_discover @credit_card.brand = 'discover' options = { - :three_d_secure => { - :cavv => 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', - :eci => '05', - :xid => 'TTBCSkVTa1ZpbDI1bjRxbGk5ODE=' + three_d_secure: { + cavv: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + eci: '05', + xid: 'TTBCSkVTa1ZpbDI1bjRxbGk5ODE=' } } @@ -381,10 +549,10 @@ def test_three_d_secure_amex @credit_card.brand = 'american_express' options = { - :three_d_secure => { - :cavv => 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', - :eci => '05', - :xid => 'TTBCSkVTa1ZpbDI1bjRxbGk5ODE=' + three_d_secure: { + cavv: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + eci: '05', + xid: 'TTBCSkVTa1ZpbDI1bjRxbGk5ODE=' } } @@ -398,10 +566,10 @@ def test_three_d_secure_jcb @credit_card.brand = 'jcb' options = { - :three_d_secure => { - :cavv => 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', - :eci => '05', - :xid => 'TTBCSkVTa1ZpbDI1bjRxbGk5ODE=' + three_d_secure: { + cavv: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + eci: '05', + xid: 'TTBCSkVTa1ZpbDI1bjRxbGk5ODE=' } } diff --git a/test/remote/gateways/remote_iats_payments_test.rb b/test/remote/gateways/remote_iats_payments_test.rb index 34d604b7b92..f7b4bfe2ec1 100644 --- a/test/remote/gateways/remote_iats_payments_test.rb +++ b/test/remote/gateways/remote_iats_payments_test.rb @@ -9,9 +9,14 @@ def setup @credit_card = credit_card('4222222222222220') @check = check(routing_number: '111111111', account_number: '12345678') @options = { - :order_id => generate_unique_id, - :billing_address => address, - :description => 'Store purchase' + order_id: generate_unique_id, + billing_address: address, + description: 'Store purchase' + } + @customer_details = { + phone: '5555555555', + email: 'test@example.com', + country: 'US' } end @@ -23,6 +28,14 @@ def test_successful_purchase assert response.authorization end + def test_successful_purchase_with_customer_details + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(@customer_details)) + assert_success response + assert response.test? + assert_equal 'Success', response.message + assert response.authorization + end + def test_failed_purchase credit_card = credit_card('4111111111111111') assert response = @gateway.purchase(200, credit_card, @options) @@ -61,7 +74,7 @@ def test_failed_refund purchase = @gateway.purchase(@amount, credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount, purchase.authorization) + assert refund = @gateway.refund(@amount + 50, purchase.authorization) assert_failure refund end @@ -71,11 +84,8 @@ def test_successful_check_refund assert refund = @gateway.refund(@amount, purchase.authorization) - # This is a dubious test. Basically testing that the refund failed b/c - # the original purchase hadn't yet cleared. No way to test immediate failure - # due to the delay in original tx processing, even for text txs. - assert_failure refund - assert_equal 'REJECT: 3', refund.message + assert_success refund + assert_equal 'Success', refund.message end def test_failed_check_refund @@ -95,6 +105,21 @@ def test_successful_store_and_unstore assert_equal 'Success', unstore.message end + def test_successful_store_and_purchase_and_refund + assert store = @gateway.store(@credit_card, @options) + assert_success store + assert store.authorization + assert_equal 'Success', store.message + + assert purchase = @gateway.purchase(@amount, store.authorization, @options) + assert_success purchase + assert purchase.authorization + assert_equal 'Success', purchase.message + + assert refund = @gateway.refund(@amount, purchase.authorization) + assert_success refund + end + def test_failed_store credit_card = credit_card('4111') assert store = @gateway.store(credit_card, @options) @@ -104,9 +129,9 @@ def test_failed_store def test_invalid_login gateway = IatsPaymentsGateway.new( - :agent_code => 'X', - :password => 'Y', - :region => 'na' + agent_code: 'X', + password: 'Y', + region: 'na' ) assert response = gateway.purchase(@amount, @credit_card) @@ -136,5 +161,4 @@ def test_check_purchase_scrubbing assert_scrubbed(@gateway.options[:agent_code], transcript) assert_scrubbed(@gateway.options[:password], transcript) end - end diff --git a/test/remote/gateways/remote_inspire_test.rb b/test/remote/gateways/remote_inspire_test.rb index 4e137b4d3ff..7541d44aa2a 100644 --- a/test/remote/gateways/remote_inspire_test.rb +++ b/test/remote/gateways/remote_inspire_test.rb @@ -5,11 +5,10 @@ def setup @gateway = InspireGateway.new(fixtures(:inspire)) @amount = rand(1001..11000) - @credit_card = credit_card('4111111111111111', :brand => 'visa') + @credit_card = credit_card('4111111111111111', brand: 'visa') @declined_amount = rand(99) - @options = { :order_id => generate_unique_id, - :billing_address => address - } + @options = { order_id: generate_unique_id, + billing_address: address } end def test_successful_purchase @@ -20,12 +19,12 @@ def test_successful_purchase def test_successful_purchase_with_echeck check = ActiveMerchant::Billing::Check.new( - :name => 'Fredd Bloggs', - :routing_number => '111000025', # Valid ABA # - Bank of America, TX - :account_number => '999999999999', - :account_holder_type => 'personal', - :account_type => 'checking' - ) + name: 'Fredd Bloggs', + routing_number: '111000025', # Valid ABA # - Bank of America, TX + account_number: '999999999999', + account_holder_type: 'personal', + account_type: 'checking' + ) response = @gateway.purchase(@amount, check, @options) assert_success response assert_equal 'This transaction has been approved', response.message @@ -51,7 +50,7 @@ def test_successful_add_to_vault_and_use assert_equal 'This transaction has been approved', response.message assert_not_nil customer_id = response.params['customer_vault_id'] - second_response = @gateway.purchase(@amount*2, customer_id, @options) + second_response = @gateway.purchase(@amount * 2, customer_id, @options) assert_equal 'This transaction has been approved', second_response.message assert_success second_response end @@ -74,7 +73,7 @@ def test_add_to_vault_with_custom_vault_id_with_store_method def test_update_vault test_add_to_vault_with_custom_vault_id - @credit_card = credit_card('4111111111111111', :month => 10) + @credit_card = credit_card('4111111111111111', month: 10) response = @gateway.update(@options[:store], @credit_card) assert_success response assert_equal 'Customer Update Successful', response.message @@ -140,7 +139,7 @@ def test_partial_refund response = @gateway.purchase(@amount, @credit_card) assert_success response - response = @gateway.refund(@amount-500, response.authorization) + response = @gateway.refund(@amount - 500, response.authorization) assert_success response end @@ -151,9 +150,9 @@ def test_failed_refund def test_invalid_login gateway = InspireGateway.new( - :login => '', - :password => '' - ) + login: '', + password: '' + ) response = gateway.purchase(@amount, @credit_card, @options) assert_equal 'Invalid Username', response.message assert_failure response diff --git a/test/remote/gateways/remote_instapay_test.rb b/test/remote/gateways/remote_instapay_test.rb index 5a8286cf234..3565cfaaae8 100644 --- a/test/remote/gateways/remote_instapay_test.rb +++ b/test/remote/gateways/remote_instapay_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class RemoteInstapayTest < Test::Unit::TestCase - def setup @gateway = InstapayGateway.new(fixtures(:instapay)) @@ -10,10 +9,10 @@ def setup @declined_card = credit_card('4000300011112220') @options = { - :order_id => generate_unique_id, - :billing_address => address, - :shipping_address => address, - :description => 'Store Purchase' + order_id: generate_unique_id, + billing_address: address, + shipping_address: address, + description: 'Store Purchase' } end @@ -24,12 +23,12 @@ def test_successful_purchase end def test_failed_purchase - assert response = @gateway.purchase(@amount, @declined_card, @options) + assert response = @gateway.purchase(@amount, @declined_card, @options) assert_failure response end def test_succesful_authorization - assert response = @gateway.authorize(@amount, @credit_card, @options) + assert response = @gateway.authorize(@amount, @credit_card, @options) assert_success response assert_equal InstapayGateway::SUCCESS_MESSAGE, response.message end @@ -50,8 +49,8 @@ def test_authorization_and_capture def test_invalid_login gateway = InstapayGateway.new( - :login => 'X', - :password => 'Y' + login: 'X', + password: 'Y' ) assert response = gateway.purchase(@amount, @credit_card) diff --git a/test/remote/gateways/remote_ipp_test.rb b/test/remote/gateways/remote_ipp_test.rb index f7e62cad46b..443e7b186eb 100644 --- a/test/remote/gateways/remote_ipp_test.rb +++ b/test/remote/gateways/remote_ipp_test.rb @@ -9,7 +9,7 @@ def setup @options = { order_id: '1', billing_address: address, - description: 'Store Purchase', + description: 'Store Purchase' } end diff --git a/test/remote/gateways/remote_iridium_test.rb b/test/remote/gateways/remote_iridium_test.rb index dc033cabe3a..24460d4c943 100644 --- a/test/remote/gateways/remote_iridium_test.rb +++ b/test/remote/gateways/remote_iridium_test.rb @@ -7,21 +7,21 @@ def setup @gateway = IridiumGateway.new(fixtures(:iridium)) @amount = 100 - @avs_card = credit_card('4921810000005462', {:verification_value => '441'}) - @cv2_card = credit_card('4976000000003436', {:verification_value => '777'}) - @avs_cv2_card = credit_card('4921810000005462', {:verification_value => '777'}) - @credit_card = credit_card('4976000000003436', {:verification_value => '452'}) + @avs_card = credit_card('4921810000005462', { verification_value: '441' }) + @cv2_card = credit_card('4976000000003436', { verification_value: '777' }) + @avs_cv2_card = credit_card('4921810000005462', { verification_value: '777' }) + @credit_card = credit_card('4976000000003436', { verification_value: '452' }) @declined_card = credit_card('4221690000004963') - our_address = address(:address1 => '32 Edward Street', - :address2 => 'Camborne', - :state => 'Cornwall', - :zip => 'TR14 8PA', - :country => '826') + our_address = address(address1: '32 Edward Street', + address2: 'Camborne', + state: 'Cornwall', + zip: 'TR14 8PA', + country: '826') @options = { - :order_id => generate_unique_id, - :billing_address => our_address, - :description => 'Store Purchase' + order_id: generate_unique_id, + billing_address: our_address, + description: 'Store Purchase' } end @@ -111,7 +111,7 @@ def test_successful_purchase_by_reference assert_success response assert(reference = response.authorization) - assert response = @gateway.purchase(@amount, reference, {:order_id => generate_unique_id}) + assert response = @gateway.purchase(@amount, reference, { order_id: generate_unique_id }) assert_success response end @@ -120,7 +120,7 @@ def test_failed_purchase_by_reference assert_success response assert response.authorization - assert response = @gateway.purchase(@amount, 'bogusref', {:order_id => generate_unique_id}) + assert response = @gateway.purchase(@amount, 'bogusref', { order_id: generate_unique_id }) assert_failure response end @@ -129,7 +129,7 @@ def test_successful_authorize_by_reference assert_success response assert(reference = response.authorization) - assert response = @gateway.authorize(@amount, reference, {:order_id => generate_unique_id}) + assert response = @gateway.authorize(@amount, reference, { order_id: generate_unique_id }) assert_success response end @@ -145,7 +145,7 @@ def test_failed_credit assert response = @gateway.purchase(@amount, @credit_card, @options) assert_success response - assert response = @gateway.credit(@amount*2, response.authorization) + assert response = @gateway.credit(@amount * 2, response.authorization) assert_failure response end @@ -164,9 +164,9 @@ def test_failed_void def test_invalid_login gateway = IridiumGateway.new( - :login => '', - :password => '' - ) + login: '', + password: '' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response diff --git a/test/remote/gateways/remote_itransact_test.rb b/test/remote/gateways/remote_itransact_test.rb index d949b17232d..55fafbb0388 100644 --- a/test/remote/gateways/remote_itransact_test.rb +++ b/test/remote/gateways/remote_itransact_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class RemoteItransactTest < Test::Unit::TestCase - def setup @gateway = ItransactGateway.new(fixtures(:itransact)) @@ -10,9 +9,9 @@ def setup @declined_card = credit_card('4000300011112220') @options = { - :order_id => '1', - :billing_address => address, - :description => 'Store Purchase' + order_id: '1', + billing_address: address, + description: 'Store Purchase' } end @@ -77,10 +76,10 @@ def test_refund_partial def test_invalid_login gateway = ItransactGateway.new( - :login => 'x', - :password => 'x', - :gateway_id => 'x' - ) + login: 'x', + password: 'x', + gateway_id: 'x' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'Invalid login credentials', response.message diff --git a/test/remote/gateways/remote_iveri_test.rb b/test/remote/gateways/remote_iveri_test.rb index 16733284a46..2b6ed046705 100644 --- a/test/remote/gateways/remote_iveri_test.rb +++ b/test/remote/gateways/remote_iveri_test.rb @@ -73,7 +73,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -96,7 +96,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund end @@ -124,6 +124,10 @@ def test_failed_void def test_successful_verify response = @gateway.verify(@credit_card, @options) assert_success response + assert_equal 'Authorisation', response.responses[0].params['transaction_command'] + assert_equal '0', response.responses[0].params['result_status'] + assert_equal 'Void', response.responses[1].params['transaction_command'] + assert_equal '0', response.responses[1].params['result_status'] assert_equal 'Succeeded', response.message end @@ -160,5 +164,4 @@ def test_transcript_scrubbing assert_scrubbed(@credit_card.verification_value, transcript) assert_scrubbed(@gateway.options[:cert_id], transcript) end - end diff --git a/test/remote/gateways/remote_ixopay_test.rb b/test/remote/gateways/remote_ixopay_test.rb new file mode 100644 index 00000000000..b695de1a0e1 --- /dev/null +++ b/test/remote/gateways/remote_ixopay_test.rb @@ -0,0 +1,248 @@ +require 'test_helper' + +class RemoteIxopayTest < Test::Unit::TestCase + def setup + @gateway = IxopayGateway.new(fixtures(:ixopay)) + + @amount = 100 + @credit_card = credit_card('4111111111111111') + @declined_card = credit_card('4000300011112220') + + @options = { + billing_address: address, + shipping_address: address, + email: 'test@example.com', + description: 'Store Purchase', + ip: '192.168.1.1', + stored_credential: stored_credential(:initial) + } + + @extra_data = { extra_data: { customData1: 'some data', customData2: 'Can be anything really' } } + end + + def test_successful_purchase + response = @gateway.purchase(@amount, @credit_card, @options) + + assert_success response + assert_equal 'FINISHED', response.message + assert_match(/[0-9a-zA-Z]+(|[0-9a-zA-Z]+)*/, response.authorization) + + assert_equal @credit_card.name, response.params.dig('return_data', 'creditcard_data', 'card_holder') + assert_equal '%02d' % @credit_card.month, response.params.dig('return_data', 'creditcard_data', 'expiry_month') + assert_equal @credit_card.year.to_s, response.params.dig('return_data', 'creditcard_data', 'expiry_year') + assert_equal @credit_card.number[0..5], response.params.dig('return_data', 'creditcard_data', 'first_six_digits') + assert_equal @credit_card.number.split(//).last(4).join, response.params.dig('return_data', 'creditcard_data', 'last_four_digits') + assert_equal 'FINISHED', response.params['return_type'] + + assert_not_nil response.params['purchase_id'] + assert_not_nil response.params['reference_id'] + end + + def test_successful_purchase_with_extra_data + response = @gateway.purchase(@amount, @credit_card, @options.merge(@extra_data)) + assert_success response + assert_equal 'FINISHED', response.message + assert_match(/[0-9a-zA-Z]+(|[0-9a-zA-Z]+)*/, response.authorization) + + assert_equal @credit_card.name, response.params.dig('return_data', 'creditcard_data', 'card_holder') + assert_equal '%02d' % @credit_card.month, response.params.dig('return_data', 'creditcard_data', 'expiry_month') + assert_equal @credit_card.year.to_s, response.params.dig('return_data', 'creditcard_data', 'expiry_year') + assert_equal @credit_card.number[0..5], response.params.dig('return_data', 'creditcard_data', 'first_six_digits') + assert_equal @credit_card.number.split(//).last(4).join, response.params.dig('return_data', 'creditcard_data', 'last_four_digits') + assert_equal 'FINISHED', response.params['return_type'] + + assert_not_nil response.params['purchase_id'] + assert_not_nil response.params['reference_id'] + end + + def test_failed_purchase + response = @gateway.purchase(@amount, @declined_card, {}) + + assert_failure response + assert_equal 'The transaction was declined', response.message + assert_equal '2003', response.error_code + end + + def test_failed_authentication + gateway = IxopayGateway.new( + username: 'baduser', + password: 'badpass', + secret: 'badsecret', + api_key: 'badapikey' + ) + + response = gateway.purchase(@amount, @credit_card, {}) + + assert_failure response + + assert_equal 'Invalid Signature', response.message + assert_equal '9999', response.error_code + end + + def test_successful_authorize_and_capture + auth = @gateway.authorize(@amount, @credit_card, @options) + + assert_success auth + assert_equal 'FINISHED', auth.message + assert_not_nil auth.params['purchase_id'] + assert_not_nil auth.params['reference_id'] + assert_not_nil auth.authorization + + assert capture = @gateway.capture(@amount, auth.authorization) + assert_success capture + assert_equal 'FINISHED', capture.message + end + + def test_successful_authorize_and_capture_with_extra_data + auth = @gateway.authorize(@amount, @credit_card, @options.merge(@extra_data)) + + assert_success auth + assert_equal 'FINISHED', auth.message + assert_not_nil auth.params['purchase_id'] + assert_not_nil auth.params['reference_id'] + assert_not_nil auth.authorization + + assert capture = @gateway.capture(@amount, auth.authorization) + assert_success capture + assert_equal 'FINISHED', capture.message + end + + def test_partial_capture + auth = @gateway.authorize(@amount, @credit_card, @options) + assert_success auth + + assert capture = @gateway.capture(@amount - 1, auth.authorization) + assert_success capture + assert_equal 'FINISHED', capture.message + end + + def test_partial_capture_with_extra_data + auth = @gateway.authorize(@amount, @credit_card, @options.merge(@extra_data)) + assert_success auth + + assert capture = @gateway.capture(@amount - 1, auth.authorization) + assert_success capture + assert_equal 'FINISHED', capture.message + end + + def test_failed_authorize + response = @gateway.authorize(@amount, @declined_card, @options) + assert_failure response + assert_equal 'The transaction was declined', response.message + assert_equal 'ERROR', response.params['return_type'] + assert_equal response.error_code, '2003' + end + + def test_failed_capture + response = @gateway.capture(@amount, nil) + + assert_failure response + assert_equal 'Transaction of type "capture" requires a referenceTransactionId', response.message + end + + def test_successful_refund + options = @options.update(currency: 'USD') + + purchase = @gateway.purchase(@amount, @credit_card, options) + assert_success purchase + + assert refund = @gateway.refund(@amount, purchase.authorization, options) + assert_success refund + assert_equal 'FINISHED', refund.message + end + + def test_successful_refund_with_extra_data + options = @options.update(currency: 'USD') + + purchase = @gateway.purchase(@amount, @credit_card, options.merge(@extra_data)) + assert_success purchase + + assert refund = @gateway.refund(@amount, purchase.authorization, options) + assert_success refund + assert_equal 'FINISHED', refund.message + end + + def test_partial_refund + purchase = @gateway.purchase(@amount, @credit_card, @options) + assert_success purchase + + assert refund = @gateway.refund(@amount - 1, purchase.authorization) + assert_success refund + end + + def test_partial_refund_with_extra_data + purchase = @gateway.purchase(@amount, @credit_card, @options.merge(@extra_data)) + assert_success purchase + + assert refund = @gateway.refund(@amount - 1, purchase.authorization) + assert_success refund + end + + def test_failed_refund + response = @gateway.refund(@amount, nil) + assert_failure response + assert_equal 'Transaction of type "refund" requires a referenceTransactionId', response.message + end + + def test_successful_void + auth = @gateway.authorize(@amount, @credit_card, @options) + assert_success auth + + assert void = @gateway.void(auth.authorization) + assert_success void + assert_equal 'FINISHED', void.message + end + + def test_successful_void_with_extra_data + auth = @gateway.authorize(@amount, @credit_card, @options.merge(@extra_data)) + assert_success auth + + assert void = @gateway.void(auth.authorization) + assert_success void + assert_equal 'FINISHED', void.message + end + + def test_failed_void + response = @gateway.void('') + assert_failure response + assert_equal 'Transaction of type "void" requires a referenceTransactionId', response.message + end + + def test_successful_verify + response = @gateway.verify(@credit_card, @options) + assert_success response + assert_match %r{FINISHED}, response.message + end + + def test_successful_verify_with_extra_data + response = @gateway.verify(@credit_card, @options.merge(@extra_data)) + assert_success response + assert_match %r{FINISHED}, response.message + end + + def test_failed_verify + response = @gateway.verify(@declined_card, @options) + assert_failure response + assert_match %r{The transaction was declined}, response.message + end + + def test_invalid_login + gateway = IxopayGateway.new(username: '', password: '', secret: '', api_key: '') + + response = gateway.purchase(@amount, @credit_card, @options) + assert_failure response + assert_match %r{Invalid Signature: Invalid authorization header}, response.message + end + + def test_transcript_scrubbing + transcript = capture_transcript(@gateway) do + @gateway.purchase(@amount, @credit_card, @options) + end + + transcript = @gateway.scrub(transcript) + + assert_scrubbed(@credit_card.number, transcript) + assert_scrubbed(@credit_card.verification_value, transcript) + assert_scrubbed(@gateway.options[:password], transcript) + end +end diff --git a/test/remote/gateways/remote_jetpay_test.rb b/test/remote/gateways/remote_jetpay_test.rb index d5d331a72f1..7f4a38c2539 100644 --- a/test/remote/gateways/remote_jetpay_test.rb +++ b/test/remote/gateways/remote_jetpay_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class RemoteJetpayTest < Test::Unit::TestCase - def setup @gateway = JetpayGateway.new(fixtures(:jetpay)) @@ -9,12 +8,12 @@ def setup @declined_card = credit_card('4000300020001000') @options = { - :billing_address => address(:country => 'US', :zip => '75008'), - :shipping_address => address(:country => 'US'), - :email => 'test@test.com', - :ip => '127.0.0.1', - :order_id => '12345', - :tax => 7 + billing_address: address(country: 'US', zip: '75008'), + shipping_address: address(country: 'US'), + email: 'test@test.com', + ip: '127.0.0.1', + order_id: '12345', + tax: 7 } end @@ -33,7 +32,7 @@ def test_unsuccessful_purchase end def test_successful_purchase_with_origin - assert response = @gateway.purchase(9900, @credit_card, {:origin => 'RECURRING'}) + assert response = @gateway.purchase(9900, @credit_card, { origin: 'RECURRING' }) assert_success response assert_equal 'APPROVED', response.message assert_not_nil response.authorization @@ -123,7 +122,7 @@ def test_capture_refund_with_token def test_refund_backwards_compatible # no need for csv - card = credit_card('4242424242424242', :verification_value => nil) + card = credit_card('4242424242424242', verification_value: nil) assert response = @gateway.purchase(9900, card, @options) assert_success response @@ -134,7 +133,7 @@ def test_refund_backwards_compatible old_authorization = [response.params['transaction_id'], response.params['approval'], 9900].join(';') # linked to a specific transaction_id - assert credit = @gateway.refund(9900, old_authorization, :credit_card => card) + assert credit = @gateway.refund(9900, old_authorization, credit_card: card) assert_success credit assert_not_nil(credit.authorization) assert_not_nil(response.params['approval']) @@ -143,7 +142,7 @@ def test_refund_backwards_compatible def test_credit # no need for csv - card = credit_card('4242424242424242', :verification_value => nil) + card = credit_card('4242424242424242', verification_value: nil) # no link to a specific transaction_id assert credit = @gateway.credit(9900, card) @@ -159,7 +158,7 @@ def test_failed_capture end def test_invalid_login - gateway = JetpayGateway.new(:login => 'bogus') + gateway = JetpayGateway.new(login: 'bogus') assert response = gateway.purchase(9900, @credit_card, @options) assert_failure response @@ -167,7 +166,7 @@ def test_invalid_login end def test_missing_login - gateway = JetpayGateway.new(:login => '') + gateway = JetpayGateway.new(login: '') assert response = gateway.purchase(9900, @credit_card, @options) assert_failure response diff --git a/test/remote/gateways/remote_jetpay_v2_certification_test.rb b/test/remote/gateways/remote_jetpay_v2_certification_test.rb index be182a8be37..a213fc82691 100644 --- a/test/remote/gateways/remote_jetpay_v2_certification_test.rb +++ b/test/remote/gateways/remote_jetpay_v2_certification_test.rb @@ -1,20 +1,19 @@ require 'test_helper' class RemoteJetpayV2CertificationTest < Test::Unit::TestCase - def setup @gateway = JetpayV2Gateway.new(fixtures(:jetpay_v2)) @unique_id = '' @options = { - :device => 'spreedly', - :application => 'spreedly', - :developer_id => 'GenkID', - :billing_address => address(:address1 => '1234 Fifth Street', :address2 => '', :city => 'Beaumont', :state => 'TX', :country => 'US', :zip => '77708'), - :shipping_address => address(:address1 => '1234 Fifth Street', :address2 => '', :city => 'Beaumont', :state => 'TX', :country => 'US', :zip => '77708'), - :email => 'test@test.com', - :ip => '127.0.0.1' + device: 'spreedly', + application: 'spreedly', + developer_id: 'GenkID', + billing_address: address(address1: '1234 Fifth Street', address2: '', city: 'Beaumont', state: 'TX', country: 'US', zip: '77708'), + shipping_address: address(address1: '1234 Fifth Street', address2: '', city: 'Beaumont', state: 'TX', country: 'US', zip: '77708'), + email: 'test@test.com', + ip: '127.0.0.1' } end @@ -25,7 +24,7 @@ def teardown def test_certification_cnp1_authorize_mastercard @options[:order_id] = 'CNP1' amount = 1000 - master = credit_card('5111111111111118', :month => 12, :year => 2017, :brand => 'master', :verification_value => '121') + master = credit_card('5111111111111118', month: 12, year: 2017, brand: 'master', verification_value: '121') assert response = @gateway.authorize(amount, master, @options) assert_success response assert_equal 'APPROVED', response.message @@ -35,7 +34,7 @@ def test_certification_cnp1_authorize_mastercard def test_certification_cnp2_authorize_visa @options[:order_id] = 'CNP2' amount = 1105 - visa = credit_card('4111111111111111', :month => 12, :year => 2017, :brand => 'visa', :verification_value => '121') + visa = credit_card('4111111111111111', month: 12, year: 2017, brand: 'visa', verification_value: '121') assert response = @gateway.authorize(amount, visa, @options) assert_failure response assert_equal 'Do not honor.', response.message @@ -45,7 +44,7 @@ def test_certification_cnp2_authorize_visa def test_certification_cnp3_cnp4_authorize_and_capture_amex @options[:order_id] = 'CNP3' amount = 1200 - amex = credit_card('378282246310005', :month => 12, :year => 2017, :brand => 'american_express', :verification_value => '1221') + amex = credit_card('378282246310005', month: 12, year: 2017, brand: 'american_express', verification_value: '1221') assert response = @gateway.authorize(amount, amex, @options) assert_success response assert_equal 'APPROVED', response.message @@ -61,7 +60,7 @@ def test_certification_cnp3_cnp4_authorize_and_capture_amex def test_certification_cnp5_purchase_discover @options[:order_id] = 'CNP5' amount = 1300 - discover = credit_card('6011111111111117', :month => 12, :year => 2017, :brand => 'discover', :verification_value => '121') + discover = credit_card('6011111111111117', month: 12, year: 2017, brand: 'discover', verification_value: '121') assert response = @gateway.purchase(amount, discover, @options) assert_success response assert_equal 'APPROVED', response.message @@ -71,7 +70,7 @@ def test_certification_cnp5_purchase_discover def test_certification_cnp6_purchase_visa @options[:order_id] = 'CNP6' amount = 1405 - visa = credit_card('4111111111111111', :month => 12, :year => 2017, :brand => 'visa', :verification_value => '120') + visa = credit_card('4111111111111111', month: 12, year: 2017, brand: 'visa', verification_value: '120') assert response = @gateway.purchase(amount, visa, @options) assert_failure response assert_equal 'Do not honor.', response.message @@ -81,7 +80,7 @@ def test_certification_cnp6_purchase_visa def test_certification_cnp7_authorize_mastercard @options[:order_id] = 'CNP7' amount = 1500 - master = credit_card('5111111111111118', :month => 12, :year => 2017, :brand => 'master', :verification_value => '120') + master = credit_card('5111111111111118', month: 12, year: 2017, brand: 'master', verification_value: '120') assert response = @gateway.authorize(amount, master, @options) assert_success response assert_equal 'APPROVED', response.message @@ -91,7 +90,7 @@ def test_certification_cnp7_authorize_mastercard def test_certification_cnp8_authorize_visa @options[:order_id] = 'CNP8' amount = 1605 - visa = credit_card('4111111111111111', :month => 12, :year => 2017, :brand => 'visa', :verification_value => '120') + visa = credit_card('4111111111111111', month: 12, year: 2017, brand: 'visa', verification_value: '120') assert response = @gateway.authorize(amount, visa, @options) assert_failure response assert_equal 'Do not honor.', response.message @@ -101,7 +100,7 @@ def test_certification_cnp8_authorize_visa def test_certification_cnp9_cnp10_authorize_and_capture_amex @options[:order_id] = 'CNP9' amount = 1700 - amex = credit_card('378282246310005', :month => 12, :year => 2017, :brand => 'american_express', :verification_value => '1220') + amex = credit_card('378282246310005', month: 12, year: 2017, brand: 'american_express', verification_value: '1220') assert response = @gateway.authorize(amount, amex, @options) assert_success response assert_equal 'APPROVED', response.message @@ -117,7 +116,7 @@ def test_certification_cnp9_cnp10_authorize_and_capture_amex def test_certification_cnp11_purchase_discover @options[:order_id] = 'CNP11' amount = 1800 - discover = credit_card('6011111111111117', :month => 12, :year => 2017, :brand => 'discover', :verification_value => '120') + discover = credit_card('6011111111111117', month: 12, year: 2017, brand: 'discover', verification_value: '120') assert response = @gateway.purchase(amount, discover, @options) assert_success response assert_equal 'APPROVED', response.message @@ -130,7 +129,7 @@ def test_certification_rec01_recurring_mastercard @options[:billing_address] = nil @options[:shipping_address] = nil amount = 2000 - master = credit_card('5111111111111118', :month => 12, :year => 2017, :brand => 'master', :verification_value => '120') + master = credit_card('5111111111111118', month: 12, year: 2017, brand: 'master', verification_value: '120') assert response = @gateway.purchase(amount, master, @options) assert_success response assert_equal 'APPROVED', response.message @@ -141,7 +140,7 @@ def test_certification_rec02_recurring_visa @options[:order_id] = 'REC02' @options[:origin] = 'RECURRING' amount = 2100 - visa = credit_card('4111111111111111', :month => 12, :year => 2017, :brand => 'visa', :verification_value => '') + visa = credit_card('4111111111111111', month: 12, year: 2017, brand: 'visa', verification_value: '') assert response = @gateway.purchase(amount, visa, @options) assert_success response assert_equal 'APPROVED', response.message @@ -152,7 +151,7 @@ def test_certification_rec03_recurring_amex @options[:order_id] = 'REC03' @options[:origin] = 'RECURRING' amount = 2200 - amex = credit_card('378282246310005', :month => 12, :year => 2017, :brand => 'american_express', :verification_value => '1221') + amex = credit_card('378282246310005', month: 12, year: 2017, brand: 'american_express', verification_value: '1221') assert response = @gateway.purchase(amount, amex, @options) assert_success response assert_equal 'APPROVED', response.message @@ -162,7 +161,7 @@ def test_certification_rec03_recurring_amex def test_certification_corp07_corp08_authorize_and_capture_discover @options[:order_id] = 'CORP07' amount = 2500 - discover = credit_card('6011111111111117', :month => 12, :year => 2018, :brand => 'discover', :verification_value => '120') + discover = credit_card('6011111111111117', month: 12, year: 2018, brand: 'discover', verification_value: '120') assert response = @gateway.authorize(amount, discover, @options) assert_success response assert_equal 'APPROVED', response.message @@ -170,7 +169,7 @@ def test_certification_corp07_corp08_authorize_and_capture_discover puts "\n#{@options[:order_id]}: #{@unique_id}" @options[:order_id] = 'CORP08' - assert response = @gateway.capture(amount, response.authorization, @options.merge(:tax_amount => '200')) + assert response = @gateway.capture(amount, response.authorization, @options.merge(tax_amount: '200')) assert_success response @unique_id = response.params['unique_id'] end @@ -178,7 +177,7 @@ def test_certification_corp07_corp08_authorize_and_capture_discover def test_certification_corp09_corp10_authorize_and_capture_visa @options[:order_id] = 'CORP09' amount = 5000 - visa = credit_card('4111111111111111', :month => 12, :year => 2018, :brand => 'visa', :verification_value => '120') + visa = credit_card('4111111111111111', month: 12, year: 2018, brand: 'visa', verification_value: '120') assert response = @gateway.authorize(amount, visa, @options) assert_success response assert_equal 'APPROVED', response.message @@ -186,7 +185,7 @@ def test_certification_corp09_corp10_authorize_and_capture_visa puts "\n#{@options[:order_id]}: #{@unique_id}" @options[:order_id] = 'CORP10' - assert response = @gateway.capture(amount, response.authorization, @options.merge(:tax_amount => '0', :tax_exempt => 'true')) + assert response = @gateway.capture(amount, response.authorization, @options.merge(tax_amount: '0', tax_exempt: 'true')) assert_success response @unique_id = response.params['unique_id'] end @@ -194,7 +193,7 @@ def test_certification_corp09_corp10_authorize_and_capture_visa def test_certification_corp11_corp12_authorize_and_capture_mastercard @options[:order_id] = 'CORP11' amount = 7500 - master = credit_card('5111111111111118', :month => 12, :year => 2018, :brand => 'master', :verification_value => '120') + master = credit_card('5111111111111118', month: 12, year: 2018, brand: 'master', verification_value: '120') assert response = @gateway.authorize(amount, master, @options) assert_success response assert_equal 'APPROVED', response.message @@ -202,7 +201,7 @@ def test_certification_corp11_corp12_authorize_and_capture_mastercard puts "\n#{@options[:order_id]}: #{@unique_id}" @options[:order_id] = 'CORP12' - assert response = @gateway.capture(amount, response.authorization, @options.merge(:tax_amount => '0', :tax_exempt => 'false', :purchase_order => '456456')) + assert response = @gateway.capture(amount, response.authorization, @options.merge(tax_amount: '0', tax_exempt: 'false', purchase_order: '456456')) assert_success response @unique_id = response.params['unique_id'] end @@ -210,7 +209,7 @@ def test_certification_corp11_corp12_authorize_and_capture_mastercard def test_certification_cred02_credit_visa @options[:order_id] = 'CRED02' amount = 100 - visa = credit_card('4111111111111111', :month => 12, :year => 2017, :brand => 'visa', :verification_value => '120') + visa = credit_card('4111111111111111', month: 12, year: 2017, brand: 'visa', verification_value: '120') assert response = @gateway.credit(amount, visa, @options) assert_success response assert_equal 'APPROVED', response.message @@ -220,7 +219,7 @@ def test_certification_cred02_credit_visa def test_certification_cred03_credit_amex @options[:order_id] = 'CRED03' amount = 200 - amex = credit_card('378282246310005', :month => 12, :year => 2017, :brand => 'american_express', :verification_value => '1220') + amex = credit_card('378282246310005', month: 12, year: 2017, brand: 'american_express', verification_value: '1220') assert response = @gateway.credit(amount, amex, @options) assert_success response assert_equal 'APPROVED', response.message @@ -230,7 +229,7 @@ def test_certification_cred03_credit_amex def test_certification_void03_void04_purchase_void_visa @options[:order_id] = 'VOID03' amount = 300 - visa = credit_card('4111111111111111', :month => 12, :year => 2017, :brand => 'visa', :verification_value => '120') + visa = credit_card('4111111111111111', month: 12, year: 2017, brand: 'visa', verification_value: '120') assert response = @gateway.purchase(amount, visa, @options) assert_success response assert_equal 'APPROVED', response.message @@ -249,7 +248,7 @@ def test_certification_void03_void04_purchase_void_visa def test_certification_void07_void08_void09_authorize_capture_void_discover @options[:order_id] = 'VOID07' amount = 400 - discover = credit_card('6011111111111117', :month => 12, :year => 2017, :brand => 'discover', :verification_value => '120') + discover = credit_card('6011111111111117', month: 12, year: 2017, brand: 'discover', verification_value: '120') assert response = @gateway.authorize(amount, discover, @options) assert_success response assert_equal 'APPROVED', response.message @@ -272,7 +271,7 @@ def test_certification_void07_void08_void09_authorize_capture_void_discover def test_certification_void12_void13_credit_void_visa @options[:order_id] = 'VOID12' amount = 800 - visa = credit_card('4111111111111111', :month => 12, :year => 2017, :brand => 'visa', :verification_value => '120') + visa = credit_card('4111111111111111', month: 12, year: 2017, brand: 'visa', verification_value: '120') assert response = @gateway.credit(amount, visa, @options) assert_success response assert_equal 'APPROVED', response.message @@ -287,7 +286,7 @@ def test_certification_void12_void13_credit_void_visa def test_certification_tok15_tokenize_mastercard @options[:order_id] = 'TOK15' - master = credit_card('5111111111111118', :month => 12, :year => 2017, :brand => 'master', :verification_value => '101') + master = credit_card('5111111111111118', month: 12, year: 2017, brand: 'master', verification_value: '101') assert response = @gateway.store(master, @options) assert_success response assert_equal 'APPROVED', response.message @@ -298,7 +297,7 @@ def test_certification_tok15_tokenize_mastercard def test_certification_tok16_authorize_with_token_request_visa @options[:order_id] = 'TOK16' amount = 3100 - visa = credit_card('4111111111111111', :month => 12, :year => 2017, :brand => 'visa', :verification_value => '101') + visa = credit_card('4111111111111111', month: 12, year: 2017, brand: 'visa', verification_value: '101') assert response = @gateway.authorize(amount, visa, @options) assert_success response assert_equal 'APPROVED', response.message @@ -310,7 +309,7 @@ def test_certification_tok16_authorize_with_token_request_visa def test_certification_tok17_purchase_with_token_request_amex @options[:order_id] = 'TOK17' amount = 3200 - amex = credit_card('378282246310005', :month => 12, :year => 2017, :brand => 'american_express', :verification_value => '1001') + amex = credit_card('378282246310005', month: 12, year: 2017, brand: 'american_express', verification_value: '1001') assert response = @gateway.purchase(amount, amex, @options) assert_success response assert_equal 'APPROVED', response.message @@ -320,7 +319,7 @@ def test_certification_tok17_purchase_with_token_request_amex end def test_certification_tok18_authorize_using_token_mastercard - master = credit_card('5111111111111118', :month => 12, :year => 2017, :brand => 'master', :verification_value => '101') + master = credit_card('5111111111111118', month: 12, year: 2017, brand: 'master', verification_value: '101') assert response = @gateway.store(master, @options) assert_success response @@ -333,7 +332,7 @@ def test_certification_tok18_authorize_using_token_mastercard end def test_certification_tok19_purchase_using_token_visa - visa = credit_card('4111111111111111', :month => 12, :year => 2017, :brand => 'visa', :verification_value => '101') + visa = credit_card('4111111111111111', month: 12, year: 2017, brand: 'visa', verification_value: '101') assert response = @gateway.store(visa, @options) assert_success response @@ -344,5 +343,4 @@ def test_certification_tok19_purchase_using_token_visa assert_equal 'APPROVED', response.message @unique_id = response.params['unique_id'] end - end diff --git a/test/remote/gateways/remote_jetpay_v2_test.rb b/test/remote/gateways/remote_jetpay_v2_test.rb index 10f1ea6322f..f2502bc7f32 100644 --- a/test/remote/gateways/remote_jetpay_v2_test.rb +++ b/test/remote/gateways/remote_jetpay_v2_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class RemoteJetpayV2Test < Test::Unit::TestCase - def setup @gateway = JetpayV2Gateway.new(fixtures(:jetpay_v2)) @@ -11,14 +10,14 @@ def setup @amount_declined = 5205 @options = { - :device => 'spreedly', - :application => 'spreedly', - :developer_id => 'GenkID', - :billing_address => address(:city => 'Durham', :state => 'NC', :country => 'US', :zip => '27701'), - :shipping_address => address(:city => 'Durham', :state => 'NC', :country => 'US', :zip => '27701'), - :email => 'test@test.com', - :ip => '127.0.0.1', - :order_id => '12345' + device: 'spreedly', + application: 'spreedly', + developer_id: 'GenkID', + billing_address: address(city: 'Durham', state: 'NC', country: 'US', zip: '27701'), + shipping_address: address(city: 'Durham', state: 'NC', country: 'US', zip: '27701'), + email: 'test@test.com', + ip: '127.0.0.1', + order_id: '12345' } end @@ -37,7 +36,7 @@ def test_failed_purchase end def test_successful_purchase_with_minimal_options - assert response = @gateway.purchase(@amount_approved, @credit_card, {:device => 'spreedly', :application => 'spreedly'}) + assert response = @gateway.purchase(@amount_approved, @credit_card, { device: 'spreedly', application: 'spreedly' }) assert_success response assert_equal 'APPROVED', response.message assert_not_nil response.authorization @@ -72,7 +71,7 @@ def test_successful_authorize_and_capture_with_tax assert_not_nil auth.authorization assert_not_nil auth.params['approval'] - assert capture = @gateway.capture(@amount_approved, auth.authorization, @options.merge(:tax_amount => '990', :purchase_order => 'ABC12345')) + assert capture = @gateway.capture(@amount_approved, auth.authorization, @options.merge(tax_amount: '990', purchase_order: 'ABC12345')) assert_success capture end @@ -147,7 +146,7 @@ def test_failed_refund end def test_successful_credit - card = credit_card('4242424242424242', :verification_value => nil) + card = credit_card('4242424242424242', verification_value: nil) assert credit = @gateway.credit(@amount_approved, card, @options) assert_success credit @@ -156,7 +155,7 @@ def test_successful_credit end def test_failed_credit - card = credit_card('2424242424242424', :verification_value => nil) + card = credit_card('2424242424242424', verification_value: nil) assert credit = @gateway.credit(@amount_approved, card, @options) assert_failure credit @@ -169,7 +168,7 @@ def test_successful_verify end def test_failed_verify - card = credit_card('2424242424242424', :verification_value => nil) + card = credit_card('2424242424242424', verification_value: nil) assert verify = @gateway.verify(card, @options) assert_failure verify @@ -177,7 +176,7 @@ def test_failed_verify end def test_invalid_login - gateway = JetpayV2Gateway.new(:login => 'bogus') + gateway = JetpayV2Gateway.new(login: 'bogus') assert response = gateway.purchase(@amount_approved, @credit_card, @options) assert_failure response @@ -185,7 +184,7 @@ def test_invalid_login end def test_missing_login - gateway = JetpayV2Gateway.new(:login => '') + gateway = JetpayV2Gateway.new(login: '') assert response = gateway.purchase(@amount_approved, @credit_card, @options) assert_failure response diff --git a/test/remote/gateways/remote_komoju_test.rb b/test/remote/gateways/remote_komoju_test.rb index 5214eb01fbf..9a5213fcd27 100644 --- a/test/remote/gateways/remote_komoju_test.rb +++ b/test/remote/gateways/remote_komoju_test.rb @@ -11,13 +11,13 @@ def setup @fraudulent_card = credit_card('4123111111111083') @options = { - :order_id => generate_unique_id, - :description => 'Store Purchase', - :tax => '10.0', - :ip => '192.168.0.1', - :email => 'valid@email.com', - :browser_language => 'en', - :browser_user_agent => 'user_agent' + order_id: generate_unique_id, + description: 'Store Purchase', + tax: '10.0', + ip: '192.168.0.1', + email: 'valid@email.com', + browser_language: 'en', + browser_user_agent: 'user_agent' } end @@ -65,7 +65,7 @@ def test_detected_fraud end def test_invalid_login - gateway = KomojuGateway.new(:login => 'abc') + gateway = KomojuGateway.new(login: 'abc') response = gateway.purchase(@amount, @credit_card, @options) assert_failure response end diff --git a/test/remote/gateways/remote_kushki_test.rb b/test/remote/gateways/remote_kushki_test.rb index b4eb060de00..90e510ab7b1 100644 --- a/test/remote/gateways/remote_kushki_test.rb +++ b/test/remote/gateways/remote_kushki_test.rb @@ -51,6 +51,50 @@ def test_failed_purchase assert_equal 'Monto de la transacción es diferente al monto de la venta inicial', response.message end + def test_successful_authorize + # Kushki only allows preauthorization for PEN, CLP, and UF. + response = @gateway.authorize(@amount, @credit_card, { currency: 'PEN' }) + assert_success response + assert_equal 'Succeeded', response.message + assert_match %r(^\d+$), response.authorization + end + + def test_failed_authorize + options = { + amount: { + subtotal_iva: '200' + } + } + response = @gateway.authorize(@amount, @credit_card, options) + assert_failure response + assert_equal 'K220', response.responses.last.error_code + assert_equal 'Monto de la transacción es diferente al monto de la venta inicial', response.message + end + + def test_successful_capture + auth = @gateway.authorize(@amount, @credit_card) + assert_success auth + + assert capture = @gateway.capture(@amount, auth.authorization) + assert_success capture + assert_equal 'Succeeded', capture.message + end + + def test_failed_capture + options = { + amount: { + subtotal_iva: '200' + } + } + auth = @gateway.authorize(@amount, @credit_card) + assert_success auth + + capture = @gateway.capture(@amount, auth.authorization, options) + assert_failure capture + assert_equal 'K012', capture.error_code + assert_equal 'Monto de captura inválido.', capture.message + end + def test_successful_refund purchase = @gateway.purchase(@amount, @credit_card) assert_success purchase @@ -81,7 +125,7 @@ def test_successful_void def test_failed_void response = @gateway.void('000') assert_failure response - assert_equal 'El monto de la transacción es requerido', response.message + assert_equal 'Cuerpo de la petición inválido.', response.message end def test_invalid_login @@ -89,7 +133,7 @@ def test_invalid_login response = gateway.purchase(@amount, @credit_card) assert_failure response - assert_match %r{ID de comercio no válido}, response.message + assert_match %r{Unauthorized}, response.message end def test_transcript_scrubbing diff --git a/test/remote/gateways/remote_linkpoint_test.rb b/test/remote/gateways/remote_linkpoint_test.rb index 1a51911712d..bb6db34f34f 100644 --- a/test/remote/gateways/remote_linkpoint_test.rb +++ b/test/remote/gateways/remote_linkpoint_test.rb @@ -36,7 +36,7 @@ def setup @amount = 100 @credit_card = credit_card('4111111111111111') - @options = { :order_id => generate_unique_id, :billing_address => address } + @options = { order_id: generate_unique_id, billing_address: address } end def test_successful_authorization @@ -91,9 +91,9 @@ def test_successfull_purchase_and_credit def test_successfull_purchase_with_item_entity @options[:line_items] = [ - {:id => '123456', :description => 'Logo T-Shirt', :price => '12.00', :quantity => '1', - :options => [{:name => 'Color', :value => 'Red'}, {:name => 'Size', :value => 'XL'}]}, - {:id => '111', :description => 'keychain', :price => '3.00', :quantity => '1'} + { id: '123456', description: 'Logo T-Shirt', price: '12.00', quantity: '1', + options: [{ name: 'Color', value: 'Red' }, { name: 'Size', value: 'XL' }] }, + { id: '111', description: 'keychain', price: '3.00', quantity: '1' } ] assert purchase = @gateway.purchase(1500, @credit_card, @options) assert_success purchase @@ -101,12 +101,11 @@ def test_successfull_purchase_with_item_entity def test_successful_recurring_payment assert response = @gateway.recurring(2400, @credit_card, - :order_id => generate_unique_id, - :installments => 12, - :startdate => 'immediate', - :periodicity => :monthly, - :billing_address => address - ) + order_id: generate_unique_id, + installments: 12, + startdate: 'immediate', + periodicity: :monthly, + billing_address: address) assert_success response assert_equal 'APPROVED', response.params['approved'] diff --git a/test/remote/gateways/remote_litle_certification_test.rb b/test/remote/gateways/remote_litle_certification_test.rb index 3a9558c701f..ee177ce116a 100644 --- a/test/remote/gateways/remote_litle_certification_test.rb +++ b/test/remote/gateways/remote_litle_certification_test.rb @@ -9,146 +9,146 @@ def setup def test1 credit_card = CreditCard.new( - :number => '4457010000000009', - :month => '01', - :year => '2021', - :verification_value => '349', - :brand => 'visa' + number: '4457010000000009', + month: '01', + year: '2021', + verification_value: '349', + brand: 'visa' ) options = { - :order_id => '1', - :billing_address => { - :name => 'John & Mary Smith', - :address1 => '1 Main St.', - :city => 'Burlington', - :state => 'MA', - :zip => '01803-3747', - :country => 'US' + order_id: '1', + billing_address: { + name: 'John & Mary Smith', + address1: '1 Main St.', + city: 'Burlington', + state: 'MA', + zip: '01803-3747', + country: 'US' } } - auth_assertions(10100, credit_card, options, :avs => 'X', :cvv => 'M') + auth_assertions(10100, credit_card, options, avs: 'X', cvv: 'M') - authorize_avs_assertions(credit_card, options, :avs => 'X', :cvv => 'M') + authorize_avs_assertions(credit_card, options, avs: 'X', cvv: 'M') - sale_assertions(10100, credit_card, options, :avs => 'X', :cvv => 'M') + sale_assertions(10100, credit_card, options, avs: 'X', cvv: 'M') end def test2 - credit_card = CreditCard.new(:number => '5112010000000003', :month => '02', - :year => '2021', :brand => 'master', - :verification_value => '261', - :name => 'Mike J. Hammer') + credit_card = CreditCard.new(number: '5112010000000003', month: '02', + year: '2021', brand: 'master', + verification_value: '261', + name: 'Mike J. Hammer') options = { - :order_id => '2', - :billing_address => { - :address1 => '2 Main St.', - :address2 => 'Apt. 222', - :city => 'Riverside', - :state => 'RI', - :zip => '02915', - :country => 'US' + order_id: '2', + billing_address: { + address1: '2 Main St.', + address2: 'Apt. 222', + city: 'Riverside', + state: 'RI', + zip: '02915', + country: 'US' } } - auth_assertions(10100, credit_card, options, :avs => 'Z', :cvv => 'M') + auth_assertions(10100, credit_card, options, avs: 'Z', cvv: 'M') - authorize_avs_assertions(credit_card, options, :avs => 'Z', :cvv => 'M') + authorize_avs_assertions(credit_card, options, avs: 'Z', cvv: 'M') - sale_assertions(10100, credit_card, options, :avs => 'Z', :cvv => 'M') + sale_assertions(10100, credit_card, options, avs: 'Z', cvv: 'M') end def test3 credit_card = CreditCard.new( - :number => '6011010000000003', - :month => '03', - :year => '2021', - :verification_value => '758', - :brand => 'discover' + number: '6011010000000003', + month: '03', + year: '2021', + verification_value: '758', + brand: 'discover' ) options = { - :order_id => '3', - :billing_address => { - :name => 'Eileen Jones', - :address1 => '3 Main St.', - :city => 'Bloomfield', - :state => 'CT', - :zip => '06002', - :country => 'US' + order_id: '3', + billing_address: { + name: 'Eileen Jones', + address1: '3 Main St.', + city: 'Bloomfield', + state: 'CT', + zip: '06002', + country: 'US' } } - auth_assertions(10100, credit_card, options, :avs => 'Z', :cvv => 'M') + auth_assertions(10100, credit_card, options, avs: 'Z', cvv: 'M') - authorize_avs_assertions(credit_card, options, :avs => 'Z', :cvv => 'M') + authorize_avs_assertions(credit_card, options, avs: 'Z', cvv: 'M') - sale_assertions(10100, credit_card, options, :avs => 'Z', :cvv => 'M') + sale_assertions(10100, credit_card, options, avs: 'Z', cvv: 'M') end def test4 credit_card = CreditCard.new( - :number => '375001000000005', - :month => '04', - :year => '2021', - :brand => 'american_express' + number: '375001000000005', + month: '04', + year: '2021', + brand: 'american_express' ) options = { - :order_id => '4', - :billing_address => { - :name => 'Bob Black', - :address1 => '4 Main St.', - :city => 'Laurel', - :state => 'MD', - :zip => '20708', - :country => 'US' + order_id: '4', + billing_address: { + name: 'Bob Black', + address1: '4 Main St.', + city: 'Laurel', + state: 'MD', + zip: '20708', + country: 'US' } } - auth_assertions(10100, credit_card, options, :avs => 'A', :cvv => nil) + auth_assertions(10100, credit_card, options, avs: 'A', cvv: nil) - authorize_avs_assertions(credit_card, options, :avs => 'A') + authorize_avs_assertions(credit_card, options, avs: 'A') - sale_assertions(10100, credit_card, options, :avs => 'A', :cvv => nil) + sale_assertions(10100, credit_card, options, avs: 'A', cvv: nil) end def test5 credit_card = ActiveMerchant::Billing::NetworkTokenizationCreditCard.new( - :number => '4100200300011001', - :month => '05', - :year => '2021', - :verification_value => '463', - :brand => 'visa', - :payment_cryptogram => 'BwABBJQ1AgAAAAAgJDUCAAAAAAA=' + number: '4100200300011001', + month: '05', + year: '2021', + verification_value: '463', + brand: 'visa', + payment_cryptogram: 'BwABBJQ1AgAAAAAgJDUCAAAAAAA=' ) options = { - :order_id => '5' + order_id: '5' } - auth_assertions(10100, credit_card, options, :avs => 'U', :cvv => 'M') + auth_assertions(10100, credit_card, options, avs: 'U', cvv: 'M') - authorize_avs_assertions(credit_card, options, :avs => 'U', :cvv => 'M') + authorize_avs_assertions(credit_card, options, avs: 'U', cvv: 'M') - sale_assertions(10100, credit_card, options, :avs => 'U', :cvv => 'M') + sale_assertions(10100, credit_card, options, avs: 'U', cvv: 'M') end def test6 - credit_card = CreditCard.new(:number => '4457010100000008', :month => '06', - :year => '2021', :brand => 'visa', - :verification_value => '992') + credit_card = CreditCard.new(number: '4457010100000008', month: '06', + year: '2021', brand: 'visa', + verification_value: '992') options = { - :order_id => '6', - :billing_address => { - :name => 'Joe Green', - :address1 => '6 Main St.', - :city => 'Derry', - :state => 'NH', - :zip => '03038', - :country => 'US' + order_id: '6', + billing_address: { + name: 'Joe Green', + address1: '6 Main St.', + city: 'Derry', + state: 'NH', + zip: '03038', + country: 'US' } } @@ -171,26 +171,26 @@ def test6 puts "Test #{options[:order_id]} Sale: #{txn_id(response)}" # 6A. void - assert response = @gateway.void(response.authorization, {:order_id => '6A'}) + assert response = @gateway.void(response.authorization, { order_id: '6A' }) assert_equal '360', response.params['response'] assert_equal 'No transaction found with specified transaction Id', response.message puts "Test #{options[:order_id]}A: #{txn_id(response)}" end def test7 - credit_card = CreditCard.new(:number => '5112010100000002', :month => '07', - :year => '2021', :brand => 'master', - :verification_value => '251') + credit_card = CreditCard.new(number: '5112010100000002', month: '07', + year: '2021', brand: 'master', + verification_value: '251') options = { - :order_id => '7', - :billing_address => { - :name => 'Jane Murray', - :address1 => '7 Main St.', - :city => 'Amesbury', - :state => 'MA', - :zip => '01913', - :country => 'US' + order_id: '7', + billing_address: { + name: 'Jane Murray', + address1: '7 Main St.', + city: 'Amesbury', + state: 'MA', + zip: '01913', + country: 'US' } } @@ -204,7 +204,7 @@ def test7 puts "Test #{options[:order_id]} Authorize: #{txn_id(response)}" # 7: authorize avs - authorize_avs_assertions(credit_card, options, :avs => 'I', :cvv => 'N', :message => 'Invalid Account Number', :success => false) + authorize_avs_assertions(credit_card, options, avs: 'I', cvv: 'N', message: 'Invalid Account Number', success: false) # 7. sale assert response = @gateway.purchase(10100, credit_card, options) @@ -217,19 +217,19 @@ def test7 end def test8 - credit_card = CreditCard.new(:number => '6011010100000002', :month => '08', - :year => '2021', :brand => 'discover', - :verification_value => '184') + credit_card = CreditCard.new(number: '6011010100000002', month: '08', + year: '2021', brand: 'discover', + verification_value: '184') options = { - :order_id => '8', - :billing_address => { - :name => 'Mark Johnson', - :address1 => '8 Main St.', - :city => 'Manchester', - :state => 'NH', - :zip => '03101', - :country => 'US' + order_id: '8', + billing_address: { + name: 'Mark Johnson', + address1: '8 Main St.', + city: 'Manchester', + state: 'NH', + zip: '03101', + country: 'US' } } @@ -243,7 +243,7 @@ def test8 puts "Test #{options[:order_id]} Authorize: #{txn_id(response)}" # 8: authorize avs - authorize_avs_assertions(credit_card, options, :avs => 'I', :cvv => 'P', :message => 'Call Discover', :success => false) + authorize_avs_assertions(credit_card, options, avs: 'I', cvv: 'P', message: 'Call Discover', success: false) # 8: sale assert response = @gateway.purchase(80080, credit_card, options) @@ -256,19 +256,19 @@ def test8 end def test9 - credit_card = CreditCard.new(:number => '375001010000003', :month => '09', - :year => '2021', :brand => 'american_express', - :verification_value => '0421') + credit_card = CreditCard.new(number: '375001010000003', month: '09', + year: '2021', brand: 'american_express', + verification_value: '0421') options = { - :order_id => '9', - :billing_address => { - :name => 'James Miller', - :address1 => '9 Main St.', - :city => 'Boston', - :state => 'MA', - :zip => '02134', - :country => 'US' + order_id: '9', + billing_address: { + name: 'James Miller', + address1: '9 Main St.', + city: 'Boston', + state: 'MA', + zip: '02134', + country: 'US' } } @@ -281,7 +281,7 @@ def test9 puts "Test #{options[:order_id]} Authorize: #{txn_id(response)}" # 9: authorize avs - authorize_avs_assertions(credit_card, options, :avs => 'I', :message => 'Pick Up Card', :success => false) + authorize_avs_assertions(credit_card, options, avs: 'I', message: 'Pick Up Card', success: false) # 9: sale assert response = @gateway.purchase(10100, credit_card, options) @@ -294,19 +294,19 @@ def test9 # Authorization Reversal Tests def test32 - credit_card = CreditCard.new(:number => '4457010000000009', :month => '01', - :year => '2021', :brand => 'visa', - :verification_value => '349') + credit_card = CreditCard.new(number: '4457010000000009', month: '01', + year: '2021', brand: 'visa', + verification_value: '349') options = { - :order_id => '32', - :billing_address => { - :name => 'John Smith', - :address1 => '1 Main St.', - :city => 'Burlington', - :state => 'MA', - :zip => '01803-3747', - :country => 'US' + order_id: '32', + billing_address: { + name: 'John Smith', + address1: '1 Main St.', + city: 'Burlington', + state: 'MA', + zip: '01803-3747', + country: 'US' } } @@ -326,21 +326,21 @@ def test32 end def test33 - credit_card = CreditCard.new(:number => '5112010000000003', :month => '01', - :year => '2021', :brand => 'master', - :verification_value => '261') + credit_card = CreditCard.new(number: '5112010000000003', month: '01', + year: '2021', brand: 'master', + verification_value: '261') options = { - :order_id => '33', - :billing_address => { - :name => 'Mike J. Hammer', - :address1 => '2 Main St.', - :address2 => 'Apt. 222', - :city => 'Riverside', - :state => 'RI', - :zip => '02915', - :country => 'US', - :payment_cryptogram => 'BwABBJQ1AgAAAAAgJDUCAAAAAAA=' + order_id: '33', + billing_address: { + name: 'Mike J. Hammer', + address1: '2 Main St.', + address2: 'Apt. 222', + city: 'Riverside', + state: 'RI', + zip: '02915', + country: 'US', + payment_cryptogram: 'BwABBJQ1AgAAAAAgJDUCAAAAAAA=' } } @@ -355,19 +355,19 @@ def test33 end def test34 - credit_card = CreditCard.new(:number => '6011010000000003', :month => '01', - :year => '2021', :brand => 'discover', - :verification_value => '758') + credit_card = CreditCard.new(number: '6011010000000003', month: '01', + year: '2021', brand: 'discover', + verification_value: '758') options = { - :order_id => '34', - :billing_address => { - :name => 'Eileen Jones', - :address1 => '3 Main St.', - :city => 'Bloomfield', - :state => 'CT', - :zip => '06002', - :country => 'US' + order_id: '34', + billing_address: { + name: 'Eileen Jones', + address1: '3 Main St.', + city: 'Bloomfield', + state: 'CT', + zip: '06002', + country: 'US' } } @@ -382,18 +382,18 @@ def test34 end def test35 - credit_card = CreditCard.new(:number => '375001000000005', :month => '01', - :year => '2021', :brand => 'american_express') + credit_card = CreditCard.new(number: '375001000000005', month: '01', + year: '2021', brand: 'american_express') options = { - :order_id => '35', - :billing_address => { - :name => 'Bob Black', - :address1 => '4 Main St.', - :city => 'Laurel', - :state => 'MD', - :zip => '20708', - :country => 'US' + order_id: '35', + billing_address: { + name: 'Bob Black', + address1: '4 Main St.', + city: 'Laurel', + state: 'MD', + zip: '20708', + country: 'US' } } @@ -414,12 +414,12 @@ def test35 end def test36 - credit_card = CreditCard.new(:number => '375000026600004', :month => '01', - :year => '2021', :brand => 'american_express') + credit_card = CreditCard.new(number: '375000026600004', month: '01', + year: '2021', brand: 'american_express') options = { - :order_id => '36' - } + order_id: '36' + } assert auth_response = @gateway.authorize(20500, credit_card, options) assert_success auth_response @@ -440,16 +440,16 @@ def test37 account_type: 'Checking' ) options = { - :order_id => '37', - :billing_address => { - :name => 'Tom Black', - :address1 => '8 Main St.', - :city => 'Manchester', - :state => 'NH', - :zip => '03101', - :country => 'US', - :email => 'test@test.com', - :phone => '2233334444' + order_id: '37', + billing_address: { + name: 'Tom Black', + address1: '8 Main St.', + city: 'Manchester', + state: 'NH', + zip: '03101', + country: 'US', + email: 'test@test.com', + phone: '2233334444' } } assert auth_response = @gateway.authorize(3001, check, options) @@ -467,16 +467,16 @@ def test38 account_type: 'Checking' ) options = { - :order_id => '38', - :billing_address => { - :name => 'John Smith', - :address1 => '8 Main St.', - :city => 'Manchester', - :state => 'NH', - :zip => '03101', - :country => 'US', - :email => 'test@test.com', - :phone => '2233334444' + order_id: '38', + billing_address: { + name: 'John Smith', + address1: '8 Main St.', + city: 'Manchester', + state: 'NH', + zip: '03101', + country: 'US', + email: 'test@test.com', + phone: '2233334444' } } assert auth_response = @gateway.authorize(3002, check, options) @@ -494,17 +494,17 @@ def test39 account_type: 'Corporate' ) options = { - :order_id => '39', - :billing_address => { - :name => 'John Smith', - :address1 => '8 Main St.', - :city => 'Manchester', - :state => 'NH', - :zip => '03101', - :country => 'US', - :company => 'Good Goods Inc', - :email => 'test@test.com', - :phone => '2233334444' + order_id: '39', + billing_address: { + name: 'John Smith', + address1: '8 Main St.', + city: 'Manchester', + state: 'NH', + zip: '03101', + country: 'US', + company: 'Good Goods Inc', + email: 'test@test.com', + phone: '2233334444' } } assert auth_response = @gateway.authorize(3003, check, options) @@ -522,17 +522,17 @@ def test40 account_type: 'Corporate' ) options = { - :order_id => '40', - :billing_address => { - :name => 'Peter Green', - :address1 => '8 Main St.', - :city => 'Manchester', - :state => 'NH', - :zip => '03101', - :country => 'US', - :company => 'Green Co', - :email => 'test@test.com', - :phone => '2233334444' + order_id: '40', + billing_address: { + name: 'Peter Green', + address1: '8 Main St.', + city: 'Manchester', + state: 'NH', + zip: '03101', + country: 'US', + company: 'Green Co', + email: 'test@test.com', + phone: '2233334444' } } assert auth_response = @gateway.authorize(3004, declined_authorize_check, options) @@ -550,16 +550,16 @@ def test41 account_type: 'Checking' ) options = { - :order_id => '41', - :billing_address => { - :name => 'Mike Hammer', - :address1 => '8 Main St.', - :city => 'Manchester', - :state => 'NH', - :zip => '03101', - :country => 'US', - :email => 'test@test.com', - :phone => '2233334444' + order_id: '41', + billing_address: { + name: 'Mike Hammer', + address1: '8 Main St.', + city: 'Manchester', + state: 'NH', + zip: '03101', + country: 'US', + email: 'test@test.com', + phone: '2233334444' } } assert purchase_response = @gateway.purchase(2008, check, options) @@ -577,16 +577,16 @@ def test42 account_type: 'Checking' ) options = { - :order_id => '42', - :billing_address => { - :name => 'Tom Black', - :address1 => '8 Main St.', - :city => 'Manchester', - :state => 'NH', - :zip => '03101', - :country => 'US', - :email => 'test@test.com', - :phone => '2233334444' + order_id: '42', + billing_address: { + name: 'Tom Black', + address1: '8 Main St.', + city: 'Manchester', + state: 'NH', + zip: '03101', + country: 'US', + email: 'test@test.com', + phone: '2233334444' } } assert purchase_response = @gateway.purchase(2004, check, options) @@ -604,17 +604,17 @@ def test43 account_type: 'Corporate' ) options = { - :order_id => '43', - :billing_address => { - :name => 'Peter Green', - :address1 => '8 Main St.', - :city => 'Manchester', - :state => 'NH', - :zip => '03101', - :country => 'US', - :company => 'Green Co', - :email => 'test@test.com', - :phone => '2233334444' + order_id: '43', + billing_address: { + name: 'Peter Green', + address1: '8 Main St.', + city: 'Manchester', + state: 'NH', + zip: '03101', + country: 'US', + company: 'Green Co', + email: 'test@test.com', + phone: '2233334444' } } assert purchase_response = @gateway.purchase(2007, check, options) @@ -632,17 +632,17 @@ def test44 account_type: 'Corporate' ) options = { - :order_id => '44', - :billing_address => { - :name => 'Peter Green', - :address1 => '8 Main St.', - :city => 'Manchester', - :state => 'NH', - :zip => '03101', - :country => 'US', - :company => 'Green Co', - :email => 'test@test.com', - :phone => '2233334444' + order_id: '44', + billing_address: { + name: 'Peter Green', + address1: '8 Main St.', + city: 'Manchester', + state: 'NH', + zip: '03101', + country: 'US', + company: 'Green Co', + email: 'test@test.com', + phone: '2233334444' } } assert purchase_response = @gateway.purchase(2009, check, options) @@ -660,16 +660,16 @@ def test45 account_type: 'Checking' ) options = { - :order_id => '45', - :billing_address => { - :name => 'John Smith', - :address1 => '8 Main St.', - :city => 'Manchester', - :state => 'NH', - :zip => '03101', - :country => 'US', - :email => 'test@test.com', - :phone => '2233334444' + order_id: '45', + billing_address: { + name: 'John Smith', + address1: '8 Main St.', + city: 'Manchester', + state: 'NH', + zip: '03101', + country: 'US', + email: 'test@test.com', + phone: '2233334444' } } assert refund_response = @gateway.refund(1001, check, options) @@ -687,18 +687,18 @@ def test46 account_type: 'Corporate' ) options = { - :order_id => '46', - :order_source => 'telephone', - :billing_address => { - :name => 'Robert Jones', - :address1 => '8 Main St.', - :city => 'Manchester', - :state => 'NH', - :zip => '03101', - :country => 'US', - :email => 'test@test.com', - :phone => '2233334444', - :company => 'Widget Inc' + order_id: '46', + order_source: 'telephone', + billing_address: { + name: 'Robert Jones', + address1: '8 Main St.', + city: 'Manchester', + state: 'NH', + zip: '03101', + country: 'US', + email: 'test@test.com', + phone: '2233334444', + company: 'Widget Inc' } } assert purchase_response = @gateway.purchase(1003, check, options) @@ -718,17 +718,17 @@ def test47 account_type: 'Corporate' ) options = { - :order_id => '47', - :billing_address => { - :name => 'Peter Green', - :address1 => '8 Main St.', - :city => 'Manchester', - :state => 'NH', - :zip => '03101', - :country => 'US', - :company => 'Green Co', - :email => 'test@test.com', - :phone => '2233334444' + order_id: '47', + billing_address: { + name: 'Peter Green', + address1: '8 Main St.', + city: 'Manchester', + state: 'NH', + zip: '03101', + country: 'US', + company: 'Green Co', + email: 'test@test.com', + phone: '2233334444' } } assert purchase_response = @gateway.purchase(1007, check, options) @@ -747,17 +747,17 @@ def test48 account_type: 'Corporate' ) options = { - :order_id => '43', - :billing_address => { - :name => 'Peter Green', - :address1 => '8 Main St.', - :city => 'Manchester', - :state => 'NH', - :zip => '03101', - :country => 'US', - :company => 'Green Co', - :email => 'test@test.com', - :phone => '2233334444' + order_id: '43', + billing_address: { + name: 'Peter Green', + address1: '8 Main St.', + city: 'Manchester', + state: 'NH', + zip: '03101', + country: 'US', + company: 'Green Co', + email: 'test@test.com', + phone: '2233334444' } } assert purchase_response = @gateway.purchase(2007, check, options) @@ -783,17 +783,17 @@ def test_echeck_void1 account_type: 'Checking' ) options = { - :order_id => '42', - :id => '236222', - :billing_address => { - :name => 'Tom Black', - :address1 => '8 Main St.', - :city => 'Manchester', - :state => 'NH', - :zip => '03101', - :country => 'US', - :email => 'test@test.com', - :phone => '2233334444' + order_id: '42', + id: '236222', + billing_address: { + name: 'Tom Black', + address1: '8 Main St.', + city: 'Manchester', + state: 'NH', + zip: '03101', + country: 'US', + email: 'test@test.com', + phone: '2233334444' } } assert purchase_response = @gateway.purchase(2004, check, options) @@ -812,17 +812,17 @@ def test_echeck_void2 account_type: 'Checking' ) options = { - :order_id => '46', - :id => '232222', - :billing_address => { - :name => 'Robert Jones', - :address1 => '8 Main St.', - :city => 'Manchester', - :state => 'NH', - :zip => '03101', - :country => 'US', - :email => 'test@test.com', - :phone => '2233334444' + order_id: '46', + id: '232222', + billing_address: { + name: 'Robert Jones', + address1: '8 Main St.', + city: 'Manchester', + state: 'NH', + zip: '03101', + country: 'US', + email: 'test@test.com', + phone: '2233334444' } } assert purchase_response = @gateway.purchase(1003, check, options) @@ -843,9 +843,9 @@ def test_echeck_void3 # Explicit Token Registration Tests def test50 - credit_card = CreditCard.new(:number => '4457119922390123') + credit_card = CreditCard.new(number: '4457119922390123') options = { - :order_id => '50' + order_id: '50' } # store @@ -861,9 +861,9 @@ def test50 end def test51 - credit_card = CreditCard.new(:number => '4457119999999999') + credit_card = CreditCard.new(number: '4457119999999999') options = { - :order_id => '51' + order_id: '51' } # store @@ -876,9 +876,9 @@ def test51 end def test52 - credit_card = CreditCard.new(:number => '4457119922390123') + credit_card = CreditCard.new(number: '4457119922390123') options = { - :order_id => '52' + order_id: '52' } # store @@ -898,8 +898,8 @@ def test53 routing_number: '011100012', account_number: '1099999998' ) - options = { - :order_id => '53' + options = { + order_id: '53' } store_response = @gateway.store(check, options) @@ -917,8 +917,8 @@ def test54 routing_number: '1145_7895', account_number: '1022222102' ) - options = { - :order_id => '54' + options = { + order_id: '54' } store_response = @gateway.store(check, options) @@ -931,13 +931,13 @@ def test54 # Implicit Token Registration Tests def test55 - credit_card = CreditCard.new(:number => '5435101234510196', - :month => '11', - :year => '2014', - :brand => 'master', - :verification_value => '987') + credit_card = CreditCard.new(number: '5435101234510196', + month: '11', + year: '2014', + brand: 'master', + verification_value: '987') options = { - :order_id => '55' + order_id: '55' } # authorize @@ -952,13 +952,13 @@ def test55 end def test56 - credit_card = CreditCard.new(:number => '5435109999999999', - :month => '11', - :year => '2014', - :brand => 'master', - :verification_value => '987') + credit_card = CreditCard.new(number: '5435109999999999', + month: '11', + year: '2014', + brand: 'master', + verification_value: '987') options = { - :order_id => '56' + order_id: '56' } # authorize @@ -970,13 +970,13 @@ def test56 end def test57_58 - credit_card = CreditCard.new(:number => '5435101234510196', - :month => '11', - :year => '2014', - :brand => 'master', - :verification_value => '987') + credit_card = CreditCard.new(number: '5435101234510196', + month: '11', + year: '2014', + brand: 'master', + verification_value: '987') options = { - :order_id => '57' + order_id: '57' } # authorize card @@ -993,10 +993,10 @@ def test57_58 # authorize token token = response.params['tokenResponse_litleToken'] options = { - :order_id => '58', - :token => { - :month => credit_card.month, - :year => credit_card.year + order_id: '58', + token: { + month: credit_card.month, + year: credit_card.year } } @@ -1011,10 +1011,10 @@ def test57_58 def test59 token = '1111000100092332' options = { - :order_id => '59', - :token => { - :month => '11', - :year => '2021' + order_id: '59', + token: { + month: '11', + year: '2021' } } @@ -1030,10 +1030,10 @@ def test59 def test60 token = '171299999999999' options = { - :order_id => '60', - :token => { - :month => '11', - :year => '2014' + order_id: '60', + token: { + month: '11', + year: '2014' } } @@ -1048,7 +1048,7 @@ def test60 def test_apple_pay_purchase options = { - :order_id => transaction_id, + order_id: transaction_id } decrypted_apple_pay = ActiveMerchant::Billing::NetworkTokenizationCreditCard.new( { @@ -1057,7 +1057,8 @@ def test_apple_pay_purchase brand: 'visa', number: '4457000300000007', payment_cryptogram: 'BwABBJQ1AgAAAAAgJDUCAAAAAAA=' - }) + } + ) assert response = @gateway.purchase(10010, decrypted_apple_pay, options) assert_success response @@ -1066,7 +1067,7 @@ def test_apple_pay_purchase def test_android_pay_purchase options = { - :order_id => transaction_id, + order_id: transaction_id } decrypted_android_pay = ActiveMerchant::Billing::NetworkTokenizationCreditCard.new( { @@ -1076,7 +1077,8 @@ def test_android_pay_purchase brand: 'visa', number: '4457000300000007', payment_cryptogram: 'BwABBJQ1AgAAAAAgJDUCAAAAAAA=' - }) + } + ) assert response = @gateway.purchase(10010, decrypted_android_pay, options) assert_success response @@ -1104,22 +1106,22 @@ def test_three_d_secure def test_authorize_and_purchase_and_credit_with_token options = { - :order_id => transaction_id, - :billing_address => { - :name => 'John Smith', - :address1 => '1 Main St.', - :city => 'Burlington', - :state => 'MA', - :zip => '01803-3747', - :country => 'US' + order_id: transaction_id, + billing_address: { + name: 'John Smith', + address1: '1 Main St.', + city: 'Burlington', + state: 'MA', + zip: '01803-3747', + country: 'US' } } - credit_card = CreditCard.new(:number => '5435101234510196', - :month => '11', - :year => '2014', - :brand => 'master', - :verification_value => '987') + credit_card = CreditCard.new(number: '5435101234510196', + month: '11', + year: '2014', + brand: 'master', + verification_value: '987') # authorize assert auth_response = @gateway.authorize(0, credit_card, options) @@ -1132,12 +1134,12 @@ def test_authorize_and_purchase_and_credit_with_token # purchase purchase_options = options.merge({ - :order_id => transaction_id, - :token => { - :month => credit_card.month, - :year => credit_card.year - } - }) + order_id: transaction_id, + token: { + month: credit_card.month, + year: credit_card.year + } + }) assert purchase_response = @gateway.purchase(100, token, purchase_options) assert_success purchase_response @@ -1146,12 +1148,12 @@ def test_authorize_and_purchase_and_credit_with_token # credit credit_options = options.merge({ - :order_id => transaction_id, - :token => { - :month => credit_card.month, - :year => credit_card.year - } - }) + order_id: transaction_id, + token: { + month: credit_card.month, + year: credit_card.year + } + }) assert credit_response = @gateway.credit(500, token, credit_options) assert_success credit_response @@ -1161,7 +1163,7 @@ def test_authorize_and_purchase_and_credit_with_token private - def auth_assertions(amount, card, options, assertions={}) + def auth_assertions(amount, card, options, assertions = {}) # 1: authorize assert response = @gateway.authorize(amount, card, options) assert_success response @@ -1171,19 +1173,19 @@ def auth_assertions(amount, card, options, assertions={}) assert_equal auth_code(options[:order_id]), response.params['authCode'] # 1A: capture - assert response = @gateway.capture(amount, response.authorization, {:id => transaction_id}) + assert response = @gateway.capture(amount, response.authorization, { id: transaction_id }) assert_equal 'Approved', response.message # 1B: credit - assert response = @gateway.credit(amount, response.authorization, {:id => transaction_id}) + assert response = @gateway.credit(amount, response.authorization, { id: transaction_id }) assert_equal 'Approved', response.message # 1C: void - assert response = @gateway.void(response.authorization, {:id => transaction_id}) + assert response = @gateway.void(response.authorization, { id: transaction_id }) assert_equal 'Approved', response.message end - def authorize_avs_assertions(credit_card, options, assertions={}) + def authorize_avs_assertions(credit_card, options, assertions = {}) assert response = @gateway.authorize(000, credit_card, options) assert_equal assertions.key?(:success) ? assertions[:success] : true, response.success? assert_equal assertions[:message] || 'Approved', response.message @@ -1191,7 +1193,7 @@ def authorize_avs_assertions(credit_card, options, assertions={}) assert_equal assertions[:cvv], response.cvv_result['code'], caller.inspect if assertions[:cvv] end - def sale_assertions(amount, card, options, assertions={}) + def sale_assertions(amount, card, options, assertions = {}) # 1: sale assert response = @gateway.purchase(amount, card, options) assert_success response @@ -1201,19 +1203,19 @@ def sale_assertions(amount, card, options, assertions={}) # assert_equal auth_code(options[:order_id]), response.params['authCode'] # 1B: credit - assert response = @gateway.credit(amount, response.authorization, {:id => transaction_id}) + assert response = @gateway.credit(amount, response.authorization, { id: transaction_id }) assert_equal 'Approved', response.message # 1C: void - assert response = @gateway.void(response.authorization, {:id => transaction_id}) + assert response = @gateway.void(response.authorization, { id: transaction_id }) assert_equal 'Approved', response.message end def three_d_secure_assertions(test_id, card, type, source, result) - credit_card = CreditCard.new(:number => card, :month => '01', - :year => '2021', :brand => type, - :verification_value => '261', - :name => 'Mike J. Hammer') + credit_card = CreditCard.new(number: card, month: '01', + year: '2021', brand: type, + verification_value: '261', + name: 'Mike J. Hammer') options = { order_id: test_id, diff --git a/test/remote/gateways/remote_litle_test.rb b/test/remote/gateways/remote_litle_test.rb index fb7759cde92..71d7bf3b8d6 100644 --- a/test/remote/gateways/remote_litle_test.rb +++ b/test/remote/gateways/remote_litle_test.rb @@ -7,7 +7,7 @@ def setup first_name: 'John', last_name: 'Smith', month: '01', - year: '2012', + year: '2024', brand: 'visa', number: '4457010000000009', verification_value: '349' @@ -53,7 +53,8 @@ def setup brand: 'visa', number: '44444444400009', payment_cryptogram: 'BwABBJQ1AgAAAAAgJDUCAAAAAAA=' - }) + } + ) @decrypted_android_pay = ActiveMerchant::Billing::NetworkTokenizationCreditCard.new( { source: :android_pay, @@ -62,7 +63,8 @@ def setup brand: 'visa', number: '4457000300000007', payment_cryptogram: 'BwABBJQ1AgAAAAAgJDUCAAAAAAA=' - }) + } + ) @check = check( name: 'Tom Black', routing_number: '011075150', @@ -96,6 +98,30 @@ def test_successful_authorization_with_merchant_data assert @gateway.authorize(10010, @credit_card1, options) end + def test_successful_capture_with_customer_id + options = @options.merge(customer_id: '8675309') + assert response = @gateway.authorize(1000, @credit_card1, options) + assert_success response + assert_equal 'Approved', response.message + end + + def test_succesful_purchase_with_customer_id + options = @options.merge(customer_id: '8675309') + assert response = @gateway.purchase(1000, @credit_card1, options) + assert_success response + assert_equal 'Approved', response.message + end + + def test_successful_refund_with_customer_id + options = @options.merge(customer_id: '8675309') + + assert purchase = @gateway.purchase(100, @credit_card1, options) + + assert refund = @gateway.refund(444, purchase.authorization, options) + assert_success refund + assert_equal 'Approved', refund.message + end + def test_successful_authorization_with_echeck options = @options.merge({ order_id: '38', @@ -115,17 +141,16 @@ def test_avs_and_cvv_result def test_unsuccessful_authorization assert response = @gateway.authorize(60060, @credit_card2, { - :order_id=>'6', - :billing_address=>{ - :name => 'Joe Green', - :address1 => '6 Main St.', - :city => 'Derry', - :state => 'NH', - :zip => '03038', - :country => 'US' - }, - } - ) + order_id: '6', + billing_address: { + name: 'Joe Green', + address1: '6 Main St.', + city: 'Derry', + state: 'NH', + zip: '03038', + country: 'US' + } + }) assert_failure response assert_equal 'Insufficient Funds', response.message end @@ -147,6 +172,23 @@ def test_successful_purchase_with_some_empty_address_parts assert_equal 'Approved', response.message end + def test_successful_purchase_with_truncated_billing_address + assert response = @gateway.purchase(10010, @credit_card1, { + order_id: '1', + email: 'test@example.com', + billing_address: { + address1: '1234 Supercalifragilisticexpialidocious', + address2: 'Unit 6', + city: '‎Lake Chargoggagoggmanchauggagoggchaubunagungamaugg', + state: 'ME', + zip: '09901', + country: 'US' + } + }) + assert_success response + assert_equal 'Approved', response.message + end + def test_successful_purchase_with_debt_repayment_flag assert response = @gateway.purchase(10010, @credit_card1, @options.merge(debt_repayment: true)) assert_success response @@ -199,15 +241,15 @@ def test_successful_purchase_with_echeck def test_unsuccessful_purchase assert response = @gateway.purchase(60060, @credit_card2, { - :order_id=>'6', - :billing_address=>{ - :name => 'Joe Green', - :address1 => '6 Main St.', - :city => 'Derry', - :state => 'NH', - :zip => '03038', - :country => 'US' - }, + order_id: '6', + billing_address: { + name: 'Joe Green', + address1: '6 Main St.', + city: 'Derry', + state: 'NH', + zip: '03038', + country: 'US' + } }) assert_failure response assert_equal 'Insufficient Funds', response.message @@ -233,11 +275,11 @@ def test_authorize_capture_refund_void def test_authorize_and_capture_with_stored_credential_recurring credit_card = CreditCard.new(@credit_card_hash.merge( - number: '4100200300011001', - month: '05', - year: '2021', - verification_value: '463' - )) + number: '4100200300011001', + month: '05', + year: '2021', + verification_value: '463' + )) initial_options = @options.merge( order_id: 'Net_Id1', @@ -277,11 +319,11 @@ def test_authorize_and_capture_with_stored_credential_recurring def test_authorize_and_capture_with_stored_credential_installment credit_card = CreditCard.new(@credit_card_hash.merge( - number: '4457010000000009', - month: '01', - year: '2021', - verification_value: '349' - )) + number: '4457010000000009', + month: '01', + year: '2021', + verification_value: '349' + )) initial_options = @options.merge( order_id: 'Net_Id2', @@ -321,11 +363,11 @@ def test_authorize_and_capture_with_stored_credential_installment def test_authorize_and_capture_with_stored_credential_mit_card_on_file credit_card = CreditCard.new(@credit_card_hash.merge( - number: '4457000800000002', - month: '01', - year: '2021', - verification_value: '349' - )) + number: '4457000800000002', + month: '01', + year: '2021', + verification_value: '349' + )) initial_options = @options.merge( order_id: 'Net_Id3', @@ -365,11 +407,11 @@ def test_authorize_and_capture_with_stored_credential_mit_card_on_file def test_authorize_and_capture_with_stored_credential_cit_card_on_file credit_card = CreditCard.new(@credit_card_hash.merge( - number: '4457000800000002', - month: '01', - year: '2021', - verification_value: '349' - )) + number: '4457000800000002', + month: '01', + year: '2021', + verification_value: '349' + )) initial_options = @options.merge( order_id: 'Net_Id3', @@ -409,11 +451,11 @@ def test_authorize_and_capture_with_stored_credential_cit_card_on_file def test_purchase_with_stored_credential_cit_card_on_file_non_ecommerce credit_card = CreditCard.new(@credit_card_hash.merge( - number: '4457000800000002', - month: '01', - year: '2021', - verification_value: '349' - )) + number: '4457000800000002', + month: '01', + year: '2021', + verification_value: '349' + )) initial_options = @options.merge( order_id: 'Net_Id3', @@ -472,7 +514,19 @@ def test_void_authorization def test_unsuccessful_void assert void = @gateway.void('123456789012345360;authorization;100') assert_failure void - assert_equal 'No transaction found with specified litleTxnId', void.message + assert_equal 'No transaction found with specified Transaction Id', void.message + end + + def test_successful_credit + assert credit = @gateway.credit(123456, @credit_card1, @options) + assert_success credit + assert_equal 'Approved', credit.message + end + + def test_failed_credit + @credit_card1.number = '1234567890' + assert credit = @gateway.credit(1, @credit_card1, @options) + assert_failure credit end def test_partial_refund @@ -528,24 +582,24 @@ def test_nil_amount_capture def test_capture_unsuccessful assert capture_response = @gateway.capture(10010, '123456789012345360') assert_failure capture_response - assert_equal 'No transaction found with specified litleTxnId', capture_response.message + assert_equal 'No transaction found with specified Transaction Id', capture_response.message end def test_refund_unsuccessful assert credit_response = @gateway.refund(10010, '123456789012345360') assert_failure credit_response - assert_equal 'No transaction found with specified litleTxnId', credit_response.message + assert_equal 'No transaction found with specified Transaction Id', credit_response.message end def test_void_unsuccessful assert void_response = @gateway.void('123456789012345360') assert_failure void_response - assert_equal 'No transaction found with specified litleTxnId', void_response.message + assert_equal 'No transaction found with specified Transaction Id', void_response.message end def test_store_successful - credit_card = CreditCard.new(@credit_card_hash.merge(:number => '4457119922390123')) - assert store_response = @gateway.store(credit_card, :order_id => '50') + credit_card = CreditCard.new(@credit_card_hash.merge(number: '4457119922390123')) + assert store_response = @gateway.store(credit_card, order_id: '50') assert_success store_response assert_equal 'Account number was successfully registered', store_response.message @@ -557,7 +611,7 @@ def test_store_successful def test_store_with_paypage_registration_id_successful paypage_registration_id = 'cDZJcmd1VjNlYXNaSlRMTGpocVZQY1NNlYE4ZW5UTko4NU9KK3p1L1p1VzE4ZWVPQVlSUHNITG1JN2I0NzlyTg=' - assert store_response = @gateway.store(paypage_registration_id, :order_id => '50') + assert store_response = @gateway.store(paypage_registration_id, order_id: '50') assert_success store_response assert_equal 'Account number was successfully registered', store_response.message @@ -566,8 +620,8 @@ def test_store_with_paypage_registration_id_successful end def test_store_unsuccessful - credit_card = CreditCard.new(@credit_card_hash.merge(:number => '4457119999999999')) - assert store_response = @gateway.store(credit_card, :order_id => '51') + credit_card = CreditCard.new(@credit_card_hash.merge(number: '4457119999999999')) + assert store_response = @gateway.store(credit_card, order_id: '51') assert_failure store_response assert_equal 'Credit card number was invalid', store_response.message @@ -575,8 +629,8 @@ def test_store_unsuccessful end def test_store_and_purchase_with_token_successful - credit_card = CreditCard.new(@credit_card_hash.merge(:number => '4100280190123000')) - assert store_response = @gateway.store(credit_card, :order_id => '50') + credit_card = CreditCard.new(@credit_card_hash.merge(number: '4100280190123000')) + assert store_response = @gateway.store(credit_card, order_id: '50') assert_success store_response token = store_response.authorization @@ -587,6 +641,18 @@ def test_store_and_purchase_with_token_successful assert_equal 'Approved', response.message end + def test_purchase_with_token_and_date_successful + assert store_response = @gateway.store(@credit_card1, order_id: '50') + assert_success store_response + + token = store_response.authorization + assert_equal store_response.params['litleToken'], token + + assert response = @gateway.purchase(10010, token, { basis_expiration_month: '01', basis_expiration_year: '2024' }) + assert_success response + assert_equal 'Approved', response.message + end + def test_echeck_store_and_purchase assert store_response = @gateway.store(@store_check) assert_success store_response @@ -615,16 +681,16 @@ def test_unsuccessful_verify def test_successful_purchase_with_dynamic_descriptors assert response = @gateway.purchase(10010, @credit_card1, @options.merge( - descriptor_name: 'SuperCompany', - descriptor_phone: '9193341121' - )) + descriptor_name: 'SuperCompany', + descriptor_phone: '9193341121' + )) assert_success response assert_equal 'Approved', response.message end def test_unsuccessful_xml_schema_validation - credit_card = CreditCard.new(@credit_card_hash.merge(:number => '123456')) - assert store_response = @gateway.store(credit_card, :order_id => '51') + credit_card = CreditCard.new(@credit_card_hash.merge(number: '123456')) + assert store_response = @gateway.store(credit_card, order_id: '51') assert_failure store_response assert_match(/^Error validating xml data against the schema/, store_response.message) diff --git a/test/remote/gateways/remote_mercado_pago_test.rb b/test/remote/gateways/remote_mercado_pago_test.rb index 0bf8cad1c8f..33e6e9b7034 100644 --- a/test/remote/gateways/remote_mercado_pago_test.rb +++ b/test/remote/gateways/remote_mercado_pago_test.rb @@ -2,33 +2,34 @@ class RemoteMercadoPagoTest < Test::Unit::TestCase def setup + exp_year = Time.now.year + 1 @gateway = MercadoPagoGateway.new(fixtures(:mercado_pago)) @argentina_gateway = MercadoPagoGateway.new(fixtures(:mercado_pago_argentina)) + @colombian_gateway = MercadoPagoGateway.new(fixtures(:mercado_pago_colombia)) @amount = 500 - @credit_card = credit_card('4509953566233704') + @credit_card = credit_card('5031433215406351') + @colombian_card = credit_card('4013540682746260') @elo_credit_card = credit_card('5067268650517446', - :month => 10, - :year => 2020, - :first_name => 'John', - :last_name => 'Smith', - :verification_value => '737' - ) + month: 10, + year: exp_year, + first_name: 'John', + last_name: 'Smith', + verification_value: '737') @cabal_credit_card = credit_card('6035227716427021', - :month => 10, - :year => 2020, - :first_name => 'John', - :last_name => 'Smith', - :verification_value => '737' - ) + month: 10, + year: exp_year, + first_name: 'John', + last_name: 'Smith', + verification_value: '737') @naranja_credit_card = credit_card('5895627823453005', - :month => 10, - :year => 2020, - :first_name => 'John', - :last_name => 'Smith', - :verification_value => '123' - ) - @declined_card = credit_card('4000300011112220') + month: 10, + year: exp_year, + first_name: 'John', + last_name: 'Smith', + verification_value: '123') + @declined_card = credit_card('5031433215406351', + first_name: 'OTHE') @options = { billing_address: address, shipping_address: address, @@ -40,7 +41,8 @@ def setup processing_mode: 'gateway', merchant_account_id: fixtures(:mercado_pago)[:merchant_account_id], fraud_scoring: true, - fraud_manual_review: true + fraud_manual_review: true, + payment_method_option_id: '123abc' } end @@ -90,6 +92,27 @@ def test_successful_purchase_with_american_express assert_equal 'accredited', response.message end + def test_successful_purchase_with_taxes_and_net_amount + # Minimum transaction amount is 0.30 EUR or ~1112 $COL on 1/27/20. + # This value must exceed that + amount = 10000_00 + + # These values need to be represented as dollars, so divide them by 100 + tax_amount = amount * 0.19 + @options[:net_amount] = (amount - tax_amount) / 100 + @options[:taxes] = [{ value: tax_amount / 100, type: 'IVA' }] + + response = @colombian_gateway.purchase(amount, @colombian_card, @options) + assert_success response + assert_equal 'accredited', response.message + end + + def test_successful_purchase_with_notification_url + response = @gateway.purchase(@amount, @credit_card, @options.merge(notification_url: 'https://www.spreedly.com/')) + assert_success response + assert_equal 'https://www.spreedly.com/', response.params['notification_url'] + end + def test_failed_purchase response = @gateway.purchase(@amount, @declined_card, @options) assert_failure response @@ -137,6 +160,12 @@ def test_successful_authorize_and_capture_with_naranja assert_equal 'accredited', capture.message end + def test_successful_authorize_with_capture_option + auth = @gateway.authorize(@amount, @credit_card, @options.merge(capture: true)) + assert_success auth + assert_equal 'accredited', auth.message + end + def test_failed_authorize response = @gateway.authorize(@amount, @declined_card, @options) assert_failure response @@ -144,7 +173,7 @@ def test_failed_authorize end def test_partial_capture - auth = @gateway.authorize(@amount+1, @credit_card, @options) + auth = @gateway.authorize(@amount + 1, @credit_card, @options) assert_success auth assert capture = @gateway.capture(@amount, auth.authorization) @@ -198,7 +227,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund end @@ -280,5 +309,4 @@ def test_transcript_scrubbing assert_scrubbed(@credit_card.verification_value, transcript) assert_scrubbed(@gateway.options[:access_token], transcript) end - end diff --git a/test/remote/gateways/remote_merchant_e_solutions_test.rb b/test/remote/gateways/remote_merchant_e_solutions_test.rb index 7226be98b4d..969d4cd14dd 100644 --- a/test/remote/gateways/remote_merchant_e_solutions_test.rb +++ b/test/remote/gateways/remote_merchant_e_solutions_test.rb @@ -11,16 +11,16 @@ def setup @declined_card = credit_card('4111111111111112') @options = { - :order_id => '123', - :billing_address => { - :name => 'John Doe', - :address1 => '123 State Street', - :address2 => 'Apartment 1', - :city => 'Nowhere', - :state => 'MT', - :country => 'US', - :zip => '55555', - :phone => '555-555-5555' + order_id: '123', + billing_address: { + name: 'John Doe', + address1: '123 State Street', + address2: 'Apartment 1', + city: 'Nowhere', + state: 'MT', + country: 'US', + zip: '55555', + phone: '555-555-5555' } } end @@ -44,7 +44,7 @@ def test_unsuccessful_purchase end def test_purchase_with_long_order_id - options = {order_id: 'thisislongerthan17characters'} + options = { order_id: 'thisislongerthan17characters' } assert response = @gateway.purchase(@amount, @credit_card, options) assert_success response assert_equal 'This transaction has been approved', response.message @@ -116,15 +116,15 @@ def test_successful_avs_check def test_unsuccessful_avs_check_with_bad_street_address options = { - :billing_address => { - :name => 'John Doe', - :address1 => '124 State Street', - :address2 => 'Apartment 1', - :city => 'Nowhere', - :state => 'MT', - :country => 'US', - :zip => '55555', - :phone => '555-555-5555' + billing_address: { + name: 'John Doe', + address1: '124 State Street', + address2: 'Apartment 1', + city: 'Nowhere', + state: 'MT', + country: 'US', + zip: '55555', + phone: '555-555-5555' } } assert response = @gateway.purchase(@amount, @credit_card, options) @@ -136,15 +136,15 @@ def test_unsuccessful_avs_check_with_bad_street_address def test_unsuccessful_avs_check_with_bad_zip options = { - :billing_address => { - :name => 'John Doe', - :address1 => '123 State Street', - :address2 => 'Apartment 1', - :city => 'Nowhere', - :state => 'MT', - :country => 'US', - :zip => '55554', - :phone => '555-555-5555' + billing_address: { + name: 'John Doe', + address1: '123 State Street', + address2: 'Apartment 1', + city: 'Nowhere', + state: 'MT', + country: 'US', + zip: '55554', + phone: '555-555-5555' } } assert response = @gateway.purchase(@amount, @credit_card, options) @@ -162,13 +162,13 @@ def test_successful_cvv_check def test_unsuccessful_cvv_check credit_card = ActiveMerchant::Billing::CreditCard.new({ - :first_name => 'John', - :last_name => 'Doe', - :number => '4111111111111111', - :month => '11', - :year => (Time.now.year + 1).to_s, - :verification_value => '555' - }) + first_name: 'John', + last_name: 'Doe', + number: '4111111111111111', + month: '11', + year: (Time.now.year + 1).to_s, + verification_value: '555' + }) assert response = @gateway.purchase(@amount, credit_card, @options) assert_equal 'N', response.cvv_result['code'] assert_equal 'CVV does not match', response.cvv_result['message'] @@ -176,9 +176,9 @@ def test_unsuccessful_cvv_check def test_invalid_login gateway = MerchantESolutionsGateway.new( - :login => '', - :password => '' - ) + login: '', + password: '' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response end @@ -191,10 +191,11 @@ def test_connection_failure_404_notfound_with_purchase end def test_successful_purchase_with_3dsecure_params - assert response = @gateway.purchase(@amount, @credit_card, @options.merge( - { :xid => 'ERERERERERERERERERERERERERE=', - :cavv => 'ERERERERERERERERERERERERERE=' - })) + options = @options.merge( + { xid: 'ERERERERERERERERERERERERERE=', + cavv: 'ERERERERERERERERERERERERERE=' } + ) + assert response = @gateway.purchase(@amount, @credit_card, options) assert_success response assert_equal 'This transaction has been approved', response.message end diff --git a/test/remote/gateways/remote_merchant_one_test.rb b/test/remote/gateways/remote_merchant_one_test.rb index 0e4f98fb23e..bad6b46aaae 100644 --- a/test/remote/gateways/remote_merchant_one_test.rb +++ b/test/remote/gateways/remote_merchant_one_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class RemoteMerchantOneTest < Test::Unit::TestCase - def setup @gateway = MerchantOneGateway.new(fixtures(:merchant_one)) @@ -10,9 +9,9 @@ def setup @declined_card = credit_card('1111111111111111') @options = { - :order_id => '1', - :description => 'Store Purchase', - :billing_address => { + order_id: '1', + description: 'Store Purchase', + billing_address: { name: 'Jim Smith', address1: '1234 My Street', address2: 'Apt 1', @@ -54,9 +53,9 @@ def test_failed_capture def test_invalid_login gateway = MerchantOneGateway.new( - :username => 'nnn', - :password => 'nnn' - ) + username: 'nnn', + password: 'nnn' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'Authentication Failed', response.message diff --git a/test/remote/gateways/remote_merchant_ware_test.rb b/test/remote/gateways/remote_merchant_ware_test.rb index b4b4dc2c899..1e46bcd8ccf 100644 --- a/test/remote/gateways/remote_merchant_ware_test.rb +++ b/test/remote/gateways/remote_merchant_ware_test.rb @@ -6,11 +6,11 @@ def setup @amount = rand(200..1199) - @credit_card = credit_card('5424180279791732', {:brand => 'master'}) + @credit_card = credit_card('5424180279791732', { brand: 'master' }) @options = { - :order_id => generate_unique_id, - :billing_address => address + order_id: generate_unique_id, + billing_address: address } end @@ -93,10 +93,10 @@ def test_failed_capture def test_invalid_login gateway = MerchantWareGateway.new( - :login => '', - :password => '', - :name => '' - ) + login: '', + password: '', + name: '' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'Server was unable to process request. ---> Invalid Credentials.', response.message diff --git a/test/remote/gateways/remote_merchant_ware_version_four_test.rb b/test/remote/gateways/remote_merchant_ware_version_four_test.rb index 155bdc2e460..2d18cbeb868 100644 --- a/test/remote/gateways/remote_merchant_ware_version_four_test.rb +++ b/test/remote/gateways/remote_merchant_ware_version_four_test.rb @@ -4,16 +4,16 @@ class RemoteMerchantWareVersionFourTest < Test::Unit::TestCase def setup @gateway = MerchantWareVersionFourGateway.new(fixtures(:merchant_ware_version_four)) @amount = rand(200..1199) - @credit_card = credit_card('5424180279791732', {:brand => 'master'}) + @credit_card = credit_card('5424180279791732', { brand: 'master' }) @declined_card = credit_card('1234567890123') @options = { - :order_id => generate_unique_id[0, 8], - :billing_address => address + order_id: generate_unique_id[0, 8], + billing_address: address } @reference_purchase_options = { - :order_id => generate_unique_id[0, 8] + order_id: generate_unique_id[0, 8] } end @@ -92,10 +92,10 @@ def test_failed_capture def test_invalid_login gateway = MerchantWareVersionFourGateway.new( - :login => '', - :password => '', - :name => '' - ) + login: '', + password: '', + name: '' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'Invalid Credentials.', response.message diff --git a/test/remote/gateways/remote_merchant_warrior_test.rb b/test/remote/gateways/remote_merchant_warrior_test.rb index d9c5e826c4a..f3ffd41635c 100644 --- a/test/remote/gateways/remote_merchant_warrior_test.rb +++ b/test/remote/gateways/remote_merchant_warrior_test.rb @@ -2,29 +2,37 @@ class RemoteMerchantWarriorTest < Test::Unit::TestCase def setup - @gateway = MerchantWarriorGateway.new(fixtures(:merchant_warrior).merge(:test => true)) + @gateway = MerchantWarriorGateway.new(fixtures(:merchant_warrior).merge(test: true)) @success_amount = 100 @failure_amount = 205 @credit_card = credit_card( - '5123456789012346', - :month => 5, - :year => Time.now.year + 2, - :verification_value => '123', - :brand => 'master' + '4564710000000004', + month: '2', + year: '29', + verification_value: '847', + brand: 'visa' + ) + + @expired_card = credit_card( + '4564710000000012', + month: '2', + year: '05', + verification_value: '963', + brand: 'visa' ) @options = { - :billing_address => { - :name => 'Longbob Longsen', - :country => 'AU', - :state => 'Queensland', - :city => 'Brisbane', - :address1 => '123 test st', - :zip => '4000' + billing_address: { + name: 'Longbob Longsen', + country: 'AU', + state: 'Queensland', + city: 'Brisbane', + address1: '123 test st', + zip: '4000' }, - :description => 'TestProduct' + description: 'TestProduct' } end @@ -44,15 +52,15 @@ def test_successful_authorize def test_successful_purchase assert purchase = @gateway.purchase(@success_amount, @credit_card, @options) - assert_equal 'Transaction approved', purchase.message assert_success purchase + assert_equal 'Transaction approved', purchase.message assert_not_nil purchase.params['transaction_id'] assert_equal purchase.params['transaction_id'], purchase.authorization end def test_failed_purchase - assert purchase = @gateway.purchase(@failure_amount, @credit_card, @options) - assert_equal 'Transaction declined', purchase.message + assert purchase = @gateway.purchase(@success_amount, @expired_card, @options) + assert_match 'Card has expired', purchase.message assert_failure purchase assert_not_nil purchase.params['transaction_id'] assert_equal purchase.params['transaction_id'], purchase.authorization @@ -68,10 +76,25 @@ def test_successful_refund def test_failed_refund assert refund = @gateway.refund(@success_amount, 'invalid-transaction-id') - assert_match %r{Invalid transactionID}, refund.message + assert_match %r{'transactionID' not found}, refund.message assert_failure refund end + def test_successful_void + assert purchase = @gateway.purchase(@success_amount, @credit_card, @options) + assert_success purchase + + assert void = @gateway.void(purchase.authorization, amount: @success_amount) + assert_success void + assert_equal 'Transaction approved', void.message + end + + def test_failed_void + assert void = @gateway.void('invalid-transaction-id', amount: @success_amount) + assert_match %r{'transactionID' not found}, void.message + assert_failure void + end + def test_capture_too_much assert auth = @gateway.authorize(300, @credit_card, @options) assert_success auth @@ -114,6 +137,37 @@ def test_successful_purchase_with_funky_names assert_success purchase end + def test_successful_purchase_with_recurring_flag + @options[:recurring_flag] = 1 + test_successful_purchase + end + + def test_successful_authorize_with_recurring_flag + @options[:recurring_flag] = 1 + test_successful_authorize + end + + def test_successful_authorize_with_soft_descriptors + @options[:descriptor_name] = 'FOO*Test' + @options[:descriptor_city] = 'Melbourne' + @options[:descriptor_state] = 'VIC' + test_successful_authorize + end + + def test_successful_purchase_with_soft_descriptors + @options[:descriptor_name] = 'FOO*Test' + @options[:descriptor_city] = 'Melbourne' + @options[:descriptor_state] = 'VIC' + test_successful_purchase + end + + def test_successful_refund_with_soft_descriptors + @options[:descriptor_name] = 'FOO*Test' + @options[:descriptor_city] = 'Melbourne' + @options[:descriptor_state] = 'VIC' + test_successful_refund + end + def test_transcript_scrubbing transcript = capture_transcript(@gateway) do @gateway.purchase(@success_amount, @credit_card, @options) diff --git a/test/remote/gateways/remote_mercury_certification_test.rb b/test/remote/gateways/remote_mercury_certification_test.rb index 56cb9de3234..9422b396241 100644 --- a/test/remote/gateways/remote_mercury_certification_test.rb +++ b/test/remote/gateways/remote_mercury_certification_test.rb @@ -13,7 +13,7 @@ def test_sale_and_reversal assert_success sale assert_equal 'AP', sale.params['text_response'] - reversal = tokenization_gateway.void(sale.authorization, options.merge(:try_reversal => true)) + reversal = tokenization_gateway.void(sale.authorization, options.merge(try_reversal: true)) assert_success reversal assert_equal 'REVERSED', reversal.params['text_response'] end @@ -45,7 +45,7 @@ def test_preauth_and_reversal assert_success preauth assert_equal 'AP', preauth.params['text_response'] - reversal = tokenization_gateway.void(preauth.authorization, options.merge(:try_reversal => true)) + reversal = tokenization_gateway.void(preauth.authorization, options.merge(try_reversal: true)) assert_success reversal assert_equal 'REVERSED', reversal.params['text_response'] end @@ -70,45 +70,45 @@ def test_preauth_capture_and_reversal def tokenization_gateway @tokenization_gateway ||= MercuryGateway.new( - :login => '023358150511666', - :password => 'xyz' + login: '023358150511666', + password: 'xyz' ) end def visa @visa ||= credit_card( '4003000123456781', - :brand => 'visa', - :month => '12', - :year => '15', - :verification_value => '123' + brand: 'visa', + month: '12', + year: '15', + verification_value: '123' ) end def disc @disc ||= credit_card( '6011000997235373', - :brand => 'discover', - :month => '12', - :year => '15', - :verification_value => '362' + brand: 'discover', + month: '12', + year: '15', + verification_value: '362' ) end def mc @mc ||= credit_card( '5439750001500248', - :brand => 'master', - :month => '12', - :year => '15', - :verification_value => '123' + brand: 'master', + month: '12', + year: '15', + verification_value: '123' ) end - def options(order_id=nil, other={}) + def options(order_id = nil, other = {}) { - :order_id => order_id, - :description => 'ActiveMerchant', + order_id: order_id, + description: 'ActiveMerchant' }.merge(other) end end diff --git a/test/remote/gateways/remote_mercury_test.rb b/test/remote/gateways/remote_mercury_test.rb index 4dd1a95b80c..37079eaf852 100644 --- a/test/remote/gateways/remote_mercury_test.rb +++ b/test/remote/gateways/remote_mercury_test.rb @@ -9,27 +9,27 @@ def setup @amount = 100 - @credit_card = credit_card('4003000123456781', :brand => 'visa', :month => '12', :year => '18') + @credit_card = credit_card('4003000123456781', brand: 'visa', month: '12', year: '18') @track_1_data = '%B4003000123456781^LONGSEN/L. ^18121200000000000000**123******?*' @track_2_data = ';5413330089010608=2512101097750213?' @options = { - :order_id => 'c111111111.1', - :description => 'ActiveMerchant' + order_id: 'c111111111.1', + description: 'ActiveMerchant' } @options_with_billing = @options.merge( - :merchant => '999', - :billing_address => { - :address1 => '4 Corporate SQ', - :zip => '30329' + merchant: '999', + billing_address: { + address1: '4 Corporate SQ', + zip: '30329' } ) @full_options = @options_with_billing.merge( - :ip => '123.123.123.123', - :merchant => 'Open Dining', - :customer => 'Tim', - :tax => '5' + ip: '123.123.123.123', + merchant: 'Open Dining', + customer: 'Tim', + tax: '5' ) close_batch @@ -101,7 +101,7 @@ def test_avs_and_cvv_results }, response.avs_result ) - assert_equal({'code'=>'M', 'message'=>'CVV matches'}, response.cvv_result) + assert_equal({ 'code' => 'M', 'message' => 'CVV matches' }, response.cvv_result) end def test_avs_and_cvv_results_with_track_data @@ -118,7 +118,7 @@ def test_avs_and_cvv_results_with_track_data }, response.avs_result ) - assert_equal({'code'=>'P', 'message'=>'CVV not processed'}, response.cvv_result) + assert_equal({ 'code' => 'P', 'message' => 'CVV not processed' }, response.cvv_result) end def test_partial_capture @@ -144,7 +144,7 @@ def test_authorize_with_bad_expiration_date end def test_mastercard_authorize_and_capture_with_refund - mc = credit_card('5499990123456781', :brand => 'master') + mc = credit_card('5499990123456781', brand: 'master') response = @gateway.authorize(200, mc, @options) assert_success response @@ -161,7 +161,7 @@ def test_mastercard_authorize_and_capture_with_refund end def test_amex_authorize_and_capture_with_refund - amex = credit_card('373953244361001', :brand => 'american_express', :verification_value => '1234') + amex = credit_card('373953244361001', brand: 'american_express', verification_value: '1234') response = @gateway.authorize(201, amex, @options) assert_success response @@ -177,7 +177,7 @@ def test_amex_authorize_and_capture_with_refund end def test_discover_authorize_and_capture - discover = credit_card('6011000997235373', :brand => 'discover') + discover = credit_card('6011000997235373', brand: 'discover') response = @gateway.authorize(225, discover, @options_with_billing) assert_success response @@ -206,7 +206,7 @@ def test_authorize_and_capture_without_tokenization assert_success response assert_equal '1.00', response.params['authorize'] - capture = gateway.capture(nil, response.authorization, :credit_card => @credit_card) + capture = gateway.capture(nil, response.authorization, credit_card: @credit_card) assert_success capture assert_equal '1.00', capture.params['authorize'] end diff --git a/test/remote/gateways/remote_metrics_global_test.rb b/test/remote/gateways/remote_metrics_global_test.rb index 3669fd41a11..329c735622f 100644 --- a/test/remote/gateways/remote_metrics_global_test.rb +++ b/test/remote/gateways/remote_metrics_global_test.rb @@ -6,11 +6,11 @@ def setup @gateway = MetricsGlobalGateway.new(fixtures(:metrics_global)) @amount = 100 - @credit_card = credit_card('4111111111111111', :verification_value => '999') + @credit_card = credit_card('4111111111111111', verification_value: '999') @options = { - :order_id => generate_unique_id, - :billing_address => address(:address1 => '888 Test Street', :zip => '77777'), - :description => 'Store purchase' + order_id: generate_unique_id, + billing_address: address(address1: '888 Test Street', zip: '77777'), + description: 'Store purchase' } end @@ -57,19 +57,19 @@ def test_authorization_and_void def test_bad_login gateway = MetricsGlobalGateway.new( - :login => 'X', - :password => 'Y' + login: 'X', + password: 'Y' ) assert response = gateway.purchase(@amount, @credit_card) assert_equal Response, response.class - assert_equal ['avs_result_code', - 'card_code', - 'response_code', - 'response_reason_code', - 'response_reason_text', - 'transaction_id'], response.params.keys.sort + assert_equal %w[avs_result_code + card_code + response_code + response_reason_code + response_reason_text + transaction_id], response.params.keys.sort assert_match(/Authentication Failed/, response.message) @@ -78,19 +78,19 @@ def test_bad_login def test_using_test_request gateway = MetricsGlobalGateway.new( - :login => 'X', - :password => 'Y' + login: 'X', + password: 'Y' ) assert response = gateway.purchase(@amount, @credit_card) assert_equal Response, response.class - assert_equal ['avs_result_code', - 'card_code', - 'response_code', - 'response_reason_code', - 'response_reason_text', - 'transaction_id'], response.params.keys.sort + assert_equal %w[avs_result_code + card_code + response_code + response_reason_code + response_reason_text + transaction_id], response.params.keys.sort assert_match(/Authentication Failed/, response.message) diff --git a/test/remote/gateways/remote_micropayment_test.rb b/test/remote/gateways/remote_micropayment_test.rb index fb4589e7d71..d5c49cf3787 100644 --- a/test/remote/gateways/remote_micropayment_test.rb +++ b/test/remote/gateways/remote_micropayment_test.rb @@ -89,7 +89,7 @@ def test_successful_void_for_purchase end def test_successful_authorize_and_capture_and_refund - response = @gateway.authorize(@amount, @credit_card, @options.merge(recurring: false)) + response = @gateway.authorize(@amount, @credit_card, @options.merge(recurring: false)) assert_success response assert_equal 'Succeeded', response.message assert_match %r(^\w+\|.+$), response.authorization diff --git a/test/remote/gateways/remote_migs_test.rb b/test/remote/gateways/remote_migs_test.rb index 69ea544201c..a920aec863d 100644 --- a/test/remote/gateways/remote_migs_test.rb +++ b/test/remote/gateways/remote_migs_test.rb @@ -10,18 +10,18 @@ def setup @amount = 100 @declined_amount = 105 - @visa = credit_card('4987654321098769', :month => 5, :year => 2021, :brand => 'visa') - @master = credit_card('5123456789012346', :month => 5, :year => 2021, :brand => 'master') - @amex = credit_card('371449635311004', :month => 5, :year => 2021, :brand => 'american_express') - @diners = credit_card('30123456789019', :month => 5, :year => 2021, :brand => 'diners_club') + @visa = credit_card('4987654321098769', month: 5, year: 2021, brand: 'visa') + @master = credit_card('5123456789012346', month: 5, year: 2021, brand: 'master') + @amex = credit_card('371449635311004', month: 5, year: 2021, brand: 'american_express') + @diners = credit_card('30123456789019', month: 5, year: 2021, brand: 'diners_club') @credit_card = @visa @valid_tx_source = 'MOTO' @invalid_tx_source = 'penguin' @options = { - :order_id => '1', - :currency => 'SAR' + order_id: '1', + currency: 'SAR' } @three_ds_options = { @@ -36,10 +36,10 @@ def setup def test_server_purchase_url options = { - :order_id => 1, - :unique_id => 9, - :return_url => 'http://localhost:8080/payments/return', - :currency => 'SAR' + order_id: 1, + unique_id: 9, + return_url: 'http://localhost:8080/payments/return', + currency: 'SAR' } choice_url = @gateway.purchase_offsite_url(@amount, options) @@ -52,7 +52,7 @@ def test_server_purchase_url } responses.each_pair do |card_type, response_text| - url = @gateway.purchase_offsite_url(@amount, options.merge(:card_type => card_type)) + url = @gateway.purchase_offsite_url(@amount, options.merge(card_type: card_type)) assert_response_match response_text, url end end @@ -157,7 +157,7 @@ def test_status end def test_invalid_login - gateway = MigsGateway.new(:login => '', :password => '') + gateway = MigsGateway.new(login: '', password: '') assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'Required field vpc_Merchant was not present in the request', response.message @@ -211,7 +211,7 @@ def assert_response_match(regexp, url) def https_response(url, cookie = nil) retry_exceptions do - headers = cookie ? {'Cookie' => cookie} : {} + headers = cookie ? { 'Cookie' => cookie } : {} response = raw_ssl_request(:get, url, nil, headers) if response.is_a?(Net::HTTPRedirection) new_cookie = [cookie, response['Set-Cookie']].compact.join(';') diff --git a/test/remote/gateways/remote_modern_payments_cim_test.rb b/test/remote/gateways/remote_modern_payments_cim_test.rb index 8c310d0fe17..ed480d5fa65 100644 --- a/test/remote/gateways/remote_modern_payments_cim_test.rb +++ b/test/remote/gateways/remote_modern_payments_cim_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class RemoteModernPaymentsCimTest < Test::Unit::TestCase - def setup @gateway = ModernPaymentsCimGateway.new(fixtures(:modern_payments)) @@ -10,8 +9,8 @@ def setup @declined_card = credit_card('4000000000000000') @options = { - :billing_address => address, - :customer => 'JIMSMITH2000' + billing_address: address, + customer: 'JIMSMITH2000' } end @@ -47,9 +46,9 @@ def test_succsessful_authorize_credit_card_payment def test_invalid_login gateway = ModernPaymentsCimGateway.new( - :login => '', - :password => '' - ) + login: '', + password: '' + ) assert response = gateway.create_customer(@options) assert_failure response assert_equal ModernPaymentsCimGateway::ERROR_MESSAGE, response.message diff --git a/test/remote/gateways/remote_modern_payments_test.rb b/test/remote/gateways/remote_modern_payments_test.rb index e0fff6eeb95..a5467e42fc0 100644 --- a/test/remote/gateways/remote_modern_payments_test.rb +++ b/test/remote/gateways/remote_modern_payments_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class RemoteModernPaymentTest < Test::Unit::TestCase - def setup @gateway = ModernPaymentsGateway.new(fixtures(:modern_payments)) @@ -10,9 +9,9 @@ def setup @declined_card = credit_card('4000000000000000') @options = { - :order_id => '1', - :billing_address => address, - :description => 'Store Purchase' + order_id: '1', + billing_address: address, + description: 'Store Purchase' } end @@ -34,9 +33,9 @@ def test_unsuccessful_purchase def test_invalid_login gateway = ModernPaymentsGateway.new( - :login => '', - :password => '' - ) + login: '', + password: '' + ) assert_raises(ActiveMerchant::ResponseError) do gateway.purchase(@amount, @credit_card, @options) diff --git a/test/remote/gateways/remote_monei_test.rb b/test/remote/gateways/remote_monei_test.rb index 984187d4dee..08866fffe00 100755 --- a/test/remote/gateways/remote_monei_test.rb +++ b/test/remote/gateways/remote_monei_test.rb @@ -74,7 +74,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -82,10 +82,10 @@ def test_multi_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_failure capture end @@ -106,7 +106,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund end @@ -114,10 +114,10 @@ def test_multi_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_failure refund end @@ -154,13 +154,12 @@ def test_failed_verify def test_invalid_login gateway = MoneiGateway.new( - :sender_id => 'mother', - :channel_id => 'there is no other', - :login => 'like mother', - :pwd => 'so treat Her right' + sender_id: 'mother', + channel_id: 'there is no other', + login: 'like mother', + pwd: 'so treat Her right' ) response = gateway.purchase(@amount, @credit_card, @options) assert_failure response end - end diff --git a/test/remote/gateways/remote_moneris_test.rb b/test/remote/gateways/remote_moneris_test.rb index e0e5a01ec3f..6302242f237 100644 --- a/test/remote/gateways/remote_moneris_test.rb +++ b/test/remote/gateways/remote_moneris_test.rb @@ -6,11 +6,11 @@ def setup @gateway = MonerisGateway.new(fixtures(:moneris)) @amount = 100 - @credit_card = credit_card('4242424242424242', :verification_value => '012') + @credit_card = credit_card('4242424242424242', verification_value: '012') @options = { - :order_id => generate_unique_id, - :customer => generate_unique_id, - :billing_address => address + order_id: generate_unique_id, + customer: generate_unique_id, + billing_address: address } end @@ -130,7 +130,7 @@ def test_successful_authorization_and_capture_and_void response = @gateway.capture(@amount, response.authorization) assert_success response - void = @gateway.void(response.authorization, :purchasecorrection => true) + void = @gateway.void(response.authorization, purchasecorrection: true) assert_success void end @@ -159,7 +159,7 @@ def test_successful_purchase_and_void purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - void = @gateway.void(purchase.authorization, :purchasecorrection => true) + void = @gateway.void(purchase.authorization, purchasecorrection: true) assert_success void end @@ -199,6 +199,45 @@ def test_successful_store @data_key = response.params['data_key'] end + def test_successful_store_with_duration + assert response = @gateway.store(@credit_card, duration: 600) + assert_success response + assert_equal 'Successfully registered cc details', response.message + assert response.params['data_key'].present? + end + + # AVS result fields are stored in the vault and returned as part of the + # XML response under (which isn't parsed by ActiveMerchant so + # we can't test for it). + # + # Actual AVS results aren't returned processed until an actual transaction is made + # so we make a second purchase request. + def test_successful_store_and_purchase_with_avs + gateway = MonerisGateway.new(fixtures(:moneris).merge(avs_enabled: true)) + + # card number triggers AVS match + @credit_card = credit_card('4761739012345637', verification_value: '012') + assert response = gateway.store(@credit_card, @options) + assert_success response + assert_equal 'Successfully registered cc details', response.message + assert response.params['data_key'].present? + data_key = response.params['data_key'] + + options_without_address = @options.dup + options_without_address.delete(:address) + assert response = gateway.purchase(@amount, data_key, options_without_address) + assert_success response + assert_equal 'Approved', response.message + assert_false response.authorization.blank? + + assert_equal(response.avs_result, { + 'code' => 'M', + 'message' => 'Street address and postal code match.', + 'street_match' => 'Y', + 'postal_match' => 'Y' + }) + end + def test_successful_unstore test_successful_store assert response = @gateway.unstore(@data_key) @@ -239,20 +278,20 @@ def test_failed_authorization_with_vault def test_cvv_match_when_not_enabled assert response = @gateway.purchase(1039, @credit_card, @options) assert_success response - assert_equal({'code' => nil, 'message' => nil}, response.cvv_result) + assert_equal({ 'code' => nil, 'message' => nil }, response.cvv_result) end def test_cvv_no_match_when_not_enabled assert response = @gateway.purchase(1053, @credit_card, @options) assert_success response - assert_equal({'code' => nil, 'message' => nil}, response.cvv_result) + assert_equal({ 'code' => nil, 'message' => nil }, response.cvv_result) end def test_cvv_match_when_enabled gateway = MonerisGateway.new(fixtures(:moneris).merge(cvv_enabled: true)) assert response = gateway.purchase(1039, @credit_card, @options) assert_success response - assert_equal({'code' => 'M', 'message' => 'CVV matches'}, response.cvv_result) + assert_equal({ 'code' => 'M', 'message' => 'CVV matches' }, response.cvv_result) end def test_avs_result_valid_when_enabled @@ -261,10 +300,10 @@ def test_avs_result_valid_when_enabled assert response = gateway.purchase(1010, @credit_card, @options) assert_success response assert_equal(response.avs_result, { - 'code' => 'A', - 'message' => 'Street address matches, but postal code does not match.', - 'street_match' => 'Y', - 'postal_match' => 'N' + 'code' => 'A', + 'message' => 'Street address matches, but postal code does not match.', + 'street_match' => 'Y', + 'postal_match' => 'N' }) end @@ -274,10 +313,10 @@ def test_avs_result_nil_when_address_absent assert response = gateway.purchase(1010, @credit_card, @options.tap { |x| x.delete(:billing_address) }) assert_success response assert_equal(response.avs_result, { - 'code' => nil, - 'message' => nil, - 'street_match' => nil, - 'postal_match' => nil + 'code' => nil, + 'message' => nil, + 'street_match' => nil, + 'postal_match' => nil }) end @@ -285,10 +324,10 @@ def test_avs_result_nil_when_efraud_disabled assert response = @gateway.purchase(@amount, @credit_card, @options) assert_success response assert_equal(response.avs_result, { - 'code' => nil, - 'message' => nil, - 'street_match' => nil, - 'postal_match' => nil + 'code' => nil, + 'message' => nil, + 'street_match' => nil, + 'postal_match' => nil }) end diff --git a/test/remote/gateways/remote_moneris_us_test.rb b/test/remote/gateways/remote_moneris_us_test.rb deleted file mode 100644 index dd5c30614f3..00000000000 --- a/test/remote/gateways/remote_moneris_us_test.rb +++ /dev/null @@ -1,261 +0,0 @@ -require 'test_helper' - -class MonerisUsRemoteTest < Test::Unit::TestCase - def setup - Base.mode = :test - - @gateway = MonerisUsGateway.new(fixtures(:moneris_us)) - @amount = 100 - @credit_card = credit_card('4242424242424242') - @options = { - :order_id => generate_unique_id, - :billing_address => address, - :description => 'Store Purchase' - } - @check = check({ - routing_number: '011000015', - account_number: '1234455', - number: 123 - }) - end - - def test_successful_purchase - assert response = @gateway.purchase(@amount, @credit_card, @options) - assert_success response - assert_equal 'Approved', response.message - assert_false response.authorization.blank? - end - - def test_successful_echeck_purchase - response = @gateway.purchase(@amount, @check, @options) - assert_success response - assert response.test? - assert_equal 'Registered', response.message - assert response.authorization - end - - def test_failed_echeck_purchase - response = @gateway.purchase(105, check(routing_number: 5), @options) - assert_failure response - assert response.test? - assert_equal 'Unspecified error', response.message - end - - def test_successful_authorization - response = @gateway.authorize(@amount, @credit_card, @options) - assert_success response - assert_false response.authorization.blank? - end - - def test_successful_verify - response = @gateway.verify(@credit_card, @options) - assert_success response - assert_equal 'Approved', response.message - assert response.authorization - end - - def test_failed_verify - response = @gateway.verify(credit_card(nil), @options) - assert_failure response - assert_match %r{Invalid pan parameter}, response.message - end - - def test_failed_authorization - response = @gateway.authorize(105, @credit_card, @options) - assert_failure response - end - - def test_successful_authorization_and_capture - response = @gateway.authorize(@amount, @credit_card, @options) - assert_success response - assert response.authorization - - response = @gateway.capture(@amount, response.authorization) - assert_success response - end - - def test_successful_authorization_and_void - response = @gateway.authorize(@amount, @credit_card, @options) - assert_success response - assert response.authorization - - # Moneris cannot void a preauthorization - # You must capture the auth transaction with an amount of $0.00 - void = @gateway.capture(0, response.authorization) - assert_success void - end - - def test_successful_purchase_and_void - purchase = @gateway.purchase(@amount, @credit_card, @options) - assert_success purchase - - void = @gateway.void(purchase.authorization) - assert_success void - end - - def test_failed_purchase_and_void - purchase = @gateway.purchase(101, @credit_card, @options) - assert_failure purchase - - void = @gateway.void(purchase.authorization) - assert_failure void - end - - def test_successful_purchase_and_refund - purchase = @gateway.purchase(@amount, @credit_card, @options) - assert_success purchase - - refund = @gateway.refund(@amount, purchase.authorization) - assert_success refund - end - - def test_failed_purchase_from_error - assert response = @gateway.purchase(150, @credit_card, @options) - assert_failure response - assert_equal 'Declined', response.message - end - - def test_successful_store - assert response = @gateway.store(@credit_card) - assert_success response - assert_equal 'Successfully registered cc details', response.message - assert response.params['data_key'].present? - @data_key = response.params['data_key'] - end - - def test_successful_echeck_store - assert response = @gateway.store(@check) - assert_success response - assert_equal 'Successfully registered ach details', response.message - assert response.params['data_key'].present? - @data_key_echeck = response.params['data_key'] - end - - def test_successful_unstore - test_successful_store - assert response = @gateway.unstore(@data_key) - assert_success response - assert_equal 'Successfully deleted cc details', response.message - assert response.params['data_key'].present? - end - - def test_successful_echeck_unstore - test_successful_echeck_store - assert response = @gateway.unstore(@data_key_echeck) - assert_success response - assert_equal 'Successfully deleted ach details', response.message - assert response.params['data_key'].present? - end - - def test_update - test_successful_store - assert response = @gateway.update(@data_key, @credit_card) - assert_success response - assert_equal 'Successfully updated cc details', response.message - assert response.params['data_key'].present? - end - - def test_echeck_update - test_successful_echeck_store - assert response = @gateway.update(@data_key_echeck, @check) - assert_success response - assert_equal 'Successfully updated ach details', response.message - assert response.params['data_key'].present? - end - - def test_successful_purchase_with_vault - test_successful_store - assert response = @gateway.purchase(@amount, @data_key, @options) - assert_success response - assert_equal 'Approved', response.message - assert_false response.authorization.blank? - end - - def test_successful_authorization_with_vault - test_successful_store - assert response = @gateway.authorize(@amount, @data_key, @options) - assert_success response - assert_false response.authorization.blank? - end - - def test_failed_authorization_with_vault - test_successful_store - response = @gateway.authorize(105, @data_key, @options) - assert_failure response - end - - def test_cvv_match_when_not_enabled - assert response = @gateway.purchase(1039, @credit_card, @options) - assert_success response - assert_equal({'code' => nil, 'message' => nil}, response.cvv_result) - end - - def test_cvv_no_match_when_not_enabled - assert response = @gateway.purchase(1053, @credit_card, @options) - assert_success response - assert_equal({'code' => nil, 'message' => nil}, response.cvv_result) - end - - def test_cvv_match_when_enabled - gateway = MonerisGateway.new(fixtures(:moneris).merge(cvv_enabled: true)) - assert response = gateway.purchase(1039, @credit_card, @options) - assert_success response - assert_equal({'code' => 'M', 'message' => 'CVV matches'}, response.cvv_result) - end - - def test_cvv_no_match_when_enabled - gateway = MonerisGateway.new(fixtures(:moneris).merge(cvv_enabled: true)) - assert response = gateway.purchase(1053, @credit_card, @options) - assert_success response - assert_equal({'code' => 'N', 'message' => 'CVV does not match'}, response.cvv_result) - end - - def test_avs_result_valid_when_enabled - gateway = MonerisGateway.new(fixtures(:moneris).merge(avs_enabled: true)) - - assert response = gateway.purchase(1010, @credit_card, @options) - assert_success response - assert_equal(response.avs_result, { - 'code' => 'A', - 'message' => 'Street address matches, but postal code does not match.', - 'street_match' => 'Y', - 'postal_match' => 'N' - }) - end - - def test_avs_result_nil_when_address_absent - gateway = MonerisGateway.new(fixtures(:moneris).merge(avs_enabled: true)) - - assert response = gateway.purchase(1010, @credit_card, @options.tap { |x| x.delete(:billing_address) }) - assert_success response - assert_equal(response.avs_result, { - 'code' => nil, - 'message' => nil, - 'street_match' => nil, - 'postal_match' => nil - }) - end - - def test_avs_result_nil_when_efraud_disabled - assert response = @gateway.purchase(@amount, @credit_card, @options) - assert_success response - assert_equal(response.avs_result, { - 'code' => nil, - 'message' => nil, - 'street_match' => nil, - 'postal_match' => nil - }) - end - - def test_transcript_scrubbing - transcript = capture_transcript(@gateway) do - @gateway.purchase(@amount, @credit_card, @options) - end - transcript = @gateway.scrub(transcript) - - assert_scrubbed(@credit_card.number, transcript) - assert_scrubbed(@credit_card.verification_value, transcript) - assert_scrubbed(@gateway.options[:password], transcript) - end - -end diff --git a/test/remote/gateways/remote_money_movers_test.rb b/test/remote/gateways/remote_money_movers_test.rb index 64165cb50d8..ddbc976fdb0 100644 --- a/test/remote/gateways/remote_money_movers_test.rb +++ b/test/remote/gateways/remote_money_movers_test.rb @@ -10,9 +10,9 @@ def setup @credit_card = credit_card('4111111111111111') @options = { - :order_id => generate_unique_id, - :billing_address => address, - :description => 'Active Merchant Remote Test Purchase' + order_id: generate_unique_id, + billing_address: address, + description: 'Active Merchant Remote Test Purchase' } end @@ -72,9 +72,9 @@ def test_authorize_and_capture def test_invalid_login gateway = MoneyMoversGateway.new( - :login => '', - :password => '' - ) + login: '', + password: '' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'Error in transaction data or system error', response.message diff --git a/test/remote/gateways/remote_mundipagg_test.rb b/test/remote/gateways/remote_mundipagg_test.rb index 9a3f6f61bfc..8701198f89c 100644 --- a/test/remote/gateways/remote_mundipagg_test.rb +++ b/test/remote/gateways/remote_mundipagg_test.rb @@ -18,11 +18,37 @@ def setup @options = { gateway_affiliation_id: fixtures(:mundipagg)[:gateway_affiliation_id], - billing_address: address({neighborhood: 'Sesame Street'}), + billing_address: address({ neighborhood: 'Sesame Street' }), description: 'Store Purchase' } - @excess_length_neighborhood = address({neighborhood: 'Super Long Neighborhood Name' * 5}) + @submerchant_options = { + submerchant: { + "merchant_category_code": '44444', + "payment_facilitator_code": '5555555', + "code": 'code2', + "name": 'Sub Tony Stark', + "document": '123456789', + "type": 'individual', + "phone": { + "country_code": '55', + "number": '000000000', + "area_code": '21' + }, + "address": { + "street": 'Malibu Point', + "number": '10880', + "complement": 'A', + "neighborhood": 'Central Malibu', + "city": 'Malibu', + "state": 'CA', + "country": 'US', + "zip_code": '24210-460' + } + } + } + + @excess_length_neighborhood = address({ neighborhood: 'Super Long Neighborhood Name' * 5 }) @neighborhood_length_error = 'Invalid parameters; The request is invalid. | The field neighborhood must be a string with a maximum length of 64.' end @@ -67,6 +93,13 @@ def test_successful_purchase_with_vr_voucher assert_equal 'Simulator|Transação de simulação autorizada com sucesso', response.message end + def test_successful_purchase_with_submerchant + options = @options.update(@submerchant_options) + response = @gateway.purchase(@amount, @credit_card, options) + assert_success response + assert_equal 'Simulator|Transação de simulação autorizada com sucesso', response.message + end + def test_failed_purchase test_failed_purchase_with(@declined_card) end @@ -92,6 +125,13 @@ def test_successful_authorize_and_capture_with_alelo_card test_successful_authorize_and_capture_with(@alelo_voucher) end + def test_successful_authorize_with_submerchant + options = @options.update(@submerchant_options) + response = @gateway.authorize(@amount, @credit_card, options) + assert_success response + assert_equal 'Simulator|Transação de simulação autorizada com sucesso', response.message + end + def test_failed_authorize test_failed_authorize_with(@declined_card) end @@ -231,7 +271,7 @@ def test_invalid_login def test_gateway_id_fallback gateway = MundipaggGateway.new(api_key: fixtures(:mundipagg)[:api_key], gateway_id: fixtures(:mundipagg)[:gateway_id]) options = { - billing_address: address({neighborhood: 'Sesame Street'}), + billing_address: address({ neighborhood: 'Sesame Street' }), description: 'Store Purchase' } response = gateway.purchase(@amount, @credit_card, options) @@ -282,7 +322,7 @@ def test_partial_capture_with(card) auth = @gateway.authorize(@amount, card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end diff --git a/test/remote/gateways/remote_nab_transact_test.rb b/test/remote/gateways/remote_nab_transact_test.rb index 55289ec9ff0..19052fe001c 100644 --- a/test/remote/gateways/remote_nab_transact_test.rb +++ b/test/remote/gateways/remote_nab_transact_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class RemoteNabTransactTest < Test::Unit::TestCase - def setup @gateway = NabTransactGateway.new(fixtures(:nab_transact)) @privileged_gateway = NabTransactGateway.new(fixtures(:nab_transact_privileged)) @@ -12,9 +11,9 @@ def setup @declined_card = credit_card('4111111111111234') @options = { - :order_id => '1', - :billing_address => address, - :description => 'NAB Transact Purchase' + order_id: '1', + billing_address: address, + description: 'NAB Transact Purchase' } end @@ -64,11 +63,11 @@ def test_unsuccessful_purchase_bad_credit_card # ensure we get the error. def test_successful_purchase_with_card_acceptor card_acceptor_options = { - :merchant_name => 'ActiveMerchant', - :merchant_location => 'Melbourne' + merchant_name: 'ActiveMerchant', + merchant_location: 'Melbourne' } card_acceptor_options.each do |key, value| - options = @options.merge({key => value}) + options = @options.merge({ key => value }) assert response = @gateway.purchase(@amount, @credit_card, options) assert_failure response assert_equal 'Permission denied', response.message @@ -122,18 +121,18 @@ def test_unsuccessful_capture_amount_greater_than_authorized authorization = auth.authorization - assert capture = @gateway.capture(@amount+100, authorization) + assert capture = @gateway.capture(@amount + 100, authorization) assert_failure capture assert_equal 'Preauth was done for smaller amount', capture.message end def test_authorize_and_capture_with_card_acceptor card_acceptor_options = { - :merchant_name => 'ActiveMerchant', - :merchant_location => 'Melbourne' + merchant_name: 'ActiveMerchant', + merchant_location: 'Melbourne' } card_acceptor_options.each do |key, value| - options = @options.merge({key => value}) + options = @options.merge({ key => value }) assert response = @gateway.authorize(@amount, @credit_card, options) assert_failure response assert_equal 'Permission denied', response.message @@ -162,11 +161,11 @@ def test_successful_refund # You need to speak to NAB Transact to have this feature enabled on # your account otherwise you will receive a "Permission denied" error def test_credit - assert response = @gateway.credit(@amount, @credit_card, {:order_id => '1'}) + assert response = @gateway.credit(@amount, @credit_card, { order_id: '1' }) assert_failure response assert_equal 'Permission denied', response.message - assert response = @privileged_gateway.credit(@amount, @credit_card, {:order_id => '1'}) + assert response = @privileged_gateway.credit(@amount, @credit_card, { order_id: '1' }) assert_success response assert_equal 'Approved', response.message end @@ -175,16 +174,16 @@ def test_failed_refund assert response = @gateway.purchase(@amount, @credit_card, @options) assert_success response authorization = response.authorization - assert response = @gateway.refund(@amount+1, authorization) + assert response = @gateway.refund(@amount + 1, authorization) assert_failure response assert_equal 'Only 2.00 AUD available for refund', response.message end def test_invalid_login gateway = NabTransactGateway.new( - :login => 'ABCFAKE', - :password => 'changeit' - ) + login: 'ABCFAKE', + password: 'changeit' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'Invalid merchant ID', response.message @@ -205,11 +204,11 @@ def test_unsuccessful_store def test_duplicate_store @gateway.unstore(1236) - assert response = @gateway.store(@credit_card, {:billing_id => 1236}) + assert response = @gateway.store(@credit_card, { billing_id: 1236 }) assert_success response assert_equal 'Successful', response.message - assert response = @gateway.store(@credit_card, {:billing_id => 1236}) + assert response = @gateway.store(@credit_card, { billing_id: 1236 }) assert_failure response assert_equal 'Duplicate CRN Found', response.message end @@ -240,7 +239,7 @@ def test_failure_trigger_purchase trigger_amount = 0 @gateway.unstore(gateway_id) - assert response = @gateway.store(@credit_card, {:billing_id => gateway_id, :amount => 150}) + assert response = @gateway.store(@credit_card, { billing_id: gateway_id, amount: 150 }) assert_success response assert_equal 'Successful', response.message @@ -260,5 +259,4 @@ def test_transcript_scrubbing assert_scrubbed(@credit_card.number, clean_transcript) assert_scrubbed(@credit_card.verification_value.to_s, clean_transcript) end - end diff --git a/test/remote/gateways/remote_ncr_secure_pay_test.rb b/test/remote/gateways/remote_ncr_secure_pay_test.rb index 239063f06e8..ddd21d8cb85 100644 --- a/test/remote/gateways/remote_ncr_secure_pay_test.rb +++ b/test/remote/gateways/remote_ncr_secure_pay_test.rb @@ -44,7 +44,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -118,5 +118,4 @@ def test_transcript_scrubbing assert_scrubbed(@credit_card.verification_value, transcript) assert_scrubbed(@gateway.options[:password], transcript) end - end diff --git a/test/remote/gateways/remote_net_registry_test.rb b/test/remote/gateways/remote_net_registry_test.rb index aeadc59b83d..2b983e8b680 100644 --- a/test/remote/gateways/remote_net_registry_test.rb +++ b/test/remote/gateways/remote_net_registry_test.rb @@ -10,15 +10,14 @@ # All purchases made in these tests are $1, so hopefully you won't be # sent broke if you forget... class NetRegistryTest < Test::Unit::TestCase - def setup @gateway = NetRegistryGateway.new(fixtures(:net_registry)) @amount = 100 @valid_creditcard = credit_card @invalid_creditcard = credit_card('41111111111111111') - @expired_creditcard = credit_card('4111111111111111', :year => '2000') - @invalid_month_creditcard = credit_card('4111111111111111', :month => '13') + @expired_creditcard = credit_card('4111111111111111', year: '2000') + @invalid_month_creditcard = credit_card('4111111111111111', month: '13') end def test_successful_purchase_and_credit @@ -59,7 +58,7 @@ def test_successful_authorization_and_capture response = @gateway.capture(@amount, response.authorization, - :credit_card => @valid_creditcard) + credit_card: @valid_creditcard) assert_success response assert_equal 'approved', response.params['status'] end @@ -88,9 +87,9 @@ def test_purchase_with_invalid_month def test_bad_login gateway = NetRegistryGateway.new( - :login => 'bad-login', - :password => 'bad-login' - ) + login: 'bad-login', + password: 'bad-login' + ) response = gateway.purchase(@amount, @valid_creditcard) assert_equal 'failed', response.params['status'] assert_failure response diff --git a/test/remote/gateways/remote_netaxept_test.rb b/test/remote/gateways/remote_netaxept_test.rb index 0ae763f5876..b4dd8771771 100644 --- a/test/remote/gateways/remote_netaxept_test.rb +++ b/test/remote/gateways/remote_netaxept_test.rb @@ -9,7 +9,7 @@ def setup @declined_card = credit_card('4925000000000087') @options = { - :order_id => generate_unique_id + order_id: generate_unique_id } end @@ -52,7 +52,7 @@ def test_failed_refund assert response = @gateway.purchase(@amount, @credit_card, @options) assert_success response - response = @gateway.refund(@amount+100, response.authorization) + response = @gateway.refund(@amount + 100, response.authorization) assert_failure response assert_equal 'Unable to credit more than captured amount', response.message end @@ -75,20 +75,20 @@ def test_failed_void end def test_error_in_transaction_setup - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:currency => 'BOGG')) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(currency: 'BOGG')) assert_failure response assert_match(/currency code/, response.message) end def test_successful_amex_purchase - credit_card = credit_card('378282246310005', :brand => 'american_express') + credit_card = credit_card('378282246310005', brand: 'american_express') assert response = @gateway.purchase(@amount, credit_card, @options) assert_success response assert_equal 'OK', response.message end def test_successful_master_purchase - credit_card = credit_card('5413000000000000', :brand => 'master') + credit_card = credit_card('5413000000000000', brand: 'master') assert response = @gateway.purchase(@amount, credit_card, @options) assert_success response assert_equal 'OK', response.message @@ -116,9 +116,9 @@ def test_query_fails def test_invalid_login gateway = NetaxeptGateway.new( - :login => '', - :password => '' - ) + login: '', + password: '' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_match(/Unable to authenticate merchant/, response.message) diff --git a/test/remote/gateways/remote_netbanx_test.rb b/test/remote/gateways/remote_netbanx_test.rb index 19b4faddd5c..491b0d39c03 100644 --- a/test/remote/gateways/remote_netbanx_test.rb +++ b/test/remote/gateways/remote_netbanx_test.rb @@ -5,12 +5,24 @@ def setup @gateway = NetbanxGateway.new(fixtures(:netbanx)) @amount = 100 @credit_card = credit_card('4530910000012345') + @credit_card_no_match_cvv = credit_card('4530910000012345', { verification_value: 666 }) @declined_amount = 11 @options = { billing_address: address, description: 'Store Purchase', currency: 'CAD' } + + @options_3ds2 = @options.merge( + three_d_secure: { + version: '2.1.0', + eci: '05', + cavv: 'AAABCIEjYgAAAAAAlCNiENiWiV+=', + ds_transaction_id: 'a3a721f3-b6fa-4cb5-84ea-c7b5c39890a2', + xid: 'OU9rcTRCY1VJTFlDWTFESXFtTHU=', + directory_response_status: 'Y' + } + ) end def test_successful_purchase @@ -18,6 +30,24 @@ def test_successful_purchase assert_success response assert_equal 'OK', response.message assert_equal response.authorization, response.params['id'] + assert_equal 'MATCH', response.params['cvvVerification'] + assert_equal 'MATCH', response.params['avsResponse'] + end + + def test_successful_purchase_avs_no_match_cvv + response = @gateway.purchase(@amount, @credit_card_no_match_cvv, @options) + assert_success response + assert_equal 'X', response.avs_result['code'] + assert_equal 'N', response.cvv_result['code'] + end + + def split_names(full_name) + names = (full_name || '').split + return [nil, nil] if names.size == 0 + + last_name = names.pop + first_name = names.join(' ') + [first_name, last_name] end def test_successful_purchase_with_more_options @@ -28,9 +58,22 @@ def test_successful_purchase_with_more_options email: 'joe@example.com' } + first_name, last_name = split_names(address[:name]) + response = @gateway.purchase(@amount, @credit_card, options) assert_equal 'OK', response.message assert_equal response.authorization, response.params['id'] + assert_equal first_name, response.params['profile']['firstName'] + assert_equal last_name, response.params['profile']['lastName'] + assert_equal options[:email], response.params['profile']['email'] + assert_equal options[:ip], response.params['customerIp'] + end + + def test_successful_purchase_with_3ds2_auth + assert response = @gateway.purchase(@amount, @credit_card, @options_3ds2) + assert_success response + assert_equal 'OK', response.message + assert_equal response.authorization, response.params['id'] end def test_failed_purchase @@ -39,6 +82,15 @@ def test_failed_purchase assert_equal 'The card has been declined due to insufficient funds.', response.message end + def test_failed_verify_before_purchase + options = { + verification_value: '' + } + response = @gateway.purchase(@amount, @credit_card, options) + assert_failure response + assert_equal 'The zip/postal code must be provided for an AVS check request.', response.message + end + def test_successful_authorize auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth @@ -63,7 +115,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization, @options) + assert capture = @gateway.capture(@amount - 1, auth.authorization, @options) assert_success capture end @@ -73,6 +125,15 @@ def test_failed_capture assert_equal 'The authorization ID included in this settlement request could not be found.', response.message end + def test_successful_authorize_and_capture_with_3ds2_auth + auth = @gateway.authorize(@amount, @credit_card, @options_3ds2) + assert_success auth + + assert capture = @gateway.capture(@amount, auth.authorization, @options_3ds2) + assert_success capture + assert_equal 'OK', capture.message + end + # def test_successful_refund # # Unfortunately when testing a refund, you need to wait until the transaction # # if batch settled by the test system, this can take up to 2h. @@ -122,7 +183,9 @@ def test_failed_capture # assert_equal 'OK', refund.message # end - def test_failed_refund + # Changed test_failed_refund to test_cancelled_refund + # Because We added the checking status. If the transactions that are pending, API call needs to be Cancellation + def test_cancelled_refund # Read comment in `test_successful_refund` method. auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth @@ -130,11 +193,23 @@ def test_failed_refund assert capture = @gateway.capture(@amount, auth.authorization, @options) assert_success capture - # the following shall fail if you run it immediately after the capture - # as noted in the comment from `test_successful_refund` - assert refund = @gateway.refund(@amount, capture.authorization) - assert_failure refund - assert_equal 'The settlement you are attempting to refund has not been batched yet. There are no settled funds available to refund.', refund.message + # The settlement you are attempting to refund has not been batched yet. There are no settled funds available to refund. + # So the following refund shall be cancelled if you run it immediately after the capture + assert cancelled_response = @gateway.refund(@amount, capture.authorization) + assert_success cancelled_response + assert_equal 'CANCELLED', cancelled_response.params['status'] + end + + def test_reject_partial_refund_on_pending_status + auth = @gateway.authorize(@amount, @credit_card, @options) + assert_success auth + + assert capture = @gateway.capture(@amount, auth.authorization, @options) + assert_success capture + + assert rejected_response = @gateway.refund(90, capture.authorization) + assert_failure rejected_response + assert_equal 'Transaction not settled. Either do a full refund or try partial refund after settlement.', rejected_response.message end def test_successful_void @@ -195,11 +270,34 @@ def test_successful_unstore def test_successful_purchase_using_stored_card merchant_customer_id = SecureRandom.hex - assert store = @gateway.store(@credit_card, @options.merge({locale: 'en_GB', merchant_customer_id: merchant_customer_id, email: 'email@example.com'})) + assert store = @gateway.store(@credit_card, @options.merge({ locale: 'en_GB', merchant_customer_id: merchant_customer_id, email: 'email@example.com' })) assert_success store assert response = @gateway.purchase(@amount, store.authorization.split('|').last) assert_success response assert_equal 'OK', response.message end + + def test_successful_verify + verify = @gateway.verify(@credit_card, @options) + assert_success verify + end + + def test_failed_verify + options = { + verification_value: '' + } + verify = @gateway.verify(@credit_card, options) + assert_failure verify + assert_equal 'The zip/postal code must be provided for an AVS check request.', verify.message + end + + def test_successful_cancel_settlement + response = @gateway.purchase(@amount, @credit_card, @options) + authorization = response.authorization + + assert cancelled_response = @gateway.refund(@amount, authorization) + assert_success cancelled_response + assert_equal 'CANCELLED', cancelled_response.params['status'] + end end diff --git a/test/remote/gateways/remote_netbilling_test.rb b/test/remote/gateways/remote_netbilling_test.rb index 7004e213627..46cafebd62b 100644 --- a/test/remote/gateways/remote_netbilling_test.rb +++ b/test/remote/gateways/remote_netbilling_test.rb @@ -6,18 +6,17 @@ def setup @credit_card = credit_card('4444111111111119') - @address = { :address1 => '1600 Amphitheatre Parkway', - :city => 'Mountain View', - :state => 'CA', - :country => 'US', - :zip => '94043', - :phone => '650-253-0001' - } + @address = { address1: '1600 Amphitheatre Parkway', + city: 'Mountain View', + state: 'CA', + country: 'US', + zip: '94043', + phone: '650-253-0001' } @options = { - :billing_address => @address, - :description => 'Internet purchase', - :order_id => 987654321 + billing_address: @address, + description: 'Internet purchase', + order_id: 987654321 } @amount = 100 @@ -89,9 +88,9 @@ def test_failed_capture def test_invalid_login gateway = NetbillingGateway.new( - :login => '', - :password => '' - ) + login: '', + password: '' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_match(/missing/i, response.message) assert_failure response diff --git a/test/remote/gateways/remote_netpay_test.rb b/test/remote/gateways/remote_netpay_test.rb index cb87c5ca3f7..148773c4f28 100644 --- a/test/remote/gateways/remote_netpay_test.rb +++ b/test/remote/gateways/remote_netpay_test.rb @@ -9,7 +9,7 @@ def setup @declined_card = credit_card('4000300011112220') @options = { - :description => 'Store Purchase' + description: 'Store Purchase' } end @@ -44,47 +44,45 @@ def test_successful_purchase_and_refund assert_equal 'Aprobada', refund.message end -=begin - # Netpay are currently adding support for authorize and capture. - # When this is complete, the following remote calls should work. - - def test_successful_authorize - assert response = @gateway.authorize(@amount, @credit_card, @options) - assert_success response - assert_equal 'Aprobada', response.message - end - - def test_unsuccessful_authorize - # We have to force a decline using the mode option - opts = @options.clone - opts[:mode] = 'D' - assert response = @gateway.authorize(@amount, @declined_card, opts) - assert_failure response - assert_match %r{Declinada}, response.message - end - - def test_successful_authorize_and_capture - assert purchase = @gateway.authorize(@amount, @credit_card, @options) - assert_success purchase - assert capture = @gateway.capture(@amount, purchase.authorization) - assert_success capture - assert_equal 'Aprobada', capture.message - end - - def test_failed_capture - assert response = @gateway.capture(@amount, '') - assert_failure response - assert_equal 'REPLACE WITH GATEWAY FAILURE MESSAGE', response.message - end - - def test_invalid_login - gateway = NetpayGateway.new( - :login => '', - :password => '' - ) - assert response = gateway.purchase(@amount, @credit_card, @options) - assert_failure response - assert_equal 'REPLACE WITH FAILURE MESSAGE', response.message - end -=end + # # Netpay are currently adding support for authorize and capture. + # # When this is complete, the following remote calls should work. + # + # def test_successful_authorize + # assert response = @gateway.authorize(@amount, @credit_card, @options) + # assert_success response + # assert_equal 'Aprobada', response.message + # end + # + # def test_unsuccessful_authorize + # # We have to force a decline using the mode option + # opts = @options.clone + # opts[:mode] = 'D' + # assert response = @gateway.authorize(@amount, @declined_card, opts) + # assert_failure response + # assert_match %r{Declinada}, response.message + # end + # + # def test_successful_authorize_and_capture + # assert purchase = @gateway.authorize(@amount, @credit_card, @options) + # assert_success purchase + # assert capture = @gateway.capture(@amount, purchase.authorization) + # assert_success capture + # assert_equal 'Aprobada', capture.message + # end + # + # def test_failed_capture + # assert response = @gateway.capture(@amount, '') + # assert_failure response + # assert_equal 'REPLACE WITH GATEWAY FAILURE MESSAGE', response.message + # end + # + # def test_invalid_login + # gateway = NetpayGateway.new( + # :login => '', + # :password => '' + # ) + # assert response = gateway.purchase(@amount, @credit_card, @options) + # assert_failure response + # assert_equal 'REPLACE WITH FAILURE MESSAGE', response.message + # end end diff --git a/test/remote/gateways/remote_network_merchants_test.rb b/test/remote/gateways/remote_network_merchants_test.rb index 290a0cad4c6..c4a43d5661c 100644 --- a/test/remote/gateways/remote_network_merchants_test.rb +++ b/test/remote/gateways/remote_network_merchants_test.rb @@ -11,9 +11,9 @@ def setup @check = check @options = { - :order_id => '1', - :billing_address => address, - :description => 'Store Purchase' + order_id: '1', + billing_address: address, + description: 'Store Purchase' } end @@ -54,7 +54,7 @@ def test_unsuccessful_purchase_with_track_data end def test_purchase_and_store - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:store => true)) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(store: true)) assert_success response assert_equal response.params['transactionid'], response.authorization assert response.params['customer_vault_id'] @@ -153,9 +153,9 @@ def test_purchase_on_stored_card def test_invalid_login gateway = NetworkMerchantsGateway.new( - :login => '', - :password => '' - ) + login: '', + password: '' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'Invalid Username', response.message @@ -163,16 +163,16 @@ def test_invalid_login def test_successful_purchase_without_state @options[:billing_address] = { - :name => 'Jim Smith', - :address1 => 'Gullhauggrenda 30', - :address2 => 'Apt 1', - :company => 'Widgets Inc', - :city => 'Baerums Verk', - :state => nil, - :zip => '1354', - :country => 'NO', - :phone => '(555)555-5555', - :fax => '(555)555-6666' + name: 'Jim Smith', + address1: 'Gullhauggrenda 30', + address2: 'Apt 1', + company: 'Widgets Inc', + city: 'Baerums Verk', + state: nil, + zip: '1354', + country: 'NO', + phone: '(555)555-5555', + fax: '(555)555-6666' } assert response = @gateway.purchase(@amount, @credit_card, @options) diff --git a/test/remote/gateways/remote_nmi_test.rb b/test/remote/gateways/remote_nmi_test.rb index 4c4784b216a..8ece3f5e942 100644 --- a/test/remote/gateways/remote_nmi_test.rb +++ b/test/remote/gateways/remote_nmi_test.rb @@ -6,24 +6,23 @@ def setup @amount = Random.rand(100...1000) @credit_card = credit_card('4111111111111111', verification_value: 917) @check = check( - :routing_number => '123123123', - :account_number => '123123123' + routing_number: '123123123', + account_number: '123123123' ) @apple_pay_card = network_tokenization_credit_card('4111111111111111', - :payment_cryptogram => 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', - :month => '01', - :year => '2024', - :source => :apple_pay, - :eci => '5', - :transaction_id => '123456789' - ) + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + month: '01', + year: '2024', + source: :apple_pay, + eci: '5', + transaction_id: '123456789') @options = { - :order_id => generate_unique_id, - :billing_address => address, - :description => 'Store purchase' + order_id: generate_unique_id, + billing_address: address, + description: 'Store purchase' } @level3_options = { - tax: 5.25, shipping: 10.51, ponumber: 1002 + tax: 5.25, shipping: 10.51, ponumber: 1002 } end @@ -95,7 +94,7 @@ def test_successful_purchase_with_additional_options options = @options.merge({ customer_id: '234', vendor_id: '456', - recurring: true, + recurring: true }) assert response = @gateway.purchase(@amount, @credit_card, options) assert_success response @@ -104,6 +103,23 @@ def test_successful_purchase_with_additional_options assert response.authorization end + def test_successful_purchase_with_three_d_secure + three_d_secure_options = @options.merge({ + three_d_secure: { + version: '2.1.0', + eci: '02', + cavv: 'jJ81HADVRtXfCBATEp01CJUAAAA', + ds_transaction_id: '97267598-FAE6-48F2-8083-C23433990FBC' + } + }) + + assert response = @gateway.purchase(@amount, @credit_card, three_d_secure_options) + assert_success response + assert response.test? + assert_equal 'Succeeded', response.message + assert response.authorization + end + def test_successful_authorization options = @options.merge(@level3_options) diff --git a/test/remote/gateways/remote_ogone_test.rb b/test/remote/gateways/remote_ogone_test.rb index 3d2b878db33..16c88c0e124 100644 --- a/test/remote/gateways/remote_ogone_test.rb +++ b/test/remote/gateways/remote_ogone_test.rb @@ -3,20 +3,19 @@ require 'test_helper' class RemoteOgoneTest < Test::Unit::TestCase - def setup @gateway = OgoneGateway.new(fixtures(:ogone)) @amount = 100 @credit_card = credit_card('4000100011112224') - @mastercard = credit_card('5399999999999999', :brand => 'mastercard') + @mastercard = credit_card('5399999999999999', brand: 'mastercard') @declined_card = credit_card('1111111111111111') - @credit_card_d3d = credit_card('4000000000000002', :verification_value => '111') + @credit_card_d3d = credit_card('4000000000000002', verification_value: '111') @options = { - :order_id => generate_unique_id[0...30], - :billing_address => address, - :description => 'Store Purchase', - :currency => fixtures(:ogone)[:currency] || 'EUR', - :origin => 'STORE' + order_id: generate_unique_id[0...30], + billing_address: address, + description: 'Store Purchase', + currency: fixtures(:ogone)[:currency] || 'EUR', + origin: 'STORE' } end @@ -28,13 +27,13 @@ def test_successful_purchase end def test_successful_purchase_with_utf8_encoding_1 - assert response = @gateway.purchase(@amount, credit_card('4000100011112224', :first_name => 'Rémy', :last_name => 'Fröåïør'), @options) + assert response = @gateway.purchase(@amount, credit_card('4000100011112224', first_name: 'Rémy', last_name: 'Fröåïør'), @options) assert_success response assert_equal OgoneGateway::SUCCESS_MESSAGE, response.message end def test_successful_purchase_with_utf8_encoding_2 - assert response = @gateway.purchase(@amount, credit_card('4000100011112224', :first_name => 'ワタシ', :last_name => 'ёжзийклмнопрсуфхцч'), @options) + assert response = @gateway.purchase(@amount, credit_card('4000100011112224', first_name: 'ワタシ', last_name: 'ёжзийклмнопрсуфхцч'), @options) assert_success response assert_equal OgoneGateway::SUCCESS_MESSAGE, response.message end @@ -62,7 +61,7 @@ def test_successful_purchase_with_utf8_encoding_2 # NOTE: You have to set the "Hash algorithm" to "SHA-512" in the "Technical information"->"Global security parameters" # section of your account admin on https://secure.ogone.com/ncol/test/frame_ogone.asp before running this test def test_successful_purchase_with_signature_encryptor_to_sha512 - gateway = OgoneGateway.new(fixtures(:ogone).merge(:signature_encryptor => 'sha512')) + gateway = OgoneGateway.new(fixtures(:ogone).merge(signature_encryptor: 'sha512')) assert response = gateway.purchase(@amount, @credit_card, @options) assert_success response assert_equal OgoneGateway::SUCCESS_MESSAGE, response.message @@ -70,7 +69,7 @@ def test_successful_purchase_with_signature_encryptor_to_sha512 # NOTE: You have to contact Ogone to make sure your test account allow 3D Secure transactions before running this test def test_successful_purchase_with_3d_secure - assert response = @gateway.purchase(@amount, @credit_card_d3d, @options.merge(:d3d => true)) + assert response = @gateway.purchase(@amount, @credit_card_d3d, @options.merge(d3d: true)) assert_success response assert_equal '46', response.params['STATUS'] assert_equal OgoneGateway::SUCCESS_MESSAGE, response.message @@ -92,7 +91,7 @@ def test_successful_purchase_without_explicit_order_id end def test_successful_purchase_with_custom_eci - 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 OgoneGateway::SUCCESS_MESSAGE, response.message end @@ -100,7 +99,7 @@ def test_successful_purchase_with_custom_eci # NOTE: You have to allow USD as a supported currency in the "Account"->"Currencies" # section of your account admin on https://secure.ogone.com/ncol/test/frame_ogone.asp before running this test def test_successful_purchase_with_custom_currency_at_the_gateway_level - gateway = OgoneGateway.new(fixtures(:ogone).merge(:currency => 'USD')) + gateway = OgoneGateway.new(fixtures(:ogone).merge(currency: 'USD')) assert response = gateway.purchase(@amount, @credit_card) assert_success response assert_equal OgoneGateway::SUCCESS_MESSAGE, response.message @@ -109,8 +108,8 @@ def test_successful_purchase_with_custom_currency_at_the_gateway_level # NOTE: You have to allow USD as a supported currency in the "Account"->"Currencies" # section of your account admin on https://secure.ogone.com/ncol/test/frame_ogone.asp before running this test def test_successful_purchase_with_custom_currency - gateway = OgoneGateway.new(fixtures(:ogone).merge(:currency => 'EUR')) - assert response = gateway.purchase(@amount, @credit_card, @options.merge(:currency => 'USD')) + gateway = OgoneGateway.new(fixtures(:ogone).merge(currency: 'EUR')) + assert response = gateway.purchase(@amount, @credit_card, @options.merge(currency: 'USD')) assert_success response assert_equal OgoneGateway::SUCCESS_MESSAGE, response.message end @@ -137,7 +136,7 @@ def test_authorize_and_capture end def test_authorize_and_capture_with_custom_eci - assert auth = @gateway.authorize(@amount, @credit_card, @options.merge(:eci => 4)) + assert auth = @gateway.authorize(@amount, @credit_card, @options.merge(eci: 4)) assert_success auth assert_equal OgoneGateway::SUCCESS_MESSAGE, auth.message assert auth.authorization @@ -161,15 +160,15 @@ def test_successful_void end def test_successful_store - assert response = @gateway.store(@credit_card, :billing_id => 'test_alias') + assert response = @gateway.store(@credit_card, billing_id: 'test_alias') assert_success response assert purchase = @gateway.purchase(@amount, 'test_alias') assert_success purchase end def test_successful_store_with_store_amount_at_the_gateway_level - gateway = OgoneGateway.new(fixtures(:ogone).merge(:store_amount => 100)) - assert response = gateway.store(@credit_card, :billing_id => 'test_alias') + gateway = OgoneGateway.new(fixtures(:ogone).merge(store_amount: 100)) + assert response = gateway.store(@credit_card, billing_id: 'test_alias') assert_success response assert purchase = gateway.purchase(@amount, 'test_alias') assert_success purchase @@ -194,7 +193,7 @@ def test_successful_refund def test_unsuccessful_refund assert purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount+1, purchase.authorization, @options) # too much refund requested + assert refund = @gateway.refund(@amount + 1, purchase.authorization, @options) # too much refund requested assert_failure refund assert refund.authorization assert_equal 'Overflow in refunds requests', refund.message @@ -221,23 +220,23 @@ def test_failed_verify def test_reference_transactions # Setting an alias - assert response = @gateway.purchase(@amount, credit_card('4000100011112224'), @options.merge(:billing_id => 'awesomeman', :order_id=>Time.now.to_i.to_s+'1')) + assert response = @gateway.purchase(@amount, credit_card('4000100011112224'), @options.merge(billing_id: 'awesomeman', order_id: Time.now.to_i.to_s + '1')) assert_success response # Updating an alias - assert response = @gateway.purchase(@amount, credit_card('4111111111111111'), @options.merge(:billing_id => 'awesomeman', :order_id=>Time.now.to_i.to_s+'2')) + assert response = @gateway.purchase(@amount, credit_card('4111111111111111'), @options.merge(billing_id: 'awesomeman', order_id: Time.now.to_i.to_s + '2')) assert_success response # Using an alias (i.e. don't provide the credit card) - assert response = @gateway.purchase(@amount, 'awesomeman', @options.merge(:order_id => Time.now.to_i.to_s + '3')) + assert response = @gateway.purchase(@amount, 'awesomeman', @options.merge(order_id: Time.now.to_i.to_s + '3')) assert_success response end def test_invalid_login gateway = OgoneGateway.new( - login: 'login', - user: 'user', - password: 'password', - signature: 'signature' - ) + login: 'login', + user: 'user', + password: 'password', + signature: 'signature' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response end diff --git a/test/remote/gateways/remote_omise_test.rb b/test/remote/gateways/remote_omise_test.rb index 4b5be3064b0..95ae0d30b66 100644 --- a/test/remote/gateways/remote_omise_test.rb +++ b/test/remote/gateways/remote_omise_test.rb @@ -6,7 +6,7 @@ def setup @amount = 8888 @credit_card = credit_card('4242424242424242') @declined_card = credit_card('4255555555555555') - @invalid_cvc = credit_card('4111111111160001', {verification_value: ''}) + @invalid_cvc = credit_card('4111111111160001', { verification_value: '' }) @options = { description: 'Active Merchant', email: 'active.merchant@testing.test', @@ -54,7 +54,7 @@ def test_successful_purchase_after_store end def test_failed_purchase_with_token - response = @gateway.purchase(@amount, nil, {token_id: 'tokn_invalid_12345'}) + response = @gateway.purchase(@amount, nil, { token_id: 'tokn_invalid_12345' }) assert_failure response end @@ -95,9 +95,8 @@ def test_successful_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase assert_equal purchase.params['amount'], @amount - response = @gateway.refund(@amount-1000, purchase.authorization) + response = @gateway.refund(@amount - 1000, purchase.authorization) assert_success response - assert_equal @amount-1000, response.params['amount'] + assert_equal @amount - 1000, response.params['amount'] end - end diff --git a/test/remote/gateways/remote_openpay_test.rb b/test/remote/gateways/remote_openpay_test.rb index 079b4d09279..0bab989b01f 100644 --- a/test/remote/gateways/remote_openpay_test.rb +++ b/test/remote/gateways/remote_openpay_test.rb @@ -48,7 +48,7 @@ def test_successful_refund end def test_unsuccessful_refund - assert response = @gateway.refund(@amount, '1', @options) + assert response = @gateway.refund(@amount, '1', @options) assert_failure response assert_not_nil response.message end diff --git a/test/remote/gateways/remote_opp_test.rb b/test/remote/gateways/remote_opp_test.rb index 652059e87ad..fa744bbd9ab 100644 --- a/test/remote/gateways/remote_opp_test.rb +++ b/test/remote/gateways/remote_opp_test.rb @@ -1,14 +1,13 @@ require 'test_helper' class RemoteOppTest < Test::Unit::TestCase - def setup @gateway = OppGateway.new(fixtures(:opp)) @amount = 100 - @valid_card = credit_card('4200000000000000', month: 05, year: 2018) - @invalid_card = credit_card('4444444444444444', month: 05, year: 2018) - @amex_card = credit_card('377777777777770 ', month: 05, year: 2018, brand: 'amex', verification_value: '1234') + @valid_card = credit_card('4200000000000000', month: 05, year: Date.today.year + 2) + @invalid_card = credit_card('4444444444444444', month: 05, year: Date.today.year + 2) + @amex_card = credit_card('377777777777770 ', month: 05, year: Date.today.year + 2, brand: 'amex', verification_value: '1234') request_type = 'complete' # 'minimal' || 'complete' time = Time.now.to_i @@ -26,7 +25,7 @@ def setup city: 'Test', state: 'TE', zip: 'AB12CD', - country: 'GB', + country: 'GB' }, shipping_address: { name: 'Muton DeMicelis', @@ -34,7 +33,7 @@ def setup city: 'Munich', state: 'Bov', zip: '81675', - country: 'DE', + country: 'DE' }, customer: { merchant_customer_id: 'your merchant/customer id', @@ -47,13 +46,13 @@ def setup company_name: 'JJ Ltd.', identification_doctype: 'PASSPORT', identification_docid: 'FakeID2342431234123', - ip: ip, - }, + ip: ip + } } @minimal_request_options = { order_id: "Order #{time}", - description: 'Store Purchase - Books', + description: 'Store Purchase - Books' } @complete_request_options['customParameters[SHOPPER_test124TestName009]'] = 'customParameters_test' @@ -140,7 +139,7 @@ def test_successful_partial_capture auth = @gateway.authorize(@amount, @valid_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture assert_match %r{Request successfully processed}, capture.message end @@ -150,7 +149,7 @@ def test_successful_partial_refund purchase = @gateway.purchase(@amount, @valid_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund assert_match %r{Request successfully processed}, refund.message end @@ -211,6 +210,6 @@ def test_transcript_scrubbing assert_scrubbed(@valid_card.number, transcript) assert_scrubbed(@valid_card.verification_value, transcript) - assert_scrubbed(@gateway.options[:password], transcript) + assert_scrubbed(@gateway.options[:access_token], transcript) end end diff --git a/test/remote/gateways/remote_optimal_payment_test.rb b/test/remote/gateways/remote_optimal_payment_test.rb index 6061a306300..045f9e22938 100644 --- a/test/remote/gateways/remote_optimal_payment_test.rb +++ b/test/remote/gateways/remote_optimal_payment_test.rb @@ -7,13 +7,14 @@ def setup @amount = 100 @declined_amount = 5 @credit_card = credit_card('4387751111011') + @expired_card = credit_card('4387751111011', month: 12, year: 2019) @options = { - :order_id => '1', - :billing_address => address, - :description => 'Basic Subscription', - :email => 'email@example.com', - :ip => '1.2.3.4' + order_id: '1', + billing_address: address, + description: 'Basic Subscription', + email: 'email@example.com', + ip: '1.2.3.4' } end @@ -57,6 +58,51 @@ def test_successful_verify assert_equal 'no_error', response.message end + def test_stored_data_auth_and_capture_after_store + response = @gateway.store(@credit_card, @options) + assert_success response + assert_equal 'no_error', response.message + + assert auth = @gateway.stored_authorize(@amount, response.authorization) + assert_success auth + assert_equal 'no_error', auth.message + assert auth.authorization + + assert capture = @gateway.capture(@amount, auth.authorization) + assert_success capture + end + + def test_stored_data_purchase_after_store + response = @gateway.store(@credit_card, @options) + assert_success response + assert_equal 'no_error', response.message + + assert stored_purchase = @gateway.stored_purchase(@amount, response.authorization) + assert_success stored_purchase + end + + def test_stored_data_auth_after_failed_store + response = @gateway.store(@expired_card, @options) + assert_failure response + assert_not_nil response.authorization + assert_equal 'ERROR', response.params['decision'] + + assert auth = @gateway.stored_authorize(@amount, response.authorization) + assert_failure auth + assert_equal 'ERROR', auth.params['decision'] + end + + def test_stored_data_purchase_after_failed_store + response = @gateway.store(@expired_card, @options) + assert_failure response + assert_not_nil response.authorization + assert_equal 'ERROR', response.params['decision'] + + assert stored_purchase = @gateway.stored_purchase(@amount, response.authorization) + assert_failure stored_purchase + assert_equal 'ERROR', stored_purchase.params['decision'] + end + def test_authorize_and_capture assert auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth @@ -141,10 +187,10 @@ def test_overloaded_stored_data_authorize_and_capture def test_invalid_login gateway = OptimalPaymentGateway.new( - :account_number => '1', - :store_id => 'bad', - :password => 'bad' - ) + account_number: '1', + store_id: 'bad', + password: 'bad' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'invalid merchant account', response.message diff --git a/test/remote/gateways/remote_orbital_test.rb b/test/remote/gateways/remote_orbital_test.rb index 92e7c3a7d9b..0acc19dfbe9 100644 --- a/test/remote/gateways/remote_orbital_test.rb +++ b/test/remote/gateways/remote_orbital_test.rb @@ -4,24 +4,29 @@ class RemoteOrbitalGatewayTest < Test::Unit::TestCase def setup Base.mode = :test @gateway = ActiveMerchant::Billing::OrbitalGateway.new(fixtures(:orbital_gateway)) + @echeck_gateway = ActiveMerchant::Billing::OrbitalGateway.new(fixtures(:orbital_asv_aoa_gateway)) + @three_ds_gateway = ActiveMerchant::Billing::OrbitalGateway.new(fixtures(:orbital_3ds_gateway)) @amount = 100 - @credit_card = credit_card('4112344112344113') + @credit_card = credit_card('4556761029983886') @declined_card = credit_card('4000300011112220') + # Electronic Check object with test credentials of saving account + @echeck = check(account_number: '072403004', account_type: 'savings', routing_number: '072403004') @options = { - :order_id => generate_unique_id, - :address => address, - :merchant_id => 'merchant1234' + order_id: generate_unique_id, + address: address, + merchant_id: 'merchant1234' } @cards = { - :visa => '4788250000028291', - :mc => '5454545454545454', - :amex => '371449635398431', - :ds => '6011000995500000', - :diners => '36438999960016', - :jcb => '3566002020140006'} + visa: '4556761029983886', + mc: '5454545454545454', + amex: '371449635398431', + ds: '6011000995500000', + diners: '36438999960016', + jcb: '3566002020140006' + } @level_2_options = { tax_indicator: '1', @@ -36,19 +41,71 @@ def setup address2: address[:address2], city: address[:city], state: address[:state], - zip: address[:zip], + zip: address[:zip] + } + + @level_3_options_visa = { + freight_amount: 1, + duty_amount: 1, + ship_from_zip: 27604, + dest_country: 'USA', + discount_amount: 1, + vat_tax: 1, + vat_rate: 25 } + @level_2_options_master = { + freight_amount: 1, + duty_amount: 1, + ship_from_zip: 27604, + dest_country: 'USA', + alt_tax: 1, + alt_ind: 25 + } + + @line_items_visa = [ + { + desc: 'another item', + prod_cd: generate_unique_id[0, 11], + qty: 1, + u_o_m: 'LBR', + tax_amt: 250, + tax_rate: 10000, + line_tot: 2500, + disc: 250, + comm_cd: '00584', + unit_cost: 2500, + gross_net: 'Y', + tax_type: 'sale', + debit_ind: 'C' + }, + { + desc: 'something else', + prod_cd: generate_unique_id[0, 11], + qty: 1, + u_o_m: 'LBR', + tax_amt: 125, + tax_rate: 5000, + line_tot: 2500, + disc: 250, + comm_cd: '00584', + unit_cost: 250000, + gross_net: 'Y', + tax_type: 'sale', + debit_ind: 'C' + } + ] + @test_suite = [ - {:card => :visa, :AVSzip => 11111, :CVD => 111, :amount => 3000}, - {:card => :visa, :AVSzip => 33333, :CVD => nil, :amount => 3801}, - {:card => :mc, :AVSzip => 44444, :CVD => nil, :amount => 4100}, - {:card => :mc, :AVSzip => 88888, :CVD => 666, :amount => 1102}, - {:card => :amex, :AVSzip => 55555, :CVD => nil, :amount => 105500}, - {:card => :amex, :AVSzip => 66666, :CVD => 2222, :amount => 7500}, - {:card => :ds, :AVSzip => 77777, :CVD => nil, :amount => 1000}, - {:card => :ds, :AVSzip => 88888, :CVD => 444, :amount => 6303}, - {:card => :jcb, :AVSzip => 33333, :CVD => nil, :amount => 2900} + { card: :visa, AVSzip: 11111, CVD: 111, amount: 3000 }, + { card: :visa, AVSzip: 33333, CVD: nil, amount: 3801 }, + { card: :mc, AVSzip: 44444, CVD: nil, amount: 4100 }, + { card: :mc, AVSzip: 88888, CVD: 666, amount: 1102 }, + { card: :amex, AVSzip: 55555, CVD: nil, amount: 105500 }, + { card: :amex, AVSzip: 66666, CVD: 2222, amount: 7500 }, + { card: :ds, AVSzip: 77777, CVD: nil, amount: 1000 }, + { card: :ds, AVSzip: 88888, CVD: 444, amount: 6303 }, + { card: :jcb, AVSzip: 33333, CVD: nil, amount: 2900 } ] end @@ -59,15 +116,33 @@ def test_successful_purchase end def test_successful_purchase_with_soft_descriptor_hash - assert response = @gateway.purchase( - @amount, @credit_card, @options.merge( - soft_descriptors: { - merchant_name: 'Merch', - product_description: 'Description', - merchant_email: 'email@example', - } - ) + options = @options.merge( + soft_descriptors: { + merchant_name: 'Merch', + product_description: 'Description', + merchant_email: 'email@example' + } + ) + assert response = @gateway.purchase(@amount, @credit_card, options) + assert_success response + assert_equal 'Approved', response.message + end + + def test_successful_purchase_with_card_indicators + options = @options.merge( + card_indicators: 'y' ) + assert response = @gateway.purchase(@amount, @credit_card, options) + assert_success response + assert_equal 'Approved', response.message + end + + def test_successful_purchase_with_card_indicators_and_line_items + options = @options.merge( + line_items: @line_items, + card_indicators: 'y' + ) + assert response = @gateway.purchase(@amount, @credit_card, options) assert_success response assert_equal 'Approved', response.message end @@ -79,15 +154,32 @@ def test_successful_purchase_with_level_2_data assert_equal 'Approved', response.message end + def test_successful_purchase_with_level_3_data + response = @gateway.purchase(@amount, @credit_card, @options.merge(level_2_data: @level_2_options, level_3_data: @level_3_options_visa, line_items: @line_items_visa)) + + assert_success response + assert_equal 'Approved', response.message + end + def test_successful_purchase_with_visa_network_tokenization_credit_card_with_eci - network_card = network_tokenization_credit_card('4788250000028291', + network_card = network_tokenization_credit_card( + '4788250000028291', payment_cryptogram: 'BwABB4JRdgAAAAAAiFF2AAAAAAA=', transaction_id: 'BwABB4JRdgAAAAAAiFF2AAAAAAA=', verification_value: '111', brand: 'visa', eci: '5' ) - assert response = @gateway.purchase(3000, network_card, @options) + # Ensure that soft descriptor fields don't conflict with network token data in schema + options = @options.merge( + soft_descriptors: { + merchant_name: 'Merch', + product_description: 'Description', + merchant_email: 'email@example' + } + ) + + assert response = @gateway.purchase(3000, network_card, options) assert_success response assert_equal 'Approved', response.message assert_false response.authorization.blank? @@ -98,8 +190,7 @@ def test_successful_purchase_with_master_card_network_tokenization_credit_card payment_cryptogram: 'BwABB4JRdgAAAAAAiFF2AAAAAAA=', transaction_id: 'BwABB4JRdgAAAAAAiFF2AAAAAAA=', verification_value: '111', - brand: 'master' - ) + brand: 'master') assert response = @gateway.purchase(3000, network_card, @options) assert_success response assert_equal 'Approved', response.message @@ -111,8 +202,7 @@ def test_successful_purchase_with_american_express_network_tokenization_credit_c payment_cryptogram: 'BwABB4JRdgAAAAAAiFF2AAAAAAA=', transaction_id: 'BwABB4JRdgAAAAAAiFF2AAAAAAA=', verification_value: '111', - brand: 'american_express' - ) + brand: 'american_express') assert response = @gateway.purchase(3000, network_card, @options) assert_success response assert_equal 'Approved', response.message @@ -124,25 +214,101 @@ def test_successful_purchase_with_discover_network_tokenization_credit_card payment_cryptogram: 'BwABB4JRdgAAAAAAiFF2AAAAAAA=', transaction_id: 'BwABB4JRdgAAAAAAiFF2AAAAAAA=', verification_value: '111', - brand: 'discover' - ) + brand: 'discover') assert response = @gateway.purchase(3000, network_card, @options) assert_success response assert_equal 'Approved', response.message assert_false response.authorization.blank? end + def test_successful_purchase_with_echeck + assert response = @echeck_gateway.purchase(20, @echeck, @options) + assert_success response + assert_equal 'Approved', response.message + assert_false response.authorization.blank? + end + + def test_successful_purchase_with_echeck_having_written_authorization + @options[:auth_method] = 'W' + assert response = @echeck_gateway.purchase(20, @echeck, @options) + assert_success response + assert_equal 'Approved', response.message + assert_false response.authorization.blank? + end + + def test_successful_purchase_with_echeck_having_internet_authorization + @options[:auth_method] = 'I' + assert response = @echeck_gateway.purchase(20, @echeck, @options) + assert_success response + assert_equal 'Approved', response.message + assert_false response.authorization.blank? + end + + def test_successful_purchase_with_echeck_having_telephonic_authorization + @options[:auth_method] = 'T' + assert response = @echeck_gateway.purchase(20, @echeck, @options) + assert_success response + assert_equal 'Approved', response.message + assert_false response.authorization.blank? + end + + def test_successful_purchase_with_echeck_having_arc_authorization + test_check = check(account_number: '000000000', account_type: 'checking', routing_number: '072403004') + assert response = @echeck_gateway.purchase(20, test_check, @options.merge({ auth_method: 'A' })) + assert_success response + assert_equal 'Approved', response.message + assert_false response.authorization.blank? + end + + def test_failed_missing_serial_for_arc_with_echeck + assert_raise do + test_check = { account_type: 'savings', routing_number: '072403004' } + @echeck_gateway.purchase(20, test_check, @options.merge({ auth_method: 'A' })) + end + end + + def test_successful_purchase_with_echeck_having_pop_authorization + test_check = check(account_number: '000000000', account_type: 'savings', routing_number: '072403004') + assert response = @echeck_gateway.purchase(20, test_check, @options.merge({ auth_method: 'P', terminal_city: 'CO', terminal_state: 'IL', image_reference_number: '00000' })) + assert_success response + assert_equal 'Approved', response.message + assert_false response.authorization.blank? + end + + def test_failed_missing_serial_for_pop_with_echeck + assert_raise do + test_check = { account_type: 'savings', routing_number: '072403004' } + @echeck_gateway.purchase(20, test_check, @options.merge({ auth_method: 'P' })) + end + end + + def test_successful_purchase_with_echeck_on_same_day + @options[:same_day] = 'Y' + assert response = @echeck_gateway.purchase(20, @echeck, @options) + assert_success response + assert_equal 'Approved', response.message + assert_false response.authorization.blank? + end + + def test_successful_purchase_with_echeck_on_next_day + @options[:same_day] = 'N' + assert response = @echeck_gateway.purchase(20, @echeck, @options) + assert_success response + assert_equal 'Approved', response.message + assert_false response.authorization.blank? + end + [ { card: { number: '4112344112344113', verification_value: '411', - brand: 'visa', + brand: 'visa' }, three_d_secure: { eci: '5', cavv: 'AAABAIcJIoQDIzAgVAkiAAAAAAA=', - xid: 'AAABAIcJIoQDIzAgVAkiAAAAAAA=', + xid: 'AAABAIcJIoQDIzAgVAkiAAAAAAA=' }, address: { address1: '55 Forever Ave', @@ -150,39 +316,42 @@ def test_successful_purchase_with_discover_network_tokenization_credit_card city: 'Concord', state: 'NH', zip: '03301', - country: 'US', - }, + country: 'US' + } }, { card: { number: '5112345112345114', verification_value: '823', - brand: 'master', + brand: 'master' }, three_d_secure: { - eci: '6', - cavv: 'Asju1ljfl86bAAAAAACm9zU6aqY=', + eci: '5', + cavv: 'AAAEEEDDDSSSAAA2243234', xid: 'Asju1ljfl86bAAAAAACm9zU6aqY=', + version: '2', + ds_transaction_id: '8dh4htokdf84jrnxyemfiosheuyfjt82jiek' }, address: { address1: 'Byway Street', address2: '', city: 'Portsmouth', state: 'MA', - zip: '', + zip: '67890', country: 'US', - }, + phone: '5555555555' + } }, { card: { number: '371144371144376', verification_value: '1234', - brand: 'american_express', + brand: 'american_express' }, three_d_secure: { eci: '5', cavv: 'AAABBWcSNIdjeUZThmNHAAAAAAA=', - xid: 'AAABBWcSNIdjeUZThmNHAAAAAAA=', + xid: 'AAABBWcSNIdjeUZThmNHAAAAAAA=' }, address: { address1: '4 Northeastern Blvd', @@ -190,8 +359,8 @@ def test_successful_purchase_with_discover_network_tokenization_credit_card city: 'Salem', state: 'NH', zip: '03105', - country: 'US', - }, + country: 'US' + } } ].each do |fixture| define_method("test_successful_#{fixture[:card][:brand]}_authorization_with_3ds") do @@ -199,12 +368,18 @@ def test_successful_purchase_with_discover_network_tokenization_credit_card verification_value: fixture[:card][:verification_value], brand: fixture[:card][:brand] }) - assert response = @gateway.authorize(100, cc, @options.merge( + options = @options.merge( order_id: '2', currency: 'USD', three_d_secure: fixture[:three_d_secure], - address: fixture[:address] - )) + address: fixture[:address], + soft_descriptors: { + merchant_name: 'Merch', + product_description: 'Description', + merchant_email: 'email@example' + } + ) + assert response = @three_ds_gateway.authorize(100, cc, options) assert_success response assert_equal 'Approved', response.message @@ -216,12 +391,13 @@ def test_successful_purchase_with_discover_network_tokenization_credit_card verification_value: fixture[:card][:verification_value], brand: fixture[:card][:brand] }) - assert response = @gateway.purchase(100, cc, @options.merge( + options = @options.merge( order_id: '2', currency: 'USD', three_d_secure: fixture[:three_d_secure], address: fixture[:address] - )) + ) + assert response = @three_ds_gateway.purchase(100, cc, options) assert_success response assert_equal 'Approved', response.message @@ -254,35 +430,30 @@ def test_successful_purchase_with_cit_stored_credentials assert_equal 'Approved', response.message end - def test_successful_purchase_with_normalized_mit_stored_credentials - stored_credential = { - stored_credential: { - initial_transaction: false, - initiator: 'merchant', - reason_type: 'unscheduled', - network_transaction_id: 'abcdefg12345678' - } - } - - response = @gateway.purchase(@amount, @credit_card, @options.merge(stored_credential)) - - assert_success response - assert_equal 'Approved', response.message + def test_purchase_using_stored_credential_recurring_cit + initial_options = stored_credential_options(:cardholder, :recurring, :initial) + assert purchase = @gateway.purchase(@amount, @credit_card, initial_options) + assert_success purchase + assert_equal 'Approved', purchase.message + assert network_transaction_id = purchase.params['mit_received_transaction_id'] + + used_options = stored_credential_options(:recurring, :cardholder, id: network_transaction_id) + assert purchase = @gateway.purchase(@amount, @credit_card, used_options) + assert_success purchase + assert_equal 'Approved', purchase.message end - def test_successful_purchase_with_normalized_cit_stored_credentials - stored_credential = { - stored_credential: { - initial_transaction: true, - initiator: 'customer', - reason_type: 'unscheduled' - } - } - - response = @gateway.purchase(@amount, @credit_card, @options.merge(stored_credential)) - - assert_success response - assert_equal 'Approved', response.message + def test_purchase_using_stored_credential_recurring_mit + initial_options = stored_credential_options(:merchant, :recurring, :initial) + assert purchase = @gateway.purchase(@amount, @credit_card, initial_options) + assert_success purchase + assert_equal 'Approved', purchase.message + assert network_transaction_id = purchase.params['mit_received_transaction_id'] + + used_options = stored_credential_options(:recurring, :merchant, id: network_transaction_id) + assert purchase = @gateway.purchase(@amount, @credit_card, used_options) + assert_success purchase + assert_equal 'Approved', purchase.message end def test_successful_purchase_with_overridden_normalized_stored_credentials @@ -302,6 +473,23 @@ def test_successful_purchase_with_overridden_normalized_stored_credentials assert_equal 'Approved', response.message end + def test_successful_force_capture_with_echeck + @options[:force_capture] = true + assert response = @echeck_gateway.purchase(@amount, @echeck, @options) + assert_success response + assert_match 'APPROVAL', response.message + assert_equal 'Approved and Completed', response.params['status_msg'] + assert_false response.authorization.blank? + end + + def test_failed_force_capture_with_echeck_due_to_invalid_amount + @options[:force_capture] = true + assert capture = @echeck_gateway.purchase(-1, @echeck, @options.merge(order_id: '2')) + assert_failure capture + assert_equal '801', capture.params['proc_status'] + assert_equal 'Error validating amount. Must be numerical and greater than 0 [-1]', capture.message + end + # Amounts of x.01 will fail def test_unsuccessful_purchase assert response = @gateway.purchase(101, @declined_card, @options) @@ -311,11 +499,11 @@ def test_unsuccessful_purchase def test_authorize_and_capture amount = @amount - assert auth = @gateway.authorize(amount, @credit_card, @options.merge(:order_id => '2')) + assert auth = @gateway.authorize(amount, @credit_card, @options.merge(order_id: '2')) assert_success auth assert_equal 'Approved', auth.message assert auth.authorization - assert capture = @gateway.capture(amount, auth.authorization, :order_id => '2') + assert capture = @gateway.capture(amount, auth.authorization, order_id: '2') assert_success capture end @@ -328,12 +516,46 @@ def test_successful_authorize_and_capture_with_level_2_data assert_success capture end + def test_successful_authorize_and_capture_with_level_3_data + auth = @gateway.authorize(@amount, @credit_card, @options.merge(level_3_data: @level_3_options)) + assert_success auth + assert_equal 'Approved', auth.message + + capture = @gateway.capture(@amount, auth.authorization, @options.merge(level_3_data: @level_3_options)) + assert_success capture + end + + def test_successful_authorize_and_capture_with_echeck + assert auth = @echeck_gateway.authorize(@amount, @echeck, @options.merge(order_id: '2')) + assert_success auth + assert_equal 'Approved', auth.message + assert auth.authorization + assert capture = @echeck_gateway.capture(@amount, auth.authorization, order_id: '2') + assert_success capture + end + + def test_failed_authorize_with_echeck_due_to_invalid_amount + assert auth = @echeck_gateway.authorize(-1, @echeck, @options.merge(order_id: '2')) + assert_failure auth + assert_equal '885', auth.params['proc_status'] + assert_equal 'Error validating amount. Must be numeric, equal to zero or greater [-1]', auth.message + end + def test_authorize_and_void - assert auth = @gateway.authorize(@amount, @credit_card, @options.merge(:order_id => '2')) + assert auth = @gateway.authorize(@amount, @credit_card, @options.merge(order_id: '2')) assert_success auth assert_equal 'Approved', auth.message assert auth.authorization - assert void = @gateway.void(auth.authorization, :order_id => '2') + assert void = @gateway.void(auth.authorization, order_id: '2') + assert_success void + end + + def test_successful_authorize_and_void_with_echeck + assert auth = @echeck_gateway.authorize(@amount, @echeck, @options.merge(order_id: '2')) + assert_success auth + assert_equal 'Approved', auth.message + assert auth.authorization + assert void = @echeck_gateway.void(auth.authorization, order_id: '2') assert_success void end @@ -346,6 +568,21 @@ def test_refund assert_success refund end + def test_successful_refund_with_echeck + assert response = @echeck_gateway.purchase(@amount, @echeck, @options) + assert_success response + assert response.authorization + assert refund = @echeck_gateway.refund(@amount, response.authorization, @options) + assert_success refund + end + + def test_failed_refund_with_echeck_due_to_invalid_authorization + assert refund = @echeck_gateway.refund(@amount, '123;123', @options) + assert_failure refund + assert_equal 'The LIDM you supplied (3F3F3F) does not match with any existing transaction', refund.message + assert_equal '881', refund.params['proc_status'] + end + def test_successful_refund_with_level_2_data amount = @amount assert response = @gateway.purchase(amount, @credit_card, @options.merge(level_2_data: @level_2_options)) @@ -361,13 +598,108 @@ def test_failed_capture assert_equal 'Bad data error', response.message end + def test_authorize_sends_with_retry + assert auth = @echeck_gateway.authorize(@amount, @credit_card, @options.merge(order_id: '4', retry_logic: 'true', trace_number: '989898')) + assert_success auth + assert_equal 'Approved', auth.message + end + + def test_authorize_sends_with_payment_delivery + assert auth = @echeck_gateway.authorize(@amount, @echeck, @options.merge(order_id: '4', payment_delivery: 'A')) + assert_success auth + assert_equal 'Approved', auth.message + end + + def test_default_payment_delivery_with_no_payment_delivery_sent + transcript = capture_transcript(@echeck_gateway) do + @echeck_gateway.authorize(@amount, @echeck, @options.merge(order_id: '4')) + end + + assert_match(/B/, transcript) + assert_match(/A/, transcript) + assert_match(/1/, transcript) + assert_match(/00/, transcript) + end + + def test_sending_echeck_adds_ecp_details_for_refund + assert auth = @echeck_gateway.authorize(@amount, @echeck, @options.merge(order_id: '2')) + assert_success auth + assert_equal 'Approved', auth.message + + capture = @echeck_gateway.capture(@amount, auth.authorization, @options) + assert_success capture + + transcript = capture_transcript(@echeck_gateway) do + refund = @echeck_gateway.refund(@amount, capture.authorization, @options.merge(payment_method: @echeck, action_code: 'W6', auth_method: 'I')) + assert_success refund + end + + assert_match(/W6/, transcript) + assert_match(/I/, transcript) + assert_match(/R/, transcript) + assert_match(/1/, transcript) + end + + def test_sending_credit_card_performs_correct_refund + assert auth = @echeck_gateway.authorize(@amount, @credit_card, @options.merge(order_id: '2')) + assert_success auth + assert_equal 'Approved', auth.message + + capture = @echeck_gateway.capture(@amount, auth.authorization, @options) + assert_success capture + + refund = @echeck_gateway.refund(@amount, capture.authorization, @options) + assert_success refund + end + + def test_echeck_purchase_with_address_responds_with_name + transcript = capture_transcript(@echeck_gateway) do + @echeck_gateway.authorize(@amount, @echeck, @options.merge(order_id: '2')) + end + + assert_match(/Jim Smith/, transcript) + assert_match(/00/, transcript) + assert_match(/Approved/, transcript) + end + + def test_echeck_purchase_with_no_address_responds_with_name + test_check_no_address = check(name: 'Test McTest') + + transcript = capture_transcript(@echeck_gateway) do + @echeck_gateway.authorize(@amount, test_check_no_address, @options.merge(order_id: '2', address: nil, billing_address: nil)) + end + + assert_match(/Test McTest/, transcript) + assert_match(/00/, transcript) + assert_match(/Approved/, transcript) + end + + def test_credit_purchase_with_address_responds_with_name + transcript = capture_transcript(@gateway) do + @gateway.authorize(@amount, @credit_card, @options.merge(order_id: '2')) + end + + assert_match(/Longbob Longsen/, transcript) + assert_match(/00/, transcript) + assert_match(/Approved/, transcript) + end + + def test_credit_purchase_with_no_address_responds_with_no_name + transcript = capture_transcript(@gateway) do + @gateway.authorize(@amount, @credit_card, @options.merge(order_id: '2', address: nil, billing_address: nil)) + end + + assert_match(/00/, transcript) + assert_match(/Approved/, transcript) + end + # == Certification Tests # ==== Section A def test_auth_only_transactions for suite in @test_suite do amount = suite[:amount] - card = credit_card(@cards[suite[:card]], :verification_value => suite[:CVD]) + card = credit_card(@cards[suite[:card]], verification_value: suite[:CVD]) @options[:address][:zip] = suite[:AVSzip] assert response = @gateway.authorize(amount, card, @options) assert_kind_of Response, response @@ -385,7 +717,7 @@ def test_auth_only_transactions def test_auth_capture_transactions for suite in @test_suite do amount = suite[:amount] - card = credit_card(@cards[suite[:card]], :verification_value => suite[:CVD]) + card = credit_card(@cards[suite[:card]], verification_value: suite[:CVD]) options = @options; options[:address][:zip] = suite[:AVSzip] assert response = @gateway.purchase(amount, card, options) assert_kind_of Response, response @@ -435,7 +767,7 @@ def test_refund_transactions def test_void_transactions [3000, 105500, 2900].each do |amount| assert auth_response = @gateway.authorize(amount, @credit_card, @options) - assert void_response = @gateway.void(auth_response.authorization, @options.merge(:transaction_index => 1)) + assert void_response = @gateway.void(auth_response.authorization, @options.merge(transaction_index: 1)) assert_kind_of Response, void_response # Makes it easier to fill in cert sheet if you print these to the command line @@ -481,4 +813,11 @@ def test_transcript_scrubbing_profile assert_scrubbed(@gateway.options[:login], transcript) assert_scrubbed(@gateway.options[:merchant_id], transcript) end + + private + + def stored_credential_options(*args, id: nil) + @options.merge(order_id: generate_unique_id, + stored_credential: stored_credential(*args, id: id)) + end end diff --git a/test/remote/gateways/remote_pagarme_test.rb b/test/remote/gateways/remote_pagarme_test.rb index 868ff0a48c3..0679cbd43c6 100644 --- a/test/remote/gateways/remote_pagarme_test.rb +++ b/test/remote/gateways/remote_pagarme_test.rb @@ -14,7 +14,7 @@ def setup @declined_card = credit_card('4242424242424242', { first_name: 'Richard', last_name: 'Deschamps', - :verification_value => '688' + verification_value: '688' }) @options = { @@ -153,5 +153,4 @@ def test_transcript_scrubbing assert_scrubbed(@credit_card.verification_value, transcript) assert_scrubbed(@gateway.options[:api_key], transcript) end - end diff --git a/test/remote/gateways/remote_pago_facil_test.rb b/test/remote/gateways/remote_pago_facil_test.rb index 254ebd33dec..b672f9e0e06 100644 --- a/test/remote/gateways/remote_pago_facil_test.rb +++ b/test/remote/gateways/remote_pago_facil_test.rb @@ -86,7 +86,7 @@ def successful_response_to random_response = yield if random_response.success? return random_response - elsif(attempts > 2) + elsif attempts > 2 raise 'Unable to get a successful response' else assert_equal 'Declined_(General).', random_response.params.fetch('error') diff --git a/test/remote/gateways/remote_pay_conex_test.rb b/test/remote/gateways/remote_pay_conex_test.rb index 22ed010bcbd..28ba5c8b055 100644 --- a/test/remote/gateways/remote_pay_conex_test.rb +++ b/test/remote/gateways/remote_pay_conex_test.rb @@ -61,7 +61,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture assert_equal 'CAPTURED', capture.message end @@ -85,7 +85,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund assert_equal 'REFUND', refund.message end diff --git a/test/remote/gateways/remote_pay_gate_xml_test.rb b/test/remote/gateways/remote_pay_gate_xml_test.rb index b16cedb0678..02d23f0e8b7 100644 --- a/test/remote/gateways/remote_pay_gate_xml_test.rb +++ b/test/remote/gateways/remote_pay_gate_xml_test.rb @@ -9,11 +9,11 @@ def setup @declined_card = credit_card('4000000000000036') @options = { - :order_id => generate_unique_id, - :billing_address => address, - :email => 'john.doe@example.com', - :ip => '127.0.0.1', - :description => 'Store Purchase', + order_id: generate_unique_id, + billing_address: address, + email: 'john.doe@example.com', + ip: '127.0.0.1', + description: 'Store Purchase' } end @@ -47,8 +47,8 @@ def test_failed_capture def test_invalid_login gateway = PayGateXmlGateway.new( - :login => '', - :password => '' + login: '', + password: '' ) assert response = gateway.authorize(@amount, @credit_card, @options) assert_failure response @@ -59,7 +59,7 @@ def test_successful_purchase_and_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - credit = @gateway.refund(@amount, purchase.authorization, :note => 'Sorry') + credit = @gateway.refund(@amount, purchase.authorization, note: 'Sorry') assert_success credit assert credit.test? end diff --git a/test/remote/gateways/remote_pay_hub_test.rb b/test/remote/gateways/remote_pay_hub_test.rb index e57fe048e4a..ae79455b5a2 100644 --- a/test/remote/gateways/remote_pay_hub_test.rb +++ b/test/remote/gateways/remote_pay_hub_test.rb @@ -7,14 +7,14 @@ def setup @credit_card = credit_card('5466410004374507', verification_value: '998') @invalid_card = credit_card('371449635398431', verification_value: '9997') @options = { - :first_name => 'Garrya', - :last_name => 'Barrya', - :email => 'payhubtest@mailinator.com', - :address => { - :address1 => '123a ahappy St.', - :city => 'Happya City', - :state => 'CA', - :zip => '94901' + first_name: 'Garrya', + last_name: 'Barrya', + email: 'payhubtest@mailinator.com', + address: { + address1: '123a ahappy St.', + city: 'Happya City', + state: 'CA', + zip: '94901' } } end diff --git a/test/remote/gateways/remote_pay_junction_test.rb b/test/remote/gateways/remote_pay_junction_test.rb index 1db822d8bb1..b5a0292cd25 100644 --- a/test/remote/gateways/remote_pay_junction_test.rb +++ b/test/remote/gateways/remote_pay_junction_test.rb @@ -10,28 +10,28 @@ class PayJunctionTest < Test::Unit::TestCase def setup @gateway = PayJunctionGateway.new(fixtures(:pay_junction)) - @credit_card = credit_card('4444333322221111', :verification_value => '999') + @credit_card = credit_card('4444333322221111', verification_value: '999') @valid_verification_value = '999' @invalid_verification_value = '1234' @valid_address = { - :address1 => '123 Test St.', - :address2 => nil, - :city => 'Somewhere', - :state => 'CA', - :zip => '90001' + address1: '123 Test St.', + address2: nil, + city: 'Somewhere', + state: 'CA', + zip: '90001' } @invalid_address = { - :address1 => '187 Apple Tree Lane.', - :address2 => nil, - :city => 'Woodside', - :state => 'CA', - :zip => '94062' + address1: '187 Apple Tree Lane.', + address2: nil, + city: 'Woodside', + state: 'CA', + zip: '94062' } - @options = { :billing_address => @valid_address, :order_id => generate_unique_id } + @options = { billing_address: @valid_address, order_id: generate_unique_id } end def test_successful_purchase @@ -90,7 +90,7 @@ def test_successful_void purchase = @gateway.purchase(AMOUNT, @credit_card, @options) assert_success purchase - assert response = @gateway.void(purchase.authorization, :order_id => order_id) + assert response = @gateway.void(purchase.authorization, order_id: order_id) assert_success response assert_equal 'void', response.params['posture'], 'Should be a capture' assert_equal purchase.authorization, response.authorization, @@ -105,7 +105,7 @@ def test_successful_instant_purchase purchase = @gateway.purchase(AMOUNT, @credit_card, @options) assert_success purchase - assert response = @gateway.purchase(AMOUNT, purchase.authorization, :order_id => generate_unique_id) + assert response = @gateway.purchase(AMOUNT, purchase.authorization, order_id: generate_unique_id) assert_equal PayJunctionGateway::SUCCESS_MESSAGE, response.message assert_equal 'capture', response.params['posture'], 'Should be captured funds' @@ -118,10 +118,9 @@ def test_successful_instant_purchase def test_successful_recurring assert response = @gateway.recurring(AMOUNT, @credit_card, - :periodicity => :monthly, - :payments => 12, - :order_id => generate_unique_id[0..15] - ) + periodicity: :monthly, + payments: 12, + order_id: generate_unique_id[0..15]) assert_equal PayJunctionGateway::SUCCESS_MESSAGE, response.message assert_equal 'charge', response.params['transaction_action'] diff --git a/test/remote/gateways/remote_pay_junction_v2_test.rb b/test/remote/gateways/remote_pay_junction_v2_test.rb index 62954ff4496..8d6ae6987bf 100644 --- a/test/remote/gateways/remote_pay_junction_v2_test.rb +++ b/test/remote/gateways/remote_pay_junction_v2_test.rb @@ -5,9 +5,10 @@ def setup @gateway = PayJunctionV2Gateway.new(fixtures(:pay_junction_v2)) @amount = 99 - @credit_card = credit_card('4444333322221111', month: 01, year: 2020, verification_value: 999) + @credit_card = credit_card('4444333322221111', month: 01, year: 2021, verification_value: 999) @options = { - order_id: generate_unique_id + order_id: generate_unique_id, + billing_address: address() } end @@ -24,6 +25,13 @@ def test_successful_purchase assert_success response assert_equal 'Approved', response.message assert response.test? + + assert_match @options[:billing_address][:company], response.params['billing']['companyName'] + assert_match @options[:billing_address][:address1], response.params['billing']['address']['address'] + assert_match @options[:billing_address][:city], response.params['billing']['address']['city'] + assert_match @options[:billing_address][:state], response.params['billing']['address']['state'] + assert_match @options[:billing_address][:country], response.params['billing']['address']['country'] + assert_match @options[:billing_address][:zip], response.params['billing']['address']['zip'] end def test_successful_purchase_sans_options @@ -60,9 +68,9 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture - assert_equal sprintf('%.2f', (@amount-1).to_f / 100), capture.params['amountTotal'] + assert_equal sprintf('%.2f', (@amount - 1).to_f / 100), capture.params['amountTotal'] end def test_failed_capture @@ -81,13 +89,13 @@ def test_successful_refund end def test_partial_refund - purchase = @gateway.purchase(@amount, @credit_card, @options) + purchase = @gateway.purchase(@amount + 50, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-50, purchase.authorization) + assert refund = @gateway.refund(@amount, purchase.authorization) assert_success refund assert_equal 'Approved', refund.message - assert_equal sprintf('%.2f', (@amount-50).to_f / 100), refund.params['amountTotal'] + assert_equal sprintf('%.2f', @amount.to_f / 100), refund.params['amountTotal'] end def test_failed_refund diff --git a/test/remote/gateways/remote_pay_secure_test.rb b/test/remote/gateways/remote_pay_secure_test.rb index ee153752bb9..4e82df22a9a 100644 --- a/test/remote/gateways/remote_pay_secure_test.rb +++ b/test/remote/gateways/remote_pay_secure_test.rb @@ -1,14 +1,13 @@ require 'test_helper' class RemotePaySecureTest < Test::Unit::TestCase - def setup @gateway = PaySecureGateway.new(fixtures(:pay_secure)) @credit_card = credit_card('4000100011112224') @options = { - :billing_address => address, - :order_id => generate_unique_id + billing_address: address, + order_id: generate_unique_id } @amount = 100 end @@ -29,9 +28,9 @@ def test_unsuccessful_purchase def test_invalid_login gateway = PaySecureGateway.new( - :login => '', - :password => '' - ) + login: '', + password: '' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_equal "MissingField: 'MERCHANT_ID'", response.message assert_failure response diff --git a/test/remote/gateways/remote_paybox_direct_3ds_test.rb b/test/remote/gateways/remote_paybox_direct_3ds_test.rb new file mode 100644 index 00000000000..a8fa0589d8f --- /dev/null +++ b/test/remote/gateways/remote_paybox_direct_3ds_test.rb @@ -0,0 +1,140 @@ +# encoding: utf-8 + +require 'test_helper' + +class RemotePayboxDirect3DSTest < Test::Unit::TestCase + def setup + fixtures = fixtures(:paybox_direct) + @gateway = PayboxDirectGateway.new(fixtures) + + @amount = 100 + @credit_card = credit_card(fixtures[:credit_card_ok_3ds]) + @declined_card = credit_card(fixtures[:credit_card_nok_3ds]) + @unenrolled_card = credit_card(fixtures[:credit_card_ok_3ds_not_enrolled]) + + @options = { + order_id: '1', + billing_address: address, + description: 'Store Purchase', + three_d_secure: { + eci: '02', + cavv: 'jJ81HADVRtXfCBATEp01CJUAAAA=', + xid: '00000000000000000501', + cavv_algorithm: '1' + } + } + end + + def test_successful_purchase + assert response = @gateway.purchase(@amount, @credit_card, @options) + assert_success response + assert_equal 'The transaction was approved', response.message + end + + def test_successful_purchase_other_eci + options = @options + options[:three_d_secure][:eci] = '05' + + assert response = @gateway.purchase(@amount, @credit_card, options) + assert_success response + assert_equal 'The transaction was approved', response.message + end + + def test_unsuccessful_purchase + assert response = @gateway.purchase(@amount, @declined_card, @options) + assert_failure response + assert_equal "PAYBOX : Num\xE9ro de porteur invalide".force_encoding('ASCII-8BIT'), response.message + end + + def test_successful_unenrolled_3ds_purchase + assert response = @gateway.purchase(@amount, @unenrolled_card, @options) + assert_success response + assert_equal 'The transaction was approved', response.message + end + + def test_authorize_and_capture + amount = @amount + assert auth = @gateway.authorize(amount, @credit_card, @options) + assert_success auth + assert_equal 'The transaction was approved', auth.message + assert auth.authorization + assert capture = @gateway.capture(amount, auth.authorization, order_id: '1') + assert_success capture + end + + def test_purchase_and_void + assert purchase = @gateway.purchase(@amount, @credit_card, @options) + assert_success purchase + assert_equal 'The transaction was approved', purchase.message + assert purchase.authorization + # Paybox requires you to remember the expiration date + assert void = @gateway.void(purchase.authorization, order_id: '1', amount: @amount) + assert_equal 'The transaction was approved', void.message + assert_success void + end + + def test_failed_capture + assert response = @gateway.capture(@amount, '', order_id: '1') + assert_failure response + assert_equal 'Mandatory values missing keyword:13 Type:1', response.message + end + + def test_purchase_and_partial_credit + assert purchase = @gateway.purchase(@amount, @credit_card, @options) + assert_success purchase + assert_equal 'The transaction was approved', purchase.message + assert purchase.authorization + assert credit = @gateway.refund(@amount / 2, purchase.authorization, order_id: '1') + assert_equal 'The transaction was approved', credit.message + assert_success credit + end + + def test_successful_refund + assert purchase = @gateway.purchase(@amount, @credit_card, @options) + assert_success purchase + + assert refund = @gateway.refund(@amount, purchase.authorization, order_id: '1') + assert_success refund + end + + def test_partial_refund + assert purchase = @gateway.purchase(@amount, @credit_card, @options) + assert_success purchase + + assert refund = @gateway.refund(@amount / 2, purchase.authorization, order_id: '1') + assert_success refund + end + + def test_failed_refund + refund = @gateway.refund(@amount, '', order_id: '2') + assert_failure refund + assert_equal 'Mandatory values missing keyword:13 Type:13', refund.message + end + + def test_failed_purchase_invalid_eci + options = @options + options[:three_d_secure][:eci] = '00' + + assert purchase = @gateway.purchase(@amount, @credit_card, options) + assert_failure purchase + assert_equal "PAYBOX : Transaction refus\xE9e".force_encoding('ASCII-8BIT'), purchase.message + end + + def test_failed_purchase_invalid_cavv + options = @options + options[:three_d_secure][:cavv] = 'jJ81HADVRtXfCBATEp01CJUAAAAVZQGY=' + + assert purchase = @gateway.purchase(@amount, @credit_card, options) + assert_failure purchase + assert_equal 'Some values exceed max length', purchase.message + end + + def test_failed_purchase_invalid_xid + options = @options + options[:three_d_secure][:xid] = '00000000000000000510123123123456789' + + assert purchase = @gateway.purchase(@amount, @credit_card, options) + assert_failure purchase + assert_equal 'Some values exceed max length', purchase.message + end +end diff --git a/test/remote/gateways/remote_paybox_direct_test.rb b/test/remote/gateways/remote_paybox_direct_test.rb index 25c03d67804..6650a2f6a1f 100644 --- a/test/remote/gateways/remote_paybox_direct_test.rb +++ b/test/remote/gateways/remote_paybox_direct_test.rb @@ -3,18 +3,18 @@ require 'test_helper' class RemotePayboxDirectTest < Test::Unit::TestCase - def setup - @gateway = PayboxDirectGateway.new(fixtures(:paybox_direct)) + fixtures = fixtures(:paybox_direct) + @gateway = PayboxDirectGateway.new(fixtures) @amount = 100 - @credit_card = credit_card('1111222233334444') - @declined_card = credit_card('1111222233334445') + @credit_card = credit_card(fixtures[:credit_card_ok]) + @declined_card = credit_card(fixtures[:credit_card_nok]) @options = { - :order_id => '1', - :billing_address => address, - :description => 'Store Purchase' + order_id: '1', + billing_address: address, + description: 'Store Purchase' } end @@ -36,7 +36,7 @@ def test_authorize_and_capture assert_success auth assert_equal 'The transaction was approved', auth.message assert auth.authorization - assert capture = @gateway.capture(amount, auth.authorization, :order_id => '1') + assert capture = @gateway.capture(amount, auth.authorization, order_id: '1') assert_success capture end @@ -46,15 +46,15 @@ def test_purchase_and_void assert_equal 'The transaction was approved', purchase.message assert purchase.authorization # Paybox requires you to remember the expiration date - assert void = @gateway.void(purchase.authorization, :order_id => '1', :amount => @amount) + assert void = @gateway.void(purchase.authorization, order_id: '1', amount: @amount) assert_equal 'The transaction was approved', void.message assert_success void end def test_failed_capture - assert response = @gateway.capture(@amount, '', :order_id => '1') + assert response = @gateway.capture(@amount, '', order_id: '1') assert_failure response - assert_equal 'Invalid data', response.message + assert_equal 'Mandatory values missing keyword:13 Type:1', response.message end def test_purchase_and_partial_credit @@ -62,7 +62,7 @@ def test_purchase_and_partial_credit assert_success purchase assert_equal 'The transaction was approved', purchase.message assert purchase.authorization - assert credit = @gateway.credit(@amount / 2, purchase.authorization, :order_id => '1') + assert credit = @gateway.refund(@amount / 2, purchase.authorization, order_id: '1') assert_equal 'The transaction was approved', credit.message assert_success credit end @@ -79,34 +79,34 @@ def test_partial_refund assert purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount/2, purchase.authorization, order_id: '1') + assert refund = @gateway.refund(@amount / 2, purchase.authorization, order_id: '1') assert_success refund end def test_failed_refund refund = @gateway.refund(@amount, '', order_id: '2') assert_failure refund - assert_equal 'Invalid data', refund.message + assert_equal 'Mandatory values missing keyword:13 Type:13', refund.message end def test_invalid_login gateway = PayboxDirectGateway.new( - login: '199988899', - password: '1999888F', - rang: 100 - ) + login: '199988899', + password: '1999888F', + rang: 100 + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response - assert_equal 'Non autorise', response.message + assert_equal 'HMAC requis', response.message end def test_invalid_login_without_rang gateway = PayboxDirectGateway.new( - login: '199988899', - password: '1999888F' - ) + login: '199988899', + password: '1999888F' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response - assert_equal 'Non autorise', response.message + assert_equal "PAYBOX : Acc\xE8s refus\xE9 ou site/rang/cl\xE9 invalide".force_encoding('ASCII-8BIT'), response.message end end diff --git a/test/remote/gateways/remote_payeezy_test.rb b/test/remote/gateways/remote_payeezy_test.rb index 789e500a456..e136c96580c 100644 --- a/test/remote/gateways/remote_payeezy_test.rb +++ b/test/remote/gateways/remote_payeezy_test.rb @@ -9,9 +9,9 @@ def setup @amount = 100 @reversal_id = "REV-#{SecureRandom.random_number(1000000)}" @options = { - :billing_address => address, - :merchant_ref => 'Store Purchase', - :ta_token => 'NOIW' + billing_address: address, + merchant_ref: 'Store Purchase', + ta_token: 'NOIW' } @options_mdd = { soft_descriptors: { @@ -33,6 +33,14 @@ def setup initiator: 'MERCHANT', auth_type_override: 'A' } + @options_standardized_stored_credentials = { + stored_credential: { + network_transaction_id: 'abc123', # Not checked if initial_transaction == true; not valid if initial_transaction == false. + initial_transaction: true, + reason_type: 'recurring', + initiator: 'cardholder' + } + } end def test_successful_store @@ -59,11 +67,13 @@ def test_unsuccessful_store def test_successful_purchase assert response = @gateway.purchase(@amount, @credit_card, @options) assert_match(/Transaction Normal/, response.message) + assert_equal '100', response.params['bank_resp_code'] + assert_equal nil, response.error_code assert_success response end def test_successful_purchase_with_echeck - options = @options.merge({customer_id_type: '1', customer_id_number: '1', client_email: 'test@example.com'}) + options = @options.merge({ customer_id_type: '1', customer_id_number: '1', client_email: 'test@example.com' }) assert response = @gateway.purchase(@amount, @check, options) assert_match(/Transaction Normal/, response.message) assert_success response @@ -81,6 +91,12 @@ def test_successful_purchase_with_stored_credentials assert_success response end + def test_successful_purchase_with_standardized_stored_credentials + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(@options_standardized_stored_credentials)) + assert_match(/Transaction Normal/, response.message) + assert_success response + end + def test_failed_purchase @amount = 501300 assert response = @gateway.purchase(@amount, @credit_card, @options) @@ -88,6 +104,13 @@ def test_failed_purchase assert_failure response end + def test_failed_purchase_with_insufficient_funds + assert response = @gateway.purchase(530200, @credit_card, @options) + assert_failure response + assert_equal '302', response.error_code + assert_match(/Insufficient Funds/, response.message) + end + def test_authorize_and_capture assert auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth @@ -119,7 +142,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -168,7 +191,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund end diff --git a/test/remote/gateways/remote_payex_test.rb b/test/remote/gateways/remote_payex_test.rb index fd37ddb6164..0eb8903fbce 100644 --- a/test/remote/gateways/remote_payex_test.rb +++ b/test/remote/gateways/remote_payex_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class RemotePayexTest < Test::Unit::TestCase - def setup @gateway = PayexGateway.new(fixtures(:payex)) @@ -10,7 +9,7 @@ def setup @declined_card = credit_card('4000300011112220') @options = { - :order_id => '1234', + order_id: '1234' } end @@ -80,7 +79,7 @@ def test_successful_store_and_purchase assert_success response assert_equal 'OK', response.message - assert response = @gateway.purchase(@amount, response.authorization, @options.merge({order_id: '5678'})) + assert response = @gateway.purchase(@amount, response.authorization, @options.merge({ order_id: '5678' })) assert_success response assert_equal 'OK', response.message end @@ -90,7 +89,7 @@ def test_successful_store_and_authorize_and_capture assert_success response assert_equal 'OK', response.message - assert response = @gateway.authorize(@amount, response.authorization, @options.merge({order_id: '5678'})) + assert response = @gateway.authorize(@amount, response.authorization, @options.merge({ order_id: '5678' })) assert_success response assert_equal 'OK', response.message assert response.authorization @@ -109,9 +108,9 @@ def test_successful_unstore def test_invalid_login gateway = PayexGateway.new( - :account => '1', - :encryption_key => '1' - ) + account: '1', + encryption_key: '1' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_not_equal 'OK', response.message diff --git a/test/remote/gateways/remote_payflow_express_test.rb b/test/remote/gateways/remote_payflow_express_test.rb index 827907d02d9..7a0377e0087 100644 --- a/test/remote/gateways/remote_payflow_express_test.rb +++ b/test/remote/gateways/remote_payflow_express_test.rb @@ -7,17 +7,16 @@ def setup @gateway = PayflowExpressGateway.new(fixtures(:payflow)) @options = { - :billing_address => - { - :name => 'Cody Fauser', - :address1 => '1234 Shady Brook Lane', - :city => 'Ottawa', - :state => 'ON', - :country => 'CA', - :zip => '90210', - :phone => '555-555-5555' - }, - :email => 'cody@example.com' + billing_address: { + name: 'Cody Fauser', + address1: '1234 Shady Brook Lane', + city: 'Ottawa', + state: 'ON', + country: 'CA', + zip: '90210', + phone: '555-555-5555' + }, + email: 'cody@example.com' } end @@ -28,9 +27,9 @@ def setup # the tests to work correctly def test_set_express_authorization @options.update( - :return_url => 'http://example.com', - :cancel_return_url => 'http://example.com', - :email => 'Buyer1@paypal.com' + return_url: 'http://example.com', + cancel_return_url: 'http://example.com', + email: 'Buyer1@paypal.com' ) response = @gateway.setup_authorization(500, @options) assert response.success? @@ -40,9 +39,9 @@ def test_set_express_authorization def test_set_express_purchase @options.update( - :return_url => 'http://example.com', - :cancel_return_url => 'http://example.com', - :email => 'Buyer1@paypal.com' + return_url: 'http://example.com', + cancel_return_url: 'http://example.com', + email: 'Buyer1@paypal.com' ) response = @gateway.setup_purchase(500, @options) assert response.success? @@ -53,25 +52,25 @@ def test_set_express_purchase def test_setup_authorization_discount_taxes_included_free_shipping amount = 2518 options = { - :ip=>'127.0.0.1', - :return_url=>'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?buyer_accepts_marketing=true&utm_nooverride=1', - :cancel_return_url=>'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?utm_nooverride=1', - :customer=>'test6@test.com', - :email=>'test6@test.com', - :order_id=>'#1092', - :currency=>'USD', - :subtotal=>2798, - :items => [ + ip: '127.0.0.1', + return_url: 'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?buyer_accepts_marketing=true&utm_nooverride=1', + cancel_return_url: 'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?utm_nooverride=1', + customer: 'test6@test.com', + email: 'test6@test.com', + order_id: '#1092', + currency: 'USD', + subtotal: 2798, + items: [ { - :name => 'test4', - :description => 'test4', - :quantity=>2, - :amount=> 1399, - :url=>'http://localhost:3000/products/test4' + name: 'test4', + description: 'test4', + quantity: 2, + amount: 1399, + url: 'http://localhost:3000/products/test4' } ], - :discount=>280, - :no_shipping=>true + discount: 280, + no_shipping: true } response = @gateway.setup_authorization(amount, options) assert response.success?, response.message @@ -80,25 +79,25 @@ def test_setup_authorization_discount_taxes_included_free_shipping def test_setup_authorization_with_discount_taxes_additional amount = 2518 options = { - :ip=>'127.0.0.1', - :return_url=>'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?buyer_accepts_marketing=true&utm_nooverride=1', - :cancel_return_url=>'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?utm_nooverride=1', - :customer=>'test6@test.com', - :email=>'test6@test.com', - :order_id=>'#1092', - :currency=>'USD', - :subtotal=>2798, - :items => [ + ip: '127.0.0.1', + return_url: 'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?buyer_accepts_marketing=true&utm_nooverride=1', + cancel_return_url: 'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?utm_nooverride=1', + customer: 'test6@test.com', + email: 'test6@test.com', + order_id: '#1092', + currency: 'USD', + subtotal: 2798, + items: [ { - :name => 'test4', - :description => 'test4', - :quantity=>2, - :amount=> 1399, - :url=>'http://localhost:3000/products/test4' + name: 'test4', + description: 'test4', + quantity: 2, + amount: 1399, + url: 'http://localhost:3000/products/test4' } ], - :discount=>280, - :no_shipping=>true + discount: 280, + no_shipping: true } response = @gateway.setup_authorization(amount, options) assert response.success?, response.message @@ -107,25 +106,25 @@ def test_setup_authorization_with_discount_taxes_additional def test_setup_authorization_with_discount_taxes_and_shipping_addtiional amount = 2518 options = { - :ip=>'127.0.0.1', - :return_url=>'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?buyer_accepts_marketing=true&utm_nooverride=1', - :cancel_return_url=>'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?utm_nooverride=1', - :customer=>'test6@test.com', - :email=>'test6@test.com', - :order_id=>'#1092', - :currency=>'USD', - :subtotal=>2798, - :items => [ + ip: '127.0.0.1', + return_url: 'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?buyer_accepts_marketing=true&utm_nooverride=1', + cancel_return_url: 'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?utm_nooverride=1', + customer: 'test6@test.com', + email: 'test6@test.com', + order_id: '#1092', + currency: 'USD', + subtotal: 2798, + items: [ { - :name => 'test4', - :description => 'test4', - :quantity=>2, - :amount=> 1399, - :url=>'http://localhost:3000/products/test4' + name: 'test4', + description: 'test4', + quantity: 2, + amount: 1399, + url: 'http://localhost:3000/products/test4' } ], - :discount=>280, - :no_shipping=>false + discount: 280, + no_shipping: false } response = @gateway.setup_authorization(amount, options) assert response.success?, response.message @@ -133,7 +132,6 @@ def test_setup_authorization_with_discount_taxes_and_shipping_addtiional end class RemotePayflowExpressUkTest < Test::Unit::TestCase - def setup @gateway = PayflowExpressUkGateway.new(fixtures(:payflow_uk)) end @@ -141,25 +139,25 @@ def setup def test_setup_authorization_discount_taxes_included_free_shipping amount = 2518 options = { - :ip=>'127.0.0.1', - :return_url=>'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?buyer_accepts_marketing=true&utm_nooverride=1', - :cancel_return_url=>'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?utm_nooverride=1', - :customer=>'test6@test.com', - :email=>'test6@test.com', - :order_id=>'#1092', - :currency=>'GBP', - :subtotal=>2798, - :items=> [ + ip: '127.0.0.1', + return_url: 'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?buyer_accepts_marketing=true&utm_nooverride=1', + cancel_return_url: 'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?utm_nooverride=1', + customer: 'test6@test.com', + email: 'test6@test.com', + order_id: '#1092', + currency: 'GBP', + subtotal: 2798, + items: [ { - :name=>'test4', - :description=>'test4', - :quantity=>2, - :amount=>1399, - :url=>'http://localhost:3000/products/test4' + name: 'test4', + description: 'test4', + quantity: 2, + amount: 1399, + url: 'http://localhost:3000/products/test4' } ], - :discount=>280, - :no_shipping=>true + discount: 280, + no_shipping: true } response = @gateway.setup_authorization(amount, options) assert response.success?, response.message @@ -168,25 +166,25 @@ def test_setup_authorization_discount_taxes_included_free_shipping def test_setup_authorization_with_discount_taxes_additional amount = 2518 options = { - :ip=>'127.0.0.1', - :return_url=>'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?buyer_accepts_marketing=true&utm_nooverride=1', - :cancel_return_url=>'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?utm_nooverride=1', - :customer=>'test6@test.com', - :email=>'test6@test.com', - :order_id=>'#1092', - :currency=>'GBP', - :subtotal=>2798, - :items=> [ + ip: '127.0.0.1', + return_url: 'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?buyer_accepts_marketing=true&utm_nooverride=1', + cancel_return_url: 'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?utm_nooverride=1', + customer: 'test6@test.com', + email: 'test6@test.com', + order_id: '#1092', + currency: 'GBP', + subtotal: 2798, + items: [ { - :name=>'test4', - :description=>'test4', - :quantity=>2, - :amount=>1399, - :url=>'http://localhost:3000/products/test4' + name: 'test4', + description: 'test4', + quantity: 2, + amount: 1399, + url: 'http://localhost:3000/products/test4' } ], - :discount=>280, - :no_shipping=>true + discount: 280, + no_shipping: true } response = @gateway.setup_authorization(amount, options) assert response.success?, response.message @@ -195,25 +193,25 @@ def test_setup_authorization_with_discount_taxes_additional def test_setup_authorization_with_discount_taxes_and_shipping_addtiional amount = 2518 options = { - :ip=>'127.0.0.1', - :return_url=>'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?buyer_accepts_marketing=true&utm_nooverride=1', - :cancel_return_url=>'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?utm_nooverride=1', - :customer=>'test6@test.com', - :email=>'test6@test.com', - :order_id=>'#1092', - :currency=>'GBP', - :subtotal=>2798, - :items=> [ + ip: '127.0.0.1', + return_url: 'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?buyer_accepts_marketing=true&utm_nooverride=1', + cancel_return_url: 'http://localhost:3000/orders/1/8e06ea26f8add7608671d433f13c2193/commit_paypal?utm_nooverride=1', + customer: 'test6@test.com', + email: 'test6@test.com', + order_id: '#1092', + currency: 'GBP', + subtotal: 2798, + items: [ { - :name=>'test4', - :description=>'test4', - :quantity=>2, - :amount=>1399, - :url=>'http://localhost:3000/products/test4' + name: 'test4', + description: 'test4', + quantity: 2, + amount: 1399, + url: 'http://localhost:3000/products/test4' } ], - :discount=>280, - :no_shipping=>false + discount: 280, + no_shipping: false } response = @gateway.setup_authorization(amount, options) assert response.success?, response.message diff --git a/test/remote/gateways/remote_payflow_test.rb b/test/remote/gateways/remote_payflow_test.rb index 43ae51f5b41..74172945edc 100644 --- a/test/remote/gateways/remote_payflow_test.rb +++ b/test/remote/gateways/remote_payflow_test.rb @@ -8,26 +8,26 @@ def setup @credit_card = credit_card( '5105105105105100', - :brand => 'master' + brand: 'master' ) @options = { - :billing_address => address, - :email => 'cody@example.com', - :customer => 'codyexample' + billing_address: address, + email: 'cody@example.com', + customer: 'codyexample' } @extra_options = { - :order_id => '123', - :description => 'Description string', - :order_desc => 'OrderDesc string', - :comment => 'Comment string', - :comment2 => 'Comment2 string' + order_id: '123', + description: 'Description string', + order_desc: 'OrderDesc string', + comment: 'Comment string', + comment2: 'Comment2 string' } @check = check( - :routing_number => '111111118', - :account_number => '1111111111' + routing_number: '111111118', + account_number: '1111111111' ) @l2_json = '{ @@ -70,6 +70,19 @@ def test_successful_purchase_with_extra_options assert !response.fraud_review? end + def test_successful_purchase_with_application_id + ActiveMerchant::Billing::PayflowGateway.application_id = 'partner_id' + + assert response = @gateway.purchase(100000, @credit_card, @options) + assert_equal 'Approved', response.message + assert_success response + assert response.test? + assert_not_nil response.authorization + assert !response.fraud_review? + ensure + ActiveMerchant::Billing::PayflowGateway.application_id = nil + end + # In order for this remote test to pass, you must go into your Payflow test # backend and enable the correct filter. Once logged in: # "Service Settings" -> @@ -119,6 +132,20 @@ def test_successful_purchase_with_l2_l3_fields assert_not_nil response.authorization end + def test_successful_purchase_with_l3_fields_and_application_id + ActiveMerchant::Billing::PayflowGateway.application_id = 'partner_id' + + options = @options.merge(level_three_fields: @l3_json) + + assert response = @gateway.purchase(100000, @credit_card, options) + assert_equal 'Approved', response.message + assert_success response + assert response.test? + assert_not_nil response.authorization + ensure + ActiveMerchant::Billing::PayflowGateway.application_id = nil + end + def test_declined_purchase assert response = @gateway.purchase(210000, @credit_card, @options) assert_equal 'Declined', response.message @@ -176,6 +203,19 @@ def test_authorize_and_capture_with_three_d_secure_option assert_success capture end + def test_successful_authorize_with_application_id + ActiveMerchant::Billing::PayflowGateway.application_id = 'partner_id' + + assert response = @gateway.authorize(100000, @credit_card, @options) + assert_equal 'Approved', response.message + assert_success response + assert response.test? + assert_not_nil response.authorization + assert !response.fraud_review? + ensure + ActiveMerchant::Billing::PayflowGateway.application_id = nil + end + def test_authorize_and_partial_capture assert auth = @gateway.authorize(100 * 2, @credit_card, @options) assert_success auth @@ -192,7 +232,7 @@ def test_authorize_and_complete_capture assert_equal 'Approved', auth.message assert auth.authorization - assert capture = @gateway.capture(100, auth.authorization, :capture_complete => 'Y') + assert capture = @gateway.capture(100, auth.authorization, capture_complete: 'Y') assert_success capture assert capture = @gateway.capture(100, auth.authorization) @@ -205,7 +245,7 @@ def test_authorize_and_uncomplete_capture assert_equal 'Approved', auth.message assert auth.authorization - assert capture = @gateway.capture(100, auth.authorization, :capture_complete => 'N') + assert capture = @gateway.capture(100, auth.authorization, capture_complete: 'N') assert_success capture assert capture = @gateway.capture(100, auth.authorization) @@ -236,7 +276,7 @@ def test_successful_verify def test_successful_verify_amex @amex_credit_card = credit_card( '378282246310005', - :brand => 'american_express' + brand: 'american_express' ) assert response = @gateway.verify(@amex_credit_card, @options) assert_success response @@ -251,8 +291,8 @@ def test_failed_verify def test_invalid_login gateway = PayflowGateway.new( - :login => '', - :password => '' + login: '', + password: '' ) assert response = gateway.purchase(100, @credit_card, @options) assert_equal 'Invalid vendor account', response.message @@ -274,7 +314,7 @@ def test_duplicate_request_id def test_create_recurring_profile response = assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.recurring(1000, @credit_card, :periodicity => :monthly) + @gateway.recurring(1000, @credit_card, periodicity: :monthly) end assert_success response assert !response.params['profile_id'].blank? @@ -283,7 +323,7 @@ def test_create_recurring_profile def test_create_recurring_profile_with_invalid_date response = assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.recurring(1000, @credit_card, :periodicity => :monthly, :starting_at => Time.now) + @gateway.recurring(1000, @credit_card, periodicity: :monthly, starting_at: Time.now) end assert_failure response assert_equal 'Field format error: Start or next payment date must be a valid future date', response.message @@ -293,7 +333,7 @@ def test_create_recurring_profile_with_invalid_date def test_create_and_cancel_recurring_profile response = assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.recurring(1000, @credit_card, :periodicity => :monthly) + @gateway.recurring(1000, @credit_card, periodicity: :monthly) end assert_success response assert !response.params['profile_id'].blank? @@ -309,10 +349,10 @@ def test_create_and_cancel_recurring_profile def test_full_feature_set_for_recurring_profiles # Test add @options.update( - :periodicity => :weekly, - :payments => '12', - :starting_at => Time.now + 1.day, - :comment => 'Test Profile' + periodicity: :weekly, + payments: '12', + starting_at: Time.now + 1.day, + comment: 'Test Profile' ) response = assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do @gateway.recurring(100, @credit_card, @options) @@ -326,10 +366,10 @@ def test_full_feature_set_for_recurring_profiles # Test modify @options.update( - :periodicity => :monthly, - :starting_at => Time.now + 1.day, - :payments => '4', - :profile_id => @recurring_profile_id + periodicity: :monthly, + starting_at: Time.now + 1.day, + payments: '4', + profile_id: @recurring_profile_id ) response = assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do @gateway.recurring(400, @credit_card, @options) @@ -349,7 +389,7 @@ def test_full_feature_set_for_recurring_profiles # Test payment history inquiry response = assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.recurring_inquiry(@recurring_profile_id, :history => true) + @gateway.recurring_inquiry(@recurring_profile_id, history: true) end assert_equal '0', response.params['result'] assert_success response @@ -383,12 +423,11 @@ def test_reference_purchase def test_recurring_with_initial_authorization response = assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do @gateway.recurring(1000, @credit_card, - :periodicity => :monthly, - :initial_transaction => { - :type => :purchase, - :amount => 500 - } - ) + periodicity: :monthly, + initial_transaction: { + type: :purchase, + amount: 500 + }) end assert_success response @@ -455,13 +494,13 @@ def test_high_verbosity def three_d_secure_option { - :three_d_secure => { - :authentication_id => 'QvDbSAxSiaQs241899E0', - :authentication_response_status => 'Y', - :eci => '02', - :cavv => 'jGvQIvG/5UhjAREALGYa6Vu/hto=', - :xid => 'UXZEYlNBeFNpYVFzMjQxODk5RTA=' - } + three_d_secure: { + authentication_id: 'QvDbSAxSiaQs241899E0', + authentication_response_status: 'Y', + eci: '02', + cavv: 'jGvQIvG/5UhjAREALGYa6Vu/hto=', + xid: 'UXZEYlNBeFNpYVFzMjQxODk5RTA=' + } } end diff --git a/test/remote/gateways/remote_payflow_uk_test.rb b/test/remote/gateways/remote_payflow_uk_test.rb index afe6791cfc8..799380eab47 100644 --- a/test/remote/gateways/remote_payflow_uk_test.rb +++ b/test/remote/gateways/remote_payflow_uk_test.rb @@ -8,26 +8,26 @@ def setup @gateway = PayflowUkGateway.new(fixtures(:payflow_uk)) @creditcard = CreditCard.new( - :number => '5105105105105100', - :month => 11, - :year => 2009, - :first_name => 'Cody', - :last_name => 'Fauser', - :verification_value => '000', - :brand => 'master' + number: '5105105105105100', + month: 11, + year: 2009, + first_name: 'Cody', + last_name: 'Fauser', + verification_value: '000', + brand: 'master' ) @options = { - :billing_address => { - :name => 'Cody Fauser', - :address1 => '1234 Shady Brook Lane', - :city => 'Ottawa', - :state => 'ON', - :country => 'CA', - :zip => '90210', - :phone => '555-555-5555' + billing_address: { + name: 'Cody Fauser', + address1: '1234 Shady Brook Lane', + city: 'Ottawa', + state: 'ON', + country: 'CA', + zip: '90210', + phone: '555-555-5555' }, - :email => 'cody@example.com' + email: 'cody@example.com' } end @@ -128,8 +128,8 @@ def test_authorize_and_void def test_invalid_login gateway = PayflowGateway.new( - :login => '', - :password => '' + login: '', + password: '' ) assert response = gateway.purchase(100, @creditcard, @options) assert_equal 'Invalid vendor account', response.message @@ -138,8 +138,8 @@ def test_invalid_login def test_duplicate_request_id gateway = PayflowUkGateway.new( - :login => @login, - :password => @password + login: @login, + password: @password ) request_id = Digest::SHA1.hexdigest(rand.to_s).slice(0, 32) diff --git a/test/remote/gateways/remote_payment_express_test.rb b/test/remote/gateways/remote_payment_express_test.rb index a2d2a3b0135..2ef9d8a62c5 100644 --- a/test/remote/gateways/remote_payment_express_test.rb +++ b/test/remote/gateways/remote_payment_express_test.rb @@ -1,17 +1,16 @@ require 'test_helper' class RemotePaymentExpressTest < Test::Unit::TestCase - def setup @gateway = PaymentExpressGateway.new(fixtures(:payment_express)) @credit_card = credit_card('4111111111111111') @options = { - :order_id => generate_unique_id, - :billing_address => address, - :email => 'cody@example.com', - :description => 'Store purchase' + order_id: generate_unique_id, + billing_address: address, + email: 'cody@example.com', + description: 'Store purchase' } @amount = 100 @@ -32,7 +31,7 @@ def test_successful_purchase_with_reference_id end def test_successful_purchase_with_ip - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:ip => '192.168.0.1')) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(ip: '192.168.0.1')) assert_success response assert_equal 'The Transaction was approved', response.message assert_not_nil response.authorization @@ -66,7 +65,7 @@ def test_purchase_and_refund assert_success purchase assert_equal 'The Transaction was approved', purchase.message assert !purchase.authorization.blank? - assert refund = @gateway.refund(amount, purchase.authorization, :description => 'Giving a refund') + assert refund = @gateway.refund(amount, purchase.authorization, description: 'Giving a refund') assert_success refund end @@ -78,14 +77,22 @@ def test_failed_capture def test_invalid_login gateway = PaymentExpressGateway.new( - :login => '', - :password => '' + login: '', + password: '' ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_match %r{Invalid Credentials}i, response.message assert_failure response end + def test_verify + assert response = @gateway.verify(@credit_card, @options) + assert_success response + assert_equal 'The Transaction was approved', response.message + assert_not_nil token = response.authorization + assert_equal token, response.token + end + def test_store_credit_card assert response = @gateway.store(@credit_card) assert_success response @@ -96,7 +103,7 @@ def test_store_credit_card def test_store_with_custom_token token = Time.now.to_i.to_s - assert response = @gateway.store(@credit_card, :billing_id => token) + assert response = @gateway.store(@credit_card, billing_id: token) assert_success response assert_equal 'The Transaction was approved', response.message assert_not_nil response.authorization @@ -146,5 +153,4 @@ def test_transcript_scrubbing assert_scrubbed(@credit_card.verification_value.to_s, clean_transcript) assert_scrubbed(@gateway.options[:password], clean_transcript) end - end diff --git a/test/remote/gateways/remote_paymentez_test.rb b/test/remote/gateways/remote_paymentez_test.rb index 831b61b07ca..c45e8ba462c 100644 --- a/test/remote/gateways/remote_paymentez_test.rb +++ b/test/remote/gateways/remote_paymentez_test.rb @@ -7,13 +7,12 @@ def setup @amount = 100 @credit_card = credit_card('4111111111111111', verification_value: '666') @elo_credit_card = credit_card('6362970000457013', - :month => 10, - :year => 2020, - :first_name => 'John', - :last_name => 'Smith', - :verification_value => '737', - :brand => 'elo' - ) + month: 10, + year: 2022, + first_name: 'John', + last_name: 'Smith', + verification_value: '737', + brand: 'elo') @declined_card = credit_card('4242424242424242', verification_value: '666') @options = { billing_address: address, @@ -23,6 +22,29 @@ def setup vat: 0, dev_reference: 'Testing' } + + @cavv = 'example-cavv-value' + @xid = 'three-ds-v1-trans-id' + @eci = '01' + @three_ds_v1_version = '1.0.2' + @three_ds_v2_version = '2.1.0' + @three_ds_server_trans_id = 'three-ds-v2-trans-id' + @authentication_response_status = 'Y' + + @three_ds_v1_mpi = { + cavv: @cavv, + eci: @eci, + version: @three_ds_v1_version, + xid: @xid + } + + @three_ds_v2_mpi = { + cavv: @cavv, + eci: @eci, + version: @three_ds_v2_version, + three_ds_server_trans_id: @three_ds_server_trans_id, + authentication_response_status: @authentication_response_status + } end def test_successful_purchase @@ -78,7 +100,8 @@ def test_successful_purchase_with_extra_params configuration1: 'value1', configuration2: 'value2', configuration3: 'value3' - }} + } + } response = @gateway.purchase(@amount, @credit_card, @options.merge(options)) assert_success response @@ -92,6 +115,18 @@ def test_successful_purchase_with_token assert_success purchase_response end + def test_successful_purchase_with_3ds1_mpi_fields + @options[:three_d_secure] = @three_ds_v1_mpi + response = @gateway.purchase(@amount, @credit_card, @options) + assert_success response + end + + def test_successful_purchase_with_3ds2_mpi_fields + @options[:three_d_secure] = @three_ds_v2_mpi + response = @gateway.purchase(@amount, @credit_card, @options) + assert_success response + end + def test_failed_purchase response = @gateway.purchase(@amount, @declined_card, @options) assert_failure response @@ -104,6 +139,7 @@ def test_successful_refund assert refund = @gateway.refund(@amount, auth.authorization, @options) assert_success refund + assert_equal 'Completed', refund.message end def test_successful_refund_with_elo @@ -112,6 +148,7 @@ def test_successful_refund_with_elo assert refund = @gateway.refund(@amount, auth.authorization, @options) assert_success refund + assert_equal 'Completed', refund.message end def test_successful_void @@ -120,6 +157,7 @@ def test_successful_void assert void = @gateway.void(auth.authorization) assert_success void + assert_equal 'Completed', void.message end def test_successful_void_with_elo @@ -128,12 +166,13 @@ def test_successful_void_with_elo assert void = @gateway.void(auth.authorization) assert_success void + assert_equal 'Completed', void.message end def test_failed_void response = @gateway.void('') assert_failure response - assert_equal 'Carrier not supported', response.message + assert_equal 'ValidationError', response.message assert_equal Gateway::STANDARD_ERROR_CODE[:config_error], response.error_code end @@ -167,11 +206,24 @@ def test_successful_authorize_and_capture_with_token def test_successful_authorize_and_capture_with_different_amount auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount + 100, auth.authorization) + amount = 99.0 + assert capture = @gateway.capture(amount, auth.authorization) assert_success capture assert_equal 'Response by mock', capture.message end + def test_successful_authorize_with_3ds1_mpi_fields + @options[:three_d_secure] = @three_ds_v1_mpi + response = @gateway.authorize(@amount, @credit_card, @options) + assert_success response + end + + def test_successful_authorize_with_3ds2_mpi_fields + @options[:three_d_secure] = @three_ds_v2_mpi + response = @gateway.authorize(@amount, @credit_card, @options) + assert_success response + end + def test_failed_authorize response = @gateway.authorize(@amount, @declined_card, @options) assert_failure response @@ -182,7 +234,8 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth assert capture = @gateway.capture(@amount - 1, auth.authorization) - assert_failure capture # Paymentez explicitly does not support partial capture; only GREATER than auth capture + assert_success capture + assert_equal 'Response by mock', capture.message end def test_failed_capture diff --git a/test/remote/gateways/remote_paymill_test.rb b/test/remote/gateways/remote_paymill_test.rb index 880f346a47d..800605d1c99 100644 --- a/test/remote/gateways/remote_paymill_test.rb +++ b/test/remote/gateways/remote_paymill_test.rb @@ -7,7 +7,7 @@ def setup @amount = 100 @credit_card = credit_card('5500000000000004') @options = { - :email => 'Longbob.Longse@example.com' + email: 'Longbob.Longse@example.com' } @declined_card = credit_card('5105105105105100', month: 5, year: 2020) @@ -171,5 +171,4 @@ def test_verify_credentials gateway = PaymillGateway.new(public_key: 'unknown_key', private_key: 'unknown_key') assert !gateway.verify_credentials end - end diff --git a/test/remote/gateways/remote_paypal_express_test.rb b/test/remote/gateways/remote_paypal_express_test.rb index c599649a814..76857c338ea 100644 --- a/test/remote/gateways/remote_paypal_express_test.rb +++ b/test/remote/gateways/remote_paypal_express_test.rb @@ -7,29 +7,28 @@ def setup @gateway = PaypalExpressGateway.new(fixtures(:paypal_certificate)) @options = { - :order_id => '230000', - :email => 'buyer@jadedpallet.com', - :billing_address => - { - :name => 'Fred Brooks', - :address1 => '1234 Penny Lane', - :city => 'Jonsetown', - :state => 'NC', - :country => 'US', - :zip => '23456' - }, - :description => 'Stuff that you purchased, yo!', - :ip => '10.0.0.1', - :return_url => 'http://example.com/return', - :cancel_return_url => 'http://example.com/cancel' + order_id: '230000', + email: 'buyer@jadedpallet.com', + billing_address: { + name: 'Fred Brooks', + address1: '1234 Penny Lane', + city: 'Jonsetown', + state: 'NC', + country: 'US', + zip: '23456' + }, + description: 'Stuff that you purchased, yo!', + ip: '10.0.0.1', + return_url: 'http://example.com/return', + cancel_return_url: 'http://example.com/cancel' } end def test_set_express_authorization @options.update( - :return_url => 'http://example.com', - :cancel_return_url => 'http://example.com', - :email => 'Buyer1@paypal.com' + return_url: 'http://example.com', + cancel_return_url: 'http://example.com', + email: 'Buyer1@paypal.com' ) response = @gateway.setup_authorization(500, @options) assert response.success? @@ -39,9 +38,9 @@ def test_set_express_authorization def test_set_express_purchase @options.update( - :return_url => 'http://example.com', - :cancel_return_url => 'http://example.com', - :email => 'Buyer1@paypal.com' + return_url: 'http://example.com', + cancel_return_url: 'http://example.com', + email: 'Buyer1@paypal.com' ) response = @gateway.setup_purchase(500, @options) assert response.success? diff --git a/test/remote/gateways/remote_paypal_test.rb b/test/remote/gateways/remote_paypal_test.rb index 220337bb2d9..d73c21528c8 100644 --- a/test/remote/gateways/remote_paypal_test.rb +++ b/test/remote/gateways/remote_paypal_test.rb @@ -8,19 +8,18 @@ def setup @declined_card = credit_card('234234234234') @params = { - :order_id => generate_unique_id, - :email => 'buyer@jadedpallet.com', - :billing_address => - { - :name => 'Longbob Longsen', - :address1 => '4321 Penny Lane', - :city => 'Jonsetown', - :state => 'NC', - :country => 'US', - :zip => '23456' - }, - :description => 'Stuff that you purchased, yo!', - :ip => '10.0.0.1' + order_id: generate_unique_id, + email: 'buyer@jadedpallet.com', + billing_address: { + name: 'Longbob Longsen', + address1: '4321 Penny Lane', + city: 'Jonsetown', + state: 'NC', + country: 'US', + zip: '23456' + }, + description: 'Stuff that you purchased, yo!', + ip: '10.0.0.1' } @amount = 100 @@ -65,6 +64,32 @@ def test_successful_purchase_with_descriptors assert response.params['transaction_id'] end + def test_successful_purchase_with_order_total_elements + order_total_elements = { + subtotal: @amount / 4, + shipping: @amount / 4, + handling: @amount / 4, + tax: @amount / 4 + } + + response = @gateway.purchase(@amount, @credit_card, @params.merge(order_total_elements)) + assert_success response + assert response.params['transaction_id'] + end + + def test_successful_purchase_with_non_fractional_currency_when_any_order_total_element_is_nil + order_total_elements = { + subtotal: @amount / 4, + shipping: @amount / 4, + handling: nil, + tax: @amount / 4 + } + + response = @gateway.purchase(@amount, @credit_card, @params.merge(order_total_elements).merge(currency: 'JPY')) + assert_success response + assert response.params['transaction_id'] + end + def test_failed_purchase response = @gateway.purchase(@amount, @declined_card, @params) assert_failure response @@ -87,6 +112,7 @@ def test_failed_authorization def test_successful_reauthorization return if not @three_days_old_auth_id + auth = @gateway.reauthorize(1000, @three_days_old_auth_id) assert_success auth assert auth.authorization @@ -99,7 +125,8 @@ def test_successful_reauthorization end def test_failed_reauthorization - return if not @three_days_old_auth_id2 # was authed for $10, attempt $20 + return if not @three_days_old_auth_id2 # was authed for $10, attempt $20 + auth = @gateway.reauthorize(2000, @three_days_old_auth_id2) assert_false auth? assert !auth.authorization @@ -118,20 +145,20 @@ def test_successful_capture def test_successful_incomplete_captures auth = @gateway.authorize(100, @credit_card, @params) assert_success auth - response = @gateway.capture(60, auth.authorization, {:complete_type => 'NotComplete'}) + response = @gateway.capture(60, auth.authorization, { complete_type: 'NotComplete' }) assert_success response assert response.params['transaction_id'] assert_equal '0.60', response.params['gross_amount'] - response_2 = @gateway.capture(40, auth.authorization) - assert_success response_2 - assert response_2.params['transaction_id'] - assert_equal '0.40', response_2.params['gross_amount'] + response2 = @gateway.capture(40, auth.authorization) + assert_success response2 + assert response2.params['transaction_id'] + assert_equal '0.40', response2.params['gross_amount'] end def test_successful_capture_updating_the_invoice_id auth = @gateway.authorize(@amount, @credit_card, @params) assert_success auth - response = @gateway.capture(@amount, auth.authorization, :order_id => "NEWID#{generate_unique_id}") + response = @gateway.capture(@amount, auth.authorization, order_id: "NEWID#{generate_unique_id}") assert_success response assert response.params['transaction_id'] assert_equal '1.00', response.params['gross_amount'] @@ -149,7 +176,7 @@ def test_purchase_and_full_credit purchase = @gateway.purchase(@amount, @credit_card, @params) assert_success purchase - credit = @gateway.refund(@amount, purchase.authorization, :note => 'Sorry') + credit = @gateway.refund(@amount, purchase.authorization, note: 'Sorry') assert_success credit assert credit.test? assert_equal 'USD', credit.params['net_refund_amount_currency_id'] @@ -191,7 +218,7 @@ def test_successful_transfer response = @gateway.purchase(@amount, @credit_card, @params) assert_success response - response = @gateway.transfer(@amount, 'joe@example.com', :subject => 'Your money', :note => 'Thanks for taking care of that') + response = @gateway.transfer(@amount, 'joe@example.com', subject: 'Your money', note: 'Thanks for taking care of that') assert_success response end @@ -206,8 +233,8 @@ def test_successful_multiple_transfer assert_success response response = @gateway.transfer([@amount, 'joe@example.com'], - [600, 'jane@example.com', {:note => 'Thanks for taking care of that'}], - :subject => 'Your money') + [600, 'jane@example.com', { note: 'Thanks for taking care of that' }], + subject: 'Your money') assert_success response end @@ -225,7 +252,7 @@ def test_successful_email_transfer response = @gateway.purchase(@amount, @credit_card, @params) assert_success response - response = @gateway.transfer([@amount, 'joe@example.com'], :receiver_type => 'EmailAddress', :subject => 'Your money', :note => 'Thanks for taking care of that') + response = @gateway.transfer([@amount, 'joe@example.com'], receiver_type: 'EmailAddress', subject: 'Your money', note: 'Thanks for taking care of that') assert_success response end @@ -233,7 +260,7 @@ def test_successful_userid_transfer response = @gateway.purchase(@amount, @credit_card, @params) assert_success response - response = @gateway.transfer([@amount, '4ET96X3PQEN8H'], :receiver_type => 'UserID', :subject => 'Your money', :note => 'Thanks for taking care of that') + response = @gateway.transfer([@amount, '4ET96X3PQEN8H'], receiver_type: 'UserID', subject: 'Your money', note: 'Thanks for taking care of that') assert_success response end @@ -241,7 +268,7 @@ def test_failed_userid_transfer response = @gateway.purchase(@amount, @credit_card, @params) assert_success response - response = @gateway.transfer([@amount, 'joe@example.com'], :receiver_type => 'UserID', :subject => 'Your money', :note => 'Thanks for taking care of that') + response = @gateway.transfer([@amount, 'joe@example.com'], receiver_type: 'UserID', subject: 'Your money', note: 'Thanks for taking care of that') assert_failure response end @@ -259,10 +286,25 @@ def test_successful_referenced_id_purchase def test_successful_purchase_with_3ds_version_1 params = @params.merge!({ three_d_secure: { - trans_status: 'Y', - eci: '05', - cavv: 'AgAAAAAAAIR8CQrXcIhbQAAAAAA', - xid: 'MDAwMDAwMDAwMDAwMDAwMzIyNzY=' + trans_status: 'Y', + eci: '05', + cavv: 'AgAAAAAAAIR8CQrXcIhbQAAAAAA', + xid: 'MDAwMDAwMDAwMDAwMDAwMzIyNzY=' + } + }) + response = @gateway.purchase(@amount, @credit_card, params) + assert_success response + assert response.params['transaction_id'] + end + + def test_successful_purchase_with_3ds_version_2 + params = @params.merge!({ + three_d_secure: { + authentication_response_status: 'Y', + eci: '05', + cavv: 'AgAAAAAAAIR8CQrXcIhbQAAAAAA', + ds_transaction_id: 'bDE9Aa1A-C5Ac-AD3a-4bBC-aC918ab1de3E', + version: '2.1.0' } }) response = @gateway.purchase(@amount, @credit_card, params) diff --git a/test/remote/gateways/remote_payscout_test.rb b/test/remote/gateways/remote_payscout_test.rb index ce0a0768a1e..9aadde0d11d 100644 --- a/test/remote/gateways/remote_payscout_test.rb +++ b/test/remote/gateways/remote_payscout_test.rb @@ -9,9 +9,9 @@ def setup @declined_card = credit_card('34343') @options = { - :order_id => '1', - :description => 'Store Purchase', - :billing_address => address + order_id: '1', + description: 'Store Purchase', + billing_address: address } end @@ -148,8 +148,8 @@ def test_not_found_transaction_id_void def test_invalid_credentials gateway = PayscoutGateway.new( - :username => 'xxx', - :password => 'xxx' + username: 'xxx', + password: 'xxx' ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response diff --git a/test/remote/gateways/remote_paystation_test.rb b/test/remote/gateways/remote_paystation_test.rb index 84285905003..5144faeb8c6 100644 --- a/test/remote/gateways/remote_paystation_test.rb +++ b/test/remote/gateways/remote_paystation_test.rb @@ -1,11 +1,10 @@ require 'test_helper' class RemotePaystationTest < Test::Unit::TestCase - def setup @gateway = PaystationGateway.new(fixtures(:paystation)) - @credit_card = credit_card('5123456789012346', :month => 5, :year => 13, :verification_value => 123) + @credit_card = credit_card('5123456789012346', month: 5, year: 13, verification_value: 123) @successful_amount = 10000 @insufficient_funds_amount = 10051 @@ -14,8 +13,8 @@ def setup @bank_error_amount = 10091 @options = { - :billing_address => address, - :description => 'Store Purchase' + billing_address: address, + description: 'Store Purchase' } end @@ -27,7 +26,7 @@ def test_successful_purchase end def test_successful_purchase_in_gbp - assert response = @gateway.purchase(@successful_amount, @credit_card, @options.merge(:currency => 'GBP')) + assert response = @gateway.purchase(@successful_amount, @credit_card, @options.merge(currency: 'GBP')) assert_success response assert_equal 'Transaction successful', response.message @@ -39,7 +38,7 @@ def test_failed_purchases ['invalid_transaction', @invalid_transaction_amount, 'Transaction Type Not Supported'], ['expired_card', @expired_card_amount, 'Expired Card'], ['bank_error', @bank_error_amount, 'Error Communicating with Bank'] - ].each do |name, amount, message| + ].each do |_name, amount, message| assert response = @gateway.purchase(amount, @credit_card, @options) assert_failure response assert_equal message, response.message @@ -48,7 +47,7 @@ def test_failed_purchases def test_storing_token time = Time.now.to_i - assert response = @gateway.store(@credit_card, @options.merge(:token => "justatest#{time}")) + assert response = @gateway.store(@credit_card, @options.merge(token: "justatest#{time}")) assert_success response assert_equal 'Future Payment Saved Ok', response.message @@ -70,7 +69,7 @@ def test_authorize_and_capture assert_success auth assert auth.authorization - assert capture = @gateway.capture(@successful_amount, auth.authorization, @options.merge(:credit_card_verification => 123)) + assert capture = @gateway.capture(@successful_amount, auth.authorization, @options.merge(credit_card_verification: 123)) assert_success capture end diff --git a/test/remote/gateways/remote_payu_in_test.rb b/test/remote/gateways/remote_payu_in_test.rb index 182c3a1cc17..c6d8c477159 100644 --- a/test/remote/gateways/remote_payu_in_test.rb +++ b/test/remote/gateways/remote_payu_in_test.rb @@ -68,7 +68,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - refund = @gateway.refund(@amount-1, purchase.authorization) + refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund end @@ -82,30 +82,28 @@ def test_3ds_enrolled_card_fails assert_failure response assert_equal '3D-secure enrolled cards are not supported.', response.message -=begin - # This is handy for testing that 3DS is working with PayU - response = response.responses.first - - # You'll probably need a new bin from http://requestb.in - bin = "" - File.open("3ds.html", "w") do |f| - f.puts %( - - -
- - - - -
- - - ) - end - puts "Test 3D-secure via `open 3ds.html`" - puts "View results at http://requestb.in/#{bin}?inspect" - puts "Finalize with: `curl -v -d PaRes='' -d MD='' '#{response.params["form_post_vars"]["TermUrl"]}'`" -=end + # # This is handy for testing that 3DS is working with PayU + # response = response.responses.first + # + # # You'll probably need a new bin from http://requestb.in + # bin = "" + # File.open("3ds.html", "w") do |f| + # f.puts %( + # + # + #
+ # + # + # + # + #
+ # + # + # ) + # end + # puts "Test 3D-secure via `open 3ds.html`" + # puts "View results at http://requestb.in/#{bin}?inspect" + # puts "Finalize with: `curl -v -d PaRes='' -d MD='' '#{response.params["form_post_vars"]["TermUrl"]}'`" end def test_transcript_scrubbing diff --git a/test/remote/gateways/remote_payu_latam_test.rb b/test/remote/gateways/remote_payu_latam_test.rb index e78fd67fffa..56afc99744f 100644 --- a/test/remote/gateways/remote_payu_latam_test.rb +++ b/test/remote/gateways/remote_payu_latam_test.rb @@ -8,9 +8,9 @@ def setup @credit_card = credit_card('4097440000000004', verification_value: '444', first_name: 'APPROVED', last_name: '') @declined_card = credit_card('4097440000000004', verification_value: '444', first_name: 'REJECTED', last_name: '') @pending_card = credit_card('4097440000000004', verification_value: '444', first_name: 'PENDING', last_name: '') - @naranja_credit_card = credit_card('5895620000000002', :verification_value => '123', :first_name => 'APPROVED', :last_name => '', :brand => 'naranja') - @cabal_credit_card = credit_card('5896570000000004', :verification_value => '123', :first_name => 'APPROVED', :last_name => '', :brand => 'cabal') - @invalid_cabal_card = credit_card('6271700000000000', :verification_value => '123', :first_name => 'APPROVED', :last_name => '', :brand => 'cabal') + @naranja_credit_card = credit_card('5895620000000002', verification_value: '123', first_name: 'APPROVED', last_name: '', brand: 'naranja') + @cabal_credit_card = credit_card('5896570000000004', verification_value: '123', first_name: 'APPROVED', last_name: '', brand: 'cabal') + @invalid_cabal_card = credit_card('6271700000000000', verification_value: '123', first_name: 'APPROVED', last_name: '', brand: 'cabal') @options = { dni_number: '5415668464654', @@ -74,8 +74,15 @@ def test_successful_purchase_with_specified_language assert response.test? end + def test_successful_purchase_with_blank_billing_address_country + response = @gateway.purchase(@amount, @credit_card, @options.merge(billing_address: { address1: 'Viamonte', country: '', zip: '10001' })) + assert_success response + assert_equal 'APPROVED', response.message + assert response.test? + end + def test_successful_purchase_with_buyer - gateway = PayuLatamGateway.new(fixtures(:payu_latam).update(:account_id => '512327', payment_country: 'BR')) + gateway = PayuLatamGateway.new(fixtures(:payu_latam).update(account_id: '512327', payment_country: 'BR')) options_buyer = { currency: 'BRL', @@ -114,7 +121,7 @@ def test_successful_purchase_with_buyer end def test_successful_purchase_brazil - gateway = PayuLatamGateway.new(fixtures(:payu_latam).update(:account_id => '512327', payment_country: 'BR')) + gateway = PayuLatamGateway.new(fixtures(:payu_latam).update(account_id: '512327', payment_country: 'BR')) options_brazil = { payment_country: 'BR', @@ -149,7 +156,7 @@ def test_successful_purchase_brazil end def test_successful_purchase_colombia - gateway = PayuLatamGateway.new(fixtures(:payu_latam).update(:account_id => '512321', payment_country: 'CO')) + gateway = PayuLatamGateway.new(fixtures(:payu_latam).update(account_id: '512321', payment_country: 'CO')) options_colombia = { payment_country: 'CO', @@ -183,7 +190,7 @@ def test_successful_purchase_colombia end def test_successful_purchase_mexico - gateway = PayuLatamGateway.new(fixtures(:payu_latam).update(:account_id => '512324', payment_country: 'MX')) + gateway = PayuLatamGateway.new(fixtures(:payu_latam).update(account_id: '512324', payment_country: 'MX')) options_mexico = { payment_country: 'MX', @@ -225,11 +232,24 @@ def test_successful_purchase_no_description end def test_failed_purchase - response = @gateway.purchase(@amount, @declined_card, @options) + response = @gateway.purchase(@amount, @declined_card) assert_failure response assert_equal 'DECLINED', response.params['transactionResponse']['state'] end + # Published API does not currently provide a way to request a CONTACT_THE_ENTITY + # def test_failed_purchase_correct_message_when_payment_network_response_error_present + # response = @gateway.purchase(@amount, @credit_card, @options) + # assert_failure response + # assert_equal 'CONTACT_THE_ENTITY | Contactar con entidad emisora', response.message + # assert_equal 'Contactar con entidad emisora', response.params['transactionResponse']['paymentNetworkResponseErrorMessage'] + + # response = @gateway.purchase(@amount, @credit_card, @options) + # assert_failure response + # assert_equal 'CONTACT_THE_ENTITY', response.message + # assert_nil response.params['transactionResponse']['paymentNetworkResponseErrorMessage'] + # end + def test_failed_purchase_with_cabal_card response = @gateway.purchase(@amount, @invalid_cabal_card, @options) assert_failure response @@ -278,7 +298,7 @@ def test_successful_authorize_with_specified_language end def test_failed_authorize - response = @gateway.authorize(@amount, @pending_card, @options) + response = @gateway.authorize(@amount, @declined_card) assert_failure response assert_equal 'DECLINED', response.params['transactionResponse']['state'] end @@ -388,14 +408,14 @@ def test_failed_verify_with_specified_amount verify = @gateway.verify(@credit_card, @options.merge(verify_amount: 499)) assert_failure verify - assert_equal 'The order value is less than minimum allowed. Minimum value allowed 5 ARS', verify.message + assert_equal 'INVALID_TRANSACTION | [The given payment value [4.99] is inferior than minimum configured value [5]]', verify.message end def test_failed_verify_with_specified_language verify = @gateway.verify(@credit_card, @options.merge(verify_amount: 499, language: 'es')) assert_failure verify - assert_equal 'The order value is less than minimum allowed. Minimum value allowed 5 ARS', verify.message + assert_equal 'INVALID_TRANSACTION | [El valor recibido [4,99] es inferior al valor mínimo configurado [5]]', verify.message end def test_transcript_scrubbing @@ -408,4 +428,10 @@ def test_transcript_scrubbing assert_scrubbed(@credit_card.verification_value.to_s, clean_transcript) assert_scrubbed(@gateway.options[:api_key], clean_transcript) end + + def test_successful_store + store = @gateway.store(@credit_card, @options) + assert_success store + assert_equal 'SUCCESS', store.message + end end diff --git a/test/remote/gateways/remote_payway_dot_com_test.rb b/test/remote/gateways/remote_payway_dot_com_test.rb new file mode 100644 index 00000000000..ea43fbd862e --- /dev/null +++ b/test/remote/gateways/remote_payway_dot_com_test.rb @@ -0,0 +1,136 @@ +require 'test_helper' + +class RemotePaywayDotComTest < Test::Unit::TestCase + def setup + @gateway = PaywayDotComGateway.new(fixtures(:payway_dot_com)) + + @amount = 100 + @credit_card = credit_card('4000100011112224', verification_value: '737') + @declined_card = credit_card('4000300011112220') + @invalid_luhn_card = credit_card('4000300011112221') + @options = { + billing_address: address, + description: 'Store Purchase', + # source_id must be provided, contact payway support for valid source_id(s) + source_id: '67' + } + end + + def test_successful_purchase + response = @gateway.purchase(@amount, @credit_card, @options) + assert_success response + assert_equal '5000', response.message[0, 4] + end + + def test_successful_purchase_with_more_options + options = { + order_id: '1', + ip: '127.0.0.1', + email: 'joe@example.com', + source_id: '67', + eci_type: '5', + tax: '7', + soft_descriptor: "Dan's Guitar Store" + } + + response = @gateway.purchase(101, @credit_card, options) + assert_success response + assert_equal '5000', response.message[0, 4] + end + + def test_failed_purchase + response = @gateway.purchase(102, @invalid_luhn_card, @options) + assert_failure response + assert_equal PaywayDotComGateway::STANDARD_ERROR_CODE_MAPPING['5035'], response.error_code + assert_equal '5035', response.message[0, 4] + end + + def test_successful_authorize + auth_only = @gateway.authorize(103, @credit_card, @options) + assert_success auth_only + assert_equal '5000', auth_only.message[0, 4] + end + + def test_successful_authorize_and_capture + auth = @gateway.authorize(104, @credit_card, @options) + assert_success auth + assert capture = @gateway.capture(@amount, auth.authorization, @options) + assert_success capture + assert_equal '5000', capture.message[0, 4] + end + + def test_failed_authorize + response = @gateway.authorize(105, @invalid_luhn_card, @options) + assert_failure response + assert_equal '5035', response.message[0, 4] + end + + def test_failed_capture + response = @gateway.capture(106, '') + assert_failure response + assert_equal '5025', response.message[0, 4] + end + + def test_successful_credit + credit = @gateway.credit(107, @credit_card, @options) + assert_success credit + assert_equal '5000', credit.message[0, 4] + end + + def test_failed_credit + response = @gateway.credit(108, @invalid_luhn_card, @options) + assert_failure response + assert_equal '5035', response.message[0, 4] + end + + def test_successful_void + auth = @gateway.authorize(109, @credit_card, @options) + assert_success auth + + assert void = @gateway.void(auth.authorization, @options) + assert_success void + assert_equal '5000', void.message[0, 4] + end + + def test_failed_void + response = @gateway.void('') + assert_failure response + assert_equal '5025', response.message[0, 4] + end + + def test_successful_void_of_sale + sale = @gateway.purchase(110, @credit_card, @options) + assert_success sale + + assert void = @gateway.void(sale.authorization, @options) + assert_success void + assert_equal '5000', void.message[0, 4] + end + + def test_successful_void_of_credit + credit = @gateway.credit(111, @credit_card, @options) + assert_success credit + + assert void = @gateway.void(credit.authorization, @options) + assert_success void + assert_equal '5000', void.message[0, 4] + end + + def test_invalid_login + gateway = PaywayDotComGateway.new(login: '', password: '', company_id: '') + + response = gateway.purchase(@amount, @credit_card, @options) + assert_failure response + assert_match %r{5001}, response.message[0, 4] + end + + def test_transcript_scrubbing + transcript = capture_transcript(@gateway) do + @gateway.purchase(@amount, @credit_card, @options) + end + transcript = @gateway.scrub(transcript) + assert_scrubbed(@credit_card.number, transcript) + assert_scrubbed(@credit_card.verification_value, transcript) + assert_scrubbed(@gateway.options[:password], transcript) + end +end diff --git a/test/remote/gateways/remote_payway_test.rb b/test/remote/gateways/remote_payway_test.rb index 9d900c8528b..5276e60e38e 100644 --- a/test/remote/gateways/remote_payway_test.rb +++ b/test/remote/gateways/remote_payway_test.rb @@ -4,47 +4,41 @@ class PaywayTest < Test::Unit::TestCase def setup @amount = 1100 - @options = {:order_id => generate_unique_id} + @options = { order_id: generate_unique_id } @gateway = ActiveMerchant::Billing::PaywayGateway.new(fixtures(:payway)) @visa = credit_card('4564710000000004', - :month => 2, - :year => 2019, - :verification_value => '847' - ) + month: 2, + year: 2019, + verification_value: '847') @mastercard = credit_card('5163200000000008', - :month => 8, - :year => 2020, - :verification_value => '070', - :brand => 'master' - ) + month: 8, + year: 2020, + verification_value: '070', + brand: 'master') @expired = credit_card('4564710000000012', - :month => 2, - :year => 2005, - :verification_value => '963' - ) + month: 2, + year: 2005, + verification_value: '963') @low = credit_card('4564710000000020', - :month => 5, - :year => 2020, - :verification_value => '234' - ) + month: 5, + year: 2020, + verification_value: '234') @stolen_mastercard = credit_card('5163200000000016', - :month => 12, - :year => 2019, - :verification_value => '728', - :brand => 'master' - ) + month: 12, + year: 2019, + verification_value: '728', + brand: 'master') @invalid = credit_card('4564720000000037', - :month => 9, - :year => 2019, - :verification_value => '030' - ) + month: 9, + year: 2019, + verification_value: '030') end def test_successful_visa @@ -85,10 +79,10 @@ def test_invalid_visa def test_invalid_login gateway = ActiveMerchant::Billing::PaywayGateway.new( - :username => 'bogus', - :password => 'bogus', - :merchant => 'TEST', - :pem => fixtures(:payway)['pem'] + username: 'bogus', + password: 'bogus', + merchant: 'TEST', + pem: fixtures(:payway)['pem'] ) assert response = gateway.purchase(@amount, @visa, @options) assert_failure response diff --git a/test/remote/gateways/remote_pin_test.rb b/test/remote/gateways/remote_pin_test.rb index 2539bc8b616..4892eaefaa3 100644 --- a/test/remote/gateways/remote_pin_test.rb +++ b/test/remote/gateways/remote_pin_test.rb @@ -5,17 +5,26 @@ def setup @gateway = PinGateway.new(fixtures(:pin)) @amount = 100 - @credit_card = credit_card('5520000000000000', :year => Time.now.year + 2) - @visa_credit_card = credit_card('4200000000000000', :year => Time.now.year + 3) + @credit_card = credit_card('5520000000000000', year: Time.now.year + 2) + @visa_credit_card = credit_card('4200000000000000', year: Time.now.year + 3) @declined_card = credit_card('4100000000000001') @options = { - :email => 'roland@pinpayments.com', - :ip => '203.59.39.62', - :order_id => '1', - :billing_address => address, - :description => "Store Purchase #{DateTime.now.to_i}" + email: 'roland@pinpayments.com', + ip: '203.59.39.62', + order_id: '1', + billing_address: address, + description: "Store Purchase #{DateTime.now.to_i}" } + + @additional_options_3ds = @options.merge( + three_d_secure: { + version: '1.0.2', + eci: '06', + cavv: 'AgAAAAAAAIR8CQrXcIhbQAAAAAA', + xid: 'MDAwMDAwMDAwMDAwMDAwMzIyNzY=' + } + ) end def test_successful_purchase @@ -53,6 +62,16 @@ def test_successful_authorize_and_capture assert_equal true, response.params['response']['captured'] end + def test_successful_authorize_and_capture_with_passthrough_3ds + authorization = @gateway.authorize(@amount, @credit_card, @additional_options_3ds) + assert_success authorization + assert_equal false, authorization.params['response']['captured'] + + response = @gateway.capture(@amount, authorization.authorization, @options) + assert_success response + assert_equal true, response.params['response']['captured'] + end + def test_failed_authorize response = @gateway.authorize(@amount, @declined_card, @options) assert_failure response @@ -94,16 +113,16 @@ def test_store_and_charge_with_pinjs_card_token } # Get a token equivalent to what is returned by Pin.js card_attrs = { - :number => @credit_card.number, - :expiry_month => @credit_card.month, - :expiry_year => @credit_card.year, - :cvc => @credit_card.verification_value, - :name => "#{@credit_card.first_name} #{@credit_card.last_name}", - :address_line1 => '42 Sevenoaks St', - :address_city => 'Lathlain', - :address_postcode => '6454', - :address_start => 'WA', - :address_country => 'Australia' + number: @credit_card.number, + expiry_month: @credit_card.month, + expiry_year: @credit_card.year, + cvc: @credit_card.verification_value, + name: "#{@credit_card.first_name} #{@credit_card.last_name}", + address_line1: '42 Sevenoaks St', + address_city: 'Lathlain', + address_postcode: '6454', + address_start: 'WA', + address_country: 'Australia' } url = @gateway.test_url + '/cards' @@ -141,7 +160,7 @@ def test_store_and_update assert_not_nil response.authorization assert_equal @credit_card.year, response.params['response']['card']['expiry_year'] - response = @gateway.update(response.authorization, @visa_credit_card, :address => address) + response = @gateway.update(response.authorization, @visa_credit_card, address: address) assert_success response assert_not_nil response.authorization assert_equal @visa_credit_card.year, response.params['response']['card']['expiry_year'] @@ -171,7 +190,7 @@ def test_failed_refund end def test_invalid_login - gateway = PinGateway.new(:api_key => '') + gateway = PinGateway.new(api_key: '') response = gateway.purchase(@amount, @credit_card, @options) assert_failure response end diff --git a/test/remote/gateways/remote_plugnpay_test.rb b/test/remote/gateways/remote_plugnpay_test.rb index f05f4dc7701..2fcf76dbdd6 100644 --- a/test/remote/gateways/remote_plugnpay_test.rb +++ b/test/remote/gateways/remote_plugnpay_test.rb @@ -6,8 +6,8 @@ def setup @good_card = credit_card('4111111111111111', first_name: 'cardtest') @bad_card = credit_card('1234123412341234') @options = { - :billing_address => address, - :description => 'Store purchaes' + billing_address: address, + description: 'Store purchaes' } @amount = 100 end diff --git a/test/remote/gateways/remote_pro_pay_test.rb b/test/remote/gateways/remote_pro_pay_test.rb index c447f996862..8ecea99cf19 100644 --- a/test/remote/gateways/remote_pro_pay_test.rb +++ b/test/remote/gateways/remote_pro_pay_test.rb @@ -67,7 +67,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization, @options) + assert capture = @gateway.capture(@amount - 1, auth.authorization, @options) assert_success capture end @@ -90,7 +90,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization, @options) + assert refund = @gateway.refund(@amount - 1, purchase.authorization, @options) assert_success refund end diff --git a/test/remote/gateways/remote_psigate_test.rb b/test/remote/gateways/remote_psigate_test.rb index 74d643794fe..d4e50fc8539 100644 --- a/test/remote/gateways/remote_psigate_test.rb +++ b/test/remote/gateways/remote_psigate_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class PsigateRemoteTest < Test::Unit::TestCase - def setup Base.mode = :test @gateway = PsigateGateway.new(fixtures(:psigate)) @@ -10,9 +9,9 @@ def setup @amount = 2400 @creditcard = credit_card('4111111111111111') @options = { - :order_id => generate_unique_id, - :billing_address => address, - :email => 'jack@example.com' + order_id: generate_unique_id, + billing_address: address, + email: 'jack@example.com' } end @@ -45,7 +44,7 @@ def test_successful_purchase_and_refund end def test_failed_purchase - assert response = @gateway.purchase(@amount, @creditcard, @options.update(:test_result => 'D')) + assert response = @gateway.purchase(@amount, @creditcard, @options.update(test_result: 'D')) assert_failure response end diff --git a/test/remote/gateways/remote_psl_card_test.rb b/test/remote/gateways/remote_psl_card_test.rb index 6b1b9e6e215..44630800f89 100644 --- a/test/remote/gateways/remote_psl_card_test.rb +++ b/test/remote/gateways/remote_psl_card_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class RemotePslCardTest < Test::Unit::TestCase - def setup @gateway = PslCardGateway.new(fixtures(:psl_card)) @@ -26,16 +25,14 @@ def setup def test_successful_visa_purchase response = @gateway.purchase(@accept_amount, @visa, - :billing_address => @visa_address - ) + billing_address: @visa_address) assert_success response assert response.test? end def test_successful_visa_debit_purchase response = @gateway.purchase(@accept_amount, @visa_debit, - :billing_address => @visa_debit_address - ) + billing_address: @visa_debit_address) assert_success response end @@ -43,75 +40,66 @@ def test_successful_visa_debit_purchase def test_visa_debit_purchase_should_not_send_debit_info_if_present @visa_debit.start_month = '07' response = @gateway.purchase(@accept_amount, @visa_debit, - :billing_address => @visa_debit_address - ) + billing_address: @visa_debit_address) assert_success response end def test_successful_visa_purchase_specifying_currency response = @gateway.purchase(@accept_amount, @visa, - :billing_address => @visa_address, - :currency => 'GBP' - ) + billing_address: @visa_address, + currency: 'GBP') assert_success response assert response.test? end def test_successful_solo_purchase response = @gateway.purchase(@accept_amount, @solo, - :billing_address => @solo_address - ) + billing_address: @solo_address) assert_success response assert response.test? end def test_referred_purchase response = @gateway.purchase(@referred_amount, @uk_maestro, - :billing_address => @uk_maestro_address - ) + billing_address: @uk_maestro_address) assert_failure response assert response.test? end def test_declined_purchase response = @gateway.purchase(@declined_amount, @uk_maestro, - :billing_address => @uk_maestro_address - ) + billing_address: @uk_maestro_address) assert_failure response assert response.test? end def test_declined_keep_card_purchase response = @gateway.purchase(@keep_card_amount, @uk_maestro, - :billing_address => @uk_maestro_address - ) + billing_address: @uk_maestro_address) assert_failure response assert response.test? end def test_successful_authorization response = @gateway.authorize(@accept_amount, @visa, - :billing_address => @visa_address - ) + billing_address: @visa_address) assert_success response assert response.test? end def test_no_login @gateway = PslCardGateway.new( - :login => '' + login: '' ) response = @gateway.authorize(@accept_amount, @uk_maestro, - :billing_address => @uk_maestro_address - ) + billing_address: @uk_maestro_address) assert_failure response assert response.test? end def test_successful_authorization_and_capture authorization = @gateway.authorize(@accept_amount, @visa, - :billing_address => @visa_address - ) + billing_address: @visa_address) assert_success authorization assert authorization.test? diff --git a/test/remote/gateways/remote_qbms_test.rb b/test/remote/gateways/remote_qbms_test.rb index 017ebd1fc95..5e9de931936 100644 --- a/test/remote/gateways/remote_qbms_test.rb +++ b/test/remote/gateways/remote_qbms_test.rb @@ -11,7 +11,7 @@ def setup @card = credit_card('4111111111111111') @options = { - :billing_address => address, + billing_address: address } end @@ -66,7 +66,7 @@ def test_successful_credit end def test_invalid_ticket - gateway = QbmsGateway.new(@gateway_options.merge(:ticket => 'test123')) + gateway = QbmsGateway.new(@gateway_options.merge(ticket: 'test123')) assert response = gateway.authorize(@amount, @card, @options) assert_instance_of Response, response @@ -102,6 +102,6 @@ def test_transcript_scrubbing private def error_card(config_id) - credit_card('4111111111111111', :first_name => "configid=#{config_id}", :last_name => '') + credit_card('4111111111111111', first_name: "configid=#{config_id}", last_name: '') end end diff --git a/test/remote/gateways/remote_quantum_test.rb b/test/remote/gateways/remote_quantum_test.rb index 370e802d66c..30bbf393c64 100644 --- a/test/remote/gateways/remote_quantum_test.rb +++ b/test/remote/gateways/remote_quantum_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class RemoteQuantumTest < Test::Unit::TestCase - def setup @gateway = QuantumGateway.new(fixtures(:quantum)) @@ -54,7 +53,7 @@ def test_void end def test_passing_billing_address - options = {:billing_address => address} + options = { billing_address: address } assert response = @gateway.purchase(@amount, @credit_card, options) assert_success response assert_equal 'Transaction is APPROVED', response.message @@ -64,9 +63,9 @@ def test_passing_billing_address # So we check to see if the parse failed and report def test_invalid_login gateway = QuantumGateway.new( - :login => '', - :password => '' - ) + login: '', + password: '' + ) assert response = gateway.purchase(@amount, @credit_card) assert_failure response assert_equal 'ERROR: Invalid Gateway Login!!', response.message diff --git a/test/remote/gateways/remote_quickbooks_test.rb b/test/remote/gateways/remote_quickbooks_test.rb index c9e95c959c8..f3457706af5 100644 --- a/test/remote/gateways/remote_quickbooks_test.rb +++ b/test/remote/gateways/remote_quickbooks_test.rb @@ -13,8 +13,7 @@ def setup order_id: '1', billing_address: address({ zip: 90210, country: 'US', - state: 'CA' - }), + state: 'CA' }), description: 'Store Purchase' } end @@ -23,12 +22,14 @@ def test_successful_purchase response = @gateway.purchase(@amount, @credit_card, @options) assert_success response assert_equal 'CAPTURED', response.message + assert_equal @gateway.options[:access_token], response.params['access_token'] + assert_equal @gateway.options[:refresh_token], response.params['refresh_token'] end def test_failed_purchase response = @gateway.purchase(@amount, @declined_card, @options) assert_failure response - assert_equal 'cardNumber is invalid.', response.message + assert_equal 'card.number is invalid.', response.message end def test_successful_authorize_and_capture @@ -89,7 +90,7 @@ def test_successful_verify def test_failed_verify response = @gateway.verify(@declined_card, @options) assert_failure response - assert_match %r{cardNumber is invalid.}, response.message + assert_match %r{card.number is invalid.}, response.message assert_equal Gateway::STANDARD_ERROR_CODE[:processing_error], response.error_code end @@ -106,7 +107,62 @@ def test_invalid_login end end - def test_dump_transcript - # See quickbooks_test.rb for an example of a scrubbed transcript + def test_successful_void + auth = @gateway.authorize(@amount, @credit_card, @options) + assert_success auth + + assert void = @gateway.void(auth.authorization) + assert_success void + assert_equal 'ISSUED', void.message + end + + def test_transcript_scrubbing + transcript = capture_transcript(@gateway) do + @gateway.purchase(@amount, @credit_card, @options) + end + transcript = @gateway.scrub(transcript) + + assert_scrubbed(@credit_card.number, transcript) + assert_scrubbed(@credit_card.verification_value, transcript) + assert_scrubbed(@gateway.options[:access_token], transcript) + assert_scrubbed(@gateway.options[:refresh_token], transcript) + end + + def test_failed_purchase_with_expired_token + @gateway.options[:access_token] = 'not_a_valid_token' + response = @gateway.purchase(@amount, @credit_card, @options) + assert_failure response + assert_equal 'AuthenticationFailed', response.params['code'] + end + + def test_successful_purchase_with_expired_token + @gateway.options[:access_token] = 'not_a_valid_token' + response = @gateway.purchase(@amount, @credit_card, @options.merge(allow_refresh: true)) + assert_success response + end + + def test_successful_purchase_without_state_in_address + options = { + order_id: '1', + billing_address: + { + zip: 90210, + # Submitting a value of an empty string for the `state` field + # results in a `region is invalid` error message from Quickbooks. + # This test ensures that an empty string is not sent from AM. + state: '', + country: '' + } + } + + response = @gateway.purchase(@amount, @credit_card, options) + assert_success response + assert_equal 'CAPTURED', response.message + end + + def test_refresh + response = @gateway.refresh + assert_success response + assert response.params['access_token'] end end diff --git a/test/remote/gateways/remote_quickpay_test.rb b/test/remote/gateways/remote_quickpay_test.rb index 760c71f096e..e547d74242d 100644 --- a/test/remote/gateways/remote_quickpay_test.rb +++ b/test/remote/gateways/remote_quickpay_test.rb @@ -8,11 +8,11 @@ def setup @amount = 100 @options = { - :order_id => generate_unique_id[0...10], - :billing_address => address + order_id: generate_unique_id[0...10], + billing_address: address } - @visa_no_cvv2 = credit_card('4000300011112220', :verification_value => nil) + @visa_no_cvv2 = credit_card('4000300011112220', verification_value: nil) @visa = credit_card('4000100011112224') @dankort = credit_card('5019717010103742') @visa_dankort = credit_card('4571100000000000') @@ -26,7 +26,7 @@ def setup @amex = credit_card('3700100000000000') # forbrugsforeningen doesn't use a verification value - @forbrugsforeningen = credit_card('6007221000000000', :verification_value => nil) + @forbrugsforeningen = credit_card('6007221000000000', verification_value: nil) end def test_successful_purchase @@ -38,7 +38,7 @@ def test_successful_purchase end def test_successful_usd_purchase - assert response = @gateway.purchase(@amount, @visa, @options.update(:currency => 'USD')) + assert response = @gateway.purchase(@amount, @visa, @options.update(currency: 'USD')) assert_equal 'OK', response.message assert_equal 'USD', response.params['currency'] assert_success response @@ -174,22 +174,22 @@ def test_successful_purchase_and_credit end def test_successful_store_and_reference_purchase - assert store = @gateway.store(@visa, @options.merge(:description => 'New subscription')) + assert store = @gateway.store(@visa, @options.merge(description: 'New subscription')) assert_success store - assert purchase = @gateway.purchase(@amount, store.authorization, @options.merge(:order_id => generate_unique_id[0...10])) + assert purchase = @gateway.purchase(@amount, store.authorization, @options.merge(order_id: generate_unique_id[0...10])) assert_success purchase end def test_failed_store - assert store = @gateway.store(credit_card('4'), @options.merge(:description => 'New subscription')) + assert store = @gateway.store(credit_card('4'), @options.merge(description: 'New subscription')) assert_failure store assert_equal 'Error in field: cardnumber', store.message end def test_invalid_login gateway = QuickpayGateway.new( - :login => '', - :password => '' + login: '', + password: '' ) assert response = gateway.purchase(@amount, @visa, @options) assert_equal 'Invalid merchant id', response.message diff --git a/test/remote/gateways/remote_quickpay_v10_test.rb b/test/remote/gateways/remote_quickpay_v10_test.rb index 8c71fcb1742..6cbb9e1533d 100644 --- a/test/remote/gateways/remote_quickpay_v10_test.rb +++ b/test/remote/gateways/remote_quickpay_v10_test.rb @@ -1,13 +1,12 @@ require 'test_helper' class RemoteQuickPayV10Test < Test::Unit::TestCase - def setup @gateway = QuickpayV10Gateway.new(fixtures(:quickpay_v10_api_key)) @amount = 100 @options = { - :order_id => generate_unique_id[0...10], - :billing_address => address(country: 'DNK') + order_id: generate_unique_id[0...10], + billing_address: address(country: 'DNK') } @valid_card = credit_card('1000000000000008') @@ -16,8 +15,8 @@ def setup @capture_rejected_card = credit_card('1000000000000032') @refund_rejected_card = credit_card('1000000000000040') - @valid_address = address(:phone => '4500000001') - @invalid_address = address(:phone => '4500000002') + @valid_address = address(phone: '4500000001') + @invalid_address = address(phone: '4500000002') end def card_brand(response) @@ -25,7 +24,7 @@ def card_brand(response) end def test_successful_purchase_with_short_country - options = @options.merge({billing_address: address(country: 'DK')}) + options = @options.merge({ billing_address: address(country: 'DK') }) assert response = @gateway.purchase(@amount, @valid_card, options) assert_equal 'OK', response.message @@ -35,7 +34,7 @@ def test_successful_purchase_with_short_country end def test_successful_purchase_with_order_id_format - options = @options.merge({order_id: "##{Time.new.to_f}"}) + options = @options.merge({ order_id: "##{Time.new.to_f}" }) assert response = @gateway.purchase(@amount, @valid_card, options) assert_equal 'OK', response.message @@ -60,7 +59,7 @@ def test_unsuccessful_purchase_with_invalid_card end def test_successful_usd_purchase - assert response = @gateway.purchase(@amount, @valid_card, @options.update(:currency => 'USD')) + assert response = @gateway.purchase(@amount, @valid_card, @options.update(currency: 'USD')) assert_equal 'OK', response.message assert_equal 'USD', response.params['currency'] assert_success response @@ -68,13 +67,13 @@ def test_successful_usd_purchase end def test_successful_purchase_with_acquirers - assert response = @gateway.purchase(@amount, @valid_card, @options.update(:acquirer => 'nets')) + assert response = @gateway.purchase(@amount, @valid_card, @options.update(acquirer: 'nets')) assert_equal 'OK', response.message assert_success response end def test_unsuccessful_purchase_with_invalid_acquirers - assert response = @gateway.purchase(@amount, @valid_card, @options.update(:acquirer => 'invalid')) + assert response = @gateway.purchase(@amount, @valid_card, @options.update(acquirer: 'invalid')) assert_failure response assert_equal 'Validation error', response.message end @@ -268,5 +267,4 @@ def test_transcript_scrubbing assert_scrubbed(@valid_card.verification_value.to_s, clean_transcript) assert_scrubbed(@gateway.options[:api_key], clean_transcript) end - end diff --git a/test/remote/gateways/remote_quickpay_v4_test.rb b/test/remote/gateways/remote_quickpay_v4_test.rb index 9eb4ca69970..a9517f6e09f 100644 --- a/test/remote/gateways/remote_quickpay_v4_test.rb +++ b/test/remote/gateways/remote_quickpay_v4_test.rb @@ -4,15 +4,15 @@ class RemoteQuickpayV4Test < Test::Unit::TestCase # These test assumes that you have not added your development IP in # the Quickpay Manager. def setup - @gateway = QuickpayGateway.new(fixtures(:quickpay_with_api_key).merge(:version => 4)) + @gateway = QuickpayGateway.new(fixtures(:quickpay_with_api_key).merge(version: 4)) @amount = 100 @options = { - :order_id => generate_unique_id[0...10], - :billing_address => address + order_id: generate_unique_id[0...10], + billing_address: address } - @visa_no_cvv2 = credit_card('4000300011112220', :verification_value => nil) + @visa_no_cvv2 = credit_card('4000300011112220', verification_value: nil) @visa = credit_card('4000100011112224') @dankort = credit_card('5019717010103742') @visa_dankort = credit_card('4571100000000000') @@ -52,7 +52,7 @@ def test_successful_purchase_with_all_fraud_parameters end def test_successful_usd_purchase - assert response = @gateway.purchase(@amount, @visa, @options.update(:currency => 'USD')) + assert response = @gateway.purchase(@amount, @visa, @options.update(currency: 'USD')) assert_equal 'OK', response.message assert_equal 'USD', response.params['currency'] assert_success response @@ -189,16 +189,16 @@ def test_successful_purchase_and_credit end def test_successful_store_and_reference_purchase - assert store = @gateway.store(@visa, @options.merge(:description => 'New subscription')) + assert store = @gateway.store(@visa, @options.merge(description: 'New subscription')) assert_success store - assert purchase = @gateway.purchase(@amount, store.authorization, @options.merge(:order_id => generate_unique_id[0...10])) + assert purchase = @gateway.purchase(@amount, store.authorization, @options.merge(order_id: generate_unique_id[0...10])) assert_success purchase end def test_invalid_login gateway = QuickpayGateway.new( - :login => '999999999', - :password => '' + login: '999999999', + password: '' ) assert response = gateway.purchase(@amount, @visa, @options) assert_equal 'Invalid merchant id', response.message diff --git a/test/remote/gateways/remote_quickpay_v5_test.rb b/test/remote/gateways/remote_quickpay_v5_test.rb index 02838bf2bb8..367711d0d0d 100644 --- a/test/remote/gateways/remote_quickpay_v5_test.rb +++ b/test/remote/gateways/remote_quickpay_v5_test.rb @@ -4,15 +4,15 @@ class RemoteQuickpayV5Test < Test::Unit::TestCase # These test assumes that you have not added your development IP in # the Quickpay Manager. def setup - @gateway = QuickpayGateway.new(fixtures(:quickpay_with_api_key).merge(:version => 5)) + @gateway = QuickpayGateway.new(fixtures(:quickpay_with_api_key).merge(version: 5)) @amount = 100 @options = { - :order_id => generate_unique_id[0...10], - :billing_address => address + order_id: generate_unique_id[0...10], + billing_address: address } - @visa_no_cvv2 = credit_card('4000300011112220', :verification_value => nil) + @visa_no_cvv2 = credit_card('4000300011112220', verification_value: nil) @visa = credit_card('4000100011112224') @dankort = credit_card('5019717010103742') @visa_dankort = credit_card('4571100000000000') @@ -52,7 +52,7 @@ def test_successful_purchase_with_all_fraud_parameters end def test_successful_usd_purchase - assert response = @gateway.purchase(@amount, @visa, @options.update(:currency => 'USD')) + assert response = @gateway.purchase(@amount, @visa, @options.update(currency: 'USD')) assert_equal 'OK', response.message assert_equal 'USD', response.params['currency'] assert_success response @@ -189,16 +189,16 @@ def test_successful_purchase_and_credit end def test_successful_store_and_reference_purchase - assert store = @gateway.store(@visa, @options.merge(:description => 'New subscription')) + assert store = @gateway.store(@visa, @options.merge(description: 'New subscription')) assert_success store - assert purchase = @gateway.purchase(@amount, store.authorization, @options.merge(:order_id => generate_unique_id[0...10])) + assert purchase = @gateway.purchase(@amount, store.authorization, @options.merge(order_id: generate_unique_id[0...10])) assert_success purchase end def test_invalid_login gateway = QuickpayGateway.new( - :login => '999999999', - :password => '' + login: '999999999', + password: '' ) assert response = gateway.purchase(@amount, @visa, @options) assert_equal 'Invalid merchant id', response.message diff --git a/test/remote/gateways/remote_quickpay_v6_test.rb b/test/remote/gateways/remote_quickpay_v6_test.rb index 2d113657c0c..39d66fceb2b 100644 --- a/test/remote/gateways/remote_quickpay_v6_test.rb +++ b/test/remote/gateways/remote_quickpay_v6_test.rb @@ -4,15 +4,15 @@ class RemoteQuickpayV6Test < Test::Unit::TestCase # These test assumes that you have not added your development IP in # the Quickpay Manager. def setup - @gateway = QuickpayGateway.new(fixtures(:quickpay_with_api_key).merge(:version => 6)) + @gateway = QuickpayGateway.new(fixtures(:quickpay_with_api_key).merge(version: 6)) @amount = 100 @options = { - :order_id => generate_unique_id[0...10], - :billing_address => address + order_id: generate_unique_id[0...10], + billing_address: address } - @visa_no_cvv2 = credit_card('4000300011112220', :verification_value => nil) + @visa_no_cvv2 = credit_card('4000300011112220', verification_value: nil) @visa = credit_card('4000100011112224') @dankort = credit_card('5019717010103742') @visa_dankort = credit_card('4571100000000000') @@ -52,7 +52,7 @@ def test_successful_purchase_with_all_fraud_parameters end def test_successful_usd_purchase - assert response = @gateway.purchase(@amount, @visa, @options.update(:currency => 'USD')) + assert response = @gateway.purchase(@amount, @visa, @options.update(currency: 'USD')) assert_equal 'OK', response.message assert_equal 'USD', response.params['currency'] assert_success response @@ -189,16 +189,16 @@ def test_successful_purchase_and_credit end def test_successful_store_and_reference_purchase - assert store = @gateway.store(@visa, @options.merge(:description => 'New subscription')) + assert store = @gateway.store(@visa, @options.merge(description: 'New subscription')) assert_success store - assert purchase = @gateway.purchase(@amount, store.authorization, @options.merge(:order_id => generate_unique_id[0...10])) + assert purchase = @gateway.purchase(@amount, store.authorization, @options.merge(order_id: generate_unique_id[0...10])) assert_success purchase end def test_invalid_login gateway = QuickpayGateway.new( - :login => '999999999', - :password => '' + login: '999999999', + password: '' ) assert response = gateway.purchase(@amount, @visa, @options) assert_equal 'Invalid merchant id', response.message diff --git a/test/remote/gateways/remote_quickpay_v7_test.rb b/test/remote/gateways/remote_quickpay_v7_test.rb index 8b8def4f168..185f9369be5 100644 --- a/test/remote/gateways/remote_quickpay_v7_test.rb +++ b/test/remote/gateways/remote_quickpay_v7_test.rb @@ -8,11 +8,11 @@ def setup @amount = 100 @options = { - :order_id => generate_unique_id[0...10], - :billing_address => address + order_id: generate_unique_id[0...10], + billing_address: address } - @visa_no_cvv2 = credit_card('4000300011112220', :verification_value => nil) + @visa_no_cvv2 = credit_card('4000300011112220', verification_value: nil) @visa = credit_card('4000100011112224') @dankort = credit_card('5019717010103742') @visa_dankort = credit_card('4571100000000000') @@ -52,7 +52,7 @@ def test_successful_purchase_with_all_fraud_parameters end def test_successful_usd_purchase - assert response = @gateway.purchase(@amount, @visa, @options.update(:currency => 'USD')) + assert response = @gateway.purchase(@amount, @visa, @options.update(currency: 'USD')) assert_equal 'OK', response.message assert_equal 'USD', response.params['currency'] assert_success response @@ -60,13 +60,13 @@ def test_successful_usd_purchase end def test_successful_purchase_with_acquirers - assert response = @gateway.purchase(@amount, @visa, @options.update(:acquirers => 'nets')) + assert response = @gateway.purchase(@amount, @visa, @options.update(acquirers: 'nets')) assert_equal 'OK', response.message assert_success response end def test_unsuccessful_purchase_with_invalid_acquirers - assert response = @gateway.purchase(@amount, @visa, @options.update(:acquirers => 'invalid')) + assert response = @gateway.purchase(@amount, @visa, @options.update(acquirers: 'invalid')) assert_equal 'Error in field: acquirers', response.message assert_failure response end @@ -201,26 +201,26 @@ def test_successful_purchase_and_credit end def test_successful_store_and_reference_purchase - assert store = @gateway.store(@visa, @options.merge(:description => 'New subscription')) + assert store = @gateway.store(@visa, @options.merge(description: 'New subscription')) assert_success store - assert purchase = @gateway.purchase(@amount, store.authorization, @options.merge(:order_id => generate_unique_id[0...10])) + assert purchase = @gateway.purchase(@amount, store.authorization, @options.merge(order_id: generate_unique_id[0...10])) assert_success purchase end def test_successful_store_with_acquirers - assert store = @gateway.store(@visa, @options.merge(:description => 'New subscription', :acquirers => 'nets')) + assert store = @gateway.store(@visa, @options.merge(description: 'New subscription', acquirers: 'nets')) assert_success store end def test_successful_store_sans_description - assert store = @gateway.store(@visa, @options.merge(:acquirers => 'nets')) + assert store = @gateway.store(@visa, @options.merge(acquirers: 'nets')) assert_success store end def test_invalid_login gateway = QuickpayGateway.new( - :login => '999999999', - :password => '' + login: '999999999', + password: '' ) assert response = gateway.purchase(@amount, @visa, @options) assert_equal 'Invalid merchant id', response.message diff --git a/test/remote/gateways/remote_qvalent_test.rb b/test/remote/gateways/remote_qvalent_test.rb index 95653323048..cb634582f3d 100644 --- a/test/remote/gateways/remote_qvalent_test.rb +++ b/test/remote/gateways/remote_qvalent_test.rb @@ -238,5 +238,4 @@ def test_successful_purchase_mastercard assert_success response assert_equal 'Succeeded', response.message end - end diff --git a/test/remote/gateways/remote_realex_test.rb b/test/remote/gateways/remote_realex_test.rb index 92b415ec0c2..a6e0ea0f069 100644 --- a/test/remote/gateways/remote_realex_test.rb +++ b/test/remote/gateways/remote_realex_test.rb @@ -1,9 +1,8 @@ require 'test_helper' class RemoteRealexTest < Test::Unit::TestCase - def setup - @gateway = RealexGateway.new(fixtures(:realex_with_account)) + @gateway = RealexGateway.new(fixtures(:realex)) # Replace the card numbers with the test account numbers from Realex @visa = card_fixtures(:realex_visa) @@ -23,15 +22,13 @@ def setup payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', verification_value: nil, eci: '05', - source: :apple_pay - ) + source: :apple_pay) @declined_apple_pay = network_tokenization_credit_card('4000120000001154', payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', verification_value: nil, eci: '05', - source: :apple_pay - ) + source: :apple_pay) @amount = 10000 end @@ -40,15 +37,14 @@ def card_fixtures(name) end def test_realex_purchase - [ @visa, @mastercard ].each do |card| + [@visa, @mastercard].each do |card| response = @gateway.purchase(@amount, card, - :order_id => generate_unique_id, - :description => 'Test Realex Purchase', - :billing_address => { - :zip => '90210', - :country => 'US' - } - ) + order_id: generate_unique_id, + description: 'Test Realex Purchase', + billing_address: { + zip: '90210', + country: 'US' + }) assert_not_nil response assert_success response assert response.test? @@ -59,13 +55,12 @@ def test_realex_purchase def test_realex_purchase_with_invalid_login gateway = RealexGateway.new( - :login => 'invalid', - :password => 'invalid' + login: 'invalid', + password: 'invalid' ) response = gateway.purchase(@amount, @visa, - :order_id => generate_unique_id, - :description => 'Invalid login test' - ) + order_id: generate_unique_id, + description: 'Invalid login test') assert_not_nil response assert_failure response @@ -76,9 +71,8 @@ def test_realex_purchase_with_invalid_login def test_realex_purchase_with_invalid_account response = RealexGateway.new(fixtures(:realex_with_account).merge(account: 'invalid')).purchase(@amount, @visa, - :order_id => generate_unique_id, - :description => 'Test Realex purchase with invalid account' - ) + order_id: generate_unique_id, + description: 'Test Realex purchase with invalid account') assert_not_nil response assert_failure response @@ -88,18 +82,17 @@ def test_realex_purchase_with_invalid_account end def test_realex_purchase_with_apple_pay - response = @gateway.purchase(1000, @apple_pay, :order_id => generate_unique_id, :description => 'Test Realex with ApplePay') + response = @gateway.purchase(1000, @apple_pay, order_id: generate_unique_id, description: 'Test Realex with ApplePay') assert_success response assert response.test? assert_equal 'Successful', response.message end def test_realex_purchase_declined - [ @visa_declined, @mastercard_declined ].each do |card| + [@visa_declined, @mastercard_declined].each do |card| response = @gateway.purchase(@amount, card, - :order_id => generate_unique_id, - :description => 'Test Realex purchase declined' - ) + order_id: generate_unique_id, + description: 'Test Realex purchase declined') assert_not_nil response assert_failure response @@ -109,7 +102,7 @@ def test_realex_purchase_declined end def test_realex_purchase_with_apple_pay_declined - response = @gateway.purchase(1101, @declined_apple_pay, :order_id => generate_unique_id, :description => 'Test Realex with ApplePay') + response = @gateway.purchase(1101, @declined_apple_pay, order_id: generate_unique_id, description: 'Test Realex with ApplePay') assert_failure response assert response.test? assert_equal '101', response.params['result'] @@ -124,10 +117,10 @@ def test_realex_purchase_with_three_d_secure_1 eci: '05', cavv: 'AgAAAAAAAIR8CQrXcIhbQAAAAAA', xid: 'MDAwMDAwMDAwMDAwMDAwMzIyNzY=', - version: '1.0.2', + version: '1.0.2' }, - :order_id => generate_unique_id, - :description => 'Test Realex with 3DS' + order_id: generate_unique_id, + description: 'Test Realex with 3DS' ) assert_success response assert response.test? @@ -142,10 +135,10 @@ def test_realex_purchase_with_three_d_secure_2 eci: '05', cavv: 'AgAAAAAAAIR8CQrXcIhbQAAAAAA', ds_transaction_id: 'bDE9Aa1A-C5Ac-AD3a-4bBC-aC918ab1de3E', - version: '2.1.0', + version: '2.1.0' }, - :order_id => generate_unique_id, - :description => 'Test Realex with 3DS' + order_id: generate_unique_id, + description: 'Test Realex with 3DS' ) assert_success response assert response.test? @@ -153,11 +146,10 @@ def test_realex_purchase_with_three_d_secure_2 end def test_realex_purchase_referral_b - [ @visa_referral_b, @mastercard_referral_b ].each do |card| + [@visa_referral_b, @mastercard_referral_b].each do |card| response = @gateway.purchase(@amount, card, - :order_id => generate_unique_id, - :description => 'Test Realex Referral B' - ) + order_id: generate_unique_id, + description: 'Test Realex Referral B') assert_not_nil response assert_failure response assert response.test? @@ -167,11 +159,10 @@ def test_realex_purchase_referral_b end def test_realex_purchase_referral_a - [ @visa_referral_a, @mastercard_referral_a ].each do |card| + [@visa_referral_a, @mastercard_referral_a].each do |card| response = @gateway.purchase(@amount, card, - :order_id => generate_unique_id, - :description => 'Test Realex Rqeferral A' - ) + order_id: generate_unique_id, + description: 'Test Realex Rqeferral A') assert_not_nil response assert_failure response assert_equal '103', response.params['result'] @@ -180,11 +171,10 @@ def test_realex_purchase_referral_a end def test_realex_purchase_coms_error - [ @visa_coms_error, @mastercard_coms_error ].each do |card| + [@visa_coms_error, @mastercard_coms_error].each do |card| response = @gateway.purchase(@amount, card, - :order_id => generate_unique_id, - :description => 'Test Realex coms error' - ) + order_id: generate_unique_id, + description: 'Test Realex coms error') assert_not_nil response assert_failure response @@ -197,9 +187,8 @@ def test_realex_expiry_month_error @visa.month = 13 response = @gateway.purchase(@amount, @visa, - :order_id => generate_unique_id, - :description => 'Test Realex expiry month error' - ) + order_id: generate_unique_id, + description: 'Test Realex expiry month error') assert_not_nil response assert_failure response @@ -211,9 +200,8 @@ def test_realex_expiry_year_error @visa.year = 2005 response = @gateway.purchase(@amount, @visa, - :order_id => generate_unique_id, - :description => 'Test Realex expiry year error' - ) + order_id: generate_unique_id, + description: 'Test Realex expiry year error') assert_not_nil response assert_failure response @@ -226,9 +214,8 @@ def test_invalid_credit_card_name @visa.last_name = '' response = @gateway.purchase(@amount, @visa, - :order_id => generate_unique_id, - :description => 'test_chname_error' - ) + order_id: generate_unique_id, + description: 'test_chname_error') assert_not_nil response assert_failure response @@ -240,9 +227,8 @@ def test_cvn @visa_cvn = @visa.clone @visa_cvn.verification_value = '111' response = @gateway.purchase(@amount, @visa_cvn, - :order_id => generate_unique_id, - :description => 'test_cvn' - ) + order_id: generate_unique_id, + description: 'test_cvn') assert_not_nil response assert_success response assert response.authorization.length > 0 @@ -250,10 +236,9 @@ def test_cvn def test_customer_number response = @gateway.purchase(@amount, @visa, - :order_id => generate_unique_id, - :description => 'test_cust_num', - :customer => 'my customer id' - ) + order_id: generate_unique_id, + description: 'test_cust_num', + customer: 'my customer id') assert_not_nil response assert_success response assert response.authorization.length > 0 @@ -261,13 +246,12 @@ def test_customer_number def test_realex_authorize response = @gateway.authorize(@amount, @visa, - :order_id => generate_unique_id, - :description => 'Test Realex Purchase', - :billing_address => { - :zip => '90210', - :country => 'US' - } - ) + order_id: generate_unique_id, + description: 'Test Realex Purchase', + billing_address: { + zip: '90210', + country: 'US' + }) assert_not_nil response assert_success response @@ -280,13 +264,12 @@ def test_realex_authorize_then_capture order_id = generate_unique_id auth_response = @gateway.authorize(@amount, @visa, - :order_id => order_id, - :description => 'Test Realex Purchase', - :billing_address => { - :zip => '90210', - :country => 'US' - } - ) + order_id: order_id, + description: 'Test Realex Purchase', + billing_address: { + zip: '90210', + country: 'US' + }) assert auth_response.test? capture_response = @gateway.capture(nil, auth_response.authorization) @@ -301,14 +284,13 @@ def test_realex_authorize_then_capture def test_realex_authorize_then_capture_with_extra_amount order_id = generate_unique_id - auth_response = @gateway.authorize(@amount*115, @visa, - :order_id => order_id, - :description => 'Test Realex Purchase', - :billing_address => { - :zip => '90210', - :country => 'US' - } - ) + auth_response = @gateway.authorize(@amount * 115, @visa, + order_id: order_id, + description: 'Test Realex Purchase', + billing_address: { + zip: '90210', + country: 'US' + }) assert auth_response.test? capture_response = @gateway.capture(@amount, auth_response.authorization) @@ -324,13 +306,12 @@ def test_realex_purchase_then_void order_id = generate_unique_id purchase_response = @gateway.purchase(@amount, @visa, - :order_id => order_id, - :description => 'Test Realex Purchase', - :billing_address => { - :zip => '90210', - :country => 'US' - } - ) + order_id: order_id, + description: 'Test Realex Purchase', + billing_address: { + zip: '90210', + country: 'US' + }) assert purchase_response.test? void_response = @gateway.void(purchase_response.authorization) @@ -344,16 +325,15 @@ def test_realex_purchase_then_void def test_realex_purchase_then_refund order_id = generate_unique_id - gateway_with_refund_password = RealexGateway.new(fixtures(:realex).merge(:rebate_secret => 'rebate')) + gateway_with_refund_password = RealexGateway.new(fixtures(:realex).merge(rebate_secret: 'rebate')) purchase_response = gateway_with_refund_password.purchase(@amount, @visa, - :order_id => order_id, - :description => 'Test Realex Purchase', - :billing_address => { - :zip => '90210', - :country => 'US' - } - ) + order_id: order_id, + description: 'Test Realex Purchase', + billing_address: { + zip: '90210', + country: 'US' + }) assert purchase_response.test? rebate_response = gateway_with_refund_password.refund(@amount, purchase_response.authorization) @@ -366,9 +346,8 @@ def test_realex_purchase_then_refund def test_realex_verify response = @gateway.verify(@visa, - :order_id => generate_unique_id, - :description => 'Test Realex verify' - ) + order_id: generate_unique_id, + description: 'Test Realex verify') assert_not_nil response assert_success response @@ -379,9 +358,8 @@ def test_realex_verify def test_realex_verify_declined response = @gateway.verify(@visa_declined, - :order_id => generate_unique_id, - :description => 'Test Realex verify declined' - ) + order_id: generate_unique_id, + description: 'Test Realex verify declined') assert_not_nil response assert_failure response @@ -391,16 +369,15 @@ def test_realex_verify_declined end def test_successful_credit - gateway_with_refund_password = RealexGateway.new(fixtures(:realex).merge(:refund_secret => 'refund')) + gateway_with_refund_password = RealexGateway.new(fixtures(:realex).merge(refund_secret: 'refund')) credit_response = gateway_with_refund_password.credit(@amount, @visa, - :order_id => generate_unique_id, - :description => 'Test Realex Credit', - :billing_address => { - :zip => '90210', - :country => 'US' - } - ) + order_id: generate_unique_id, + description: 'Test Realex Credit', + billing_address: { + zip: '90210', + country: 'US' + }) assert_not_nil credit_response assert_success credit_response @@ -410,13 +387,12 @@ def test_successful_credit def test_failed_credit credit_response = @gateway.credit(@amount, @visa, - :order_id => generate_unique_id, - :description => 'Test Realex Credit', - :billing_address => { - :zip => '90210', - :country => 'US' - } - ) + order_id: generate_unique_id, + description: 'Test Realex Credit', + billing_address: { + zip: '90210', + country: 'US' + }) assert_not_nil credit_response assert_failure credit_response @@ -425,15 +401,14 @@ def test_failed_credit end def test_maps_avs_and_cvv_response_codes - [ @visa, @mastercard ].each do |card| + [@visa, @mastercard].each do |card| response = @gateway.purchase(@amount, card, - :order_id => generate_unique_id, - :description => 'Test Realex Purchase', - :billing_address => { - :zip => '90210', - :country => 'US' - } - ) + order_id: generate_unique_id, + description: 'Test Realex Purchase', + billing_address: { + zip: '90210', + country: 'US' + }) assert_not_nil response assert_success response assert_equal 'M', response.avs_result['code'] @@ -444,13 +419,12 @@ def test_maps_avs_and_cvv_response_codes def test_transcript_scrubbing transcript = capture_transcript(@gateway) do @gateway.purchase(@amount, @visa_declined, - :order_id => generate_unique_id, - :description => 'Test Realex Purchase', - :billing_address => { - :zip => '90210', - :country => 'US' - } - ) + order_id: generate_unique_id, + description: 'Test Realex Purchase', + billing_address: { + zip: '90210', + country: 'US' + }) end clean_transcript = @gateway.scrub(transcript) diff --git a/test/remote/gateways/remote_redsys_sha256_test.rb b/test/remote/gateways/remote_redsys_sha256_test.rb index 34e6af62895..b7fd561377d 100644 --- a/test/remote/gateways/remote_redsys_sha256_test.rb +++ b/test/remote/gateways/remote_redsys_sha256_test.rb @@ -3,23 +3,103 @@ class RemoteRedsysSHA256Test < Test::Unit::TestCase def setup @gateway = RedsysGateway.new(fixtures(:redsys_sha256)) + @amount = 100 @credit_card = credit_card('4548812049400004') @declined_card = credit_card @threeds2_credit_card = credit_card('4918019199883839') @options = { - order_id: generate_order_id, + order_id: generate_order_id } end def test_successful_purchase - response = @gateway.purchase(100, @credit_card, @options) + response = @gateway.purchase(@amount, @credit_card, @options) + assert_success response + assert_equal 'Transaction Approved', response.message + end + + def test_successful_purchase_threeds1_as_mpi_has_no_effect + # 1.0.2 is NOT supported by RedSys External MPI; thus, behaviour should be same as if not present. + xid = '97267598-FAE6-48F2-8083-C23433990FBC' + cavv = '123' + eci = '01' + version = '1.0.2' + + response = @gateway.purchase( + @amount, + @credit_card, + @options.merge( + three_d_secure: { + version: version, + xid: xid, + cavv: cavv, + eci: eci + }, + description: 'description', + store: 'store', + sca_exemption: 'MOTO' + ) + ) + + assert_success response + assert_equal 'Transaction Approved', response.message + end + + def test_succesful_purchase_threeds1_as_mpi + xid = '97267598-FAE6-48F2-8083-C23433990FBC' + cavv = '123' + eci = '01' + version = '0.0.0' + + response = @gateway.purchase( + @amount, + @credit_card, + @options.merge( + three_d_secure: { + version: version, + xid: xid, + cavv: cavv, + eci: eci + }, + description: 'description', + store: 'store', + sca_exemption: 'MOTO' + ) + ) + + assert_success response + assert_equal 'Transaction Approved', response.message + end + + def test_successful_purchase_threeds2_as_mpi + three_ds_server_trans_id = '97267598-FAE6-48F2-8083-C23433990FBC' + ds_transaction_id = '97267598-FAE6-48F2-8083-C23433990FBC' + eci = '01' + version = '2.1.0' + + response = @gateway.purchase( + @amount, + @credit_card, + @options.merge( + three_d_secure: { + version: version, + ds_transaction_id: ds_transaction_id, + three_ds_server_trans_id: three_ds_server_trans_id, + eci: eci + }, + description: 'description', + store: 'store', + sca_exemption: 'MOTO' + ) + ) + assert_success response assert_equal 'Transaction Approved', response.message end def test_successful_authorize_3ds options = @options.merge(execute_threed: true, terminal: 12) - response = @gateway.authorize(100, @credit_card, options) + response = @gateway.authorize(@amount, @credit_card, options) assert_success response assert response.params['ds_emv3ds'] assert_equal 'NO_3DS_v2', JSON.parse(response.params['ds_emv3ds'])['protocolVersion'] @@ -29,7 +109,7 @@ def test_successful_authorize_3ds def test_successful_purchase_3ds options = @options.merge(execute_threed: true, terminal: 12) - response = @gateway.purchase(100, @threeds2_credit_card, options) + response = @gateway.purchase(@amount, @threeds2_credit_card, options) assert_success response assert three_ds_data = JSON.parse(response.params['ds_emv3ds']) assert_equal '2.1.0', three_ds_data['protocolVersion'] @@ -40,13 +120,13 @@ def test_successful_purchase_3ds # Requires account configuration to allow setting moto flag def test_purchase_with_moto_flag - response = @gateway.purchase(100, @credit_card, @options.merge(moto: true, metadata: { manual_entry: true })) + response = @gateway.purchase(@amount, @credit_card, @options.merge(moto: true, metadata: { manual_entry: true })) assert_equal 'SIS0488 ERROR', response.message end def test_successful_3ds_authorize_with_exemption options = @options.merge(execute_threed: true, terminal: 12) - response = @gateway.authorize(100, @credit_card, options.merge(sca_exemption: 'LWV')) + response = @gateway.authorize(@amount, @credit_card, options.merge(sca_exemption: 'LWV')) assert_success response assert response.params['ds_emv3ds'] assert_equal 'NO_3DS_v2', JSON.parse(response.params['ds_emv3ds'])['protocolVersion'] @@ -54,13 +134,13 @@ def test_successful_3ds_authorize_with_exemption end def test_purchase_with_invalid_order_id - response = @gateway.purchase(100, @credit_card, order_id: "a%4#{generate_order_id}") + response = @gateway.purchase(@amount, @credit_card, order_id: "a%4#{generate_order_id}") assert_success response assert_equal 'Transaction Approved', response.message end def test_successful_purchase_using_vault_id - response = @gateway.purchase(100, @credit_card, @options.merge(store: true)) + response = @gateway.purchase(@amount, @credit_card, @options.merge(store: true)) assert_success response assert_equal 'Transaction Approved', response.message @@ -68,44 +148,44 @@ def test_successful_purchase_using_vault_id assert_not_nil credit_card_token @options[:order_id] = generate_order_id - response = @gateway.purchase(100, credit_card_token, @options) + response = @gateway.purchase(@amount, credit_card_token, @options) assert_success response assert_equal 'Transaction Approved', response.message end def test_failed_purchase - response = @gateway.purchase(100, @declined_card, @options) + response = @gateway.purchase(@amount, @declined_card, @options) assert_failure response assert_equal 'SIS0093 ERROR', response.message end def test_purchase_and_refund - purchase = @gateway.purchase(100, @credit_card, @options) + purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - refund = @gateway.refund(100, purchase.authorization) + refund = @gateway.refund(@amount, purchase.authorization) assert_success refund end # Multiple currencies are not supported in test, but should at least fail. def test_purchase_and_refund_with_currency - response = @gateway.purchase(600, @credit_card, @options.merge(:currency => 'PEN')) + response = @gateway.purchase(600, @credit_card, @options.merge(currency: 'PEN')) assert_failure response assert_equal 'SIS0027 ERROR', response.message end def test_successful_authorise_and_capture - authorize = @gateway.authorize(100, @credit_card, @options) + authorize = @gateway.authorize(@amount, @credit_card, @options) assert_success authorize assert_equal 'Transaction Approved', authorize.message assert_not_nil authorize.authorization - capture = @gateway.capture(100, authorize.authorization) + capture = @gateway.capture(@amount, authorize.authorization) assert_success capture assert_match(/Refund.*approved/, capture.message) end def test_successful_authorise_using_vault_id - authorize = @gateway.authorize(100, @credit_card, @options.merge(store: true)) + authorize = @gateway.authorize(@amount, @credit_card, @options.merge(store: true)) assert_success authorize assert_equal 'Transaction Approved', authorize.message assert_not_nil authorize.authorization @@ -114,20 +194,20 @@ def test_successful_authorise_using_vault_id assert_not_nil credit_card_token @options[:order_id] = generate_order_id - authorize = @gateway.authorize(100, credit_card_token, @options) + authorize = @gateway.authorize(@amount, credit_card_token, @options) assert_success authorize assert_equal 'Transaction Approved', authorize.message assert_not_nil authorize.authorization end def test_failed_authorize - response = @gateway.authorize(100, @declined_card, @options) + response = @gateway.authorize(@amount, @declined_card, @options) assert_failure response assert_equal 'SIS0093 ERROR', response.message end def test_successful_void - authorize = @gateway.authorize(100, @credit_card, @options) + authorize = @gateway.authorize(@amount, @credit_card, @options) assert_success authorize void = @gateway.void(authorize.authorization) @@ -137,7 +217,7 @@ def test_successful_void end def test_failed_void - authorize = @gateway.authorize(100, @credit_card, @options) + authorize = @gateway.authorize(@amount, @credit_card, @options) assert_success authorize void = @gateway.void(authorize.authorization) diff --git a/test/remote/gateways/remote_redsys_test.rb b/test/remote/gateways/remote_redsys_test.rb index cfaf52723b2..688045c1965 100644 --- a/test/remote/gateways/remote_redsys_test.rb +++ b/test/remote/gateways/remote_redsys_test.rb @@ -3,29 +3,99 @@ class RemoteRedsysTest < Test::Unit::TestCase def setup @gateway = RedsysGateway.new(fixtures(:redsys)) + @amount = 100 @credit_card = credit_card('4548812049400004') @declined_card = credit_card @options = { order_id: generate_order_id, description: 'Test Description' } - @amount = 100 end def test_successful_purchase - response = @gateway.purchase(100, @credit_card, @options) + response = @gateway.purchase(@amount, @credit_card, @options) + assert_success response + assert_equal 'Transaction Approved', response.message + end + + def test_successful_purchase_threeds2 + three_ds_server_trans_id = '97267598-FAE6-48F2-8083-C23433990FBC' + ds_transaction_id = '97267598-FAE6-48F2-8083-C23433990FBC' + version = '2.1.0' + eci = '02' + + response = @gateway.purchase( + 100, + @credit_card, + @options.merge( + three_d_secure: { + version: version, + ds_transaction_id: ds_transaction_id, + three_ds_server_trans_id: three_ds_server_trans_id, + eci: eci + } + ) + ) + + assert_success response + assert_equal 'Transaction Approved', response.message + end + + def test_successful_purchase_threeds1 + xid = '97267598-FAE6-48F2-8083-C23433990FBC' + cavv = 'jJ81HADVRtXfCBATEp01CJUAAAA=' + eci = '02' + + response = @gateway.purchase( + @amount, + @credit_card, + @options.merge( + three_d_secure: { + eci: eci, + cavv: cavv, + xid: xid + } + ) + ) + + assert_success response + assert_equal 'Transaction Approved', response.message + end + + def test_successful_purchase_with_stored_credentials + initial_options = @options.merge( + stored_credential: { + initial_transaction: true, + reason_type: 'recurring' + } + ) + initial_response = @gateway.purchase(@amount, @credit_card, initial_options) + assert_success initial_response + assert_equal 'Transaction Approved', initial_response.message + assert_not_nil initial_response.params['ds_merchant_cof_txnid'] + network_transaction_id = initial_response.params['ds_merchant_cof_txnid'] + + used_options = @options.merge( + order_id: generate_order_id, + stored_credential: { + initial_transaction: false, + reason_type: 'unscheduled', + network_transaction_id: network_transaction_id + } + ) + response = @gateway.purchase(@amount, @credit_card, used_options) assert_success response assert_equal 'Transaction Approved', response.message end def test_purchase_with_invalid_order_id - response = @gateway.purchase(100, @credit_card, order_id: "a%4#{generate_order_id}") + response = @gateway.purchase(@amount, @credit_card, order_id: "a%4#{generate_order_id}") assert_success response assert_equal 'Transaction Approved', response.message end def test_successful_purchase_using_vault_id - response = @gateway.purchase(100, @credit_card, @options.merge(store: true)) + response = @gateway.purchase(@amount, @credit_card, @options.merge(store: true)) assert_success response assert_equal 'Transaction Approved', response.message @@ -33,44 +103,44 @@ def test_successful_purchase_using_vault_id assert_not_nil credit_card_token @options[:order_id] = generate_order_id - response = @gateway.purchase(100, credit_card_token, @options) + response = @gateway.purchase(@amount, credit_card_token, @options) assert_success response assert_equal 'Transaction Approved', response.message end def test_failed_purchase - response = @gateway.purchase(100, @declined_card, @options) + response = @gateway.purchase(@amount, @declined_card, @options) assert_failure response assert_equal 'SIS0093 ERROR', response.message end def test_purchase_and_refund - purchase = @gateway.purchase(100, @credit_card, @options) + purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - refund = @gateway.refund(100, purchase.authorization) + refund = @gateway.refund(@amount, purchase.authorization) assert_success refund end # Multiple currencies are not supported in test, but should at least fail. def test_purchase_and_refund_with_currency - response = @gateway.purchase(600, @credit_card, @options.merge(:currency => 'PEN')) + response = @gateway.purchase(600, @credit_card, @options.merge(currency: 'PEN')) assert_failure response assert_equal 'SIS0027 ERROR', response.message end def test_successful_authorise_and_capture - authorize = @gateway.authorize(100, @credit_card, @options) + authorize = @gateway.authorize(@amount, @credit_card, @options) assert_success authorize assert_equal 'Transaction Approved', authorize.message assert_not_nil authorize.authorization - capture = @gateway.capture(100, authorize.authorization) + capture = @gateway.capture(@amount, authorize.authorization) assert_success capture assert_match(/Refund.*approved/, capture.message) end def test_successful_authorise_using_vault_id - authorize = @gateway.authorize(100, @credit_card, @options.merge(store: true)) + authorize = @gateway.authorize(@amount, @credit_card, @options.merge(store: true)) assert_success authorize assert_equal 'Transaction Approved', authorize.message assert_not_nil authorize.authorization @@ -79,20 +149,20 @@ def test_successful_authorise_using_vault_id assert_not_nil credit_card_token @options[:order_id] = generate_order_id - authorize = @gateway.authorize(100, credit_card_token, @options) + authorize = @gateway.authorize(@amount, credit_card_token, @options) assert_success authorize assert_equal 'Transaction Approved', authorize.message assert_not_nil authorize.authorization end def test_failed_authorize - response = @gateway.authorize(100, @declined_card, @options) + response = @gateway.authorize(@amount, @declined_card, @options) assert_failure response assert_equal 'SIS0093 ERROR', response.message end def test_successful_void - authorize = @gateway.authorize(100, @credit_card, @options) + authorize = @gateway.authorize(@amount, @credit_card, @options) assert_success authorize void = @gateway.void(authorize.authorization) @@ -102,7 +172,7 @@ def test_successful_void end def test_failed_void - authorize = @gateway.authorize(100, @credit_card, @options) + authorize = @gateway.authorize(@amount, @credit_card, @options) assert_success authorize void = @gateway.void(authorize.authorization) diff --git a/test/remote/gateways/remote_s5_test.rb b/test/remote/gateways/remote_s5_test.rb index 1c9f31bf0ab..b1c831ea98a 100644 --- a/test/remote/gateways/remote_s5_test.rb +++ b/test/remote/gateways/remote_s5_test.rb @@ -90,7 +90,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -111,7 +111,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization) + assert refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund end diff --git a/test/remote/gateways/remote_safe_charge_test.rb b/test/remote/gateways/remote_safe_charge_test.rb index fc64bacb1c1..4cce73f3473 100644 --- a/test/remote/gateways/remote_safe_charge_test.rb +++ b/test/remote/gateways/remote_safe_charge_test.rb @@ -19,6 +19,15 @@ def setup @three_ds_enrolled_card = credit_card('4012 0010 3749 0014') @three_ds_non_enrolled_card = credit_card('5333 3062 3122 6927') @three_ds_invalid_pa_res_card = credit_card('4012 0010 3749 0006') + + @network_token_credit_card = ActiveMerchant::Billing::NetworkTokenizationCreditCard.new({ + brand: 'Visa', + payment_cryptogram: 'UnVBR0RlYm42S2UzYWJKeWJBdWQ=', + number: '4012001037490014', + source: :network_token, + month: '12', + year: 2020 + }) end def test_successful_3ds_purchase @@ -56,6 +65,77 @@ def test_successful_purchase assert_equal 'Success', response.message end + def test_successful_purchase_with_mpi_options_3ds_1 + options = @options.merge({ + three_d_secure: { + xid: '00000000000000000501', + eci: '05', + cavv: 'jJ81HADVRtXfCBATEp01CJUAAAA=' + } + }) + + response = @gateway.purchase(@amount, @three_ds_enrolled_card, options) + assert_success response + assert_equal 'Success', response.message + end + + def test_successful_purchase_with_mpi_options_3ds_2 + options = @options.merge({ + three_d_secure: { + version: '2.1.0', + ds_transaction_id: 'c5b808e7-1de1-4069-a17b-f70d3b3b1645', + eci: '05', + cavv: 'Vk83Y2t0cHRzRFZzRlZlR0JIQXo=' + } + }) + + response = @gateway.purchase(@amount, @three_ds_enrolled_card, options) + assert_success response + assert_equal 'Success', response.message + end + + def test_successful_network_tokenization_request + options = @options.merge({ + three_d_secure: { + eci: '05' + } + }) + + response = @gateway.purchase(@amount, @network_token_credit_card, options) + assert_success response + assert_equal 'Success', response.message + end + + def test_failed_purchase_with_mpi_options_3ds_2 + options = @options.merge({ + three_d_secure: { + version: '2.1.0', + ds_transaction_id: 'c5b808e7-1de1-4069-a17b-f70d3b3b1645', + eci: '05', + cavv: 'Vk83Y2t0cHRzRFZzRlZlR0JIQXo=' + } + }) + + response = @gateway.purchase(@amount, @declined_card, options) + assert_failure response + assert_equal 'Decline', response.message + end + + def test_successful_authorize_with_mpi_options_3ds_2 + options = @options.merge({ + three_d_secure: { + version: '2.1.0', + ds_transaction_id: 'c5b808e7-1de1-4069-a17b-f70d3b3b1645', + eci: '05', + cavv: 'Vk83Y2t0cHRzRFZzRlZlR0JIQXo=' + } + }) + + response = @gateway.authorize(@amount, @three_ds_enrolled_card, options) + assert_success response + assert_equal 'Success', response.message + end + def test_successful_purchase_with_more_options options = { order_id: '1', @@ -121,7 +201,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -230,5 +310,4 @@ def test_transcript_scrubbing assert_scrubbed(@credit_card.verification_value, transcript) assert_scrubbed(@gateway.options[:client_password], transcript) end - end diff --git a/test/remote/gateways/remote_sage_pay_test.rb b/test/remote/gateways/remote_sage_pay_test.rb index c7647d53969..fdc8543d2d1 100644 --- a/test/remote/gateways/remote_sage_pay_test.rb +++ b/test/remote/gateways/remote_sage_pay_test.rb @@ -12,90 +12,90 @@ def setup @gateway = SagePayGateway.new(fixtures(:sage_pay)) @amex = CreditCard.new( - :number => '374200000000004', - :month => 12, - :year => next_year, - :verification_value => 4887, - :first_name => 'Tekin', - :last_name => 'Suleyman', - :brand => 'american_express' + number: '374200000000004', + month: 12, + year: next_year, + verification_value: 4887, + first_name: 'Tekin', + last_name: 'Suleyman', + brand: 'american_express' ) @maestro = CreditCard.new( - :number => '5641820000000005', - :month => 12, - :year => next_year, - :issue_number => '01', - :start_month => 12, - :start_year => next_year - 2, - :verification_value => 123, - :first_name => 'Tekin', - :last_name => 'Suleyman', - :brand => 'maestro' + number: '5641820000000005', + month: 12, + year: next_year, + issue_number: '01', + start_month: 12, + start_year: next_year - 2, + verification_value: 123, + first_name: 'Tekin', + last_name: 'Suleyman', + brand: 'maestro' ) @visa = CreditCard.new( - :number => '4929000000006', - :month => 6, - :year => next_year, - :verification_value => 123, - :first_name => 'Tekin', - :last_name => 'Suleyman', - :brand => 'visa' + number: '4929000000006', + month: 6, + year: next_year, + verification_value: 123, + first_name: 'Tekin', + last_name: 'Suleyman', + brand: 'visa' ) @mastercard = CreditCard.new( - :number => '5404000000000001', - :month => 12, - :year => next_year, - :verification_value => 419, - :first_name => 'Tekin', - :last_name => 'Suleyman', - :brand => 'master' + number: '5404000000000001', + month: 12, + year: next_year, + verification_value: 419, + first_name: 'Tekin', + last_name: 'Suleyman', + brand: 'master' ) @electron = CreditCard.new( - :number => '4917300000000008', - :month => 12, - :year => next_year, - :verification_value => 123, - :first_name => 'Tekin', - :last_name => 'Suleyman', - :brand => 'electron' + number: '4917300000000008', + month: 12, + year: next_year, + verification_value: 123, + first_name: 'Tekin', + last_name: 'Suleyman', + brand: 'electron' ) @declined_card = CreditCard.new( - :number => '4111111111111111', - :month => 9, - :year => next_year, - :first_name => 'Tekin', - :last_name => 'Suleyman', - :brand => 'visa' + number: '4111111111111111', + month: 9, + year: next_year, + first_name: 'Tekin', + last_name: 'Suleyman', + brand: 'visa' ) @options = { - :billing_address => { - :name => 'Tekin Suleyman', - :address1 => 'Flat 10 Lapwing Court', - :address2 => 'West Didsbury', - :city => 'Manchester', - :county => 'Greater Manchester', - :country => 'GB', - :zip => 'M20 2PS' + billing_address: { + name: 'Tekin Suleyman', + address1: 'Flat 10 Lapwing Court', + address2: 'West Didsbury', + city: 'Manchester', + county: 'Greater Manchester', + country: 'GB', + zip: 'M20 2PS' }, - :shipping_address => { - :name => 'Tekin Suleyman', - :address1 => '120 Grosvenor St', - :city => 'Manchester', - :county => 'Greater Manchester', - :country => 'GB', - :zip => 'M1 7QW' + shipping_address: { + name: 'Tekin Suleyman', + address1: '120 Grosvenor St', + city: 'Manchester', + county: 'Greater Manchester', + country: 'GB', + zip: 'M1 7QW' }, - :order_id => generate_unique_id, - :description => 'Store purchase', - :ip => '86.150.65.37', - :email => 'tekin@tekin.co.uk', - :phone => '0161 123 4567' + order_id: generate_unique_id, + description: 'Store purchase', + ip: '86.150.65.37', + email: 'tekin@tekin.co.uk', + phone: '0161 123 4567' } @amount = 100 @@ -132,9 +132,8 @@ def test_successful_authorization_and_capture_and_refund assert_success capture assert refund = @gateway.refund(@amount, capture.authorization, - :description => 'Crediting trx', - :order_id => generate_unique_id - ) + description: 'Crediting trx', + order_id: generate_unique_id) assert_success refund end @@ -159,9 +158,8 @@ def test_successful_purchase_and_refund assert_success purchase assert refund = @gateway.refund(@amount, purchase.authorization, - :description => 'Crediting trx', - :order_id => generate_unique_id - ) + description: 'Crediting trx', + order_id: generate_unique_id) assert_success refund end @@ -331,7 +329,7 @@ def test_invalid_login message = SagePayGateway.simulate ? 'VSP Simulator cannot find your vendor name. Ensure you have have supplied a Vendor field with your VSP Vendor name assigned to it.' : '3034 : The Vendor or VendorName value is required.' gateway = SagePayGateway.new( - :login => '' + login: '' ) assert response = gateway.purchase(@amount, @mastercard, @options) assert_equal message, response.message @@ -364,13 +362,13 @@ def test_successful_store_and_authorize end def test_successful_token_creation_from_purchase - assert response = @gateway.purchase(@amount, @visa, @options.merge(:store => true)) + assert response = @gateway.purchase(@amount, @visa, @options.merge(store: true)) assert_success response assert !response.authorization.blank? end def test_successful_token_creation_from_authorize - assert response = @gateway.authorize(@amount, @visa, @options.merge(:store => true)) + assert response = @gateway.authorize(@amount, @visa, @options.merge(store: true)) assert_success response assert !response.authorization.blank? end @@ -414,56 +412,56 @@ def next_year # Based on example from http://www.sagepay.co.uk/support/basket-xml # Only kept required fields to make sense def basket_xml - <<-XML - - - DVD 1 - 2 - 24.50 - 00.50 - 25.00 - 50.00 - - + <<~XML + + + DVD 1 + 2 + 24.50 + 00.50 + 25.00 + 50.00 + + XML end # Example from http://www.sagepay.co.uk/support/customer-xml def customer_xml - <<-XML - - W - 1983-01-01 - 020 1234567 - 0799 1234567 - 0 - 10 - CUST123 - + <<~XML + + W + 1983-01-01 + 020 1234567 + 0799 1234567 + 0 + 10 + CUST123 + XML end # Example from https://www.sagepay.co.uk/support/12/36/protocol-3-00-surcharge-xml def surcharge_xml - <<-XML - - - DELTA - 2.50 - - - VISA - 2.50 - - - AMEX - 1.50 - - - MC - 1.50 - - + <<~XML + + + DELTA + 2.50 + + + VISA + 2.50 + + + AMEX + 1.50 + + + MC + 1.50 + + XML end end diff --git a/test/remote/gateways/remote_sage_test.rb b/test/remote/gateways/remote_sage_test.rb index 5107a12e97d..8ec91e95810 100644 --- a/test/remote/gateways/remote_sage_test.rb +++ b/test/remote/gateways/remote_sage_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class RemoteSageTest < Test::Unit::TestCase - def setup @gateway = SageGateway.new(fixtures(:sage)) @@ -16,10 +15,10 @@ def setup @declined_card = credit_card('4000') @options = { - :order_id => generate_unique_id, - :billing_address => address, - :shipping_address => address, - :email => 'longbob@example.com' + order_id: generate_unique_id, + billing_address: address, + shipping_address: address, + email: 'longbob@example.com' } end @@ -157,7 +156,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @visa, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization, @options) + assert refund = @gateway.refund(@amount - 1, purchase.authorization, @options) assert_success refund assert_equal 'APPROVED', refund.message end @@ -192,9 +191,9 @@ def test_failed_unstore_visa def test_invalid_login gateway = SageGateway.new( - :login => '', - :password => '' - ) + login: '', + password: '' + ) assert response = gateway.purchase(@amount, @visa, @options) assert_failure response assert_equal 'SECURITY VIOLATION', response.message @@ -231,5 +230,4 @@ def test_echeck_scrubbing assert_scrubbed(@check.routing_number, transcript) assert_scrubbed(@gateway.options[:password], transcript) end - end diff --git a/test/remote/gateways/remote_sallie_mae_test.rb b/test/remote/gateways/remote_sallie_mae_test.rb index f2b47acef22..e9f30994baf 100644 --- a/test/remote/gateways/remote_sallie_mae_test.rb +++ b/test/remote/gateways/remote_sallie_mae_test.rb @@ -9,8 +9,8 @@ def setup @declined_card = credit_card('4000300011112220') @options = { - :billing_address => address, - :description => 'Store Purchase' + billing_address: address, + description: 'Store Purchase' } end @@ -43,7 +43,7 @@ def test_failed_capture end def test_invalid_login - gateway = SallieMaeGateway.new(:login => '') + gateway = SallieMaeGateway.new(login: '') assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'Invalid merchant', response.message diff --git a/test/remote/gateways/remote_secure_net_test.rb b/test/remote/gateways/remote_secure_net_test.rb index fc92a5276e1..a37510fe077 100644 --- a/test/remote/gateways/remote_secure_net_test.rb +++ b/test/remote/gateways/remote_secure_net_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class SecureNetTest < Test::Unit::TestCase - def setup Base.mode = :test @gateway = SecureNetGateway.new(fixtures(:secure_net)) @@ -29,9 +28,9 @@ def test_expired_credit_card def test_invalid_login gateway = SecureNetGateway.new( - :login => '9988776', - :password => 'RabbitEarsPo' - ) + login: '9988776', + password: 'RabbitEarsPo' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'SECURE KEY IS INVALID FOR SECURENET ID PROVIDED', response.message @@ -135,5 +134,4 @@ def test_transcript_scrubbing assert_scrubbed(@credit_card.verification_value, transcript) assert_scrubbed(@gateway.options[:password], transcript) end - end diff --git a/test/remote/gateways/remote_secure_pay_au_test.rb b/test/remote/gateways/remote_secure_pay_au_test.rb index fc99db2ef81..13323f9572b 100644 --- a/test/remote/gateways/remote_secure_pay_au_test.rb +++ b/test/remote/gateways/remote_secure_pay_au_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class RemoteSecurePayAuTest < Test::Unit::TestCase - class MyCreditCard include ActiveMerchant::Billing::CreditCardMethods attr_accessor :number, :month, :year, :first_name, :last_name, :verification_value, :brand @@ -15,12 +14,12 @@ def setup @gateway = SecurePayAuGateway.new(fixtures(:secure_pay_au)) @amount = 100 - @credit_card = credit_card('4242424242424242', {:month => 9, :year => 15}) + @credit_card = credit_card('4242424242424242', { month: 9, year: 15 }) @options = { - :order_id => '2', - :billing_address => address, - :description => 'Store Purchase' + order_id: '2', + billing_address: address, + description: 'Store Purchase' } end @@ -32,13 +31,13 @@ def test_successful_purchase def test_successful_purchase_with_custom_credit_card_class options = { - :number => 4242424242424242, - :month => 9, - :year => Time.now.year + 1, - :first_name => 'Longbob', - :last_name => 'Longsen', - :verification_value => '123', - :brand => 'visa' + number: 4242424242424242, + month: 9, + year: Time.now.year + 1, + first_name: 'Longbob', + last_name: 'Longsen', + verification_value: '123', + brand: 'visa' } credit_card = MyCreditCard.new(options) assert response = @gateway.purchase(@amount, credit_card, @options) @@ -73,7 +72,7 @@ def test_failed_capture assert auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount+1, auth.authorization) + assert capture = @gateway.capture(@amount + 1, auth.authorization) assert_failure capture assert_equal 'Preauth was done for smaller amount', capture.message end @@ -93,7 +92,7 @@ def test_failed_refund assert_success response authorization = response.authorization - assert response = @gateway.refund(@amount+1, authorization) + assert response = @gateway.refund(@amount + 1, authorization) assert_failure response assert_equal 'Only $1.0 available for refund', response.message end @@ -115,13 +114,13 @@ def test_failed_void assert_success response authorization = response.authorization - assert response = @gateway.void(authorization+'1') + assert response = @gateway.void(authorization + '1') assert_failure response assert_equal 'Unable to retrieve original FDR txn', response.message end def test_successful_unstore - @gateway.store(@credit_card, {:billing_id => 'test1234', :amount => 15000}) rescue nil + @gateway.store(@credit_card, { billing_id: 'test1234', amount: 15000 }) rescue nil assert response = @gateway.unstore('test1234') assert_success response @@ -140,23 +139,23 @@ def test_repeat_unstore def test_successful_store @gateway.unstore('test1234') rescue nil - assert response = @gateway.store(@credit_card, {:billing_id => 'test1234', :amount => 15000}) + assert response = @gateway.store(@credit_card, { billing_id: 'test1234', amount: 15000 }) assert_success response assert_equal 'Successful', response.message end def test_failed_store - @gateway.store(@credit_card, {:billing_id => 'test1234', :amount => 15000}) rescue nil # Ensure it already exists + @gateway.store(@credit_card, { billing_id: 'test1234', amount: 15000 }) rescue nil # Ensure it already exists - assert response = @gateway.store(@credit_card, {:billing_id => 'test1234', :amount => 15000}) + assert response = @gateway.store(@credit_card, { billing_id: 'test1234', amount: 15000 }) assert_failure response assert_equal 'Duplicate Client ID Found', response.message end def test_successful_triggered_payment - @gateway.store(@credit_card, {:billing_id => 'test1234', :amount => 15000}) rescue nil # Ensure it already exists + @gateway.store(@credit_card, { billing_id: 'test1234', amount: 15000 }) rescue nil # Ensure it already exists assert response = @gateway.purchase(12300, 'test1234', @options) assert_success response @@ -176,9 +175,9 @@ def test_failure_triggered_payment def test_invalid_login gateway = SecurePayAuGateway.new( - :login => 'a', - :password => 'a' - ) + login: 'a', + password: 'a' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'Invalid merchant ID', response.message diff --git a/test/remote/gateways/remote_secure_pay_tech_test.rb b/test/remote/gateways/remote_secure_pay_tech_test.rb index 3b76bf77eef..30e46ee0e07 100644 --- a/test/remote/gateways/remote_secure_pay_tech_test.rb +++ b/test/remote/gateways/remote_secure_pay_tech_test.rb @@ -9,8 +9,8 @@ def setup @accepted_amount = 10000 @declined_amount = 10075 - @credit_card = credit_card('4987654321098769', :month => '5', :year => '2013') - @options = { :billing_address => address } + @credit_card = credit_card('4987654321098769', month: '5', year: '2013') + @options = { billing_address: address } end def test_successful_purchase @@ -43,9 +43,9 @@ def test_unsuccessful_cvv_check def test_invalid_login gateway = SecurePayTechGateway.new( - :login => 'foo', - :password => 'bar' - ) + login: 'foo', + password: 'bar' + ) assert response = gateway.purchase(@accepted_amount, @credit_card, @options) assert_equal 'Bad or malformed request', response.message assert_failure response diff --git a/test/remote/gateways/remote_secure_pay_test.rb b/test/remote/gateways/remote_secure_pay_test.rb index 63f83f5e40b..dec1ff43d41 100644 --- a/test/remote/gateways/remote_secure_pay_test.rb +++ b/test/remote/gateways/remote_secure_pay_test.rb @@ -1,19 +1,17 @@ require 'test_helper' class RemoteSecurePayTest < Test::Unit::TestCase - def setup @gateway = SecurePayGateway.new(fixtures(:secure_pay)) @credit_card = credit_card('4111111111111111', - :month => '7', - :year => '2014' - ) + month: '7', + year: '2014') @options = { - :order_id => generate_unique_id, - :description => 'Store purchase', - :billing_address => address + order_id: generate_unique_id, + description: 'Store purchase', + billing_address: address } @amount = 100 diff --git a/test/remote/gateways/remote_skipjack_test.rb b/test/remote/gateways/remote_skipjack_test.rb index d8ec78f732b..096aaee9602 100644 --- a/test/remote/gateways/remote_skipjack_test.rb +++ b/test/remote/gateways/remote_skipjack_test.rb @@ -7,15 +7,14 @@ def setup @gateway = SkipJackGateway.new(fixtures(:skip_jack)) @credit_card = credit_card('4445999922225', - :verification_value => '999' - ) + verification_value: '999') @amount = 100 @options = { - :order_id => generate_unique_id, - :email => 'email@foo.com', - :billing_address => address + order_id: generate_unique_id, + email: 'email@foo.com', + billing_address: address } end @@ -75,7 +74,7 @@ def test_successful_authorization_and_credit authorization = @gateway.authorize(@amount, @credit_card, @options) assert_success authorization - capture = @gateway.capture(@amount, authorization.authorization, :force_settlement => true) + capture = @gateway.capture(@amount, authorization.authorization, force_settlement: true) assert_success capture # developer login won't change transaction immediately to settled, so status will have to mismatch @@ -107,9 +106,9 @@ def test_status_unkown_order def test_invalid_login gateway = SkipJackGateway.new( - :login => '555555555555', - :password => '999999999999' - ) + login: '555555555555', + password: '999999999999' + ) response = gateway.authorize(@amount, @credit_card, @options) assert_failure response diff --git a/test/remote/gateways/remote_so_easy_pay_test.rb b/test/remote/gateways/remote_so_easy_pay_test.rb index e24d837703b..be0ed41b96f 100644 --- a/test/remote/gateways/remote_so_easy_pay_test.rb +++ b/test/remote/gateways/remote_so_easy_pay_test.rb @@ -1,21 +1,20 @@ require 'test_helper' class RemoteSoEasyPayTest < Test::Unit::TestCase - def setup @gateway = SoEasyPayGateway.new(fixtures(:so_easy_pay)) @amount = 100 - @credit_card = credit_card('4111111111111111', {:verification_value => '000', :month => '12', :year => '2015'}) + @credit_card = credit_card('4111111111111111', { verification_value: '000', month: '12', year: '2015' }) @declined_card = credit_card('4000300011112220') @options = { - :currency => 'EUR', - :ip => '192.168.19.123', - :email => 'test@blaha.com', - :order_id => generate_unique_id, - :billing_address => address, - :description => 'Store Purchase' + currency: 'EUR', + ip: '192.168.19.123', + email: 'test@blaha.com', + order_id: generate_unique_id, + billing_address: address, + description: 'Store Purchase' } end @@ -54,9 +53,9 @@ def test_successful_void def test_invalid_login gateway = SoEasyPayGateway.new( - :login => 'one', - :password => 'wrong' - ) + login: 'one', + password: 'wrong' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'Website verification failed, wrong websiteID or password', response.message diff --git a/test/remote/gateways/remote_spreedly_core_test.rb b/test/remote/gateways/remote_spreedly_core_test.rb index a162d35a6fc..5393149a3f7 100644 --- a/test/remote/gateways/remote_spreedly_core_test.rb +++ b/test/remote/gateways/remote_spreedly_core_test.rb @@ -1,14 +1,13 @@ require 'test_helper' class RemoteSpreedlyCoreTest < Test::Unit::TestCase - def setup @gateway = SpreedlyCoreGateway.new(fixtures(:spreedly_core)) @amount = 100 @credit_card = credit_card('5555555555554444') @declined_card = credit_card('4012888888881881') - @check = check({routing_number: '021000021', account_number: '9876543210'}) + @check = check({ routing_number: '021000021', account_number: '9876543210' }) @existing_payment_method = '3rEkRlZur2hXKbwwRBidHJAIUTO' @declined_payment_method = 'UPfh3J3JbekLeYC88BP741JWnS5' @existing_transaction = 'PJ5ICgM6h7v9pBNxDCJjRHDDxBC' @@ -71,8 +70,8 @@ def test_successful_purchase_with_check def test_successful_purchase_with_card_and_address options = { - :email => 'joebob@example.com', - :billing_address => address, + email: 'joebob@example.com', + billing_address: address } assert response = @gateway.purchase(@amount, @credit_card, options) @@ -124,8 +123,8 @@ def test_successful_authorize_and_capture_with_credit_card def test_successful_authorize_with_card_and_address options = { - :email => 'joebob@example.com', - :billing_address => address, + email: 'joebob@example.com', + billing_address: address } assert response = @gateway.authorize(@amount, @credit_card, options) @@ -174,28 +173,28 @@ def test_successful_store end def test_successful_store_simple_data - assert response = @gateway.store(@credit_card, { :data => 'SomeData' }) + assert response = @gateway.store(@credit_card, { data: 'SomeData' }) assert_success response assert_equal 'SomeData', response.params['payment_method_data'] end def test_successful_store_nested_data options = { - :data => { - :first_attribute => { :sub_dude => 'ExcellentSubValue' }, - :second_attribute => 'AnotherValue' + data: { + first_attribute: { sub_dude: 'ExcellentSubValue' }, + second_attribute: 'AnotherValue' } } assert response = @gateway.store(@credit_card, options) assert_success response - expected_data = { 'first_attribute' => { 'sub_dude'=>'ExcellentSubValue' }, 'second_attribute' =>'AnotherValue' } + expected_data = { 'first_attribute' => { 'sub_dude' => 'ExcellentSubValue' }, 'second_attribute' => 'AnotherValue' } assert_equal expected_data, response.params['payment_method_data'] end def test_successful_store_with_address options = { - :email => 'joebob@example.com', - :billing_address => address, + email: 'joebob@example.com', + billing_address: address } assert response = @gateway.store(@credit_card, options) @@ -209,7 +208,7 @@ def test_successful_store_with_address end def test_failed_store - assert response = @gateway.store(credit_card('5555555555554444', :last_name => ' ')) + assert response = @gateway.store(credit_card('5555555555554444', last_name: ' ')) assert_failure response assert_equal "Last name can't be blank", response.message end @@ -292,7 +291,7 @@ def test_failed_find_transaction end def test_invalid_login - gateway = SpreedlyCoreGateway.new(:login => 'Bogus', :password => 'MoreBogus', :gateway_token => 'EvenMoreBogus') + gateway = SpreedlyCoreGateway.new(login: 'Bogus', password: 'MoreBogus', gateway_token: 'EvenMoreBogus') assert response = gateway.purchase(@amount, @existing_payment_method) assert_failure response diff --git a/test/remote/gateways/remote_stripe_3ds_test.rb b/test/remote/gateways/remote_stripe_3ds_test.rb index fb596dc05ae..58a2f84d3b4 100644 --- a/test/remote/gateways/remote_stripe_3ds_test.rb +++ b/test/remote/gateways/remote_stripe_3ds_test.rb @@ -10,13 +10,13 @@ def setup @billing_details = address() @options = { - :currency => 'USD', - :description => 'ActiveMerchant Test Purchase', - :email => 'wow@example.com', - :execute_threed => true, - :redirect_url => 'http://www.example.com/redirect', - :callback_url => 'http://www.example.com/callback', - :billing_address => @billing_details + currency: 'USD', + description: 'ActiveMerchant Test Purchase', + email: 'wow@example.com', + execute_threed: true, + redirect_url: 'http://www.example.com/redirect', + callback_url: 'http://www.example.com/callback', + billing_address: @billing_details } @credit_card = credit_card('4000000000003063') @non_3ds_card = credit_card('378282246310005') @@ -35,15 +35,15 @@ def test_create_non3ds_card_source end def test_create_3ds_source - card_source = @gateway.send(:create_source, @amount, @credit_card, 'card', @options) - assert response = @gateway.send(:create_source, @amount, card_source.params['id'], 'three_d_secure', @options) + card_source = @gateway.send(:create_source, @amount, @credit_card, 'card', @options) + assert response = @gateway.send(:create_source, @amount, card_source.params['id'], 'three_d_secure', @options) assert_success response assert_three_ds_source(response) end def test_show_3ds_source - card_source = @gateway.send(:create_source, @amount, @credit_card, 'card', @options) - assert three_d_secure_source = @gateway.send(:create_source, @amount, card_source.params['id'], 'three_d_secure', @options) + card_source = @gateway.send(:create_source, @amount, @credit_card, 'card', @options) + assert three_d_secure_source = @gateway.send(:create_source, @amount, card_source.params['id'], 'three_d_secure', @options) assert_success three_d_secure_source assert_three_ds_source(three_d_secure_source) @@ -58,75 +58,75 @@ def test_create_webhook_endpoint assert_equal 'enabled', response.params['status'] assert_nil response.params['application'] - deleted_response = @gateway.send(:delete_webhook_endpoint, @options.merge(:webhook_id => response.params['id'])) + deleted_response = @gateway.send(:delete_webhook_endpoint, @options.merge(webhook_id: response.params['id'])) assert_equal true, deleted_response.params['deleted'] end def test_create_webhook_endpoint_on_connected_account - response = @gateway.send(:create_webhook_endpoint, @options.merge({stripe_account: @stripe_account}), ['source.chargeable']) + response = @gateway.send(:create_webhook_endpoint, @options.merge({ stripe_account: @stripe_account }), ['source.chargeable']) assert_includes response.params['enabled_events'], 'source.chargeable' assert_equal @options[:callback_url], response.params['url'] assert_equal 'enabled', response.params['status'] assert_not_nil response.params['application'] - deleted_response = @gateway.send(:delete_webhook_endpoint, @options.merge(:webhook_id => response.params['id'])) + deleted_response = @gateway.send(:delete_webhook_endpoint, @options.merge(webhook_id: response.params['id'])) assert_equal true, deleted_response.params['deleted'] end def test_delete_webhook_endpoint webhook = @gateway.send(:create_webhook_endpoint, @options, ['source.chargeable']) - response = @gateway.send(:delete_webhook_endpoint, @options.merge(:webhook_id => webhook.params['id'])) + response = @gateway.send(:delete_webhook_endpoint, @options.merge(webhook_id: webhook.params['id'])) assert_equal response.params['id'], webhook.params['id'] assert_equal true, response.params['deleted'] end def test_delete_webhook_endpoint_on_connected_account - webhook = @gateway.send(:create_webhook_endpoint, @options.merge({stripe_account: @stripe_account}), ['source.chargeable']) - response = @gateway.send(:delete_webhook_endpoint, @options.merge(:webhook_id => webhook.params['id'])) + webhook = @gateway.send(:create_webhook_endpoint, @options.merge({ stripe_account: @stripe_account }), ['source.chargeable']) + response = @gateway.send(:delete_webhook_endpoint, @options.merge(webhook_id: webhook.params['id'])) assert_equal response.params['id'], webhook.params['id'] assert_equal true, response.params['deleted'] end def test_show_webhook_endpoint webhook = @gateway.send(:create_webhook_endpoint, @options, ['source.chargeable']) - response = @gateway.send(:show_webhook_endpoint, @options.merge(:webhook_id => webhook.params['id'])) + response = @gateway.send(:show_webhook_endpoint, @options.merge(webhook_id: webhook.params['id'])) assert_includes response.params['enabled_events'], 'source.chargeable' assert_equal @options[:callback_url], response.params['url'] assert_equal 'enabled', response.params['status'] assert_nil response.params['application'] - deleted_response = @gateway.send(:delete_webhook_endpoint, @options.merge(:webhook_id => response.params['id'])) + deleted_response = @gateway.send(:delete_webhook_endpoint, @options.merge(webhook_id: response.params['id'])) assert_equal true, deleted_response.params['deleted'] end def test_show_webhook_endpoint_on_connected_account - webhook = @gateway.send(:create_webhook_endpoint, @options.merge({stripe_account: @stripe_account}), ['source.chargeable']) - response = @gateway.send(:show_webhook_endpoint, @options.merge({:webhook_id => webhook.params['id'], stripe_account: @stripe_account})) + webhook = @gateway.send(:create_webhook_endpoint, @options.merge({ stripe_account: @stripe_account }), ['source.chargeable']) + response = @gateway.send(:show_webhook_endpoint, @options.merge({ webhook_id: webhook.params['id'], stripe_account: @stripe_account })) assert_includes response.params['enabled_events'], 'source.chargeable' assert_equal @options[:callback_url], response.params['url'] assert_equal 'enabled', response.params['status'] assert_not_nil response.params['application'] - deleted_response = @gateway.send(:delete_webhook_endpoint, @options.merge(:webhook_id => response.params['id'])) + deleted_response = @gateway.send(:delete_webhook_endpoint, @options.merge(webhook_id: response.params['id'])) assert_equal true, deleted_response.params['deleted'] end def test_list_webhook_endpoints webhook1 = @gateway.send(:create_webhook_endpoint, @options, ['source.chargeable']) - webhook2 = @gateway.send(:create_webhook_endpoint, @options.merge({stripe_account: @stripe_account}), ['source.chargeable']) + webhook2 = @gateway.send(:create_webhook_endpoint, @options.merge({ stripe_account: @stripe_account }), ['source.chargeable']) assert_nil webhook1.params['application'] assert_not_nil webhook2.params['application'] - response = @gateway.send(:list_webhook_endpoints, @options.merge({limit: 100})) + response = @gateway.send(:list_webhook_endpoints, @options.merge({ limit: 100 })) assert_not_nil response.params assert_equal 'list', response.params['object'] assert response.params['data'].size >= 2 webhook_id_set = Set.new(response.params['data'].map { |webhook| webhook['id'] }.uniq) assert Set[webhook1.params['id'], webhook2.params['id']].subset?(webhook_id_set) - deleted_response1 = @gateway.send(:delete_webhook_endpoint, @options.merge(:webhook_id => webhook1.params['id'])) - deleted_response2 = @gateway.send(:delete_webhook_endpoint, @options.merge(:webhook_id => webhook2.params['id'])) + deleted_response1 = @gateway.send(:delete_webhook_endpoint, @options.merge(webhook_id: webhook1.params['id'])) + deleted_response2 = @gateway.send(:delete_webhook_endpoint, @options.merge(webhook_id: webhook2.params['id'])) assert_equal true, deleted_response1.params['deleted'] assert_equal true, deleted_response2.params['deleted'] end @@ -135,7 +135,7 @@ def test_3ds_purchase card_source_response = @gateway.send(:create_source, @amount, @credit_card, 'card', @options) assert_card_source(card_source_response) - assert three_ds_source_response = @gateway.send(:create_source, @amount, card_source_response.params['id'], 'three_d_secure', @options) + assert three_ds_source_response = @gateway.send(:create_source, @amount, card_source_response.params['id'], 'three_d_secure', @options) assert_success three_ds_source_response assert_three_ds_source(three_ds_source_response) @@ -190,5 +190,4 @@ def assert_three_ds_source(response) assert_equal 'three_d_secure', response.params['type'] assert_equal false, response.params['three_d_secure']['authenticated'] end - end diff --git a/test/remote/gateways/remote_stripe_android_pay_test.rb b/test/remote/gateways/remote_stripe_android_pay_test.rb index 5abf0974a17..6daee95f62b 100644 --- a/test/remote/gateways/remote_stripe_android_pay_test.rb +++ b/test/remote/gateways/remote_stripe_android_pay_test.rb @@ -8,9 +8,9 @@ def setup @amount = 100 @options = { - :currency => 'USD', - :description => 'ActiveMerchant Test Purchase', - :email => 'wow@example.com' + currency: 'USD', + description: 'ActiveMerchant Test Purchase', + email: 'wow@example.com' } end @@ -19,8 +19,7 @@ def test_successful_purchase_with_android_pay_raw_cryptogram payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', verification_value: nil, eci: '05', - source: :android_pay - ) + source: :android_pay) assert response = @gateway.purchase(@amount, credit_card, @options) assert_success response assert_equal 'charge', response.params['object'] @@ -35,8 +34,7 @@ def test_successful_auth_with_android_pay_raw_cryptogram payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', verification_value: nil, eci: '05', - source: :android_pay - ) + source: :android_pay) assert response = @gateway.authorize(@amount, credit_card, @options) assert_success response assert_equal 'charge', response.params['object'] diff --git a/test/remote/gateways/remote_stripe_apple_pay_test.rb b/test/remote/gateways/remote_stripe_apple_pay_test.rb index c5231114490..f6d844feaba 100644 --- a/test/remote/gateways/remote_stripe_apple_pay_test.rb +++ b/test/remote/gateways/remote_stripe_apple_pay_test.rb @@ -8,9 +8,9 @@ def setup @amount = 100 @options = { - :currency => 'USD', - :description => 'ActiveMerchant Test Purchase', - :email => 'wow@example.com' + currency: 'USD', + description: 'ActiveMerchant Test Purchase', + email: 'wow@example.com' } @apple_pay_payment_token = apple_pay_payment_token end @@ -54,7 +54,7 @@ def test_successful_void_with_apple_pay_payment_token end def test_successful_store_with_apple_pay_payment_token - assert response = @gateway.store(@apple_pay_payment_token, {:description => 'Active Merchant Test Customer', :email => 'email@example.com'}) + assert response = @gateway.store(@apple_pay_payment_token, { description: 'Active Merchant Test Customer', email: 'email@example.com' }) assert_success response assert_equal 'customer', response.params['object'] assert_equal 'Active Merchant Test Customer', response.params['description'] @@ -66,10 +66,10 @@ def test_successful_store_with_apple_pay_payment_token end def test_successful_store_with_existing_customer_and_apple_pay_payment_token - assert response = @gateway.store(@credit_card, {:description => 'Active Merchant Test Customer'}) + assert response = @gateway.store(@credit_card, { description: 'Active Merchant Test Customer' }) assert_success response - assert response = @gateway.store(@apple_pay_payment_token, {:customer => response.params['id'], :description => 'Active Merchant Test Customer', :email => 'email@example.com'}) + assert response = @gateway.store(@apple_pay_payment_token, { customer: response.params['id'], description: 'Active Merchant Test Customer', email: 'email@example.com' }) assert_success response assert_equal 2, response.responses.size @@ -86,9 +86,9 @@ def test_successful_store_with_existing_customer_and_apple_pay_payment_token end def test_successful_recurring_with_apple_pay_payment_token - assert response = @gateway.store(@apple_pay_payment_token, {:description => 'Active Merchant Test Customer', :email => 'email@example.com'}) + assert response = @gateway.store(@apple_pay_payment_token, { description: 'Active Merchant Test Customer', email: 'email@example.com' }) assert_success response - assert recharge_options = @options.merge(:customer => response.params['id']) + assert recharge_options = @options.merge(customer: response.params['id']) assert response = @gateway.purchase(@amount, nil, recharge_options) assert_success response assert_equal 'charge', response.params['object'] @@ -105,8 +105,7 @@ def test_successful_purchase_with_apple_pay_raw_cryptogram_with_eci payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', verification_value: nil, eci: '05', - source: :apple_pay - ) + source: :apple_pay) assert response = @gateway.purchase(@amount, credit_card, @options) assert_success response assert_equal 'charge', response.params['object'] @@ -120,8 +119,7 @@ def test_successful_purchase_with_apple_pay_raw_cryptogram_without_eci credit_card = network_tokenization_credit_card('4242424242424242', payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', verification_value: nil, - source: :apple_pay - ) + source: :apple_pay) assert response = @gateway.purchase(@amount, credit_card, @options) assert_success response assert_equal 'charge', response.params['object'] @@ -136,8 +134,7 @@ def test_successful_auth_with_apple_pay_raw_cryptogram_with_eci payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', verification_value: nil, eci: '05', - source: :apple_pay - ) + source: :apple_pay) assert response = @gateway.authorize(@amount, credit_card, @options) assert_success response assert_equal 'charge', response.params['object'] @@ -151,8 +148,7 @@ def test_successful_auth_with_apple_pay_raw_cryptogram_without_eci credit_card = network_tokenization_credit_card('4242424242424242', payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', verification_value: nil, - source: :apple_pay - ) + source: :apple_pay) assert response = @gateway.authorize(@amount, credit_card, @options) assert_success response assert_equal 'charge', response.params['object'] @@ -161,5 +157,4 @@ def test_successful_auth_with_apple_pay_raw_cryptogram_without_eci assert_equal 'wow@example.com', response.params['metadata']['email'] assert_match CHARGE_ID_REGEX, response.authorization end - end diff --git a/test/remote/gateways/remote_stripe_connect_test.rb b/test/remote/gateways/remote_stripe_connect_test.rb index 8309d62f98d..f206eece901 100644 --- a/test/remote/gateways/remote_stripe_connect_test.rb +++ b/test/remote/gateways/remote_stripe_connect_test.rb @@ -10,21 +10,21 @@ def setup @new_credit_card = credit_card('5105105105105100') @options = { - :currency => 'USD', - :description => 'ActiveMerchant Test Purchase', - :email => 'wow@example.com', - :stripe_account => fixtures(:stripe_destination)[:stripe_user_id] + currency: 'USD', + description: 'ActiveMerchant Test Purchase', + email: 'wow@example.com', + stripe_account: fixtures(:stripe_destination)[:stripe_user_id] } end def test_application_fee_for_stripe_connect - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:application_fee => 12)) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(application_fee: 12)) assert_success response end def test_successful_refund_with_application_fee - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:application_fee => 12)) - assert refund = @gateway.refund(@amount, response.authorization, @options.merge(:refund_application_fee => true)) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(application_fee: 12)) + assert refund = @gateway.refund(@amount, response.authorization, @options.merge(refund_application_fee: true)) assert_success refund # Verify the application fee is refunded @@ -35,8 +35,8 @@ def test_successful_refund_with_application_fee end def test_refund_partial_application_fee - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:application_fee => 12)) - assert refund = @gateway.refund(@amount-20, response.authorization, @options.merge(:refund_fee_amount => '10')) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(application_fee: 12)) + assert refund = @gateway.refund(@amount - 20, response.authorization, @options.merge(refund_fee_amount: '10')) assert_success refund # Verify the application fee is partially refunded @@ -47,8 +47,8 @@ def test_refund_partial_application_fee end def test_refund_application_fee_amount_zero - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:application_fee => 12)) - assert refund = @gateway.refund(@amount-20, response.authorization, @options.merge(:refund_fee_amount => '0')) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(application_fee: 12)) + assert refund = @gateway.refund(@amount - 20, response.authorization, @options.merge(refund_fee_amount: '0')) assert_success refund # Verify the application fee is not refunded diff --git a/test/remote/gateways/remote_stripe_emv_test.rb b/test/remote/gateways/remote_stripe_emv_test.rb index 6d2742d7d35..2e9baee7d8e 100644 --- a/test/remote/gateways/remote_stripe_emv_test.rb +++ b/test/remote/gateways/remote_stripe_emv_test.rb @@ -14,9 +14,9 @@ def setup } @options = { - :currency => 'USD', - :description => 'ActiveMerchant Test Purchase', - :email => 'wow@example.com' + currency: 'USD', + description: 'ActiveMerchant Test Purchase', + email: 'wow@example.com' } # This capture hex says that the payload is a transaction cryptogram (TC) but does not @@ -140,7 +140,7 @@ def test_purchase_and_void_with_emv_contactless_credit_card end def test_authorization_emv_credit_card_in_us_with_metadata - assert authorization = @gateway.authorize(@amount, @emv_credit_cards[:us], @options.merge({:metadata => {:this_is_a_random_key_name => 'with a random value', :i_made_up_this_key_too => 'canyoutell'}, :order_id => '42', :email => 'foo@wonderfullyfakedomain.com'})) + assert authorization = @gateway.authorize(@amount, @emv_credit_cards[:us], @options.merge({ metadata: { this_is_a_random_key_name: 'with a random value', i_made_up_this_key_too: 'canyoutell' }, order_id: '42', email: 'foo@wonderfullyfakedomain.com' })) assert_success authorization end end diff --git a/test/remote/gateways/remote_stripe_payment_intents_test.rb b/test/remote/gateways/remote_stripe_payment_intents_test.rb index d88c68af801..3e712659fad 100644 --- a/test/remote/gateways/remote_stripe_payment_intents_test.rb +++ b/test/remote/gateways/remote_stripe_payment_intents_test.rb @@ -3,30 +3,45 @@ class RemoteStripeIntentsTest < Test::Unit::TestCase def setup @gateway = StripePaymentIntentsGateway.new(fixtures(:stripe)) - @customer = fixtures(:stripe)[:customer_id] + @customer = fixtures(:stripe_verified_bank_account)[:customer_id] @amount = 2000 @three_ds_payment_method = 'pm_card_threeDSecure2Required' @visa_payment_method = 'pm_card_visa' @declined_payment_method = 'pm_card_chargeDeclined' @three_ds_moto_enabled = 'pm_card_authenticationRequiredOnSetup' @three_ds_authentication_required = 'pm_card_authenticationRequired' + @three_ds_authentication_required_setup_for_off_session = 'pm_card_authenticationRequiredSetupForOffSession' + @three_ds_off_session_credit_card = credit_card('4000002500003155', + verification_value: '737', + month: 10, + year: 2022) + @three_ds_1_credit_card = credit_card('4000000000003063', + verification_value: '737', + month: 10, + year: 2021) @three_ds_credit_card = credit_card('4000000000003220', verification_value: '737', month: 10, - year: 2020 - ) + year: 2021) + @three_ds_not_required_card = credit_card('4000000000003055', + verification_value: '737', + month: 10, + year: 2021) + @three_ds_external_data_card = credit_card('4000002760003184', + verification_value: '737', + month: 10, + year: 2021) @visa_card = credit_card('4242424242424242', verification_value: '737', month: 10, - year: 2020 - ) + year: 2021) @destination_account = fixtures(:stripe_destination)[:stripe_user_id] end def test_authorization_and_void options = { currency: 'GBP', - customer: @customer, + customer: @customer } assert authorization = @gateway.authorize(@amount, @visa_payment_method, options) @@ -38,20 +53,84 @@ def test_authorization_and_void end def test_successful_purchase + options = { + currency: 'GBP', + customer: @customer + } + assert purchase = @gateway.purchase(@amount, @visa_payment_method, options) + + assert_equal 'succeeded', purchase.params['status'] + assert purchase.params.dig('charges', 'data')[0]['captured'] + end + + def test_purchases_with_same_idempotency_key + options = { + currency: 'GBP', + customer: @customer, + idempotency_key: SecureRandom.hex + } + assert purchase1 = @gateway.purchase(@amount, @visa_payment_method, options) + assert_equal 'succeeded', purchase1.params['status'] + assert purchase1.params.dig('charges', 'data')[0]['captured'] + + assert purchase2 = @gateway.purchase(@amount, @visa_payment_method, options) + assert purchase2.success? + assert_equal purchase1.authorization, purchase2.authorization + assert_equal purchase1.params['charges']['data'][0]['id'], purchase2.params['charges']['data'][0]['id'] + end + + def test_credit_card_purchases_with_same_idempotency_key options = { currency: 'GBP', customer: @customer, + idempotency_key: SecureRandom.hex } + assert purchase1 = @gateway.purchase(@amount, @visa_card, options) + assert_equal 'succeeded', purchase1.params['status'] + assert purchase1.params.dig('charges', 'data')[0]['captured'] + + assert purchase2 = @gateway.purchase(@amount, @visa_card, options) + assert purchase2.success? + assert_equal purchase1.authorization, purchase2.authorization + assert_equal purchase1.params['charges']['data'][0]['id'], purchase2.params['charges']['data'][0]['id'] + end + + def test_purchases_with_same_idempotency_key_different_options + options = { + currency: 'GBP', + customer: @customer, + idempotency_key: SecureRandom.hex + } + assert purchase = @gateway.purchase(@amount, @visa_payment_method, options) + assert_equal 'succeeded', purchase.params['status'] + assert purchase.params.dig('charges', 'data')[0]['captured'] + + options[:currency] = 'USD' assert purchase = @gateway.purchase(@amount, @visa_payment_method, options) + refute purchase.success? + assert_match(/^Keys for idempotent requests can only be used with the same parameters they were first used with/, purchase.message) + end + def test_credit_card_purchases_with_same_idempotency_key_different_options + options = { + currency: 'GBP', + customer: @customer, + idempotency_key: SecureRandom.hex + } + assert purchase = @gateway.purchase(@amount, @visa_card, options) assert_equal 'succeeded', purchase.params['status'] assert purchase.params.dig('charges', 'data')[0]['captured'] + + options[:currency] = 'USD' + assert purchase = @gateway.purchase(@amount, @visa_card, options) + refute purchase.success? + assert_match(/^Keys for idempotent requests can only be used with the same parameters they were first used with/, purchase.message) end def test_unsuccessful_purchase options = { currency: 'GBP', - customer: @customer, + customer: @customer } assert purchase = @gateway.purchase(@amount, @declined_payment_method, options) @@ -59,6 +138,74 @@ def test_unsuccessful_purchase refute purchase.params.dig('error', 'payment_intent', 'charges', 'data')[0]['captured'] end + def test_successful_purchase_with_external_auth_data_3ds_1 + options = { + currency: 'GBP', + three_d_secure: { + eci: '05', + cavv: '4BQwsg4yuKt0S1LI1nDZTcO9vUM=', + xid: 'd+NEBKSpEMauwleRhdrDY06qj4A=' + } + } + + assert purchase = @gateway.purchase(@amount, @three_ds_external_data_card, options) + + assert_equal 'succeeded', purchase.params['status'] + assert purchase.params.dig('charges', 'data')[0]['captured'] + end + + def test_successful_purchase_with_external_auth_data_3ds_2 + options = { + currency: 'GBP', + three_d_secure: { + version: '2.1.0', + eci: '02', + cavv: 'jJ81HADVRtXfCBATEp01CJUAAAA=', + ds_transaction_id: 'f879ea1c-aa2c-4441-806d-e30406466d79' + } + } + + assert purchase = @gateway.purchase(@amount, @three_ds_external_data_card, options) + + assert_equal 'succeeded', purchase.params['status'] + assert purchase.params.dig('charges', 'data')[0]['captured'] + end + + def test_successful_purchase_with_customer_token_and_external_auth_data_3ds_2 + options = { + currency: 'GBP', + customer: @customer, + three_d_secure: { + version: '2.1.0', + eci: '02', + cavv: 'jJ81HADVRtXfCBATEp01CJUAAAA=', + ds_transaction_id: 'f879ea1c-aa2c-4441-806d-e30406466d79' + } + } + + assert purchase = @gateway.purchase(@amount, @three_ds_authentication_required, options) + + assert_equal 'succeeded', purchase.params['status'] + assert purchase.params.dig('charges', 'data')[0]['captured'] + end + + def test_successful_authorization_with_external_auth_data_3ds_2 + options = { + currency: 'GBP', + three_d_secure: { + version: '2.1.0', + eci: '02', + cavv: 'jJ81HADVRtXfCBATEp01CJUAAAA=', + ds_transaction_id: 'f879ea1c-aa2c-4441-806d-e30406466d79' + } + } + + assert authorization = @gateway.authorize(@amount, @three_ds_external_data_card, options) + + assert_equal 'requires_capture', authorization.params['status'] + refute authorization.params.dig('charges', 'data')[0]['captured'] + end + def test_create_payment_intent_manual_capture_method options = { currency: 'USD', @@ -102,7 +249,7 @@ def test_create_payment_intent_with_customer def test_create_payment_intent_with_credit_card options = { currency: 'USD', - customer: @customer, + customer: @customer } assert response = @gateway.create_intent(@amount, @three_ds_credit_card, options) @@ -116,7 +263,8 @@ def test_create_payment_intent_with_return_url currency: 'USD', customer: @customer, confirm: true, - return_url: 'https://www.example.com' + return_url: 'https://www.example.com', + execute_threed: true } assert response = @gateway.create_intent(@amount, @three_ds_credit_card, options) @@ -126,12 +274,15 @@ def test_create_payment_intent_with_return_url end def test_create_payment_intent_with_metadata + suffix = 'SUFFIX' + options = { currency: 'USD', customer: @customer, description: 'ActiveMerchant Test Purchase', receipt_email: 'test@example.com', statement_descriptor: 'Statement Descriptor', + statement_descriptor_suffix: suffix, metadata: { key_1: 'value_1', key_2: 'value_2' } } @@ -142,6 +293,7 @@ def test_create_payment_intent_with_metadata assert_equal 'ActiveMerchant Test Purchase', response.params['description'] assert_equal 'test@example.com', response.params['receipt_email'] assert_equal 'Statement Descriptor', response.params['statement_descriptor'] + assert_equal suffix, response.params['statement_descriptor_suffix'] end def test_create_payment_intent_that_saves_payment_method @@ -181,13 +333,131 @@ def test_3ds_unauthenticated_authorize_with_off_session options = { currency: 'USD', customer: @customer, - off_session: true, + off_session: true } assert response = @gateway.authorize(@amount, @three_ds_credit_card, options) assert_failure response end + def test_create_setup_intent_with_setup_future_usage + [@three_ds_credit_card, @three_ds_authentication_required_setup_for_off_session].each do |card_to_use| + assert authorize_response = @gateway.create_setup_intent(card_to_use, { + address: { + email: 'test@example.com', + name: 'John Doe', + line1: '1 Test Ln', + city: 'Durham', + tracking_number: '123456789' + }, + currency: 'USD', + confirm: true, + execute_threed: true, + return_url: 'https://example.com' + }) + + assert_equal 'requires_action', authorize_response.params['status'] + assert_match 'https://hooks.stripe.com', authorize_response.params.dig('next_action', 'redirect_to_url', 'url') + + # since we cannot "click" the stripe hooks URL to confirm the authorization + # we will at least confirm we can retrieve the created setup_intent and it contains the structure we expect + setup_intent_id = authorize_response.params['id'] + + assert si_reponse = @gateway.retrieve_setup_intent(setup_intent_id) + assert_equal 'requires_action', si_reponse.params['status'] + + assert_not_empty si_reponse.params.dig('latest_attempt', 'payment_method_details', 'card') + assert_nil si_reponse.params.dig('latest_attempt', 'payment_method_details', 'card', 'network_transaction_id') + end + end + + def test_retrieving_error_for_non_existant_setup_intent + assert si_reponse = @gateway.retrieve_setup_intent('seti_does_not_exist') + assert_nil si_reponse.params['status'] + assert_nil si_reponse.params.dig('latest_attempt', 'payment_method_details', 'card', 'network_transaction_id') + + assert_match 'resource_missing', si_reponse.params.dig('error', 'code') + assert_match "No such setupintent: 'seti_does_not_exist'", si_reponse.params.dig('error', 'message') + end + + def test_3ds_unauthenticated_authorize_with_off_session_requires_capture + [@three_ds_off_session_credit_card, @three_ds_authentication_required_setup_for_off_session].each do |card_to_use| + assert authorize_response = @gateway.authorize(@amount, card_to_use, { + address: { + email: 'test@example.com', + name: 'John Doe', + line1: '1 Test Ln', + city: 'Durham', + tracking_number: '123456789' + }, + currency: 'USD', + confirm: true, + setup_future_usage: 'off_session', + execute_threed: true, + three_d_secure: { + version: '2.2.0', + eci: '02', + cavv: 'jJ81HADVRtXfCBATEp01CJUAAAA=', + ds_transaction_id: 'f879ea1c-aa2c-4441-806d-e30406466d79' + } + }) + + assert_success authorize_response + assert_equal 'requires_capture', authorize_response.params['status'] + assert_not_empty authorize_response.params.dig('charges', 'data')[0]['payment_method_details']['card']['network_transaction_id'] + end + end + + def test_purchase_works_with_stored_credentials + [@three_ds_off_session_credit_card, @three_ds_authentication_required_setup_for_off_session].each do |card_to_use| + assert purchase = @gateway.purchase(@amount, card_to_use, { + currency: 'USD', + execute_threed: true, + confirm: true, + off_session: true, + stored_credential: { + network_transaction_id: '1098510912210968', # TEST env seems happy with any value :/ + ds_transaction_id: 'null' # this is not req + } + }) + + assert_success purchase + assert_equal 'succeeded', purchase.params['status'] + assert purchase.params.dig('charges', 'data')[0]['captured'] + end + end + + def test_purchase_works_with_stored_credentials_without_optional_ds_transaction_id + [@three_ds_off_session_credit_card, @three_ds_authentication_required_setup_for_off_session].each do |card_to_use| + assert purchase = @gateway.purchase(@amount, card_to_use, { + currency: 'USD', + execute_threed: true, + confirm: true, + off_session: true, + stored_credential: { + network_transaction_id: '1098510912210968', # TEST env seems happy with any value :/ + } + }) + + assert_success purchase + assert_equal 'succeeded', purchase.params['status'] + assert purchase.params.dig('charges', 'data')[0]['captured'] + end + end + + def test_purchase_fails_on_unexpected_3ds_initiation + options = { + currency: 'USD', + customer: @customer, + confirm: true, + return_url: 'https://www.example.com' + } + + assert response = @gateway.purchase(100, @three_ds_credit_card, options) + assert_failure response + assert_match 'Received unexpected 3DS authentication response', response.message + end + def test_create_payment_intent_with_shipping_address options = { currency: 'USD', @@ -223,17 +493,26 @@ def test_create_payment_intent_with_billing_address end def test_create_payment_intent_with_connected_account + transfer_group = 'XFERGROUP' + application_fee = 100 + + # You may not provide the application_fee_amount parameter and the transfer_data[amount] parameter + # simultaneously. They are mutually exclusive. options = { currency: 'USD', customer: @customer, - application_fee: 100, - transfer_destination: @destination_account + application_fee: application_fee, + transfer_destination: @destination_account, + on_behalf_of: @destination_account, + transfer_group: transfer_group } assert response = @gateway.create_intent(@amount, nil, options) assert_success response - assert_equal 100, response.params['application_fee_amount'] + assert_equal application_fee, response.params['application_fee_amount'] + assert_equal transfer_group, response.params['transfer_group'] + assert_equal @destination_account, response.params['on_behalf_of'] assert_equal @destination_account, response.params.dig('transfer_data', 'destination') end @@ -243,7 +522,7 @@ def test_create_a_payment_intent_and_confirm customer: @customer, return_url: 'https://www.example.com', confirmation_method: 'manual', - capture_method: 'manual', + capture_method: 'manual' } assert create_response = @gateway.create_intent(@amount, @three_ds_payment_method, options) assert_equal 'requires_confirmation', create_response.params['status'] @@ -273,6 +552,46 @@ def test_create_a_payment_intent_and_manually_capture assert_equal 'Payment complete.', capture_response.params.dig('charges', 'data')[0].dig('outcome', 'seller_message') end + def test_failed_create_a_payment_intent_with_set_error_on_requires_action + options = { + currency: 'GBP', + customer: @customer, + confirm: true, + error_on_requires_action: true + } + assert create_response = @gateway.create_intent(@amount, @three_ds_credit_card, options) + assert create_response.message.include?('This payment required an authentication action to complete, but `error_on_requires_action` was set.') + end + + def test_successful_create_a_payment_intent_with_set_error_on_requires_action + options = { + currency: 'GBP', + customer: @customer, + confirm: true, + error_on_requires_action: true + } + assert create_response = @gateway.create_intent(@amount, @visa_payment_method, options) + assert_equal 'succeeded', create_response.params['status'] + end + + def test_amount_localization + amount = 200000 + options = { + currency: 'XPF', + customer: @customer, + confirmation_method: 'manual', + capture_method: 'manual', + confirm: true + } + assert create_response = @gateway.create_intent(amount, @visa_payment_method, options) + intent_id = create_response.params['id'] + assert_equal 'requires_capture', create_response.params['status'] + + assert capture_response = @gateway.capture(amount, intent_id, options) + assert_equal 'succeeded', capture_response.params['status'] + assert_equal 2000, capture_response.params['amount'] + end + def test_auth_and_capture_with_destination_account_and_fee options = { currency: 'GBP', @@ -321,19 +640,20 @@ def test_failed_capture_after_creation end def test_create_a_payment_intent_and_update - update_amount = 2050 + amount = 200000 + update_amount = 250000 options = { - currency: 'GBP', + currency: 'XPF', customer: @customer, confirmation_method: 'manual', - capture_method: 'manual', + capture_method: 'manual' } - assert create_response = @gateway.create_intent(@amount, @visa_payment_method, options) + assert create_response = @gateway.create_intent(amount, @visa_payment_method, options) intent_id = create_response.params['id'] - assert_equal @amount, create_response.params['amount'] + assert_equal 2000, create_response.params['amount'] assert update_response = @gateway.update_intent(update_amount, intent_id, nil, options.merge(payment_method_types: 'card')) - assert_equal update_amount, update_response.params['amount'] + assert_equal 2500, update_response.params['amount'] assert_equal 'requires_confirmation', update_response.params['status'] end @@ -354,6 +674,31 @@ def test_create_a_payment_intent_and_void assert_equal 'requested_by_customer', cancel_response.params['cancellation_reason'] end + def test_create_a_payment_intent_and_void_requires_unique_idempotency_key + idempotency_key = SecureRandom.hex + options = { + currency: 'GBP', + customer: @customer, + return_url: 'https://www.example.com', + confirmation_method: 'manual', + capture_method: 'manual', + idempotency_key: idempotency_key + } + assert create_response = @gateway.create_intent(@amount, @three_ds_payment_method, options) + assert_equal 'requires_confirmation', create_response.params['status'] + intent_id = create_response.params['id'] + + assert get_response = @gateway.show_intent(intent_id, options) + assert_equal 'requires_confirmation', get_response.params['status'] + + assert_failure cancel_response = @gateway.void(intent_id, cancellation_reason: 'requested_by_customer', idempotency_key: idempotency_key) + assert_match(/^Keys for idempotent requests can only be used for the same endpoint they were first used for/, cancel_response.message) + + assert cancel_response = @gateway.void(intent_id, cancellation_reason: 'requested_by_customer', idempotency_key: "#{idempotency_key}-auto-void") + assert_equal 'canceled', cancel_response.params['status'] + assert_equal 'requested_by_customer', cancel_response.params['cancellation_reason'] + end + def test_failed_void_after_capture options = { currency: 'GBP', @@ -392,9 +737,42 @@ def test_refund_a_payment_intent assert_equal refund.authorization, refund_id end - def test_successful_store_purchase_and_unstore + def test_refund_when_payment_intent_not_captured options = { currency: 'GBP', + customer: @customer, + confirmation_method: 'manual', + capture_method: 'manual', + confirm: true + } + assert create_response = @gateway.create_intent(@amount, @visa_payment_method, options) + intent_id = create_response.params['id'] + + refund = @gateway.refund(@amount - 20, intent_id) + assert_failure refund + assert refund.params['error'] + end + + def test_refund_when_payment_intent_requires_action + options = { + currency: 'GBP', + customer: @customer, + confirmation_method: 'manual', + capture_method: 'manual', + confirm: true + } + assert create_response = @gateway.create_intent(@amount, @three_ds_authentication_required, options) + assert_equal 'requires_action', create_response.params['status'] + intent_id = create_response.params['id'] + + refund = @gateway.refund(@amount - 20, intent_id) + assert_failure refund + assert_match(/has a status of requires_action/, refund.message) + end + + def test_successful_store_purchase_and_unstore + options = { + currency: 'GBP' } assert store = @gateway.store(@visa_card, options) assert store.params['customer'].start_with?('cus_') @@ -406,10 +784,66 @@ def test_successful_store_purchase_and_unstore assert_nil unstore.params['customer'] end + def test_successful_store_with_idempotency_key + idempotency_key = SecureRandom.hex + + options = { + currency: 'GBP', + idempotency_key: idempotency_key + } + + assert store1 = @gateway.store(@visa_card, options) + assert store1.success? + assert store1.params['customer'].start_with?('cus_') + + assert store2 = @gateway.store(@visa_card, options) + assert store2.success? + assert_equal store1.authorization, store2.authorization + assert_equal store1.params['id'], store2.params['id'] + end + + def test_successful_store_with_false_validate_option + options = { + currency: 'GBP', + validate: false + } + assert store = @gateway.store(@visa_card, options) + assert store.params['customer'].start_with?('cus_') + assert_equal 'unchecked', store.params['card']['checks']['cvc_check'] + end + + def test_successful_store_with_true_validate_option + options = { + currency: 'GBP', + validate: true + } + assert store = @gateway.store(@visa_card, options) + assert store.params['customer'].start_with?('cus_') + assert_equal 'pass', store.params['card']['checks']['cvc_check'] + end + + def test_successful_verify + options = { + customer: @customer + } + assert verify = @gateway.verify(@visa_payment_method, options) + + assert_equal 'succeeded', verify.params['status'] + end + + def test_failed_verify + options = { + customer: @customer + } + assert verify = @gateway.verify(@declined_payment_method, options) + + assert_equal 'Your card was declined.', verify.message + end + def test_moto_enabled_card_requires_action_when_not_marked options = { currency: 'GBP', - confirm: true, + confirm: true } assert purchase = @gateway.purchase(@amount, @three_ds_moto_enabled, options) @@ -420,7 +854,7 @@ def test_moto_enabled_card_succeeds_when_marked options = { currency: 'GBP', confirm: true, - moto: true, + moto: true } assert purchase = @gateway.purchase(@amount, @three_ds_moto_enabled, options) @@ -432,7 +866,7 @@ def test_certain_cards_require_action_even_when_marked_as_moto options = { currency: 'GBP', confirm: true, - moto: true, + moto: true } assert purchase = @gateway.purchase(@amount, @three_ds_authentication_required, options) @@ -440,12 +874,26 @@ def test_certain_cards_require_action_even_when_marked_as_moto assert_equal 'Your card was declined. This transaction requires authentication.', purchase.message end + def test_request_three_d_secure + options = { + currency: 'GBP', + request_three_d_secure: 'any' + } + assert purchase = @gateway.purchase(@amount, @three_ds_not_required_card, options) + assert_equal 'requires_action', purchase.params['status'] + + options = { + currency: 'GBP' + } + assert purchase = @gateway.purchase(@amount, @three_ds_not_required_card, options) + assert_equal 'succeeded', purchase.params['status'] + end + def test_transcript_scrubbing options = { currency: 'GBP', customer: @customer, confirmation_method: 'manual', - capture_method: 'manual', return_url: 'https://www.example.com/return', confirm: true } diff --git a/test/remote/gateways/remote_stripe_test.rb b/test/remote/gateways/remote_stripe_test.rb index 04a5b144138..7f60e25fed8 100644 --- a/test/remote/gateways/remote_stripe_test.rb +++ b/test/remote/gateways/remote_stripe_test.rb @@ -13,14 +13,14 @@ def setup @check = check({ bank_name: 'STRIPE TEST BANK', account_number: '000123456789', - routing_number: '110000000', + routing_number: '110000000' }) @verified_bank_account = fixtures(:stripe_verified_bank_account) @options = { - :currency => 'USD', - :description => 'ActiveMerchant Test Purchase', - :email => 'wow@example.com' + currency: 'USD', + description: 'ActiveMerchant Test Purchase', + email: 'wow@example.com' } end @@ -46,7 +46,7 @@ def test_successful_purchase end def test_successful_purchase_with_blank_referer - options = @options.merge({referrer: ''}) + options = @options.merge({ referrer: '' }) assert response = @gateway.purchase(@amount, @credit_card, options) assert_success response assert_equal 'charge', response.params['object'] @@ -57,7 +57,7 @@ def test_successful_purchase_with_blank_referer end def test_successful_purchase_with_recurring_flag - custom_options = @options.merge(:eci => 'recurring') + custom_options = @options.merge(eci: 'recurring') assert response = @gateway.purchase(@amount, @credit_card, custom_options) assert_success response assert_equal 'charge', response.params['object'] @@ -68,7 +68,7 @@ def test_successful_purchase_with_recurring_flag def test_successful_purchase_with_destination destination = fixtures(:stripe_destination)[:stripe_user_id] - custom_options = @options.merge(:destination => destination) + custom_options = @options.merge(destination: destination) assert response = @gateway.purchase(@amount, @credit_card, custom_options) assert_success response assert_equal 'charge', response.params['object'] @@ -80,7 +80,7 @@ def test_successful_purchase_with_destination def test_successful_purchase_with_destination_and_amount destination = fixtures(:stripe_destination)[:stripe_user_id] - custom_options = @options.merge(:destination => destination, :destination_amount => @amount - 20) + custom_options = @options.merge(destination: destination, destination_amount: @amount - 20) assert response = @gateway.purchase(@amount, @credit_card, custom_options) assert_success response assert_equal 'charge', response.params['object'] @@ -109,7 +109,7 @@ def test_successful_purchase_with_level3_data 'product_description' => 'A totes different item', 'tax_amount' => 10, 'unit_cost' => 50, - 'quantity' => 1, + 'quantity' => 1 } ] @@ -122,6 +122,30 @@ def test_successful_purchase_with_level3_data assert_equal 'wow@example.com', response.params['metadata']['email'] end + def test_purchase_with_connected_account + destination = fixtures(:stripe_destination)[:stripe_user_id] + transfer_group = 'XFERGROUP' + application_fee_amount = 100 + + # You may not provide the application_fee_amount parameter and the transfer_data[amount] parameter + # simultaneously. They are mutually exclusive. + options = @options.merge({ + customer: @customer, + application_fee_amount: application_fee_amount, + transfer_destination: destination, + on_behalf_of: destination, + transfer_group: transfer_group + }) + + assert response = @gateway.purchase(@amount, @credit_card, options) + + assert_success response + assert_equal application_fee_amount, response.params['application_fee_amount'] + assert_equal transfer_group, response.params['transfer_group'] + assert_equal destination, response.params['on_behalf_of'] + assert_equal destination, response.params.dig('transfer_data', 'destination') + end + def test_unsuccessful_purchase assert response = @gateway.purchase(@amount, @declined_card, @options) assert_failure response @@ -132,7 +156,7 @@ def test_unsuccessful_purchase def test_unsuccessful_purchase_with_destination_and_amount destination = fixtures(:stripe_destination)[:stripe_user_id] - custom_options = @options.merge(:destination => destination, :destination_amount => @amount + 20) + custom_options = @options.merge(destination: destination, destination_amount: @amount + 20) assert response = @gateway.purchase(@amount, @credit_card, custom_options) assert_failure response assert_match %r{must be less than or equal to the charge amount}, response.message @@ -156,6 +180,23 @@ def test_unsuccessful_direct_bank_account_purchase assert_equal 'Direct bank account transactions are not supported. Bank accounts must be stored and verified before use.', response.message end + def test_unsuccessful_echeck_auth_with_verified_account + customer_id = @verified_bank_account[:customer_id] + bank_account_id = @verified_bank_account[:bank_account_id] + + payment = [customer_id, bank_account_id].join('|') + + response = @gateway.authorize(@amount, payment, @options) + assert_failure response + assert_equal 'You cannot pass capture=false for this payment type.', response.message + end + + def test_unsuccessful_direct_bank_account_auth + response = @gateway.authorize(@amount, @check, @options) + assert_failure response + assert_equal 'Direct bank account transactions are not supported for authorize.', response.message + end + def test_authorization_and_capture assert authorization = @gateway.authorize(@amount, @credit_card, @options) assert_success authorization @@ -169,7 +210,7 @@ def test_authorization_and_capture def test_authorization_and_capture_with_destination destination = fixtures(:stripe_destination)[:stripe_user_id] - custom_options = @options.merge(:destination => destination) + custom_options = @options.merge(destination: destination) assert authorization = @gateway.authorize(@amount, @credit_card, custom_options) assert_success authorization @@ -184,7 +225,7 @@ def test_authorization_and_capture_with_destination def test_authorization_and_capture_with_destination_and_amount destination = fixtures(:stripe_destination)[:stripe_user_id] - custom_options = @options.merge(:destination => destination, :destination_amount => @amount - 20) + custom_options = @options.merge(destination: destination, destination_amount: @amount - 20) assert authorization = @gateway.authorize(@amount, @credit_card, custom_options) assert_success authorization @@ -467,20 +508,18 @@ def test_successful_purchase_using_stored_card_on_existing_customer assert_equal '5100', response.params['source']['last4'] end - def test_successful_purchase_using_stored_card_and_deprecated_api + def test_successful_purchase_using_stored_card_with_customer_id assert store = @gateway.store(@credit_card) assert_success store - recharge_options = @options.merge(:customer => store.params['id']) - assert_deprecation_warning do - response = @gateway.purchase(@amount, nil, recharge_options) - assert_success response - assert_equal '4242', response.params['source']['last4'] - end + recharge_options = @options.merge(customer: store.params['id']) + response = @gateway.purchase(@amount, nil, recharge_options) + assert_success response + assert_equal '4242', response.params['source']['last4'] end def test_successful_unstore - creation = @gateway.store(@credit_card, {:description => 'Active Merchant Unstore Customer'}) + creation = @gateway.store(@credit_card, { description: 'Active Merchant Unstore Customer' }) card_id = creation.params['sources']['data'].first['id'] assert response = @gateway.unstore(creation.authorization) @@ -491,7 +530,7 @@ def test_successful_unstore end def test_successful_unstore_using_deprecated_api - creation = @gateway.store(@credit_card, {:description => 'Active Merchant Unstore Customer'}) + creation = @gateway.store(@credit_card, { description: 'Active Merchant Unstore Customer' }) card_id = creation.params['sources']['data'].first['id'] customer_id = creation.params['id'] @@ -535,7 +574,7 @@ def test_successful_purchase_from_stored_and_verified_bank_account end def test_invalid_login - gateway = StripeGateway.new(:login => 'active_merchant_test') + gateway = StripeGateway.new(login: 'active_merchant_test') assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_match 'Invalid API Key provided', response.message @@ -562,25 +601,25 @@ def test_card_present_authorize_and_capture end def test_creditcard_purchase_with_customer - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:customer => '1234')) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(customer: '1234')) assert_success response assert_equal 'charge', response.params['object'] assert response.params['paid'] end def test_expanding_objects - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:expand => 'balance_transaction')) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(expand: 'balance_transaction')) assert_success response assert response.params['balance_transaction'].is_a?(Hash) assert_equal 'balance_transaction', response.params['balance_transaction']['object'] end def test_successful_update - creation = @gateway.store(@credit_card, {:description => 'Active Merchant Update Credit Card'}) + creation = @gateway.store(@credit_card, { description: 'Active Merchant Update Credit Card' }) customer_id = creation.params['id'] card_id = creation.params['sources']['data'].first['id'] - assert response = @gateway.update(customer_id, card_id, { :name => 'John Doe', :address_line1 => '123 Main Street', :address_city => 'Pleasantville', :address_state => 'NY', :address_zip => '12345', :exp_year => Time.now.year + 2, :exp_month => 6 }) + assert response = @gateway.update(customer_id, card_id, { name: 'John Doe', address_line1: '123 Main Street', address_city: 'Pleasantville', address_state: 'NY', address_zip: '12345', exp_year: Time.now.year + 2, exp_month: 6 }) assert_success response assert_equal 'John Doe', response.params['name'] assert_equal '123 Main Street', response.params['address_line1'] @@ -659,11 +698,18 @@ def test_stripe_account_header assert_success response end + def test_statement_descriptor_suffix + suffix = 'SUFFIX' + + assert response = @gateway.purchase(@amount, @credit_card, statement_descriptor_suffix: suffix) + assert_success response + assert_equal suffix, response.params['statement_descriptor_suffix'] + end + def test_verify_credentials assert @gateway.verify_credentials gateway = StripeGateway.new(login: 'an_unknown_api_key') assert !gateway.verify_credentials end - end diff --git a/test/remote/gateways/remote_swipe_checkout_test.rb b/test/remote/gateways/remote_swipe_checkout_test.rb index 6299a506fd2..db3c144ff3e 100644 --- a/test/remote/gateways/remote_swipe_checkout_test.rb +++ b/test/remote/gateways/remote_swipe_checkout_test.rb @@ -8,7 +8,7 @@ def setup @accepted_card = credit_card('1234123412341234') @declined_card = credit_card('1111111111111111') @invalid_card = credit_card('1000000000000000') - @empty_card = credit_card('') + @empty_card = credit_card('') @options = { order_id: '1', @@ -24,7 +24,7 @@ def test_successful_purchase end def test_region_switching - assert response = @gateway.purchase(@amount, @accepted_card, @options.merge(:region => 'CA')) + assert response = @gateway.purchase(@amount, @accepted_card, @options.merge(region: 'CA')) assert_success response assert_equal 'Transaction approved', response.message end diff --git a/test/remote/gateways/remote_tns_test.rb b/test/remote/gateways/remote_tns_test.rb index 2a55bbd1853..6155f16f5fa 100644 --- a/test/remote/gateways/remote_tns_test.rb +++ b/test/remote/gateways/remote_tns_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class RemoteTnsTest < Test::Unit::TestCase - def setup TnsGateway.ssl_strict = false # Sandbox has an improperly installed cert @gateway = TnsGateway.new(fixtures(:tns)) @@ -37,7 +36,7 @@ def test_successful_purchase_sans_options def test_successful_purchase_with_more_options more_options = @options.merge({ ip: '127.0.0.1', - email: 'joe@example.com', + email: 'joe@example.com' }) assert response = @gateway.purchase(@amount, @credit_card, @options.merge(more_options)) @@ -116,9 +115,9 @@ def test_successful_verify def test_invalid_login gateway = TnsGateway.new( - :userid => 'nosuch', - :password => 'thing' - ) + userid: 'nosuch', + password: 'thing' + ) response = gateway.authorize(@amount, @credit_card, @options) assert_failure response assert_equal 'ERROR - INVALID_REQUEST - Invalid credentials.', response.message diff --git a/test/remote/gateways/remote_trans_first_test.rb b/test/remote/gateways/remote_trans_first_test.rb index 3423954560e..2202d87b4e8 100644 --- a/test/remote/gateways/remote_trans_first_test.rb +++ b/test/remote/gateways/remote_trans_first_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class RemoteTransFirstTest < Test::Unit::TestCase - def setup @gateway = TransFirstGateway.new(fixtures(:trans_first)) @@ -9,9 +8,9 @@ def setup @check = check @amount = 1201 @options = { - :order_id => generate_unique_id, - :invoice => 'ActiveMerchant Sale', - :billing_address => address + order_id: generate_unique_id, + invoice: 'ActiveMerchant Sale', + billing_address: address } end @@ -107,8 +106,8 @@ def test_successful_refund_with_echeck def test_invalid_login gateway = TransFirstGateway.new( - :login => '', - :password => '' + login: '', + password: '' ) assert response = gateway.purchase(1100, @credit_card, @options) assert_failure response diff --git a/test/remote/gateways/remote_trans_first_transaction_express_test.rb b/test/remote/gateways/remote_trans_first_transaction_express_test.rb index 3e69c82ecee..04b4e69f7f0 100644 --- a/test/remote/gateways/remote_trans_first_transaction_express_test.rb +++ b/test/remote/gateways/remote_trans_first_transaction_express_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class RemoteTransFirstTransactionExpressTest < Test::Unit::TestCase - def setup @gateway = TransFirstTransactionExpressGateway.new(fixtures(:trans_first_transaction_express)) @@ -16,7 +15,7 @@ def setup city: 'Broomfield', state: 'CO', zip: '85284', - phone: '(333) 444-5555', + phone: '(333) 444-5555' }) @options = { @@ -59,12 +58,12 @@ def test_successful_purchase_with_only_required options = @options.dup options[:shipping_address] = { address1: '450 Main', - zip: '85284', + zip: '85284' } options[:billing_address] = { address1: '450 Main', - zip: '85284', + zip: '85284' } response = @gateway.purchase(@amount, @credit_card, options) @@ -82,13 +81,13 @@ def test_successful_purchase_without_address2 options[:shipping_address] = { address1: '450 Main', address2: '', - zip: '85284', + zip: '85284' } options[:billing_address] = { address1: '450 Main', address2: '', - zip: '85284', + zip: '85284' } response = @gateway.purchase(@amount, @credit_card, options) @@ -98,12 +97,12 @@ def test_successful_purchase_without_address2 def test_successful_purchase_without_cvv credit_card_opts = { - :number => 4485896261017708, - :month => Date.new((Time.now.year + 1), 9, 30).month, - :year => Date.new((Time.now.year + 1), 9, 30).year, - :first_name => 'Longbob', - :last_name => 'Longsen', - :brand => 'visa' + number: 4485896261017708, + month: Date.new((Time.now.year + 1), 9, 30).month, + year: Date.new((Time.now.year + 1), 9, 30).year, + first_name: 'Longbob', + last_name: 'Longsen', + brand: 'visa' } credit_card = CreditCard.new(credit_card_opts) @@ -114,13 +113,13 @@ def test_successful_purchase_without_cvv def test_successful_purchase_with_empty_string_cvv credit_card_opts = { - :number => 4485896261017708, - :month => Date.new((Time.now.year + 1), 9, 30).month, - :year => Date.new((Time.now.year + 1), 9, 30).year, - :first_name => 'Longbob', - :last_name => 'Longsen', - :verification_value => '', - :brand => 'visa' + number: 4485896261017708, + month: Date.new((Time.now.year + 1), 9, 30).month, + year: Date.new((Time.now.year + 1), 9, 30).year, + first_name: 'Longbob', + last_name: 'Longsen', + verification_value: '', + brand: 'visa' } credit_card = CreditCard.new(credit_card_opts) @@ -131,11 +130,11 @@ def test_successful_purchase_with_empty_string_cvv def test_successful_purchase_without_name credit_card_opts = { - :number => 4485896261017708, - :month => Date.new((Time.now.year + 1), 9, 30).month, - :year => Date.new((Time.now.year + 1), 9, 30).year, - :first_name => '', - :last_name => '' + number: 4485896261017708, + month: Date.new((Time.now.year + 1), 9, 30).month, + year: Date.new((Time.now.year + 1), 9, 30).year, + first_name: '', + last_name: '' } credit_card = CreditCard.new(credit_card_opts) @@ -144,9 +143,9 @@ def test_successful_purchase_without_name assert_equal 'Succeeded', response.message credit_card_opts = { - :number => 4485896261017708, - :month => Date.new((Time.now.year + 1), 9, 30).month, - :year => Date.new((Time.now.year + 1), 9, 30).year + number: 4485896261017708, + month: Date.new((Time.now.year + 1), 9, 30).month, + year: Date.new((Time.now.year + 1), 9, 30).year } credit_card = CreditCard.new(credit_card_opts) diff --git a/test/remote/gateways/remote_transact_pro_test.rb b/test/remote/gateways/remote_transact_pro_test.rb index 5e5c428ae29..504a5b65d29 100644 --- a/test/remote/gateways/remote_transact_pro_test.rb +++ b/test/remote/gateways/remote_transact_pro_test.rb @@ -57,7 +57,7 @@ def test_partial_capture assert_success auth assert_raise(ArgumentError) do - @gateway.capture(@amount-1, auth.authorization) + @gateway.capture(@amount - 1, auth.authorization) end end @@ -80,7 +80,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - refund = @gateway.refund(@amount-1, purchase.authorization) + refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund assert_equal 'Refund Success', refund.message end @@ -89,7 +89,7 @@ def test_failed_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - refund = @gateway.refund(@amount+1, purchase.authorization) + refund = @gateway.refund(@amount + 1, purchase.authorization) assert_failure refund end diff --git a/test/remote/gateways/remote_transax_test.rb b/test/remote/gateways/remote_transax_test.rb index 1e7bbc00399..7685274b61d 100644 --- a/test/remote/gateways/remote_transax_test.rb +++ b/test/remote/gateways/remote_transax_test.rb @@ -5,15 +5,15 @@ def setup @gateway = TransaxGateway.new(fixtures(:transax)) @amount = 100 - @credit_card = credit_card('4111111111111111', :year => 10, :month => 10) + @credit_card = credit_card('4111111111111111', year: 10, month: 10) @declined_card = credit_card(0xDEADBEEF_0000.to_s) @check = check() @options = { - :order_id => '1', - :billing_address => address, - :description => 'Store Purchase' + order_id: '1', + billing_address: address, + description: 'Store Purchase' } end @@ -76,13 +76,13 @@ def test_purchase_and_update assert_success response assert_equal 'This transaction has been approved', response.message assert response.authorization - assert update = @gateway.amend(response.authorization, :shipping_carrier => 'usps') + assert update = @gateway.amend(response.authorization, shipping_carrier: 'usps') assert_equal 'This transaction has been approved', update.message assert_success update end def test_successful_purchase_with_sku - @options['product_sku_#']='123456' + @options['product_sku_#'] = '123456' assert response = @gateway.purchase(@amount, @credit_card, @options) assert_success response assert_equal 'This transaction has been approved', response.message @@ -115,9 +115,9 @@ def test_failed_verify def test_invalid_login gateway = TransaxGateway.new( - :login => '', - :password => '' - ) + login: '', + password: '' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'Invalid Username', response.message diff --git a/test/remote/gateways/remote_trust_commerce_test.rb b/test/remote/gateways/remote_trust_commerce_test.rb index 9625597ffc1..62dbd023fa9 100644 --- a/test/remote/gateways/remote_trust_commerce_test.rb +++ b/test/remote/gateways/remote_trust_commerce_test.rb @@ -6,7 +6,7 @@ def setup @credit_card = credit_card('4111111111111111') @declined_credit_card = credit_card('4111111111111112') - @check = check({account_number: 55544433221, routing_number: 789456124}) + @check = check({ account_number: 55544433221, routing_number: 789456124 }) @amount = 100 @@ -14,19 +14,19 @@ def setup @invalid_verification_value = '1234' @valid_address = { - :address1 => '123 Test St.', - :address2 => nil, - :city => 'Somewhere', - :state => 'CA', - :zip => '90001' + address1: '123 Test St.', + address2: nil, + city: 'Somewhere', + state: 'CA', + zip: '90001' } @invalid_address = { - :address1 => '187 Apple Tree Lane.', - :address2 => nil, - :city => 'Woodside', - :state => 'CA', - :zip => '94062' + address1: '187 Apple Tree Lane.', + address2: nil, + city: 'Woodside', + state: 'CA', + zip: '94062' } # The Trust Commerce API does not return anything different when custom fields are present. @@ -38,12 +38,12 @@ def setup } @options = { - :ip => '10.10.10.10', - :order_id => '#1000.1', - :email => 'cody@example.com', - :billing_address => @valid_address, - :shipping_address => @valid_address, - :custom_fields => custom_fields + ip: '10.10.10.10', + order_id: '#1000.1', + email: 'cody@example.com', + billing_address: @valid_address, + shipping_address: @valid_address, + custom_fields: custom_fields } end @@ -52,9 +52,9 @@ def test_bad_login assert response = @gateway.purchase(@amount, @credit_card, @options) assert_equal Response, response.class - assert_equal ['error', - 'offenders', - 'status'], response.params.keys.sort + assert_equal %w[error + offenders + status], response.params.keys.sort assert_match %r{A field was improperly formatted, such as non-digit characters in a number field}, response.message @@ -88,7 +88,7 @@ def test_unsuccessful_purchase_with_invalid_cvv end def test_purchase_with_avs_for_invalid_address - assert response = @gateway.purchase(@amount, @credit_card, @options.update(:billing_address => @invalid_address)) + assert response = @gateway.purchase(@amount, @credit_card, @options.update(billing_address: @invalid_address)) assert_equal 'N', response.params['avs'] assert_match %r{The transaction was successful}, response.message assert_success response @@ -107,7 +107,7 @@ def test_purchase_and_void end def test_successful_authorize_with_avs - assert response = @gateway.authorize(@amount, @credit_card, :billing_address => @valid_address) + assert response = @gateway.authorize(@amount, @credit_card, billing_address: @valid_address) assert_equal 'Y', response.avs_result['code'] assert_match %r{The transaction was successful}, response.message @@ -124,7 +124,7 @@ def test_unsuccessful_authorize_with_invalid_cvv end def test_authorization_with_avs_for_invalid_address - assert response = @gateway.authorize(@amount, @credit_card, @options.update(:billing_address => @invalid_address)) + assert response = @gateway.authorize(@amount, @credit_card, @options.update(billing_address: @invalid_address)) assert_equal 'N', response.params['avs'] assert_match %r{The transaction was successful}, response.message assert_success response @@ -190,14 +190,14 @@ def test_unstore_failure end def test_successful_recurring - assert response = @gateway.recurring(@amount, @credit_card, :periodicity => :weekly) + assert response = @gateway.recurring(@amount, @credit_card, periodicity: :weekly) assert_match %r{The transaction was successful}, response.message assert_success response end def test_failed_recurring - assert response = @gateway.recurring(@amount, @declined_credit_card, :periodicity => :weekly) + assert response = @gateway.recurring(@amount, @declined_credit_card, periodicity: :weekly) assert_bad_data_response(response) end @@ -205,7 +205,7 @@ def test_failed_recurring def test_transcript_scrubbing @credit_card.verification_value = @invalid_verification_value transcript = capture_transcript(@gateway) do - @gateway.purchase(@amount, @credit_card, @options) + @gateway.purchase(@amount, @credit_card, @options) end clean_transcript = @gateway.scrub(transcript) diff --git a/test/remote/gateways/remote_usa_epay_advanced_test.rb b/test/remote/gateways/remote_usa_epay_advanced_test.rb index 021f73d910a..83fbe0343b8 100644 --- a/test/remote/gateways/remote_usa_epay_advanced_test.rb +++ b/test/remote/gateways/remote_usa_epay_advanced_test.rb @@ -8,89 +8,89 @@ def setup @amount = 2111 @credit_card = ActiveMerchant::Billing::CreditCard.new( - :number => '4000100011112224', - :month => 9, - :year => Time.now.year + 1, - :brand => 'visa', - :verification_value => '123', - :first_name => 'Fred', - :last_name => 'Flintstone' + number: '4000100011112224', + month: 9, + year: Time.now.year + 1, + brand: 'visa', + verification_value: '123', + first_name: 'Fred', + last_name: 'Flintstone' ) @bad_credit_card = ActiveMerchant::Billing::CreditCard.new( - :number => '4000300011112220', - :month => 9, - :year => 14, - :brand => 'visa', - :verification_value => '999', - :first_name => 'Fred', - :last_name => 'Flintstone' + number: '4000300011112220', + month: 9, + year: 14, + brand: 'visa', + verification_value: '999', + first_name: 'Fred', + last_name: 'Flintstone' ) @check = ActiveMerchant::Billing::Check.new( - :account_number => '123456789', - :routing_number => '120450780', - :account_type => 'checking', - :first_name => 'Fred', - :last_name => 'Flintstone' + account_number: '123456789', + routing_number: '120450780', + account_type: 'checking', + first_name: 'Fred', + last_name: 'Flintstone' ) cc_method = [ - {:name => 'My CC', :sort => 5, :method => @credit_card}, - {:name => 'Other CC', :sort => 12, :method => @credit_card} + { name: 'My CC', sort: 5, method: @credit_card }, + { name: 'Other CC', sort: 12, method: @credit_card } ] @options = { - :client_ip => '127.0.0.1', - :billing_address => address, + client_ip: '127.0.0.1', + billing_address: address } @transaction_options = { - :order_id => '1', - :description => 'Store Purchase' + order_id: '1', + description: 'Store Purchase' } @customer_options = { - :id => 123, - :notes => 'Customer note.', - :data => 'complex data', - :url => 'somesite.com', - :payment_methods => cc_method + id: 123, + notes: 'Customer note.', + data: 'complex data', + url: 'somesite.com', + payment_methods: cc_method } @update_customer_options = { - :notes => 'NEW NOTE!' + notes: 'NEW NOTE!' } @add_payment_options = { - :make_default => true, - :payment_method => { - :name => 'My new card.', - :sort => 10, - :method => @credit_card + make_default: true, + payment_method: { + name: 'My new card.', + sort: 10, + method: @credit_card } } @run_transaction_options = { - :payment_method => @credit_card, - :command => 'sale', - :amount => 10000 + payment_method: @credit_card, + command: 'sale', + amount: 10000 } @run_transaction_check_options = { - :payment_method => @check, - :command => 'check', - :amount => 10000 + payment_method: @check, + command: 'check', + amount: 10000 } @run_sale_options = { - :payment_method => @credit_card, - :amount => 5000 + payment_method: @credit_card, + amount: 5000 } @run_check_sale_options = { - :payment_method => @check, - :amount => 2500 + payment_method: @check, + amount: 2500 } end @@ -138,10 +138,10 @@ def test_refund def test_invalid_login gateway = UsaEpayAdvancedGateway.new( - :login => '', - :password => '', - :software_id => '' - ) + login: '', + password: '', + software_id: '' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'Invalid software ID', response.message @@ -158,7 +158,7 @@ def test_update_customer response = @gateway.add_customer(@options.merge(@customer_options)) customer_number = response.params['add_customer_return'] - @options.merge!(@update_customer_options.merge!(:customer_number => customer_number)) + @options.merge!(@update_customer_options.merge!(customer_number: customer_number)) response = @gateway.update_customer(@options) assert response.params['update_customer_return'] end @@ -167,7 +167,7 @@ def test_quick_update_customer response = @gateway.add_customer(@options.merge(@customer_options)) customer_number = response.params['add_customer_return'] - response = @gateway.quick_update_customer({customer_number: customer_number, update_data: @update_customer_options}) + response = @gateway.quick_update_customer({ customer_number: customer_number, update_data: @update_customer_options }) assert response.params['quick_update_customer_return'] end @@ -175,10 +175,10 @@ def test_enable_disable_customer response = @gateway.add_customer(@options.merge(@customer_options)) customer_number = response.params['add_customer_return'] - response = @gateway.enable_customer(:customer_number => customer_number) + response = @gateway.enable_customer(customer_number: customer_number) assert response.params['enable_customer_return'] - response = @gateway.disable_customer(:customer_number => customer_number) + response = @gateway.disable_customer(customer_number: customer_number) assert response.params['disable_customer_return'] end @@ -186,7 +186,7 @@ def test_add_customer_payment_method response = @gateway.add_customer(@options.merge(@customer_options)) customer_number = response.params['add_customer_return'] - @options.merge!(:customer_number => customer_number).merge!(@add_payment_options) + @options.merge!(customer_number: customer_number).merge!(@add_payment_options) response = @gateway.add_customer_payment_method(@options) assert response.params['add_customer_payment_method_return'] end @@ -196,7 +196,7 @@ def test_add_customer_payment_method_verify customer_number = response.params['add_customer_return'] @add_payment_options[:payment_method][:method] = @bad_credit_card - @options.merge!(:customer_number => customer_number, :verify => true).merge!(@add_payment_options) + @options.merge!(customer_number: customer_number, verify: true).merge!(@add_payment_options) response = @gateway.add_customer_payment_method(@options) assert response.params['faultstring'] end @@ -205,7 +205,7 @@ def test_get_customer_payment_methods response = @gateway.add_customer(@options.merge(@customer_options)) customer_number = response.params['add_customer_return'] - response = @gateway.get_customer_payment_methods(:customer_number => customer_number) + response = @gateway.get_customer_payment_methods(customer_number: customer_number) assert response.params['get_customer_payment_methods_return']['item'] end @@ -213,10 +213,10 @@ def test_get_customer_payment_method response = @gateway.add_customer(@options.merge(@customer_options)) customer_number = response.params['add_customer_return'] - response = @gateway.get_customer_payment_methods(:customer_number => customer_number) + response = @gateway.get_customer_payment_methods(customer_number: customer_number) id = response.params['get_customer_payment_methods_return']['item'][0]['method_id'] - response = @gateway.get_customer_payment_method(:customer_number => customer_number, :method_id => id) + response = @gateway.get_customer_payment_method(customer_number: customer_number, method_id: id) assert response.params['get_customer_payment_method_return'] end @@ -224,12 +224,12 @@ def test_update_customer_payment_method response = @gateway.add_customer(@options.merge(@customer_options)) customer_number = response.params['add_customer_return'] - @options.merge!(:customer_number => customer_number).merge!(@add_payment_options) + @options.merge!(customer_number: customer_number).merge!(@add_payment_options) response = @gateway.add_customer_payment_method(@options) payment_method_id = response.params['add_customer_payment_method_return'] - update_payment_options = @add_payment_options[:payment_method].merge(:method_id => payment_method_id, - :name => 'Updated Card.') + update_payment_options = @add_payment_options[:payment_method].merge(method_id: payment_method_id, + name: 'Updated Card.') response = @gateway.update_customer_payment_method(update_payment_options) assert response.params['update_customer_payment_method_return'] @@ -239,11 +239,11 @@ def test_delete_customer_payment_method response = @gateway.add_customer(@options.merge(@customer_options)) customer_number = response.params['add_customer_return'] - @options.merge!(:customer_number => customer_number).merge!(@add_payment_options) + @options.merge!(customer_number: customer_number).merge!(@add_payment_options) response = @gateway.add_customer_payment_method(@options) id = response.params['add_customer_payment_method_return'] - response = @gateway.delete_customer_payment_method(:customer_number => customer_number, :method_id => id) + response = @gateway.delete_customer_payment_method(customer_number: customer_number, method_id: id) assert response.params['delete_customer_payment_method_return'] end @@ -251,7 +251,7 @@ def test_delete_customer response = @gateway.add_customer(@options.merge(@customer_options)) customer_number = response.params['add_customer_return'] - response = @gateway.delete_customer(:customer_number => customer_number) + response = @gateway.delete_customer(customer_number: customer_number) assert response.params['delete_customer_return'] end @@ -259,8 +259,8 @@ def test_run_customer_transaction response = @gateway.add_customer(@options.merge(@customer_options)) customer_number = response.params['add_customer_return'] - response = @gateway.run_customer_transaction(:customer_number => customer_number, # :method_id => 0, # optional - :command => 'Sale', :amount => 3000) + response = @gateway.run_customer_transaction(customer_number: customer_number, # :method_id => 0, # optional + command: 'Sale', amount: 3000) assert response.params['run_customer_transaction_return'] end @@ -322,7 +322,7 @@ def test_capture_transaction response = @gateway.run_auth_only(options) reference_number = response.params['run_auth_only_return']['ref_num'] - options = @options.merge(:reference_number => reference_number) + options = @options.merge(reference_number: reference_number) response = @gateway.capture_transaction(options) assert response.params['capture_transaction_return'] end @@ -332,7 +332,7 @@ def test_void_transaction response = @gateway.run_sale(options) reference_number = response.params['run_sale_return']['ref_num'] - options = @options.merge(:reference_number => reference_number) + options = @options.merge(reference_number: reference_number) response = @gateway.void_transaction(options) assert response.params['void_transaction_return'] end @@ -342,7 +342,7 @@ def test_refund_transaction response = @gateway.run_sale(options) reference_number = response.params['run_sale_return']['ref_num'] - options = @options.merge(:reference_number => reference_number, :amount => 0) + options = @options.merge(reference_number: reference_number, amount: 0) response = @gateway.refund_transaction(options) assert response.params['refund_transaction_return'] end @@ -353,7 +353,7 @@ def test_override_transaction response = @gateway.run_check_sale(options) reference_number = response.params['run_check_sale_return']['ref_num'] - response = @gateway.override_transaction(:reference_number => reference_number, :reason => 'Because I said so') + response = @gateway.override_transaction(reference_number: reference_number, reason: 'Because I said so') assert response.params['faultstring'] end @@ -362,7 +362,7 @@ def test_run_quick_sale response = @gateway.run_sale(@options) reference_number = response.params['run_sale_return']['ref_num'] - response = @gateway.run_quick_sale(:reference_number => reference_number, :amount => 9900) + response = @gateway.run_quick_sale(reference_number: reference_number, amount: 9900) assert response.params['run_quick_sale_return'] end @@ -371,7 +371,7 @@ def test_run_quick_sale_check response = @gateway.run_check_sale(@options) reference_number = response.params['run_check_sale_return']['ref_num'] - response = @gateway.run_quick_sale(:reference_number => reference_number, :amount => 9900) + response = @gateway.run_quick_sale(reference_number: reference_number, amount: 9900) assert response.params['run_quick_sale_return'] end @@ -380,7 +380,7 @@ def test_run_quick_credit response = @gateway.run_sale(@options) reference_number = response.params['run_sale_return']['ref_num'] - response = @gateway.run_quick_credit(:reference_number => reference_number, :amount => 0) + response = @gateway.run_quick_credit(reference_number: reference_number, amount: 0) assert response.params['run_quick_credit_return'] end @@ -389,7 +389,7 @@ def test_run_quick_credit_check response = @gateway.run_check_sale(@options) reference_number = response.params['run_check_sale_return']['ref_num'] - response = @gateway.run_quick_credit(:reference_number => reference_number, :amount => 1234) + response = @gateway.run_quick_credit(reference_number: reference_number, amount: 1234) assert response.params['run_quick_credit_return'] end @@ -399,7 +399,7 @@ def test_get_transaction response = @gateway.run_sale(@options.merge(@run_sale_options)) reference_number = response.params['run_sale_return']['ref_num'] - response = @gateway.get_transaction(:reference_number => reference_number) + response = @gateway.get_transaction(reference_number: reference_number) assert response.params['get_transaction_return'] end @@ -407,7 +407,7 @@ def test_get_transaction_status response = @gateway.run_sale(@options.merge(@run_sale_options)) reference_number = response.params['run_sale_return']['ref_num'] - response = @gateway.get_transaction_status(:reference_number => reference_number) + response = @gateway.get_transaction_status(reference_number: reference_number) assert response.params['get_transaction_status_return'] end @@ -415,11 +415,11 @@ def test_get_transaction_custom response = @gateway.run_sale(@options.merge(@run_sale_options)) reference_number = response.params['run_sale_return']['ref_num'] - response = @gateway.get_transaction_custom(:reference_number => reference_number, - :fields => ['Response.StatusCode', 'Response.Status']) + response = @gateway.get_transaction_custom(reference_number: reference_number, + fields: ['Response.StatusCode', 'Response.Status']) assert response.params['get_transaction_custom_return'] - response = @gateway.get_transaction_custom(:reference_number => reference_number, - :fields => ['Response.StatusCode']) + response = @gateway.get_transaction_custom(reference_number: reference_number, + fields: ['Response.StatusCode']) assert response.params['get_transaction_custom_return'] end @@ -427,7 +427,7 @@ def test_get_check_trace response = @gateway.run_check_sale(@options.merge(@run_check_sale_options)) reference_number = response.params['run_check_sale_return']['ref_num'] - response = @gateway.get_check_trace(:reference_number => reference_number) + response = @gateway.get_check_trace(reference_number: reference_number) assert response.params['get_check_trace_return'] end diff --git a/test/remote/gateways/remote_usa_epay_transaction_test.rb b/test/remote/gateways/remote_usa_epay_transaction_test.rb index 476b2461206..99892f13f45 100644 --- a/test/remote/gateways/remote_usa_epay_transaction_test.rb +++ b/test/remote/gateways/remote_usa_epay_transaction_test.rb @@ -8,7 +8,7 @@ def setup @credit_card_with_track_data = credit_card_with_track_data('4000100011112224') @invalid_transaction_card = credit_card('4000300511112225') @check = check - @options = { :billing_address => address(:zip => '27614', :state => 'NC'), :shipping_address => address } + @options = { billing_address: address(zip: '27614', state: 'NC'), shipping_address: address } @amount = 100 end @@ -52,19 +52,19 @@ def test_successful_purchase_with_manual_entry end def test_successful_purchase_with_extra_details - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:order_id => generate_unique_id, :description => 'socool')) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(order_id: generate_unique_id, description: 'socool')) assert_equal 'Success', response.message assert_success response end def test_successful_purchase_with_extra_test_mode - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:test_mode => true)) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(test_mode: true)) assert_equal 'Success', response.message assert_success response end def test_successful_purchase_with_email_receipt - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:email => 'hank@hill.com', :cust_receipt => 'Yes')) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(email: 'hank@hill.com', cust_receipt: 'Yes')) assert_equal 'Success', response.message assert_success response end @@ -100,8 +100,8 @@ def test_successful_purchase_with_custom_fields def test_successful_purchase_with_line_items line_items = [ - {sku: 'abc123', cost: 119, quantity: 1}, - {sku: 'def456', cost: 200, quantity: 2, name: 'an item' } + { sku: 'abc123', cost: 119, quantity: 1 }, + { sku: 'def456', cost: 200, quantity: 2, name: 'an item' } ] assert response = @gateway.purchase(@amount, @credit_card, @options.merge(line_items: line_items)) @@ -113,7 +113,7 @@ def test_unsuccessful_purchase # For some reason this will fail with "You have tried this card too # many times, please contact merchant" unless a unique order id is # passed. - assert response = @gateway.purchase(@amount, @declined_card, @options.merge(:order_id => generate_unique_id)) + assert response = @gateway.purchase(@amount, @declined_card, @options.merge(order_id: generate_unique_id)) assert_failure response assert_match(/declined/i, response.message) assert Gateway::STANDARD_ERROR_CODE[:card_declined], response.error_code @@ -209,7 +209,7 @@ def test_unsuccessful_void_release end def test_invalid_key - gateway = UsaEpayTransactionGateway.new(:login => '') + gateway = UsaEpayTransactionGateway.new(login: '') assert response = gateway.purchase(@amount, @credit_card, @options) assert_equal 'Specified source key not found.', response.message assert_failure response diff --git a/test/remote/gateways/remote_vanco_test.rb b/test/remote/gateways/remote_vanco_test.rb index 077b9b1a248..1e8041c05e1 100644 --- a/test/remote/gateways/remote_vanco_test.rb +++ b/test/remote/gateways/remote_vanco_test.rb @@ -73,7 +73,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - refund = @gateway.refund(@amount-1, purchase.authorization) + refund = @gateway.refund(@amount - 1, purchase.authorization) assert_success refund end @@ -81,7 +81,7 @@ def test_failed_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - refund = @gateway.refund(@amount+500, purchase.authorization) + refund = @gateway.refund(@amount + 500, purchase.authorization) assert_failure refund assert_match(/Amount Cannot Be Greater Than/, refund.message) end diff --git a/test/remote/gateways/remote_verifi_test.rb b/test/remote/gateways/remote_verifi_test.rb index 2514864a96f..8cb815df077 100644 --- a/test/remote/gateways/remote_verifi_test.rb +++ b/test/remote/gateways/remote_verifi_test.rb @@ -10,9 +10,9 @@ def setup # Replace with your login and password for the Verifi test environment @options = { - :order_id => '37', - :email => 'test@example.com', - :billing_address => address + order_id: '37', + email: 'test@example.com', + billing_address: address } @amount = 100 @@ -85,8 +85,8 @@ def test_purchase_and_credit def test_bad_login gateway = VerifiGateway.new( - :login => 'X', - :password => 'Y' + login: 'X', + password: 'Y' ) assert response = gateway.purchase(@amount, @credit_card, @options) diff --git a/test/remote/gateways/remote_viaklix_test.rb b/test/remote/gateways/remote_viaklix_test.rb index c3dc47c1a43..c4d4c63094a 100644 --- a/test/remote/gateways/remote_viaklix_test.rb +++ b/test/remote/gateways/remote_viaklix_test.rb @@ -8,10 +8,10 @@ def setup @bad_credit_card = credit_card('invalid') @options = { - :order_id => '#1000.1', - :email => 'paul@domain.com', - :description => 'Test Transaction', - :billing_address => address + order_id: '#1000.1', + email: 'paul@domain.com', + description: 'Test Transaction', + billing_address: address } @amount = 100 end diff --git a/test/remote/gateways/remote_visanet_peru_test.rb b/test/remote/gateways/remote_visanet_peru_test.rb index 950705e68b5..9309d63a622 100644 --- a/test/remote/gateways/remote_visanet_peru_test.rb +++ b/test/remote/gateways/remote_visanet_peru_test.rb @@ -58,7 +58,7 @@ def test_successful_authorize_and_capture assert_equal @options[:order_id], response.params['externalTransactionId'] assert_equal '1.00', response.params['data']['IMP_AUTORIZADO'] - capture = @gateway.capture(response.authorization, @options) + capture = @gateway.capture(@amount, response.authorization, @options) assert_success capture assert_equal 'OK', capture.message assert capture.authorization @@ -91,7 +91,7 @@ def test_failed_authorize_bad_email end def test_failed_capture - response = @gateway.capture('900000044') + response = @gateway.capture(@amount, '900000044') assert_failure response assert_match(/NUMORDEN 900000044 no se encuentra registrado/, response.message) assert_equal 400, response.error_code diff --git a/test/remote/gateways/remote_webpay_test.rb b/test/remote/gateways/remote_webpay_test.rb index 3b0e099ea33..42662e25e8e 100644 --- a/test/remote/gateways/remote_webpay_test.rb +++ b/test/remote/gateways/remote_webpay_test.rb @@ -3,7 +3,6 @@ require 'test_helper' class RemoteWebpayTest < Test::Unit::TestCase - def setup @gateway = WebpayGateway.new(fixtures(:webpay)) @@ -14,8 +13,8 @@ def setup @new_credit_card = credit_card('5105105105105100') @options = { - :description => 'ActiveMerchant Test Purchase', - :email => 'wow@example.com' + description: 'ActiveMerchant Test Purchase', + email: 'wow@example.com' } end @@ -33,13 +32,13 @@ def test_appropriate_purchase_amount end def test_purchase_description - assert response = @gateway.purchase(@amount, @credit_card, { :description => 'TheDescription', :email => 'email@example.com' }) + assert response = @gateway.purchase(@amount, @credit_card, { description: 'TheDescription', email: 'email@example.com' }) assert_equal 'TheDescription', response.params['description'], "Use the description if it's specified." - assert response = @gateway.purchase(@amount, @credit_card, { :email => 'email@example.com' }) + assert response = @gateway.purchase(@amount, @credit_card, { email: 'email@example.com' }) assert_equal 'email@example.com', response.params['description'], 'Use the email if no description is specified.' - assert response = @gateway.purchase(@amount, @credit_card, { }) + assert response = @gateway.purchase(@amount, @credit_card, {}) assert_nil response.params['description'], 'No description or email specified.' end @@ -105,7 +104,7 @@ def test_unsuccessful_refund end def test_successful_store - assert response = @gateway.store(@credit_card, {:description => 'Active Merchant Test Customer', :email => 'email@example.com'}) + assert response = @gateway.store(@credit_card, { description: 'Active Merchant Test Customer', email: 'email@example.com' }) assert_success response assert_equal 'customer', response.params['object'] assert_equal 'Active Merchant Test Customer', response.params['description'] @@ -114,7 +113,7 @@ def test_successful_store end def test_successful_update - creation = @gateway.store(@credit_card, {:description => 'Active Merchant Update Customer'}) + creation = @gateway.store(@credit_card, { description: 'Active Merchant Update Customer' }) assert response = @gateway.update(creation.params['id'], @new_credit_card) assert_success response assert_equal 'Active Merchant Update Customer', response.params['description'] @@ -122,17 +121,16 @@ def test_successful_update end def test_successful_unstore - creation = @gateway.store(@credit_card, {:description => 'Active Merchant Unstore Customer'}) + creation = @gateway.store(@credit_card, { description: 'Active Merchant Unstore Customer' }) assert response = @gateway.unstore(creation.params['id']) assert_success response assert_equal true, response.params['deleted'] end def test_invalid_login - gateway = WebpayGateway.new(:login => 'active_merchant_test') + gateway = WebpayGateway.new(login: 'active_merchant_test') assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'Invalid API key provided. Check your API key is correct.', response.message end - end diff --git a/test/remote/gateways/remote_wepay_test.rb b/test/remote/gateways/remote_wepay_test.rb index 4a1b01f061d..a227956ddec 100644 --- a/test/remote/gateways/remote_wepay_test.rb +++ b/test/remote/gateways/remote_wepay_test.rb @@ -128,7 +128,7 @@ def test_unsuccessful_store_via_create_with_cvv # end def test_successful_store_with_defaulted_email - response = @gateway.store(@credit_card, {billing_address: address}) + response = @gateway.store(@credit_card, { billing_address: address }) assert_success response end @@ -169,7 +169,7 @@ def test_authorize_and_capture authorize = @gateway.authorize(@amount, @credit_card, @options) assert_success authorize - sleep 30 # Wait for authorization to clear. Doesn't always work. + sleep 30 # Wait for authorization to clear. Doesn't always work. assert capture = @gateway.capture(nil, authorize.authorization) assert_success capture end diff --git a/test/remote/gateways/remote_wirecard_test.rb b/test/remote/gateways/remote_wirecard_test.rb index 586e1567351..213d037d231 100644 --- a/test/remote/gateways/remote_wirecard_test.rb +++ b/test/remote/gateways/remote_wirecard_test.rb @@ -119,14 +119,14 @@ def test_successful_purchase_with_german_address_german_state_and_german_phone end def test_successful_purchase_with_german_address_no_state_and_invalid_phone - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(billing_address: @german_address.merge({state: nil, phone: '1234'}))) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(billing_address: @german_address.merge({ state: nil, phone: '1234' }))) assert_success response assert response.message[/THIS IS A DEMO/] end def test_successful_purchase_with_german_address_and_valid_phone - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(billing_address: @german_address.merge({phone: '+049-261-1234-123'}))) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(billing_address: @german_address.merge({ phone: '+049-261-1234-123' }))) assert_success response assert response.message[/THIS IS A DEMO/] @@ -190,13 +190,13 @@ def test_successful_store_then_purchase_by_reference end def test_successful_authorization_as_recurring_transaction_type_initial - assert response = @gateway.authorize(@amount, @credit_card, @options.merge(:recurring => 'Initial')) + assert response = @gateway.authorize(@amount, @credit_card, @options.merge(recurring: 'Initial')) assert_success response assert response.authorization end def test_successful_purchase_as_recurring_transaction_type_initial - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:recurring => 'Initial')) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(recurring: 'Initial')) assert_success response assert response.authorization end @@ -258,7 +258,7 @@ def test_invalid_login def test_transcript_scrubbing transcript = capture_transcript(@gateway) do - @gateway.purchase(@amount, @credit_card, @options) + @gateway.purchase(@amount, @credit_card, @options) end clean_transcript = @gateway.scrub(transcript) diff --git a/test/remote/gateways/remote_world_net_test.rb b/test/remote/gateways/remote_world_net_test.rb index 67d198f1fbf..d7db06354fd 100644 --- a/test/remote/gateways/remote_world_net_test.rb +++ b/test/remote/gateways/remote_world_net_test.rb @@ -8,7 +8,7 @@ def setup @declined_amount = 101 @credit_card = credit_card('3779810000000005') @options = { - order_id: generate_order_id, + order_id: generate_order_id } @refund_options = { operator: 'mr.nobody', @@ -28,7 +28,7 @@ def test_successful_purchase_with_more_options email: 'joe@example.com', billing_address: address, description: 'Store Purchase', - ip: '127.0.0.1', + ip: '127.0.0.1' } response = @gateway.purchase(@amount, @credit_card, options) @@ -72,7 +72,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -95,7 +95,7 @@ def test_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - assert refund = @gateway.refund(@amount-1, purchase.authorization, @refund_options) + assert refund = @gateway.refund(@amount - 1, purchase.authorization, @refund_options) assert_success refund end diff --git a/test/remote/gateways/remote_worldpay_online_payments_test.rb b/test/remote/gateways/remote_worldpay_online_payments_test.rb index 4f0b2ff05c2..bcb99f603fa 100644 --- a/test/remote/gateways/remote_worldpay_online_payments_test.rb +++ b/test/remote/gateways/remote_worldpay_online_payments_test.rb @@ -67,7 +67,7 @@ def test_partial_capture auth = @gateway.authorize(@amount, @credit_card, @options) assert_success auth - assert capture = @gateway.capture(@amount-1, auth.authorization) + assert capture = @gateway.capture(@amount - 1, auth.authorization) assert_success capture end @@ -104,7 +104,7 @@ def test_failed_partial_refund purchase = @gateway.purchase(@amount, @credit_card, @options) assert_success purchase - refund = @gateway.refund(@amount+1, purchase.authorization) + refund = @gateway.refund(@amount + 1, purchase.authorization) assert_failure refund end diff --git a/test/remote/gateways/remote_worldpay_test.rb b/test/remote/gateways/remote_worldpay_test.rb index 66b29c40f56..2dea6bc860e 100644 --- a/test/remote/gateways/remote_worldpay_test.rb +++ b/test/remote/gateways/remote_worldpay_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class RemoteWorldpayTest < Test::Unit::TestCase - def setup @gateway = WorldpayGateway.new(fixtures(:world_pay_gateway)) @cftgateway = WorldpayGateway.new(fixtures(:world_pay_gateway_cft)) @@ -9,20 +8,19 @@ def setup @amount = 100 @credit_card = credit_card('4111111111111111') @elo_credit_card = credit_card('4514 1600 0000 0008', - :month => 10, - :year => 2020, - :first_name => 'John', - :last_name => 'Smith', - :verification_value => '737', - :brand => 'elo' - ) + month: 10, + year: 2020, + first_name: 'John', + last_name: 'Smith', + verification_value: '737', + brand: 'elo') @cabal_card = credit_card('6035220000000006') @naranja_card = credit_card('5895620000000002') @sodexo_voucher = credit_card('6060704495764400', brand: 'sodexo') - @declined_card = credit_card('4111111111111111', :first_name => nil, :last_name => 'REFUSED') - @threeDS_card = credit_card('4111111111111111', :first_name => nil, :last_name => '3D') - @threeDS2_card = credit_card('4111111111111111', :first_name => nil, :last_name => '3DS_V2_FRICTIONLESS_IDENTIFIED') - @threeDS_card_external_MPI = credit_card('4444333322221111', :first_name => 'AA', :last_name => 'BD') + @declined_card = credit_card('4111111111111111', first_name: nil, last_name: 'REFUSED') + @threeDS_card = credit_card('4111111111111111', first_name: nil, last_name: '3D') + @threeDS2_card = credit_card('4111111111111111', first_name: nil, last_name: '3DS_V2_FRICTIONLESS_IDENTIFIED') + @threeDS_card_external_MPI = credit_card('4444333322221111', first_name: 'AA', last_name: 'BD') @options = { order_id: generate_unique_id, @@ -58,8 +56,15 @@ def test_successful_purchase_with_naranja assert_equal 'SUCCESS', response.message end + def test_successful_purchase_skipping_capture + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(skip_capture: true)) + assert_success response + assert response.responses.length == 1 + assert_equal 'SUCCESS', response.message + end + def test_successful_authorize_avs_and_cvv - card = credit_card('4111111111111111', :verification_value => 555) + card = credit_card('4111111111111111', verification_value: 555) assert response = @gateway.authorize(@amount, card, @options.merge(billing_address: address.update(zip: 'CCCC'))) assert_success response assert_equal 'SUCCESS', response.message @@ -68,7 +73,21 @@ def test_successful_authorize_avs_and_cvv end def test_successful_3ds2_authorize - options = @options.merge({execute_threed: true, three_ds_version: '2.0'}) + options = @options.merge({ execute_threed: true, three_ds_version: '2.0' }) + assert response = @gateway.authorize(@amount, @threeDS2_card, options) + assert_success response + assert_equal 'SUCCESS', response.message + end + + def test_successful_3ds2_authorize_with_browser_size + options = @options.merge({ execute_threed: true, three_ds_version: '2.0', browser_size: '390x400' }) + assert response = @gateway.authorize(@amount, @threeDS2_card, options) + assert_success response + assert_equal 'SUCCESS', response.message + end + + def test_successful_authorize_with_risk_data + options = @options.merge({ execute_threed: true, three_ds_version: '2.0', risk_data: risk_data }) assert response = @gateway.authorize(@amount, @threeDS2_card, options) assert_success response assert_equal 'SUCCESS', response.message @@ -148,14 +167,15 @@ def test_authorize_and_purchase_with_instalments def test_successful_authorize_with_3ds session_id = generate_unique_id options = @options.merge( - { - execute_threed: true, - accept_header: 'text/html', - user_agent: 'Mozilla/5.0', - session_id: session_id, - ip: '127.0.0.1', - cookie: 'machine=32423423' - }) + { + execute_threed: true, + accept_header: 'text/html', + user_agent: 'Mozilla/5.0', + session_id: session_id, + ip: '127.0.0.1', + cookie: 'machine=32423423' + } + ) assert first_message = @gateway.authorize(@amount, @threeDS_card, options) assert_equal "A transaction status of 'AUTHORISED' is required.", first_message.message assert first_message.test? @@ -181,7 +201,7 @@ def test_successful_auth_and_capture_with_normalized_stored_credential network_transaction_id: nil } - assert auth = @gateway.authorize(@amount, @credit_card, @options.merge({stored_credential: stored_credential_params})) + assert auth = @gateway.authorize(@amount, @credit_card, @options.merge({ stored_credential: stored_credential_params })) assert_success auth assert auth.authorization assert auth.params['scheme_response'] @@ -241,15 +261,16 @@ def test_successful_authorize_with_3ds_with_normalized_stored_credentials network_transaction_id: nil } options = @options.merge( - { - execute_threed: true, - accept_header: 'text/html', - user_agent: 'Mozilla/5.0', - session_id: session_id, - ip: '127.0.0.1', - cookie: 'machine=32423423', - stored_credential: stored_credential_params - }) + { + execute_threed: true, + accept_header: 'text/html', + user_agent: 'Mozilla/5.0', + session_id: session_id, + ip: '127.0.0.1', + cookie: 'machine=32423423', + stored_credential: stored_credential_params + } + ) assert first_message = @gateway.authorize(@amount, @threeDS_card, options) assert_equal "A transaction status of 'AUTHORISED' is required.", first_message.message assert first_message.test? @@ -263,15 +284,16 @@ def test_successful_authorize_with_3ds_with_normalized_stored_credentials def test_successful_authorize_with_3ds_with_gateway_specific_stored_credentials session_id = generate_unique_id options = @options.merge( - { - execute_threed: true, - accept_header: 'text/html', - user_agent: 'Mozilla/5.0', - session_id: session_id, - ip: '127.0.0.1', - cookie: 'machine=32423423', - stored_credential_usage: 'FIRST' - }) + { + execute_threed: true, + accept_header: 'text/html', + user_agent: 'Mozilla/5.0', + session_id: session_id, + ip: '127.0.0.1', + cookie: 'machine=32423423', + stored_credential_usage: 'FIRST' + } + ) assert first_message = @gateway.authorize(@amount, @threeDS_card, options) assert_equal "A transaction status of 'AUTHORISED' is required.", first_message.message assert first_message.test? @@ -306,13 +328,14 @@ def test_successful_authorize_with_3ds_with_gateway_specific_stored_credentials def test_failed_authorize_with_3ds session_id = generate_unique_id options = @options.merge( - { - execute_threed: true, - accept_header: 'text/html', - session_id: session_id, - ip: '127.0.0.1', - cookie: 'machine=32423423' - }) + { + execute_threed: true, + accept_header: 'text/html', + session_id: session_id, + ip: '127.0.0.1', + cookie: 'machine=32423423' + } + ) assert first_message = @gateway.authorize(@amount, @threeDS_card, options) assert_match %r{missing info for 3D-secure transaction}i, first_message.message assert first_message.test? @@ -363,7 +386,7 @@ def test_failed_capture end def test_billing_address - assert_success @gateway.authorize(@amount, @credit_card, @options.merge(:billing_address => address)) + assert_success @gateway.authorize(@amount, @credit_card, @options.merge(billing_address: address)) end def test_partial_address @@ -371,7 +394,13 @@ def test_partial_address billing_address.delete(:address1) billing_address.delete(:zip) billing_address.delete(:country) - assert_success @gateway.authorize(@amount, @credit_card, @options.merge(:billing_address => billing_address)) + assert_success @gateway.authorize(@amount, @credit_card, @options.merge(billing_address: billing_address)) + end + + def test_state_omitted + billing_address = address + billing_address.delete(:state) + assert_success @gateway.authorize(@amount, @credit_card, @options.merge(billing_address: billing_address)) end def test_ip_address @@ -398,21 +427,21 @@ def test_void_nonexistent_transaction end def test_authorize_fractional_currency - assert_success(result = @gateway.authorize(1234, @credit_card, @options.merge(:currency => 'USD'))) + assert_success(result = @gateway.authorize(1234, @credit_card, @options.merge(currency: 'USD'))) assert_equal 'USD', result.params['amount_currency_code'] assert_equal '1234', result.params['amount_value'] assert_equal '2', result.params['amount_exponent'] end def test_authorize_nonfractional_currency - assert_success(result = @gateway.authorize(1234, @credit_card, @options.merge(:currency => 'IDR'))) + assert_success(result = @gateway.authorize(1234, @credit_card, @options.merge(currency: 'IDR'))) assert_equal 'IDR', result.params['amount_currency_code'] assert_equal '12', result.params['amount_value'] assert_equal '0', result.params['amount_exponent'] end def test_authorize_three_decimal_currency - assert_success(result = @gateway.authorize(1234, @credit_card, @options.merge(:currency => 'OMR'))) + assert_success(result = @gateway.authorize(1234, @credit_card, @options.merge(currency: 'OMR'))) assert_equal 'OMR', result.params['amount_currency_code'] assert_equal '1234', result.params['amount_value'] assert_equal '3', result.params['amount_exponent'] @@ -420,11 +449,11 @@ def test_authorize_three_decimal_currency def test_reference_transaction assert_success(original = @gateway.authorize(100, @credit_card, @options)) - assert_success(@gateway.authorize(200, original.authorization, :order_id => generate_unique_id)) + assert_success(@gateway.authorize(200, original.authorization, order_id: generate_unique_id)) end def test_invalid_login - gateway = WorldpayGateway.new(:login => '', :password => '') + gateway = WorldpayGateway.new(login: '', password: '') assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert_equal 'Invalid credentials', response.message @@ -477,7 +506,7 @@ def test_successful_mastercard_credit_on_cft_gateway def test_transcript_scrubbing transcript = capture_transcript(@gateway) do - @gateway.purchase(@amount, @credit_card, @options) + @gateway.purchase(@amount, @credit_card, @options) end clean_transcript = @gateway.scrub(transcript) @@ -554,6 +583,12 @@ def test_successful_store assert_match @store_options[:customer], response.authorization end + def test_successful_purchase_with_statement_narrative + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(statement_narrative: 'Merchant Statement Narrative')) + assert_success response + assert_equal 'SUCCESS', response.message + end + def test_successful_authorize_using_token assert store = @gateway.store(@credit_card, @store_options) assert_success store @@ -632,4 +667,89 @@ def test_failed_verify_using_token assert_equal '5', response.error_code assert_match %r{REFUSED}, response.message end + + private + + def risk_data + return @risk_data if @risk_data + + authentication_time = Time.now + shopper_account_creation_date = Date.today + shopper_account_modification_date = Date.today - 1.day + shopper_account_password_change_date = Date.today - 2.days + shopper_account_shipping_address_first_use_date = Date.today - 3.day + shopper_account_payment_account_first_use_date = Date.today - 4.day + transaction_risk_data_pre_order_date = Date.today + 1.day + + @risk_data = { + authentication_risk_data: { + authentication_method: 'localAccount', + authentication_date: { + day_of_month: authentication_time.strftime('%d'), + month: authentication_time.strftime('%m'), + year: authentication_time.strftime('%Y'), + hour: authentication_time.strftime('%H'), + minute: authentication_time.strftime('%M'), + second: authentication_time.strftime('%S') + } + }, + shopper_account_risk_data: { + transactions_attempted_last_day: '1', + transactions_attempted_last_year: '2', + purchases_completed_last_six_months: '3', + add_card_attempts_last_day: '4', + previous_suspicious_activity: 'false', # Boolean (true or false) + shipping_name_matches_account_name: 'true', # Boolean (true or false) + shopper_account_age_indicator: 'lessThanThirtyDays', # Possible Values: noAccount, createdDuringTransaction, lessThanThirtyDays, thirtyToSixtyDays, moreThanSixtyDays + shopper_account_change_indicator: 'thirtyToSixtyDays', # Possible values: changedDuringTransaction, lessThanThirtyDays, thirtyToSixtyDays, moreThanSixtyDays + shopper_account_password_change_indicator: 'noChange', # Possible Values: noChange, changedDuringTransaction, lessThanThirtyDays, thirtyToSixtyDays, moreThanSixtyDays + shopper_account_shipping_address_usage_indicator: 'moreThanSixtyDays', # Possible Values: thisTransaction, lessThanThirtyDays, thirtyToSixtyDays, moreThanSixtyDays + shopper_account_payment_account_indicator: 'thirtyToSixtyDays', # Possible Values: noAccount, duringTransaction, lessThanThirtyDays, thirtyToSixtyDays, moreThanSixtyDays + shopper_account_creation_date: { + day_of_month: shopper_account_creation_date.strftime('%d'), + month: shopper_account_creation_date.strftime('%m'), + year: shopper_account_creation_date.strftime('%Y') + }, + shopper_account_modification_date: { + day_of_month: shopper_account_modification_date.strftime('%d'), + month: shopper_account_modification_date.strftime('%m'), + year: shopper_account_modification_date.strftime('%Y') + }, + shopper_account_password_change_date: { + day_of_month: shopper_account_password_change_date.strftime('%d'), + month: shopper_account_password_change_date.strftime('%m'), + year: shopper_account_password_change_date.strftime('%Y') + }, + shopper_account_shipping_address_first_use_date: { + day_of_month: shopper_account_shipping_address_first_use_date.strftime('%d'), + month: shopper_account_shipping_address_first_use_date.strftime('%m'), + year: shopper_account_shipping_address_first_use_date.strftime('%Y') + }, + shopper_account_payment_account_first_use_date: { + day_of_month: shopper_account_payment_account_first_use_date.strftime('%d'), + month: shopper_account_payment_account_first_use_date.strftime('%m'), + year: shopper_account_payment_account_first_use_date.strftime('%Y') + } + }, + transaction_risk_data: { + shipping_method: 'digital', + delivery_timeframe: 'electronicDelivery', + delivery_email_address: 'abe@lincoln.gov', + reordering_previous_purchases: 'false', + pre_order_purchase: 'false', + gift_card_count: '0', + transaction_risk_data_gift_card_amount: { + value: '123', + currency: 'EUR', + exponent: '2', + debit_credit_indicator: 'credit' + }, + transaction_risk_data_pre_order_date: { + day_of_month: transaction_risk_data_pre_order_date.strftime('%d'), + month: transaction_risk_data_pre_order_date.strftime('%m'), + year: transaction_risk_data_pre_order_date.strftime('%Y') + } + } + } + end end diff --git a/test/remote/gateways/remote_worldpay_us_test.rb b/test/remote/gateways/remote_worldpay_us_test.rb index a0e50945fa6..29cce46d447 100644 --- a/test/remote/gateways/remote_worldpay_us_test.rb +++ b/test/remote/gateways/remote_worldpay_us_test.rb @@ -5,9 +5,9 @@ def setup @gateway = WorldpayUsGateway.new(fixtures(:worldpay_us)) @amount = 100 - @credit_card = credit_card('4446661234567892', :verification_value => '987') + @credit_card = credit_card('4446661234567892', verification_value: '987') @declined_card = credit_card('4000300011112220') - @check = check(:number => '12345654321') + @check = check(number: '12345654321') @options = { order_id: generate_unique_id, @@ -23,7 +23,7 @@ def test_successful_purchase end def test_successful_purchase_on_backup_url - gateway = WorldpayUsGateway.new(fixtures(:worldpay_us).merge({ use_backup_url: true})) + gateway = WorldpayUsGateway.new(fixtures(:worldpay_us).merge({ use_backup_url: true })) response = gateway.purchase(@amount, @credit_card, @options) assert_success response assert_equal 'Succeeded', response.message @@ -101,16 +101,16 @@ def test_failed_verify end def test_passing_billing_address - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:billing_address => address)) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(billing_address: address)) assert_success response end def test_invalid_login gateway = WorldpayUsGateway.new( - :acctid => '', - :subid => '', - :merchantpin => '' - ) + acctid: '', + subid: '', + merchantpin: '' + ) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response assert response.message =~ /DECLINED/ diff --git a/test/schema/cyber_source/CyberSourceTransaction_1.159.xsd b/test/schema/cyber_source/CyberSourceTransaction_1.164.xsd similarity index 95% rename from test/schema/cyber_source/CyberSourceTransaction_1.159.xsd rename to test/schema/cyber_source/CyberSourceTransaction_1.164.xsd index d388650f072..8333412b1a0 100644 --- a/test/schema/cyber_source/CyberSourceTransaction_1.159.xsd +++ b/test/schema/cyber_source/CyberSourceTransaction_1.164.xsd @@ -1,5 +1,5 @@ - + @@ -155,6 +155,10 @@ + + + + @@ -204,7 +208,20 @@ + + + + + + + + + + + + + @@ -244,6 +261,8 @@ + + @@ -443,6 +462,23 @@ + + + + + + + + + + + + + + + + + @@ -455,6 +491,9 @@ + + + @@ -1121,6 +1160,14 @@ + + + + + + + + @@ -1154,6 +1201,8 @@ + + @@ -1201,18 +1250,28 @@ - - - - + + + + + + + + + + + + + + @@ -1231,6 +1290,7 @@ + @@ -1367,6 +1427,12 @@ + + + + + + @@ -1958,6 +2024,8 @@ type="tns:ECCreditService" minOccurs="0" /> + + @@ -2307,6 +2376,8 @@ + + @@ -2358,6 +2429,7 @@ + @@ -2585,6 +2657,13 @@ + + + + + + + @@ -2609,6 +2688,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2627,6 +2734,23 @@ + + + + + + + + + + + + + + + + + @@ -3010,6 +3134,9 @@ + + + @@ -3386,7 +3513,8 @@ - + + @@ -3495,7 +3623,17 @@ + + + + + + + + + + @@ -3560,6 +3698,7 @@ + @@ -3803,6 +3942,7 @@ + @@ -3838,6 +3978,7 @@ + @@ -4345,6 +4486,7 @@ + @@ -4355,7 +4497,7 @@ - + @@ -4551,6 +4693,7 @@ + @@ -4559,6 +4702,7 @@ + @@ -4907,6 +5051,8 @@ + + @@ -4920,7 +5066,6 @@ - @@ -4928,5 +5073,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/schema/orbital/Request_PTI83.xsd b/test/schema/orbital/Request_PTI83.xsd new file mode 100644 index 00000000000..e2d7e825180 --- /dev/null +++ b/test/schema/orbital/Request_PTI83.xsd @@ -0,0 +1,1142 @@ + + + + + Top level element for all XML request transaction types + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + New order Transaction Types + + + + + + Auth Only No Capture + + + + + Auth and Capture + + + + + Force Auth No Capture and no online authorization + + + + + Force Auth No Capture and no online authorization + + + + + Force Auth and Capture no online authorization + + + + + Refund and Capture no online authorization + + + + + + + New order Industry Types + + + + + + Ecommerce transaction + + + + + Recurring Payment transaction + + + + + Mail Order Telephone Order transaction + + + + + Interactive Voice Response + + + + + Interactive Voice Response + + + + + + + + + + + + Tax not provided + + + + + Tax included + + + + + Non-taxable transaction + + + + + + + + + + + + + + + + + Stratus + + + + + Tandam + + + + + + + + + + + + No mapping to order data + + + + + Use customer reference for OrderID + + + + + Use customer reference for both Order Id and Order Description + + + + + Use customer reference for Order Description + + + + + + + + + + + + + + + + + + + Auto Generate the CustomerRefNum + + + + + Use OrderID as the CustomerRefNum + + + + + Use CustomerRefNum Element + + + + + Use the description as the CustomerRefNum + + + + + Ignore. We will Ignore this entry if it's passed in the XML + + + + + + + + + + + + + + + + + + + American Express + + + + + Carte Blanche + + + + + Diners Club + + + + + Discover + + + + + GE Twinpay Credit + + + + + GECC Private Label Credit + + + + + JCB + + + + + Mastercard + + + + + Visa + + + + + GE Twinpay Debit + + + + + Switch / Solo + + + + + Electronic Check + + + + + Flex Cache + + + + + European Direct Debit + + + + + Bill Me Later + + + + + PINLess Debit + + + + + International Maestro + + + + + ChaseNet Credit + + + + + ChaseNet Signature Debit + + + + + + + + + + + + + + + + + + + Credit Card + + + + + Swith/Solo + + + + + Electronic Check + + + + + PINLess Debit + + + + + European Direct Debit + + + + + International Maestro + + + + + Chasenet Credit + + + + + Chasenet Signature Debit + + + + + Auto Assign + + + + + Use Token as Account Number + + + + + + + + + + + + + + + + + + + United States + + + + + Canada + + + + + Germany + + + + + Great Britain + + + + + + + + + + + + + + + + + Yes + + + + + Yes + + + + + No + + + + + No + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + First Recurring Transaction + + + + + Subsequent Recurring Transactions + + + + + First Installment Transaction + + + + + Subsequent Installment Transactions + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/support/mercury_helper.rb b/test/support/mercury_helper.rb index a8afafa25e5..6641b95633a 100644 --- a/test/support/mercury_helper.rb +++ b/test/support/mercury_helper.rb @@ -46,7 +46,7 @@ def hashify_xml!(xml, response) private - def close_batch(gateway=@gateway) + def close_batch(gateway = @gateway) gateway = ActiveMerchant::Billing::MercuryGateway.new(gateway.options) gateway.extend(BatchClosing) gateway.close_batch diff --git a/test/test_helper.rb b/test/test_helper.rb index 361857a3afb..44dfb10f62d 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,4 +1,4 @@ -$:.unshift File.expand_path('../../lib', __FILE__) +$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) require 'bundler/setup' @@ -31,7 +31,7 @@ class SubclassGateway < SimpleTestGateway module ActiveMerchant module Assertions - AssertionClass = defined?(Minitest) ? MiniTest::Assertion : Test::Unit::AssertionFailedError + ASSERTION_CLASS = defined?(Minitest) ? MiniTest::Assertion : Test::Unit::AssertionFailedError def assert_field(field, value) clean_backtrace do @@ -68,20 +68,20 @@ def assert_false(boolean, message = nil) # # A message will automatically show the inspection of the response # object if things go afoul. - def assert_success(response, message=nil) + def assert_success(response, message = nil) clean_backtrace do assert response.success?, build_message(nil, "#{message + "\n" if message}Response expected to succeed: ", response) end end # The negative of +assert_success+ - def assert_failure(response, message=nil) + def assert_failure(response, message = nil) clean_backtrace do assert !response.success?, build_message(nil, "#{message + "\n" if message}Response expected to fail: ", response) end end - def assert_valid(model, message=nil) + def assert_valid(model, message = nil) errors = model.validate clean_backtrace do @@ -101,7 +101,7 @@ def assert_not_valid(model) errors end - def assert_deprecation_warning(message=nil) + def assert_deprecation_warning(message = nil) ActiveMerchant.expects(:deprecated).with(message || anything) yield end @@ -129,14 +129,14 @@ def assert_scrubbed(unexpected_value, transcript) def clean_backtrace(&block) yield - rescue AssertionClass => e + rescue ASSERTION_CLASS => e path = File.expand_path(__FILE__) - raise AssertionClass, e.message, (e.backtrace.reject { |line| File.expand_path(line) =~ /#{path}/ }) + raise ASSERTION_CLASS, e.message, (e.backtrace.reject { |line| File.expand_path(line).match?(/#{path}/) }) end end module Fixtures - HOME_DIR = RUBY_PLATFORM =~ /mswin32/ ? ENV['HOMEPATH'] : ENV['HOME'] unless defined?(HOME_DIR) + HOME_DIR = RUBY_PLATFORM.match?('mswin32') ? ENV['HOMEPATH'] : ENV['HOME'] unless defined?(HOME_DIR) LOCAL_CREDENTIALS = File.join(HOME_DIR.to_s, '.active_merchant/fixtures.yml') unless defined?(LOCAL_CREDENTIALS) DEFAULT_CREDENTIALS = File.join(File.dirname(__FILE__), 'fixtures.yml') unless defined?(DEFAULT_CREDENTIALS) @@ -152,13 +152,13 @@ def formatted_expiration_date(credit_card) def credit_card(number = '4242424242424242', options = {}) defaults = { - :number => number, - :month => default_expiration_date.month, - :year => default_expiration_date.year, - :first_name => 'Longbob', - :last_name => 'Longsen', - :verification_value => options[:verification_value] || '123', - :brand => 'visa' + number: number, + month: default_expiration_date.month, + year: default_expiration_date.year, + first_name: 'Longbob', + last_name: 'Longsen', + verification_value: options[:verification_value] || '123', + brand: 'visa' }.update(options) Billing::CreditCard.new(defaults) @@ -168,7 +168,7 @@ def credit_card_with_track_data(number = '4242424242424242', options = {}) exp_date = default_expiration_date.strftime('%y%m') defaults = { - :track_data => "%B#{number}^LONGSEN/L. ^#{exp_date}1200000000000000**123******?", + track_data: "%B#{number}^LONGSEN/L. ^#{exp_date}1200000000000000**123******?" }.update(options) Billing::CreditCard.new(defaults) @@ -176,13 +176,13 @@ def credit_card_with_track_data(number = '4242424242424242', options = {}) def network_tokenization_credit_card(number = '4242424242424242', options = {}) defaults = { - :number => number, - :month => default_expiration_date.month, - :year => default_expiration_date.year, - :first_name => 'Longbob', - :last_name => 'Longsen', - :verification_value => '123', - :brand => 'visa' + number: number, + month: default_expiration_date.month, + year: default_expiration_date.year, + first_name: 'Longbob', + last_name: 'Longsen', + verification_value: '123', + brand: 'visa' }.update(options) Billing::NetworkTokenizationCreditCard.new(defaults) @@ -190,13 +190,13 @@ def network_tokenization_credit_card(number = '4242424242424242', options = {}) def check(options = {}) defaults = { - :name => 'Jim Smith', - :bank_name => 'Bank of Elbonia', - :routing_number => '244183602', - :account_number => '15378535', - :account_holder_type => 'personal', - :account_type => 'checking', - :number => '1' + name: 'Jim Smith', + bank_name: 'Bank of Elbonia', + routing_number: '244183602', + account_number: '15378535', + account_holder_type: 'personal', + account_type: 'checking', + number: '1' }.update(options) Billing::Check.new(defaults) @@ -216,8 +216,7 @@ def apple_pay_payment_token(options = {}) ActiveMerchant::Billing::ApplePayPaymentToken.new(defaults[:payment_data], payment_instrument_name: defaults[:payment_instrument_name], payment_network: defaults[:payment_network], - transaction_identifier: defaults[:transaction_identifier] - ) + transaction_identifier: defaults[:transaction_identifier]) end def address(options = {}) @@ -293,7 +292,7 @@ def symbolize_keys(hash) return unless hash.is_a?(Hash) hash.symbolize_keys! - hash.each { |k, v| symbolize_keys(v) } + hash.each { |_k, v| symbolize_keys(v) } end end end @@ -322,49 +321,19 @@ def dump_transcript_and_fail(gateway, amount, credit_card, params) end end -module ActionViewHelperTestHelper - def self.included(base) - base.send(:include, ActiveMerchant::Billing::Integrations::ActionViewHelper) - base.send(:include, ActionView::Helpers::FormHelper) - base.send(:include, ActionView::Helpers::FormTagHelper) - base.send(:include, ActionView::Helpers::UrlHelper) - base.send(:include, ActionView::Helpers::TagHelper) - base.send(:include, ActionView::Helpers::CaptureHelper) - base.send(:include, ActionView::Helpers::TextHelper) - base.send(:attr_accessor, :output_buffer) - end - - def setup - @controller = Class.new do - attr_reader :url_for_options - def url_for(options, *parameters_for_method_reference) - @url_for_options = options - end - end - @controller = @controller.new - @output_buffer = '' - end - - protected - - def protect_against_forgery? - false - end -end - class MockResponse attr_reader :code, :body, :message attr_accessor :headers - def self.succeeded(body, message='') + def self.succeeded(body, message = '') MockResponse.new(200, body, message) end - def self.failed(body, http_status_code=422, message='') + def self.failed(body, http_status_code = 422, message = '') MockResponse.new(http_status_code, body, message) end - def initialize(code, body, message='', headers={}) + def initialize(code, body, message = '', headers = {}) @code, @body, @message, @headers = code, body, message, headers end diff --git a/test/unit/avs_result_test.rb b/test/unit/avs_result_test.rb index f3b960647b7..7e069c6f1ac 100644 --- a/test/unit/avs_result_test.rb +++ b/test/unit/avs_result_test.rb @@ -6,7 +6,7 @@ def test_nil end def test_no_match - result = AVSResult.new(:code => 'N') + result = AVSResult.new(code: 'N') assert_equal 'N', result.code assert_equal 'N', result.street_match assert_equal 'N', result.postal_match @@ -14,7 +14,7 @@ def test_no_match end def test_only_street_match - result = AVSResult.new(:code => 'A') + result = AVSResult.new(code: 'A') assert_equal 'A', result.code assert_equal 'Y', result.street_match assert_equal 'N', result.postal_match @@ -22,7 +22,7 @@ def test_only_street_match end def test_only_postal_match - result = AVSResult.new(:code => 'W') + result = AVSResult.new(code: 'W') assert_equal 'W', result.code assert_equal 'N', result.street_match assert_equal 'Y', result.postal_match @@ -30,30 +30,30 @@ def test_only_postal_match end def test_nil_data - result = AVSResult.new(:code => nil) + result = AVSResult.new(code: nil) assert_nil result.code assert_nil result.message end def test_empty_data - result = AVSResult.new(:code => '') + result = AVSResult.new(code: '') assert_nil result.code assert_nil result.message end def test_to_hash - avs_data = AVSResult.new(:code => 'X').to_hash + avs_data = AVSResult.new(code: 'X').to_hash assert_equal 'X', avs_data['code'] assert_equal AVSResult.messages['X'], avs_data['message'] end def test_street_match - avs_data = AVSResult.new(:street_match => 'Y') + avs_data = AVSResult.new(street_match: 'Y') assert_equal 'Y', avs_data.street_match end def test_postal_match - avs_data = AVSResult.new(:postal_match => 'Y') + avs_data = AVSResult.new(postal_match: 'Y') assert_equal 'Y', avs_data.postal_match end end diff --git a/test/unit/base_test.rb b/test/unit/base_test.rb index 6e5ac461ab7..82e13503378 100644 --- a/test/unit/base_test.rb +++ b/test/unit/base_test.rb @@ -12,7 +12,6 @@ def teardown def test_should_return_a_new_gateway_specified_by_symbol_name assert_equal BogusGateway, Base.gateway(:bogus) assert_equal MonerisGateway, Base.gateway(:moneris) - assert_equal MonerisUsGateway, Base.gateway(:moneris_us) assert_equal AuthorizeNetGateway, Base.gateway(:authorize_net) assert_equal UsaEpayGateway, Base.gateway(:usa_epay) assert_equal LinkpointGateway, Base.gateway(:linkpoint) diff --git a/test/unit/check_test.rb b/test/unit/check_test.rb index e5908553ab9..9f38fca657f 100644 --- a/test/unit/check_test.rb +++ b/test/unit/check_test.rb @@ -12,14 +12,14 @@ def test_validation end def test_first_name_last_name - check = Check.new(:name => 'Fred Bloggs') + check = Check.new(name: 'Fred Bloggs') assert_equal 'Fred', check.first_name assert_equal 'Bloggs', check.last_name assert_equal 'Fred Bloggs', check.name end def test_nil_name - check = Check.new(:name => nil) + check = Check.new(name: nil) assert_nil check.first_name assert_nil check.last_name assert_equal '', check.name @@ -27,11 +27,11 @@ def test_nil_name def test_valid assert_valid Check.new( - :name => 'Fred Bloggs', - :routing_number => VALID_ABA, - :account_number => ACCOUNT_NUMBER, - :account_holder_type => 'personal', - :account_type => 'checking' + name: 'Fred Bloggs', + routing_number: VALID_ABA, + account_number: ACCOUNT_NUMBER, + account_holder_type: 'personal', + account_type: 'checking' ) end @@ -40,12 +40,12 @@ def test_credit_card? end def test_invalid_routing_number - errors = assert_not_valid Check.new(:routing_number => INVALID_ABA) + errors = assert_not_valid Check.new(routing_number: INVALID_ABA) assert_equal ['is invalid'], errors[:routing_number] end def test_malformed_routing_number - errors = assert_not_valid Check.new(:routing_number => MALFORMED_ABA) + errors = assert_not_valid Check.new(routing_number: MALFORMED_ABA) assert_equal ['is invalid'], errors[:routing_number] end diff --git a/test/unit/connection_test.rb b/test/unit/connection_test.rb index ac8c29a4f1d..3ef0b493486 100644 --- a/test/unit/connection_test.rb +++ b/test/unit/connection_test.rb @@ -1,13 +1,12 @@ require 'test_helper' class ConnectionTest < Test::Unit::TestCase - def setup - @ok = stub(:code => 200, :message => 'OK', :body => 'success') + @ok = stub(code: 200, message: 'OK', body: 'success') @endpoint = 'https://example.com/tx.php' @connection = ActiveMerchant::Connection.new(@endpoint) - @connection.logger = stub(:info => nil, :debug => nil, :error => nil) + @connection.logger = stub(info: nil, debug: nil, error: nil) end def test_connection_endpoint_parses_string_to_uri @@ -30,7 +29,7 @@ def test_connection_passes_env_proxy_by_default spy = Net::HTTP.new('example.com', 443) Net::HTTP.expects(:new).with('example.com', 443, :ENV, nil).returns(spy) spy.expects(:start).returns(true) - spy.expects(:get).with('/tx.php', {'connection' => 'close'}).returns(@ok) + spy.expects(:get).with('/tx.php', { 'connection' => 'close' }).returns(@ok) @connection.request(:get, nil, {}) end @@ -40,13 +39,13 @@ def test_connection_does_pass_requested_proxy spy = Net::HTTP.new('example.com', 443) Net::HTTP.expects(:new).with('example.com', 443, 'proxy.example.com', 8080).returns(spy) spy.expects(:start).returns(true) - spy.expects(:get).with('/tx.php', {'connection' => 'close'}).returns(@ok) + spy.expects(:get).with('/tx.php', { 'connection' => 'close' }).returns(@ok) @connection.request(:get, nil, {}) end def test_connection_does_not_mutate_headers_argument headers = { 'Content-Type' => 'text/xml' }.freeze - Net::HTTP.any_instance.expects(:get).with('/tx.php', headers.merge({'connection' => 'close'})).returns(@ok) + Net::HTTP.any_instance.expects(:get).with('/tx.php', headers.merge({ 'connection' => 'close' })).returns(@ok) Net::HTTP.any_instance.expects(:start).returns(true) @connection.request(:get, nil, headers) assert_equal({ 'Content-Type' => 'text/xml' }, headers) @@ -54,28 +53,28 @@ def test_connection_does_not_mutate_headers_argument def test_successful_get_request @connection.logger.expects(:info).twice - Net::HTTP.any_instance.expects(:get).with('/tx.php', {'connection' => 'close'}).returns(@ok) + Net::HTTP.any_instance.expects(:get).with('/tx.php', { 'connection' => 'close' }).returns(@ok) Net::HTTP.any_instance.expects(:start).returns(true) response = @connection.request(:get, nil, {}) assert_equal 'success', response.body end def test_successful_post_request - Net::HTTP.any_instance.expects(:post).with('/tx.php', 'data', ActiveMerchant::Connection::RUBY_184_POST_HEADERS.merge({'connection' => 'close'})).returns(@ok) + Net::HTTP.any_instance.expects(:post).with('/tx.php', 'data', ActiveMerchant::Connection::RUBY_184_POST_HEADERS.merge({ 'connection' => 'close' })).returns(@ok) Net::HTTP.any_instance.expects(:start).returns(true) response = @connection.request(:post, 'data', {}) assert_equal 'success', response.body end def test_successful_put_request - Net::HTTP.any_instance.expects(:put).with('/tx.php', 'data', {'connection' => 'close'}).returns(@ok) + Net::HTTP.any_instance.expects(:put).with('/tx.php', 'data', { 'connection' => 'close' }).returns(@ok) Net::HTTP.any_instance.expects(:start).returns(true) response = @connection.request(:put, 'data', {}) assert_equal 'success', response.body end def test_successful_delete_request - Net::HTTP.any_instance.expects(:delete).with('/tx.php', {'connection' => 'close'}).returns(@ok) + Net::HTTP.any_instance.expects(:delete).with('/tx.php', { 'connection' => 'close' }).returns(@ok) Net::HTTP.any_instance.expects(:start).returns(true) response = @connection.request(:delete, nil, {}) assert_equal 'success', response.body @@ -244,5 +243,4 @@ def test_wiredump_service_raises_on_frozen_object @connection.wiredump_device = transcript end end - end diff --git a/test/unit/country_test.rb b/test/unit/country_test.rb index 6251e6fa095..8f8669ce7e1 100644 --- a/test/unit/country_test.rb +++ b/test/unit/country_test.rb @@ -2,7 +2,7 @@ class CountryTest < Test::Unit::TestCase def test_country_from_hash - country = ActiveMerchant::Country.new(:name => 'Canada', :alpha2 => 'CA', :alpha3 => 'CAN', :numeric => '124') + country = ActiveMerchant::Country.new(name: 'Canada', alpha2: 'CA', alpha3: 'CAN', numeric: '124') assert_equal 'CA', country.code(:alpha2).value assert_equal 'CAN', country.code(:alpha3).value assert_equal '124', country.code(:numeric).value diff --git a/test/unit/credit_card_methods_test.rb b/test/unit/credit_card_methods_test.rb index 400dc07c3a7..d32c87280fd 100644 --- a/test/unit/credit_card_methods_test.rb +++ b/test/unit/credit_card_methods_test.rb @@ -12,6 +12,8 @@ def maestro_card_numbers 5612590000000000 5817500000000000 5818000000000000 6390000000000000 6390700000000000 6390990000000000 6761999999999999 6763000000000000 6799999999999999 + 5000330000000000 5811499999999999 5010410000000000 + 5010630000000000 5892440000000000 ] end @@ -23,6 +25,24 @@ def non_maestro_card_numbers ] end + def maestro_bins + %w[500032 500057 501015 501016 501018 501020 501021 501023 501024 501025 501026 501027 501028 501029 + 501038 501039 501040 501041 501043 501045 501047 501049 501051 501053 501054 501055 501056 501057 + 501058 501060 501061 501062 501063 501066 501067 501072 501075 501080 501081 501082 501083 501087 + 501089 501091 501092 501095 501104 501105 501107 501108 501500 501879 502113 502301 503175 503645 + 503670 504310 504338 504363 504533 504587 504620 504639 504656 504738 504781 504910 507001 507002 + 507004 507082 507090 560014 560565 561033 572402 572610 572626 576904 578614 585274 585697 586509 + 588729 588792 589244 589407 589471 589605 589633 589647 589671 590043 590206 590263 590265 + 590278 590361 590362 590379 590393 590590 591235 591420 591481 591620 591770 591948 591994 592024 + 592161 592184 592186 592201 592384 592393 592528 592566 592704 592735 592879 592884 593074 593264 + 593272 593355 593496 593556 593589 593666 593709 593825 593963 593994 594184 594409 594468 594475 + 594581 594665 594691 594710 594874 594968 595355 595364 595532 595547 595561 595568 595743 595929 + 596245 596289 596399 596405 596590 596608 596645 596646 596791 596808 596815 596846 597077 597094 + 597143 597370 597410 597765 597855 597862 598053 598054 598395 598585 598793 598794 598815 598835 + 598838 598880 598889 599000 599069 599089 599148 599191 599310 599741 599742 599867 601070 604983 + 606126 636380 636422 636502 636639 637046 637756 639130 690032] + end + def test_should_be_able_to_identify_valid_expiry_months assert_false valid_month?(-1) assert_false valid_month?(13) @@ -100,6 +120,7 @@ def test_should_detect_electron_dk_as_visa def test_should_detect_diners_club assert_equal 'diners_club', CreditCard.brand?('36148010000000') + assert_equal 'diners_club', CreditCard.brand?('3000000000000004') end def test_should_detect_diners_club_dk @@ -114,6 +135,7 @@ def test_should_detect_maestro_cards assert_equal 'maestro', CreditCard.brand?('675675000000000') maestro_card_numbers.each { |number| assert_equal 'maestro', CreditCard.brand?(number) } + maestro_bins.each { |bin| assert_equal 'maestro', CreditCard.brand?("#{bin}0000000000") } non_maestro_card_numbers.each { |number| assert_not_equal 'maestro', CreditCard.brand?(number) } end @@ -130,6 +152,30 @@ def test_should_detect_sodexo_card assert_equal 'sodexo', CreditCard.brand?('6060694495764400') end + def test_should_detect_alia_card + assert_equal 'alia', CreditCard.brand?('5049970000000000') + assert_equal 'alia', CreditCard.brand?('5058780000000000') + assert_equal 'alia', CreditCard.brand?('6010300000000000') + assert_equal 'alia', CreditCard.brand?('6010730000000000') + assert_equal 'alia', CreditCard.brand?('5058740000000000') + end + + def test_alia_number_not_validated + 10.times do + number = rand(5058740000000001..5058749999999999).to_s + assert_equal 'alia', CreditCard.brand?(number) + assert CreditCard.valid_number?(number) + end + end + + def test_should_detect_olimpica_card + assert_equal 'olimpica', CreditCard.brand?('6368530000000000') + end + + def test_should_detect_creditel_card + assert_equal 'creditel', CreditCard.brand?('6019330047539016') + end + def test_should_detect_vr_card assert_equal 'vr', CreditCard.brand?('6370364495764400') end @@ -137,7 +183,11 @@ def test_should_detect_vr_card def test_should_detect_elo_card assert_equal 'elo', CreditCard.brand?('5090510000000000') assert_equal 'elo', CreditCard.brand?('5067530000000000') + assert_equal 'elo', CreditCard.brand?('6277800000000000') assert_equal 'elo', CreditCard.brand?('6509550000000000') + assert_equal 'elo', CreditCard.brand?('5090890000000000') + assert_equal 'elo', CreditCard.brand?('5092570000000000') + assert_equal 'elo', CreditCard.brand?('5094100000000000') end def test_should_detect_alelo_card @@ -145,6 +195,9 @@ def test_should_detect_alelo_card assert_equal 'alelo', CreditCard.brand?('5067700000000028') assert_equal 'alelo', CreditCard.brand?('5067600000000036') assert_equal 'alelo', CreditCard.brand?('5067600000000044') + assert_equal 'alelo', CreditCard.brand?('5099920000000000') + assert_equal 'alelo', CreditCard.brand?('5067630000000000') + assert_equal 'alelo', CreditCard.brand?('5098870000000000') end def test_should_detect_naranja_card @@ -169,6 +222,23 @@ def test_should_detect_cabal_card assert_equal 'cabal', CreditCard.brand?('6035224400000000') end + # UnionPay BINs beginning with 62 overlap with Discover's range of valid card numbers. + # We intentionally misidentify these cards as Discover, which works because transactions with + # UnionPay cards will run on Discover rails. + def test_should_detect_unionpay_cards_beginning_with_62_as_discover + assert_equal 'discover', CreditCard.brand?('6212345678901265') + assert_equal 'discover', CreditCard.brand?('6221260000000000') + assert_equal 'discover', CreditCard.brand?('6250941006528599') + assert_equal 'discover', CreditCard.brand?('6212345678900000003') + end + + def test_should_detect_unionpay_card + assert_equal 'unionpay', CreditCard.brand?('8100000000000000') + assert_equal 'unionpay', CreditCard.brand?('814400000000000000') + assert_equal 'unionpay', CreditCard.brand?('8171999927660000') + assert_equal 'unionpay', CreditCard.brand?('8171999900000000021') + end + def test_should_detect_when_an_argument_brand_does_not_match_calculated_brand assert CreditCard.matching_brand?('4175001000000000', 'visa') assert_false CreditCard.matching_brand?('4175001000000000', 'master') @@ -194,7 +264,6 @@ def test_detecting_full_range_of_maestro_card_numbers def test_matching_discover_card assert_equal 'discover', CreditCard.brand?('6011000000000000') assert_equal 'discover', CreditCard.brand?('6500000000000000') - assert_equal 'discover', CreditCard.brand?('6221260000000000') assert_equal 'discover', CreditCard.brand?('6450000000000000') assert_not_equal 'discover', CreditCard.brand?('6010000000000000') @@ -213,6 +282,12 @@ def test_matching_valid_naranja assert CreditCard.valid_number?(number) end + def test_matching_valid_creditel + number = '6019330047539016' + assert_equal 'creditel', CreditCard.brand?(number) + assert CreditCard.valid_number?(number) + end + def test_16_digit_maestro_uk number = '6759000000000000' assert_equal 16, number.length @@ -232,11 +307,11 @@ def test_19_digit_maestro_uk end def test_carnet_cards - numbers = [ - '5062280000000000', - '6046220312312312', - '6393889871239871', - '5022751231231231' + numbers = %w[ + 5062280000000000 + 6046220312312312 + 6393889871239871 + 5022751231231231 ] numbers.each do |num| assert_equal 16, num.length diff --git a/test/unit/credit_card_test.rb b/test/unit/credit_card_test.rb index d31748f17bb..23b2fa42743 100644 --- a/test/unit/credit_card_test.rb +++ b/test/unit/credit_card_test.rb @@ -49,7 +49,7 @@ def test_cards_with_empty_names_should_not_be_valid end def test_should_be_able_to_liberate_a_bogus_card - c = credit_card('', :brand => 'bogus') + c = credit_card('', brand: 'bogus') assert_valid c c.brand = 'visa' @@ -150,11 +150,11 @@ def test_should_be_invalid_with_empty_year end def test_should_not_be_valid_for_edge_year_cases - @visa.year = Time.now.year - 1 + @visa.year = Time.now.year - 1 errors = assert_not_valid @visa assert errors[:year] - @visa.year = Time.now.year + 21 + @visa.year = Time.now.year + 21 errors = assert_not_valid @visa assert errors[:year] end @@ -173,20 +173,20 @@ def test_expired_card_should_have_one_error_on_year end def test_should_identify_wrong_card_brand - c = credit_card(:brand => 'master') + c = credit_card(brand: 'master') assert_not_valid c end def test_should_display_number - assert_equal 'XXXX-XXXX-XXXX-1234', CreditCard.new(:number => '1111222233331234').display_number - assert_equal 'XXXX-XXXX-XXXX-1234', CreditCard.new(:number => '111222233331234').display_number - assert_equal 'XXXX-XXXX-XXXX-1234', CreditCard.new(:number => '1112223331234').display_number + assert_equal 'XXXX-XXXX-XXXX-1234', CreditCard.new(number: '1111222233331234').display_number + assert_equal 'XXXX-XXXX-XXXX-1234', CreditCard.new(number: '111222233331234').display_number + assert_equal 'XXXX-XXXX-XXXX-1234', CreditCard.new(number: '1112223331234').display_number - assert_equal 'XXXX-XXXX-XXXX-', CreditCard.new(:number => nil).display_number - assert_equal 'XXXX-XXXX-XXXX-', CreditCard.new(:number => '').display_number - assert_equal 'XXXX-XXXX-XXXX-123', CreditCard.new(:number => '123').display_number - assert_equal 'XXXX-XXXX-XXXX-1234', CreditCard.new(:number => '1234').display_number - assert_equal 'XXXX-XXXX-XXXX-1234', CreditCard.new(:number => '01234').display_number + assert_equal 'XXXX-XXXX-XXXX-', CreditCard.new(number: nil).display_number + assert_equal 'XXXX-XXXX-XXXX-', CreditCard.new(number: '').display_number + assert_equal 'XXXX-XXXX-XXXX-123', CreditCard.new(number: '123').display_number + assert_equal 'XXXX-XXXX-XXXX-1234', CreditCard.new(number: '1234').display_number + assert_equal 'XXXX-XXXX-XXXX-1234', CreditCard.new(number: '01234').display_number end def test_should_correctly_identify_card_brand @@ -204,7 +204,7 @@ def test_should_be_able_to_require_a_verification_value def test_should_not_be_valid_when_requiring_a_verification_value CreditCard.require_verification_value = true - card = credit_card('4242424242424242', :verification_value => nil) + card = credit_card('4242424242424242', verification_value: nil) assert_not_valid card card.verification_value = '1234' @@ -214,7 +214,7 @@ def test_should_not_be_valid_when_requiring_a_verification_value card.verification_value = '123' assert_valid card - card = credit_card('341111111111111', :verification_value => '123', :brand => 'american_express') + card = credit_card('341111111111111', verification_value: '123', brand: 'american_express') errors = assert_not_valid card assert_equal errors[:verification_value], ['should be 4 digits'] @@ -224,7 +224,7 @@ def test_should_not_be_valid_when_requiring_a_verification_value def test_should_be_valid_when_not_requiring_a_verification_value CreditCard.require_verification_value = true - card = credit_card('4242424242424242', :verification_value => nil, :require_verification_value => false) + card = credit_card('4242424242424242', verification_value: nil, require_verification_value: false) assert_valid card card.verification_value = '1234' @@ -242,12 +242,12 @@ def test_bogus_cards_are_not_valid_without_verification_value end def test_should_return_last_four_digits_of_card_number - ccn = CreditCard.new(:number => '4779139500118580') + ccn = CreditCard.new(number: '4779139500118580') assert_equal '8580', ccn.last_digits end def test_bogus_last_digits - ccn = CreditCard.new(:number => '1') + ccn = CreditCard.new(number: '1') assert_equal '1', ccn.last_digits end @@ -262,12 +262,12 @@ def test_should_return_empty_string_for_last_digits_of_nil_card_number end def test_should_return_first_four_digits_of_card_number - ccn = CreditCard.new(:number => '4779139500118580') + ccn = CreditCard.new(number: '4779139500118580') assert_equal '477913', ccn.first_digits end def test_should_return_first_bogus_digit_of_card_number - ccn = CreditCard.new(:number => '1') + ccn = CreditCard.new(number: '1') assert_equal '1', ccn.first_digits end @@ -275,7 +275,7 @@ def test_should_be_true_when_credit_card_has_a_first_name c = CreditCard.new assert_false c.first_name? - c = CreditCard.new(:first_name => 'James') + c = CreditCard.new(first_name: 'James') assert c.first_name? end @@ -283,7 +283,7 @@ def test_should_be_true_when_credit_card_has_a_last_name c = CreditCard.new assert_false c.last_name? - c = CreditCard.new(:last_name => 'Herdman') + c = CreditCard.new(last_name: 'Herdman') assert c.last_name? end @@ -291,48 +291,48 @@ def test_should_test_for_a_full_name c = CreditCard.new assert_false c.name? - c = CreditCard.new(:first_name => 'James', :last_name => 'Herdman') + c = CreditCard.new(first_name: 'James', last_name: 'Herdman') assert c.name? end def test_should_handle_full_name_when_first_or_last_is_missing - c = CreditCard.new(:first_name => 'James') + c = CreditCard.new(first_name: 'James') assert c.name? assert_equal 'James', c.name - c = CreditCard.new(:last_name => 'Herdman') + c = CreditCard.new(last_name: 'Herdman') assert c.name? assert_equal 'Herdman', c.name end def test_should_assign_a_full_name - c = CreditCard.new :name => 'James Herdman' + c = CreditCard.new name: 'James Herdman' assert_equal 'James', c.first_name assert_equal 'Herdman', c.last_name - c = CreditCard.new :name => 'Rocket J. Squirrel' + c = CreditCard.new name: 'Rocket J. Squirrel' assert_equal 'Rocket J.', c.first_name assert_equal 'Squirrel', c.last_name - c = CreditCard.new :name => 'Twiggy' + c = CreditCard.new name: 'Twiggy' assert_equal '', c.first_name assert_equal 'Twiggy', c.last_name assert_equal 'Twiggy', c.name end def test_should_remove_trailing_whitespace_on_name - c = CreditCard.new(:last_name => 'Herdman') + c = CreditCard.new(last_name: 'Herdman') assert_equal 'Herdman', c.name - c = CreditCard.new(:last_name => 'Herdman', first_name: '') + c = CreditCard.new(last_name: 'Herdman', first_name: '') assert_equal 'Herdman', c.name end def test_should_remove_leading_whitespace_on_name - c = CreditCard.new(:first_name => 'James') + c = CreditCard.new(first_name: 'James') assert_equal 'James', c.name - c = CreditCard.new(:last_name => '', first_name: 'James') + c = CreditCard.new(last_name: '', first_name: 'James') assert_equal 'James', c.name end @@ -349,29 +349,29 @@ def test_validate_new_card # The following is a regression for a bug where the keys of the # credit card card_companies hash were not duped when detecting the brand def test_create_and_validate_credit_card_from_brand - credit_card = CreditCard.new(:brand => CreditCard.brand?('4242424242424242')) + credit_card = CreditCard.new(brand: CreditCard.brand?('4242424242424242')) assert_nothing_raised do credit_card.validate end end def test_autodetection_of_credit_card_brand - credit_card = CreditCard.new(:number => '4242424242424242') + credit_card = CreditCard.new(number: '4242424242424242') assert_equal 'visa', credit_card.brand end def test_card_brand_should_not_be_autodetected_when_provided - credit_card = CreditCard.new(:number => '4242424242424242', :brand => 'master') + credit_card = CreditCard.new(number: '4242424242424242', brand: 'master') assert_equal 'master', credit_card.brand end def test_detecting_bogus_card - credit_card = CreditCard.new(:number => '1') + credit_card = CreditCard.new(number: '1') assert_equal 'bogus', credit_card.brand end def test_validating_bogus_card - credit_card = credit_card('1', :brand => nil) + credit_card = credit_card('1', brand: nil) assert_valid credit_card end diff --git a/test/unit/gateways/adyen_test.rb b/test/unit/gateways/adyen_test.rb index 21ea73b3a0a..a1f48e8d711 100644 --- a/test/unit/gateways/adyen_test.rb +++ b/test/unit/gateways/adyen_test.rb @@ -11,74 +11,74 @@ def setup ) @credit_card = credit_card('4111111111111111', - :month => 8, - :year => 2018, - :first_name => 'Test', - :last_name => 'Card', - :verification_value => '737', - :brand => 'visa' - ) + month: 8, + year: 2018, + first_name: 'Test', + last_name: 'Card', + verification_value: '737', + brand: 'visa') @elo_credit_card = credit_card('5066 9911 1111 1118', - :month => 10, - :year => 2020, - :first_name => 'John', - :last_name => 'Smith', - :verification_value => '737', - :brand => 'elo' - ) + month: 10, + year: 2020, + first_name: 'John', + last_name: 'Smith', + verification_value: '737', + brand: 'elo') @cabal_credit_card = credit_card('6035 2277 1642 7021', - :month => 10, - :year => 2020, - :first_name => 'John', - :last_name => 'Smith', - :verification_value => '737', - :brand => 'cabal' - ) + month: 10, + year: 2020, + first_name: 'John', + last_name: 'Smith', + verification_value: '737', + brand: 'cabal') + + @unionpay_credit_card = credit_card('8171 9999 0000 0000 021', + month: 10, + year: 2030, + first_name: 'John', + last_name: 'Smith', + verification_value: '737', + brand: 'unionpay') @three_ds_enrolled_card = credit_card('4212345678901237', brand: :visa) @apple_pay_card = network_tokenization_credit_card('4111111111111111', - :payment_cryptogram => 'YwAAAAAABaYcCMX/OhNRQAAAAAA=', - :month => '08', - :year => '2018', - :source => :apple_pay, - :verification_value => nil - ) + payment_cryptogram: 'YwAAAAAABaYcCMX/OhNRQAAAAAA=', + month: '08', + year: '2018', + source: :apple_pay, + verification_value: nil) @amount = 100 @options = { billing_address: address(), + shipping_address: address(), shopper_reference: 'John Smith', order_id: '345123', installments: 2, - stored_credential: {reason_type: 'unscheduled'} + stored_credential: { reason_type: 'unscheduled' }, + email: 'john.smith@test.com', + ip: '77.110.174.153' } - @normalized_initial_stored_credential = { - stored_credential: { - initial_transaction: true, - reason_type: 'unscheduled' - } - } - - @normalized_stored_credential = { - stored_credential: { - initial_transaction: false, - reason_type: 'recurring' - } + @options_shopper_data = { + email: 'john.smith@test.com', + ip: '77.110.174.153', + shopper_email: 'john2.smith@test.com', + shopper_ip: '192.168.100.100' } @normalized_3ds_2_options = { reference: '345123', - shopper_email: 'john.smith@test.com', - shopper_ip: '77.110.174.153', + email: 'john.smith@test.com', + ip: '77.110.174.153', shopper_reference: 'John Smith', billing_address: address(), order_id: '123', - stored_credential: {reason_type: 'unscheduled'}, + stored_credential: { reason_type: 'unscheduled' }, three_ds_2: { channel: 'browser', browser_info: { @@ -139,12 +139,27 @@ def test_successful_authorize_with_3ds refute response.params['paRequest'].blank? end + def test_failed_authorize_with_unexpected_3ds + @gateway.expects(:ssl_post).returns(successful_authorize_with_3ds_response) + response = @gateway.authorize(@amount, @three_ds_enrolled_card, @options) + assert_failure response + assert_match 'Received unexpected 3DS authentication response', response.message + end + + def test_successful_authorize_with_recurring_contract_type + stub_comms do + @gateway.authorize(100, @credit_card, @options.merge({ recurring_contract_type: 'ONECLICK' })) + end.check_request do |_endpoint, data, _headers| + assert_equal 'ONECLICK', JSON.parse(data)['recurring']['contract'] + end.respond_with(successful_authorize_response) + end + def test_adds_3ds1_standalone_fields eci = '05' cavv = '3q2+78r+ur7erb7vyv66vv\/\/\/\/8=' cavv_algorithm = '1' xid = 'ODUzNTYzOTcwODU5NzY3Qw==' - directory_response_status = 'C' + enrolled = 'Y' authentication_response_status = 'Y' options_with_3ds1_standalone = @options.merge( three_d_secure: { @@ -152,18 +167,18 @@ def test_adds_3ds1_standalone_fields cavv: cavv, cavv_algorithm: cavv_algorithm, xid: xid, - directory_response_status: directory_response_status, + enrolled: enrolled, authentication_response_status: authentication_response_status } ) stub_comms do @gateway.authorize(@amount, @credit_card, options_with_3ds1_standalone) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_equal eci, JSON.parse(data)['mpiData']['eci'] assert_equal cavv, JSON.parse(data)['mpiData']['cavv'] assert_equal cavv_algorithm, JSON.parse(data)['mpiData']['cavvAlgorithm'] assert_equal xid, JSON.parse(data)['mpiData']['xid'] - assert_equal directory_response_status, JSON.parse(data)['mpiData']['directoryResponse'] + assert_equal enrolled, JSON.parse(data)['mpiData']['directoryResponse'] assert_equal authentication_response_status, JSON.parse(data)['mpiData']['authenticationResponse'] end.respond_with(successful_authorize_response) end @@ -187,7 +202,7 @@ def test_adds_3ds2_standalone_fields ) stub_comms do @gateway.authorize(@amount, @credit_card, options_with_3ds2_standalone) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_equal version, JSON.parse(data)['mpiData']['threeDSVersion'] assert_equal eci, JSON.parse(data)['mpiData']['eci'] assert_equal cavv, JSON.parse(data)['mpiData']['cavv'] @@ -214,6 +229,15 @@ def test_failed_authorise3d assert_failure response end + def test_failed_authorise3ds2 + @gateway.expects(:ssl_post).returns(failed_authorize_3ds2_response) + + response = @gateway.send(:commit, 'authorise3ds2', {}, {}) + + assert_equal '3D Not Authenticated', response.message + assert_failure response + end + def test_successful_capture @gateway.expects(:ssl_post).returns(successful_capture_response) response = @gateway.capture(@amount, '7914775043909934') @@ -242,7 +266,7 @@ def test_successful_purchase def test_successful_purchase_with_elo_card response = stub_comms do @gateway.purchase(@amount, @elo_credit_card, @options) - end.respond_with(successful_authorize_with_elo_response, successful_capture_with_elo_repsonse) + end.respond_with(simple_successful_authorize_response, simple_successful_capture_repsonse) assert_success response assert_equal '8835511210681145#8835511210689965#', response.authorization assert response.test? @@ -251,17 +275,26 @@ def test_successful_purchase_with_elo_card def test_successful_purchase_with_cabal_card response = stub_comms do @gateway.purchase(@amount, @cabal_credit_card, @options) - end.respond_with(successful_authorize_with_cabal_response, successful_capture_with_cabal_repsonse) + end.respond_with(simple_successful_authorize_response, simple_successful_capture_repsonse) assert_success response - assert_equal '883567090118045A#883567090119063C#', response.authorization + assert_equal '8835511210681145#8835511210689965#', response.authorization + assert response.test? + end + + def test_successful_purchase_with_unionpay_card + response = stub_comms do + @gateway.purchase(@amount, @unionpay_credit_card, @options) + end.respond_with(simple_successful_authorize_response, simple_successful_capture_repsonse) + assert_success response + assert_equal '8835511210681145#8835511210689965#', response.authorization assert response.test? end def test_successful_maestro_purchase response = stub_comms do - @gateway.purchase(@amount, @credit_card, @options.merge({selected_brand: 'maestro', overwrite_brand: 'true'})) - end.check_request do |endpoint, data, headers| - if endpoint =~ /authorise/ + @gateway.purchase(@amount, @credit_card, @options.merge({ selected_brand: 'maestro', overwrite_brand: 'true' })) + end.check_request do |endpoint, data, _headers| + if /authorise/.match?(endpoint) assert_match(/"overwriteBrand":true/, data) assert_match(/"selectedBrand":"maestro"/, data) end @@ -274,7 +307,7 @@ def test_successful_maestro_purchase def test_3ds_2_fields_sent stub_comms do @gateway.authorize(@amount, @credit_card, @normalized_3ds_2_options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| data = JSON.parse(data) assert_equal 'browser', data['threeDS2RequestData']['deviceChannel'] assert_equal 'unknown', data['browserInfo']['acceptHeader'] @@ -291,31 +324,66 @@ def test_3ds_2_fields_sent def test_installments_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_equal 2, JSON.parse(data)['installments']['value'] end.respond_with(successful_authorize_response) end def test_capture_delay_hours_sent stub_comms do - @gateway.authorize(@amount, @credit_card, @options.merge({capture_delay_hours: 4})) - end.check_request do |endpoint, data, headers| + @gateway.authorize(@amount, @credit_card, @options.merge({ capture_delay_hours: 4 })) + end.check_request do |_endpoint, data, _headers| assert_equal 4, JSON.parse(data)['captureDelayHours'] end.respond_with(successful_authorize_response) end def test_custom_routing_sent stub_comms do - @gateway.authorize(@amount, @credit_card, @options.merge({custom_routing_flag: 'abcdefg'})) - end.check_request do |endpoint, data, headers| + @gateway.authorize(@amount, @credit_card, @options.merge({ custom_routing_flag: 'abcdefg' })) + end.check_request do |_endpoint, data, _headers| assert_equal 'abcdefg', JSON.parse(data)['additionalData']['customRoutingFlag'] end.respond_with(successful_authorize_response) end + def test_splits_sent + split_data = [{ + 'amount' => { + 'currency' => 'USD', + 'value' => 50 + }, + 'type' => 'MarketPlace', + 'account' => '163298747', + 'reference' => 'QXhlbFN0b2x0ZW5iZXJnCg' + }, { + 'amount' => { + 'currency' => 'USD', + 'value' => 50 + }, + 'type' => 'Commission', + 'reference' => 'THVjYXNCbGVkc29lCg' + }] + + options = @options.merge({ splits: split_data }) + stub_comms do + @gateway.authorize(@amount, @credit_card, options) + end.check_request do |_endpoint, data, _headers| + assert_equal split_data, JSON.parse(data)['splits'] + end.respond_with(successful_authorize_response) + end + + def test_execute_threed_false_with_additional_data + stub_comms do + @gateway.authorize(@amount, @credit_card, @options.merge({ execute_threed: false, overwrite_brand: true, selected_brand: 'maestro' })) + end.check_request do |_endpoint, data, _headers| + assert_match(/"additionalData":{"overwriteBrand":true,"executeThreeD":false}/, data) + assert_match(/"selectedBrand":"maestro"/, data) + end.respond_with(successful_authorize_response) + end + def test_execute_threed_false_sent_3ds2 stub_comms do - @gateway.authorize(@amount, '123', @normalized_3ds_2_options.merge({execute_threed: false})) - end.check_request do |endpoint, data, headers| + @gateway.authorize(@amount, '123', @normalized_3ds_2_options.merge({ execute_threed: false })) + end.check_request do |_endpoint, data, _headers| refute JSON.parse(data)['additionalData']['scaExemption'] assert_false JSON.parse(data)['additionalData']['executeThreeD'] end.respond_with(successful_authorize_response) @@ -323,8 +391,8 @@ def test_execute_threed_false_sent_3ds2 def test_sca_exemption_not_sent_if_execute_threed_missing_3ds2 stub_comms do - @gateway.authorize(@amount, '123', @normalized_3ds_2_options.merge({scaExemption: 'lowValue'})) - end.check_request do |endpoint, data, headers| + @gateway.authorize(@amount, '123', @normalized_3ds_2_options.merge({ scaExemption: 'lowValue' })) + end.check_request do |_endpoint, data, _headers| refute JSON.parse(data)['additionalData']['scaExemption'] refute JSON.parse(data)['additionalData']['executeThreeD'] end.respond_with(successful_authorize_response) @@ -332,8 +400,8 @@ def test_sca_exemption_not_sent_if_execute_threed_missing_3ds2 def test_sca_exemption_and_execute_threed_false_sent_3ds2 stub_comms do - @gateway.authorize(@amount, '123', @normalized_3ds_2_options.merge({sca_exemption: 'lowValue', execute_threed: false})) - end.check_request do |endpoint, data, headers| + @gateway.authorize(@amount, '123', @normalized_3ds_2_options.merge({ sca_exemption: 'lowValue', execute_threed: false })) + end.check_request do |_endpoint, data, _headers| assert_equal 'lowValue', JSON.parse(data)['additionalData']['scaExemption'] assert_false JSON.parse(data)['additionalData']['executeThreeD'] end.respond_with(successful_authorize_response) @@ -341,8 +409,8 @@ def test_sca_exemption_and_execute_threed_false_sent_3ds2 def test_sca_exemption_and_execute_threed_true_sent_3ds2 stub_comms do - @gateway.authorize(@amount, '123', @normalized_3ds_2_options.merge({sca_exemption: 'lowValue', execute_threed: true})) - end.check_request do |endpoint, data, headers| + @gateway.authorize(@amount, '123', @normalized_3ds_2_options.merge({ sca_exemption: 'lowValue', execute_threed: true })) + end.check_request do |_endpoint, data, _headers| assert_equal 'lowValue', JSON.parse(data)['additionalData']['scaExemption'] assert JSON.parse(data)['additionalData']['executeThreeD'] end.respond_with(successful_authorize_response) @@ -350,8 +418,8 @@ def test_sca_exemption_and_execute_threed_true_sent_3ds2 def test_sca_exemption_not_sent_when_execute_threed_true_3ds1 stub_comms do - @gateway.authorize(@amount, '123', @options.merge({sca_exemption: 'lowValue', execute_threed: true})) - end.check_request do |endpoint, data, headers| + @gateway.authorize(@amount, '123', @options.merge({ sca_exemption: 'lowValue', execute_threed: true })) + end.check_request do |_endpoint, data, _headers| refute JSON.parse(data)['additionalData']['scaExemption'] assert JSON.parse(data)['additionalData']['executeThreeD'] end.respond_with(successful_authorize_response) @@ -359,8 +427,8 @@ def test_sca_exemption_not_sent_when_execute_threed_true_3ds1 def test_sca_exemption_not_sent_when_execute_threed_false_3ds1 stub_comms do - @gateway.authorize(@amount, '123', @options.merge({sca_exemption: 'lowValue', execute_threed: false})) - end.check_request do |endpoint, data, headers| + @gateway.authorize(@amount, '123', @options.merge({ sca_exemption: 'lowValue', execute_threed: false })) + end.check_request do |_endpoint, data, _headers| refute JSON.parse(data)['additionalData']['scaExemption'] refute JSON.parse(data)['additionalData']['executeThreeD'] end.respond_with(successful_authorize_response) @@ -368,8 +436,8 @@ def test_sca_exemption_not_sent_when_execute_threed_false_3ds1 def test_update_shopper_statement_and_industry_usage_sent stub_comms do - @gateway.adjust(@amount, '123', @options.merge({update_shopper_statement: 'statement note', industry_usage: 'DelayedCharge'})) - end.check_request do |endpoint, data, headers| + @gateway.adjust(@amount, '123', @options.merge({ update_shopper_statement: 'statement note', industry_usage: 'DelayedCharge' })) + end.check_request do |_endpoint, data, _headers| assert_equal 'statement note', JSON.parse(data)['additionalData']['updateShopperStatement'] assert_equal 'DelayedCharge', JSON.parse(data)['additionalData']['industryUsage'] end.respond_with(successful_adjust_response) @@ -377,8 +445,8 @@ def test_update_shopper_statement_and_industry_usage_sent def test_risk_data_sent stub_comms do - @gateway.authorize(@amount, @credit_card, @options.merge({risk_data: {'operatingSystem' => 'HAL9000'}})) - end.check_request do |endpoint, data, headers| + @gateway.authorize(@amount, @credit_card, @options.merge({ risk_data: { 'operatingSystem' => 'HAL9000' } })) + end.check_request do |_endpoint, data, _headers| assert_equal 'HAL9000', JSON.parse(data)['additionalData']['riskdata.operatingSystem'] end.respond_with(successful_authorize_response) end @@ -390,8 +458,8 @@ def test_risk_data_complex_data 'basket.item.productTitle' => 'Blue T Shirt', 'promotions.promotion.promotionName' => 'Big Sale promotion' } - @gateway.authorize(@amount, @credit_card, @options.merge({risk_data: risk_data})) - end.check_request do |endpoint, data, headers| + @gateway.authorize(@amount, @credit_card, @options.merge({ risk_data: risk_data })) + end.check_request do |_endpoint, data, _headers| parsed = JSON.parse(data) assert_equal 'express', parsed['additionalData']['riskdata.deliveryMethod'] assert_equal 'Blue T Shirt', parsed['additionalData']['riskdata.basket.item.productTitle'] @@ -399,35 +467,116 @@ def test_risk_data_complex_data end.respond_with(successful_authorize_response) end - def test_successful_authorize_with_normalized_stored_credentials + 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(/"shopperInteraction":"Ecommerce"/, data) + assert_match(/"recurringProcessingModel":"Subscription"/, data) + end.respond_with(successful_authorize_response) + + assert_success response + end + + def test_stored_credential_recurring_cit_used + @credit_card.verification_value = nil + 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(/"shopperInteraction":"ContAuth"/, data) + assert_match(/"recurringProcessingModel":"Subscription"/, 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(/"shopperInteraction":"ContAuth"/, data) + assert_match(/"recurringProcessingModel":"Subscription"/, data) + end.respond_with(successful_authorize_response) + + assert_success response + end + + def test_stored_credential_recurring_mit_used @credit_card.verification_value = nil - stub_comms do - @gateway.authorize(50, @credit_card, @options.merge(@normalized_stored_credential)) - end.check_request do |endpoint, data, headers| + 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(/"shopperInteraction":"ContAuth"/, data) assert_match(/"recurringProcessingModel":"Subscription"/, data) end.respond_with(successful_authorize_response) + + assert_success response end - def test_successful_initial_authorize_with_normalized_stored_credentials - stub_comms do - @gateway.authorize(50, @credit_card, @options.merge(@normalized_initial_stored_credential)) - end.check_request do |endpoint, data, headers| + 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(/"shopperInteraction":"Ecommerce"/, data) assert_match(/"recurringProcessingModel":"CardOnFile"/, data) end.respond_with(successful_authorize_response) + + assert_success response + end + + def test_stored_credential_unscheduled_cit_used + @credit_card.verification_value = nil + 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(/"shopperInteraction":"ContAuth"/, data) + assert_match(/"recurringProcessingModel":"CardOnFile"/, 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(/"shopperInteraction":"ContAuth"/, data) + assert_match(/"recurringProcessingModel":"UnscheduledCardOnFile"/, data) + end.respond_with(successful_authorize_response) + + assert_success response + end + + def test_stored_credential_unscheduled_mit_used + @credit_card.verification_value = nil + 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(/"shopperInteraction":"ContAuth"/, data) + assert_match(/"recurringProcessingModel":"UnscheduledCardOnFile"/, 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: 'JPY')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/"amount\":{\"value\":\"2\",\"currency\":\"JPY\"}/, data) end.respond_with(successful_authorize_response) stub_comms do @gateway.authorize(200, @credit_card, @options.merge(currency: 'CLP')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/"amount\":{\"value\":\"200\",\"currency\":\"CLP\"}/, data) end.respond_with(successful_authorize_response) end @@ -465,6 +614,22 @@ def test_failed_refund assert_failure response end + def test_failed_credit + @gateway.expects(:ssl_post).returns(failed_credit_response) + response = @gateway.refund(@amount, '') + assert_nil response.authorization + assert_equal 'Reference Missing', response.message + assert_failure response + end + + def test_successful_credit + @gateway.expects(:ssl_post).returns(successful_credit_response) + response = @gateway.credit(@amount, '883614109029400G') + assert_equal '#883614109029400G#', response.authorization + assert_equal 'Received', response.message + assert_success response + end + def test_successful_void @gateway.expects(:ssl_post).returns(successful_void_response) response = @gateway.void('7914775043909934') @@ -508,16 +673,41 @@ def test_failed_synchronous_adjust assert_failure response end + def test_successful_tokenize_only_store + response = stub_comms do + @gateway.store(@credit_card, @options.merge({ tokenize_only: true })) + end.check_request do |_endpoint, data, _headers| + assert_equal 'CardOnFile', JSON.parse(data)['recurringProcessingModel'] + end.respond_with(successful_store_response) + assert_equal '#8835205392522157#', response.authorization + end + def test_successful_store response = stub_comms do @gateway.store(@credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_equal 'CardOnFile', JSON.parse(data)['recurringProcessingModel'] end.respond_with(successful_store_response) assert_success response assert_equal '#8835205392522157#8315202663743702', response.authorization end + def test_successful_store_with_recurring_contract_type + stub_comms do + @gateway.store(@credit_card, @options.merge({ recurring_contract_type: 'ONECLICK' })) + end.check_request do |_endpoint, data, _headers| + assert_equal 'ONECLICK', JSON.parse(data)['recurring']['contract'] + end.respond_with(successful_store_response) + end + + def test_recurring_contract_type_set_for_reference_purchase + stub_comms do + @gateway.store('123', @options) + end.check_request do |_endpoint, data, _headers| + assert_equal 'RECURRING', JSON.parse(data)['recurring']['contract'] + end.respond_with(successful_store_response) + end + def test_failed_store @gateway.expects(:ssl_post).returns(failed_store_response) response = @gateway.store(@credit_card, @options) @@ -525,6 +715,23 @@ def test_failed_store assert_equal 'Refused', response.message end + def test_successful_unstore + response = stub_comms do + @gateway.unstore(shopper_reference: 'shopper_reference', + recurring_detail_reference: 'detail_reference') + end.respond_with(successful_unstore_response) + assert_success response + assert_equal '[detail-successfully-disabled]', response.message + end + + def test_failed_unstore + @gateway.expects(:ssl_post).returns(failed_unstore_response) + response = @gateway.unstore(shopper_reference: 'random_reference', + recurring_detail_reference: 'detail_reference') + assert_failure response + assert_equal 'Contract not found', response.message + end + def test_successful_verify response = stub_comms do @gateway.verify(@credit_card, @options) @@ -563,18 +770,41 @@ def test_scrub_network_tokenization_card assert_equal @gateway.scrub(pre_scrubbed), post_scrubbed end + def test_shopper_data + post = { card: { billingAddress: {} } } + @gateway.send(:add_shopper_data, post, @options) + assert_equal 'john.smith@test.com', post[:shopperEmail] + assert_equal '77.110.174.153', post[:shopperIP] + end + + def test_shopper_data_backwards_compatibility + post = { card: { billingAddress: {} } } + @gateway.send(:add_shopper_data, post, @options_shopper_data) + assert_equal 'john2.smith@test.com', post[:shopperEmail] + assert_equal '192.168.100.100', post[:shopperIP] + end + def test_add_address - post = {:card => {:billingAddress => {}}} + post = { card: { billingAddress: {} } } @options[:billing_address].delete(:address1) @options[:billing_address].delete(:address2) @options[:billing_address].delete(:state) + @options[:shipping_address].delete(:state) @gateway.send(:add_address, post, @options) + # Billing Address assert_equal 'NA', post[:billingAddress][:street] assert_equal 'NA', post[:billingAddress][:houseNumberOrName] assert_equal 'NA', post[:billingAddress][:stateOrProvince] assert_equal @options[:billing_address][:zip], post[:billingAddress][:postalCode] assert_equal @options[:billing_address][:city], post[:billingAddress][:city] assert_equal @options[:billing_address][:country], post[:billingAddress][:country] + # Shipping Address + assert_equal 'NA', post[:deliveryAddress][:stateOrProvince] + assert_equal @options[:shipping_address][:address1], post[:deliveryAddress][:street] + assert_equal @options[:shipping_address][:address2], post[:deliveryAddress][:houseNumberOrName] + assert_equal @options[:shipping_address][:zip], post[:deliveryAddress][:postalCode] + assert_equal @options[:shipping_address][:city], post[:deliveryAddress][:city] + assert_equal @options[:shipping_address][:country], post[:deliveryAddress][:country] end def test_authorize_with_network_tokenization_credit_card_no_name @@ -582,7 +812,7 @@ def test_authorize_with_network_tokenization_credit_card_no_name @apple_pay_card.last_name = nil response = stub_comms do @gateway.authorize(@amount, @apple_pay_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_equal 'Not Provided', JSON.parse(data)['card']['holderName'] end.respond_with(successful_authorize_response) assert_success response @@ -591,7 +821,7 @@ def test_authorize_with_network_tokenization_credit_card_no_name def test_authorize_with_network_tokenization_credit_card response = stub_comms do @gateway.authorize(@amount, @apple_pay_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parsed = JSON.parse(data) assert_equal 'YwAAAAAABaYcCMX/OhNRQAAAAAA=', parsed['mpiData']['cavv'] assert_equal '07', parsed['mpiData']['eci'] @@ -600,6 +830,114 @@ def test_authorize_with_network_tokenization_credit_card assert_success response end + def test_authorize_with_sub_merchant_id + sub_merchant_data = { + sub_merchant_id: '123451234512345', + sub_merchant_name: 'Wildsea', + sub_merchant_street: '1234 Street St', + sub_merchant_city: 'Night City', + sub_merchant_state: 'East Block', + sub_merchant_postal_code: '112233', + sub_merchant_country: 'EUR', + sub_merchant_tax_id: '12345abcde67', + sub_merchant_mcc: '1234' + } + response = stub_comms do + @gateway.authorize(@amount, @credit_card, @options.merge(sub_merchant_data)) + end.check_request do |_endpoint, data, _headers| + parsed = JSON.parse(data) + assert parsed['additionalData']['subMerchantID'] + assert parsed['additionalData']['subMerchantName'] + assert parsed['additionalData']['subMerchantStreet'] + assert parsed['additionalData']['subMerchantCity'] + assert parsed['additionalData']['subMerchantState'] + assert parsed['additionalData']['subMerchantPostalCode'] + assert parsed['additionalData']['subMerchantCountry'] + assert parsed['additionalData']['subMerchantTaxId'] + end.respond_with(successful_authorize_response) + assert_success response + end + + def test_authorize_with_sub_sellers + sub_seller_options = { + "subMerchant.numberOfSubSellers": '2', + "subMerchant.subSeller1.id": '111111111', + "subMerchant.subSeller1.name": 'testSub1', + "subMerchant.subSeller1.street": 'Street1', + "subMerchant.subSeller1.postalCode": '12242840', + "subMerchant.subSeller1.city": 'Sao jose dos campos', + "subMerchant.subSeller1.state": 'SP', + "subMerchant.subSeller1.country": 'BRA', + "subMerchant.subSeller1.taxId": '12312312340', + "subMerchant.subSeller1.mcc": '5691', + "subMerchant.subSeller1.debitSettlementBank": '1', + "subMerchant.subSeller1.debitSettlementAgency": '1', + "subMerchant.subSeller1.debitSettlementAccountType": '1', + "subMerchant.subSeller1.debitSettlementAccount": '1', + "subMerchant.subSeller1.creditSettlementBank": '1', + "subMerchant.subSeller1.creditSettlementAgency": '1', + "subMerchant.subSeller1.creditSettlementAccountType": '1', + "subMerchant.subSeller1.creditSettlementAccount": '1', + "subMerchant.subSeller2.id": '22222222', + "subMerchant.subSeller2.name": 'testSub2', + "subMerchant.subSeller2.street": 'Street2', + "subMerchant.subSeller2.postalCode": '12300000', + "subMerchant.subSeller2.city": 'Jacarei', + "subMerchant.subSeller2.state": 'SP', + "subMerchant.subSeller2.country": 'BRA', + "subMerchant.subSeller2.taxId": '12312312340', + "subMerchant.subSeller2.mcc": '5691', + "subMerchant.subSeller2.debitSettlementBank": '1', + "subMerchant.subSeller2.debitSettlementAgency": '1', + "subMerchant.subSeller2.debitSettlementAccountType": '1', + "subMerchant.subSeller2.debitSettlementAccount": '1', + "subMerchant.subSeller2.creditSettlementBank": '1', + "subMerchant.subSeller2.creditSettlementAgency": '1', + "subMerchant.subSeller2.creditSettlementAccountType": '1', + "subMerchant.subSeller2.creditSettlementAccount": '1' + } + response = stub_comms do + @gateway.authorize(@amount, @credit_card, @options.merge(sub_merchant_data: sub_seller_options)) + end.check_request do |_endpoint, data, _headers| + parsed = JSON.parse(data) + additional_data = parsed['additionalData'] + assert additional_data['subMerchant.numberOfSubSellers'] + assert additional_data['subMerchant.subSeller1.id'] + assert additional_data['subMerchant.subSeller1.name'] + assert additional_data['subMerchant.subSeller1.street'] + assert additional_data['subMerchant.subSeller1.city'] + assert additional_data['subMerchant.subSeller1.state'] + assert additional_data['subMerchant.subSeller1.postalCode'] + assert additional_data['subMerchant.subSeller1.country'] + assert additional_data['subMerchant.subSeller1.taxId'] + assert additional_data['subMerchant.subSeller1.debitSettlementBank'] + assert additional_data['subMerchant.subSeller1.debitSettlementAgency'] + assert additional_data['subMerchant.subSeller1.debitSettlementAccountType'] + assert additional_data['subMerchant.subSeller1.debitSettlementAccount'] + assert additional_data['subMerchant.subSeller1.creditSettlementBank'] + assert additional_data['subMerchant.subSeller1.creditSettlementAgency'] + assert additional_data['subMerchant.subSeller1.creditSettlementAccountType'] + assert additional_data['subMerchant.subSeller1.creditSettlementAccount'] + assert additional_data['subMerchant.subSeller2.id'] + assert additional_data['subMerchant.subSeller2.name'] + assert additional_data['subMerchant.subSeller2.street'] + assert additional_data['subMerchant.subSeller2.city'] + assert additional_data['subMerchant.subSeller2.state'] + assert additional_data['subMerchant.subSeller2.postalCode'] + assert additional_data['subMerchant.subSeller2.country'] + assert additional_data['subMerchant.subSeller2.taxId'] + assert additional_data['subMerchant.subSeller2.debitSettlementBank'] + assert additional_data['subMerchant.subSeller2.debitSettlementAgency'] + assert additional_data['subMerchant.subSeller2.debitSettlementAccountType'] + assert additional_data['subMerchant.subSeller2.debitSettlementAccount'] + assert additional_data['subMerchant.subSeller2.creditSettlementBank'] + assert additional_data['subMerchant.subSeller2.creditSettlementAgency'] + assert additional_data['subMerchant.subSeller2.creditSettlementAccountType'] + assert additional_data['subMerchant.subSeller2.creditSettlementAccount'] + end.respond_with(successful_authorize_response) + assert_success response + end + def test_extended_avs_response response = stub_comms do @gateway.verify(@credit_card, @options) @@ -608,10 +946,10 @@ def test_extended_avs_response end def test_optional_idempotency_key_header - options = @options.merge(:idempotency_key => 'test123') + options = @options.merge(idempotency_key: 'test123') 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 headers['Idempotency-Key'] end.respond_with(successful_authorize_response) assert_success response @@ -619,6 +957,16 @@ def test_optional_idempotency_key_header 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 pre_scrubbed <<-PRE_SCRUBBED opening connection to pal-test.adyen.com:443... @@ -763,7 +1111,7 @@ def failed_purchase_response RESPONSE end - def successful_authorize_with_elo_response + def simple_successful_authorize_response <<-RESPONSE { "pspReference":"8835511210681145", @@ -773,7 +1121,7 @@ def successful_authorize_with_elo_response RESPONSE end - def successful_capture_with_elo_repsonse + def simple_successful_capture_repsonse <<-RESPONSE { "pspReference":"8835511210689965", @@ -782,25 +1130,6 @@ def successful_capture_with_elo_repsonse RESPONSE end - def successful_authorize_with_cabal_response - <<-RESPONSE - { - "pspReference":"883567090118045A", - "resultCode":"Authorised", - "authCode":"77651" - } - RESPONSE - end - - def successful_capture_with_cabal_repsonse - <<-RESPONSE - { - "pspReference":"883567090119063C", - "response":"[capture-received]" - } - RESPONSE - end - def successful_authorize_response <<-RESPONSE { @@ -830,6 +1159,26 @@ def failed_authorize_response RESPONSE end + def failed_authorize_3ds2_response + <<-RESPONSE + { + "additionalData": + { + "threeds2.threeDS2Result.dsTransID": "1111-abc-234", + "threeds2.threeDS2Result.eci":"07", + "threeds2.threeDS2Result.threeDSServerTransID":"222-cde-321", + "threeds2.threeDS2Result.transStatusReason":"01", + "threeds2.threeDS2Result.messageVersion":"2.1.0", + "threeds2.threeDS2Result.authenticationValue":"ABCDEFG", + "threeds2.threeDS2Result.transStatus":"N" + }, + "pspReference":"8514775559925128", + "refusalReason":"3D Not Authenticated", + "resultCode":"Refused" + } + RESPONSE + end + def successful_capture_response <<-RESPONSE { @@ -870,6 +1219,26 @@ def failed_refund_response RESPONSE end + def successful_credit_response + <<-RESPONSE + { + "pspReference": "883614109029400G", + "resultCode": "Received" + } + RESPONSE + end + + def failed_credit_response + <<-RESPONSE + { + "status":422, + "errorCode":"130", + "message":"Reference Missing", + "errorType":"validation" + } + RESPONSE + end + def successful_void_response <<-RESPONSE { @@ -948,6 +1317,12 @@ def failed_authorize_avs_response RESPONSE end + def successful_tokenize_only_store_response + <<-RESPONSE + {"alias":"P481159492341538","aliasType":"Default","pspReference":"881574707964582B","recurringDetailReference":"8415747079647045","result":"Success"} + RESPONSE + end + def successful_store_response <<-RESPONSE {"additionalData":{"recurring.recurringDetailReference":"8315202663743702","recurring.shopperReference":"John Smith"},"pspReference":"8835205392522157","resultCode":"Authorised","authCode":"94571"} @@ -960,6 +1335,18 @@ def failed_store_response RESPONSE end + def successful_unstore_response + <<-RESPONSE + {"response":"[detail-successfully-disabled]"} + RESPONSE + end + + def failed_unstore_response + <<-RESPONSE + {"status":422,"errorCode":"800","message":"Contract not found","errorType":"validation"} + RESPONSE + end + def extended_avs_response <<-RESPONSE {\"additionalData\":{\"cvcResult\":\"1 Matches\",\"cvcResultRaw\":\"Y\",\"avsResult\":\"20 Name, address and zip match\",\"avsResultRaw\":\"M\"}} diff --git a/test/unit/gateways/allied_wallet_test.rb b/test/unit/gateways/allied_wallet_test.rb index fb291c7c4b4..9da275b48bd 100644 --- a/test/unit/gateways/allied_wallet_test.rb +++ b/test/unit/gateways/allied_wallet_test.rb @@ -78,7 +78,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(/123456/, data) end.respond_with(successful_void_response) @@ -88,7 +88,7 @@ def test_successful_void 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) @@ -105,7 +105,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(/123456/, data) end.respond_with(successful_refund_response) diff --git a/test/unit/gateways/authorize_net_arb_test.rb b/test/unit/gateways/authorize_net_arb_test.rb index 5c18ff468ff..2b32c503d60 100644 --- a/test/unit/gateways/authorize_net_arb_test.rb +++ b/test/unit/gateways/authorize_net_arb_test.rb @@ -6,8 +6,8 @@ class AuthorizeNetArbTest < Test::Unit::TestCase def setup ActiveMerchant.expects(:deprecated).with('ARB functionality in ActiveMerchant is deprecated and will be removed in a future version. Please contact the ActiveMerchant maintainers if you have an interest in taking ownership of a separate gem that continues support for it.') @gateway = AuthorizeNetArbGateway.new( - :login => 'X', - :password => 'Y' + login: 'X', + password: 'Y' ) @amount = 100 @credit_card = credit_card @@ -19,16 +19,15 @@ def test_successful_recurring @gateway.expects(:ssl_post).returns(successful_recurring_response) response = @gateway.recurring(@amount, @credit_card, - :billing_address => address.merge(:first_name => 'Jim', :last_name => 'Smith'), - :interval => { - :length => 10, - :unit => :days + billing_address: address.merge(first_name: 'Jim', last_name: 'Smith'), + interval: { + length: 10, + unit: :days }, - :duration => { - :start_date => Time.now.strftime('%Y-%m-%d'), - :occurrences => 30 - } - ) + duration: { + start_date: Time.now.strftime('%Y-%m-%d'), + occurrences: 30 + }) assert_instance_of Response, response assert response.success? @@ -39,7 +38,7 @@ def test_successful_recurring def test_successful_update_recurring @gateway.expects(:ssl_post).returns(successful_update_recurring_response) - response = @gateway.update_recurring(:subscription_id => @subscription_id, :amount => @amount * 2) + response = @gateway.update_recurring(subscription_id: @subscription_id, amount: @amount * 2) assert_instance_of Response, response assert response.success? @@ -69,73 +68,73 @@ def test_successful_status_recurring end def test_expdate_formatting - assert_equal '2009-09', @gateway.send(:expdate, credit_card('4111111111111111', :month => '9', :year => '2009')) - assert_equal '2013-11', @gateway.send(:expdate, credit_card('4111111111111111', :month => '11', :year => '2013')) + assert_equal '2009-09', @gateway.send(:expdate, credit_card('4111111111111111', month: '9', year: '2009')) + assert_equal '2013-11', @gateway.send(:expdate, credit_card('4111111111111111', month: '11', year: '2013')) end private def successful_recurring_response - <<-XML - - Sample - - Ok - - I00001 - Successful. - - - #{@subscription_id} - + <<~XML + + Sample + + Ok + + I00001 + Successful. + + + #{@subscription_id} + XML end def successful_update_recurring_response - <<-XML - - Sample - - Ok - - I00001 - Successful. - - - #{@subscription_id} - + <<~XML + + Sample + + Ok + + I00001 + Successful. + + + #{@subscription_id} + XML end def successful_cancel_recurring_response - <<-XML - - Sample - - Ok - - I00001 - Successful. - - - #{@subscription_id} - + <<~XML + + Sample + + Ok + + I00001 + Successful. + + + #{@subscription_id} + XML end def successful_status_recurring_response - <<-XML - - Sample - - Ok - - I00001 - Successful. - - - #{@subscription_status} - + <<~XML + + Sample + + Ok + + I00001 + Successful. + + + #{@subscription_status} + XML end end diff --git a/test/unit/gateways/authorize_net_cim_test.rb b/test/unit/gateways/authorize_net_cim_test.rb index 1d9bd462192..c126f364cb0 100644 --- a/test/unit/gateways/authorize_net_cim_test.rb +++ b/test/unit/gateways/authorize_net_cim_test.rb @@ -5,8 +5,8 @@ class AuthorizeNetCimTest < Test::Unit::TestCase def setup @gateway = AuthorizeNetCimGateway.new( - :login => 'X', - :password => 'Y' + login: 'X', + password: 'Y' ) @amount = 100 @credit_card = credit_card @@ -15,40 +15,40 @@ def setup @customer_payment_profile_id = '7813' @customer_address_id = '4321' @payment = { - :credit_card => @credit_card + credit_card: @credit_card } @profile = { - :merchant_customer_id => 'Up to 20 chars', # Optional - :description => 'Up to 255 Characters', # Optional - :email => 'Up to 255 Characters', # Optional - :payment_profiles => { # Optional - :customer_type => 'individual or business', # Optional - :bill_to => @address, - :payment => @payment + merchant_customer_id: 'Up to 20 chars', # Optional + description: 'Up to 255 Characters', # Optional + email: 'Up to 255 Characters', # Optional + payment_profiles: { # Optional + customer_type: 'individual or business', # Optional + bill_to: @address, + payment: @payment }, - :ship_to_list => { - :first_name => 'John', - :last_name => 'Doe', - :company => 'Widgets, Inc', - :address1 => '1234 Fake Street', - :city => 'Anytown', - :state => 'MD', - :zip => '12345', - :country => 'USA', - :phone_number => '(123)123-1234', # Optional - Up to 25 digits (no letters) - :fax_number => '(123)123-1234' # Optional - Up to 25 digits (no letters) + ship_to_list: { + first_name: 'John', + last_name: 'Doe', + company: 'Widgets, Inc', + address1: '1234 Fake Street', + city: 'Anytown', + state: 'MD', + zip: '12345', + country: 'USA', + phone_number: '(123)123-1234', # Optional - Up to 25 digits (no letters) + fax_number: '(123)123-1234' # Optional - Up to 25 digits (no letters) } } @options = { - :ref_id => '1234', # Optional - :profile => @profile + ref_id: '1234', # Optional + profile: @profile } end def test_expdate_formatting - assert_equal '2009-09', @gateway.send(:expdate, credit_card('4111111111111111', :month => '9', :year => '2009')) - assert_equal '2013-11', @gateway.send(:expdate, credit_card('4111111111111111', :month => '11', :year => '2013')) - assert_equal 'XXXX', @gateway.send(:expdate, credit_card('XXXX1234', :month => nil, :year => nil)) + assert_equal '2009-09', @gateway.send(:expdate, credit_card('4111111111111111', month: '9', year: '2009')) + assert_equal '2013-11', @gateway.send(:expdate, credit_card('4111111111111111', month: '11', year: '2013')) + assert_equal 'XXXX', @gateway.send(:expdate, credit_card('XXXX1234', month: nil, year: nil)) end def test_should_create_customer_profile_request @@ -65,13 +65,13 @@ def test_should_create_customer_payment_profile_request @gateway.expects(:ssl_post).returns(successful_create_customer_payment_profile_response) assert response = @gateway.create_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :payment_profile => { - :customer_type => 'individual', - :bill_to => @address, - :payment => @payment + customer_profile_id: @customer_profile_id, + payment_profile: { + customer_type: 'individual', + bill_to: @address, + payment: @payment }, - :validation_mode => :test + validation_mode: :test ) assert_instance_of Response, response assert_success response @@ -83,17 +83,17 @@ def test_should_create_customer_shipping_address_request @gateway.expects(:ssl_post).returns(successful_create_customer_shipping_address_response) assert response = @gateway.create_customer_shipping_address( - :customer_profile_id => @customer_profile_id, - :address => { - :first_name => 'John', - :last_name => 'Doe', - :company => 'Widgets, Inc', - :address1 => '1234 Fake Street', - :city => 'Anytown', - :state => 'MD', - :country => 'USA', - :phone_number => '(123)123-1234', - :fax_number => '(123)123-1234' + customer_profile_id: @customer_profile_id, + address: { + first_name: 'John', + last_name: 'Doe', + company: 'Widgets, Inc', + address1: '1234 Fake Street', + city: 'Anytown', + state: 'MD', + country: 'USA', + phone_number: '(123)123-1234', + fax_number: '(123)123-1234' } ) assert_instance_of Response, response @@ -106,11 +106,11 @@ def test_should_create_customer_profile_transaction_auth_only_and_then_prior_aut @gateway.expects(:ssl_post).returns(successful_create_customer_profile_transaction_response(:auth_only)) assert response = @gateway.create_customer_profile_transaction( - :transaction => { - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :type => :auth_only, - :amount => @amount + transaction: { + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + type: :auth_only, + amount: @amount } ) assert_instance_of Response, response @@ -163,12 +163,12 @@ def test_should_create_customer_profile_transaction_auth_only_and_then_prior_aut @gateway.expects(:ssl_post).returns(successful_create_customer_profile_transaction_response(:prior_auth_capture)) assert response = @gateway.create_customer_profile_transaction( - :transaction => { - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :type => :prior_auth_capture, - :amount => @amount, - :trans_id => trans_id + transaction: { + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + type: :prior_auth_capture, + amount: @amount, + trans_id: trans_id } ) assert_instance_of Response, response @@ -187,11 +187,11 @@ def test_should_create_customer_profile_transaction_auth_only_and_then_capture_o @gateway.expects(:ssl_post).returns(successful_create_customer_profile_transaction_response(:auth_only)) assert response = @gateway.create_customer_profile_transaction( - :transaction => { - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :type => :auth_only, - :amount => @amount + transaction: { + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + type: :auth_only, + amount: @amount } ) assert_instance_of Response, response @@ -204,12 +204,12 @@ def test_should_create_customer_profile_transaction_auth_only_and_then_capture_o @gateway.expects(:ssl_post).returns(successful_create_customer_profile_transaction_response(:capture_only)) assert response = @gateway.create_customer_profile_transaction( - :transaction => { - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :type => :capture_only, - :amount => @amount, - :approval_code => approval_code + transaction: { + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + type: :capture_only, + amount: @amount, + approval_code: approval_code } ) assert_instance_of Response, response @@ -221,17 +221,17 @@ def test_should_create_customer_profile_transaction_auth_capture_request @gateway.expects(:ssl_post).returns(successful_create_customer_profile_transaction_response(:auth_capture)) assert response = @gateway.create_customer_profile_transaction( - :transaction => { - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :type => :auth_capture, - :order => { - :invoice_number => '1234', - :description => 'Test Order Description', - :purchase_order_number => '4321' + transaction: { + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + type: :auth_capture, + order: { + invoice_number: '1234', + description: 'Test Order Description', + purchase_order_number: '4321' }, - :amount => @amount, - :card_code => '123' + amount: @amount, + card_code: '123' } ) assert_instance_of Response, response @@ -245,16 +245,16 @@ def test_should_create_customer_profile_transaction_auth_capture_request_for_ver @gateway.expects(:ssl_post).returns(successful_create_customer_profile_transaction_response(:auth_capture_version_3_1)) assert response = @gateway.create_customer_profile_transaction( - :transaction => { - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :type => :auth_capture, - :order => { - :invoice_number => '1234', - :description => 'Test Order Description', - :purchase_order_number => '4321' + transaction: { + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + type: :auth_capture, + order: { + invoice_number: '1234', + description: 'Test Order Description', + purchase_order_number: '4321' }, - :amount => @amount + amount: @amount } ) assert_instance_of Response, response @@ -311,7 +311,7 @@ def test_should_create_customer_profile_transaction_auth_capture_request_for_ver def test_should_delete_customer_profile_request @gateway.expects(:ssl_post).returns(successful_delete_customer_profile_response) - assert response = @gateway.delete_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.delete_customer_profile(customer_profile_id: @customer_profile_id) assert_instance_of Response, response assert_success response assert_equal @customer_profile_id, response.authorization @@ -320,7 +320,7 @@ def test_should_delete_customer_profile_request def test_should_delete_customer_payment_profile_request @gateway.expects(:ssl_post).returns(successful_delete_customer_payment_profile_response) - assert response = @gateway.delete_customer_payment_profile(:customer_profile_id => @customer_profile_id, :customer_payment_profile_id => @customer_payment_profile_id) + assert response = @gateway.delete_customer_payment_profile(customer_profile_id: @customer_profile_id, customer_payment_profile_id: @customer_payment_profile_id) assert_instance_of Response, response assert_success response assert_nil response.authorization @@ -329,7 +329,7 @@ def test_should_delete_customer_payment_profile_request def test_should_delete_customer_shipping_address_request @gateway.expects(:ssl_post).returns(successful_delete_customer_shipping_address_response) - assert response = @gateway.delete_customer_shipping_address(:customer_profile_id => @customer_profile_id, :customer_address_id => @customer_address_id) + assert response = @gateway.delete_customer_shipping_address(customer_profile_id: @customer_profile_id, customer_address_id: @customer_address_id) assert_instance_of Response, response assert_success response assert_nil response.authorization @@ -338,7 +338,7 @@ def test_should_delete_customer_shipping_address_request def test_should_get_customer_profile_request @gateway.expects(:ssl_post).returns(successful_get_customer_profile_response) - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert_instance_of Response, response assert_success response assert_equal @customer_profile_id, response.authorization @@ -355,7 +355,7 @@ def test_should_get_customer_profile_ids_request def test_should_get_customer_profile_request_with_multiple_payment_profiles @gateway.expects(:ssl_post).returns(successful_get_customer_profile_response_with_multiple_payment_profiles) - assert response = @gateway.get_customer_profile(:customer_profile_id => @customer_profile_id) + assert response = @gateway.get_customer_profile(customer_profile_id: @customer_profile_id) assert_instance_of Response, response assert_success response @@ -367,9 +367,9 @@ def test_should_get_customer_payment_profile_request @gateway.expects(:ssl_post).returns(successful_get_customer_payment_profile_response) assert response = @gateway.get_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :unmask_expiration_date => true + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + unmask_expiration_date: true ) assert_instance_of Response, response assert_success response @@ -382,8 +382,8 @@ def test_should_get_customer_shipping_address_request @gateway.expects(:ssl_post).returns(successful_get_customer_shipping_address_response) assert response = @gateway.get_customer_shipping_address( - :customer_profile_id => @customer_profile_id, - :customer_address_id => @customer_address_id + customer_profile_id: @customer_profile_id, + customer_address_id: @customer_address_id ) assert_instance_of Response, response assert_success response @@ -394,9 +394,9 @@ def test_should_update_customer_profile_request @gateway.expects(:ssl_post).returns(successful_update_customer_profile_response) assert response = @gateway.update_customer_profile( - :profile => { - :customer_profile_id => @customer_profile_id, - :email => 'new email address' + profile: { + customer_profile_id: @customer_profile_id, + email: 'new email address' } ) assert_instance_of Response, response @@ -408,10 +408,10 @@ def test_should_update_customer_payment_profile_request @gateway.expects(:ssl_post).returns(successful_update_customer_payment_profile_response) assert response = @gateway.update_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :payment_profile => { - :customer_payment_profile_id => @customer_payment_profile_id, - :customer_type => 'business' + customer_profile_id: @customer_profile_id, + payment_profile: { + customer_payment_profile_id: @customer_payment_profile_id, + customer_type: 'business' } ) assert_instance_of Response, response @@ -420,21 +420,21 @@ def test_should_update_customer_payment_profile_request end def test_should_update_customer_payment_profile_request_with_last_four_digits - last_four_credit_card = ActiveMerchant::Billing::CreditCard.new(:number => '4242') # Credit card with only last four digits + last_four_credit_card = ActiveMerchant::Billing::CreditCard.new(number: '4242') # Credit card with only last four digits response = stub_comms do @gateway.update_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :payment_profile => { - :customer_payment_profile_id => @customer_payment_profile_id, - :bill_to => address(:address1 => '345 Avenue B', - :address2 => 'Apt 101'), - :payment => { - :credit_card => last_four_credit_card + customer_profile_id: @customer_profile_id, + payment_profile: { + customer_payment_profile_id: @customer_payment_profile_id, + bill_to: address(address1: '345 Avenue B', + address2: 'Apt 101'), + payment: { + credit_card: last_four_credit_card } } ) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match %r{XXXX4242}, data end.respond_with(successful_update_customer_payment_profile_response) @@ -447,10 +447,10 @@ def test_should_update_customer_shipping_address_request @gateway.expects(:ssl_post).returns(successful_update_customer_shipping_address_response) assert response = @gateway.update_customer_shipping_address( - :customer_profile_id => @customer_profile_id, - :address => { - :customer_address_id => @customer_address_id, - :city => 'New City' + customer_profile_id: @customer_profile_id, + address: { + customer_address_id: @customer_address_id, + city: 'New City' } ) assert_instance_of Response, response @@ -462,10 +462,10 @@ def test_should_validate_customer_payment_profile_request @gateway.expects(:ssl_post).returns(successful_validate_customer_payment_profile_response) assert response = @gateway.validate_customer_payment_profile( - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :customer_address_id => @customer_address_id, - :validation_mode => :live + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + customer_address_id: @customer_address_id, + validation_mode: :live ) assert_instance_of Response, response assert_success response @@ -478,9 +478,9 @@ def test_should_create_customer_profile_transaction_auth_capture_and_then_void_r @gateway.expects(:ssl_post).returns(successful_create_customer_profile_transaction_response(:void)) assert response = @gateway.create_customer_profile_transaction( - :transaction => { - :type => :void, - :trans_id => response.params['direct_response']['transaction_id'] + transaction: { + type: :void, + trans_id: response.params['direct_response']['transaction_id'] } ) assert_instance_of Response, response @@ -495,12 +495,12 @@ def test_should_create_customer_profile_transaction_auth_capture_and_then_refund @gateway.expects(:ssl_post).returns(unsuccessful_create_customer_profile_transaction_response(:refund)) assert response = @gateway.create_customer_profile_transaction( - :transaction => { - :type => :refund, - :amount => 1, - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :trans_id => response.params['direct_response']['transaction_id'] + transaction: { + type: :refund, + amount: 1, + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + trans_id: response.params['direct_response']['transaction_id'] } ) assert_instance_of Response, response @@ -519,13 +519,13 @@ def test_should_create_customer_profile_transaction_auth_capture_and_then_refund @gateway.expects(:ssl_post).returns(unsuccessful_create_customer_profile_transaction_response(:refund)) assert response = @gateway.create_customer_profile_transaction( - :transaction => { - :type => :refund, - :amount => 1, + transaction: { + type: :refund, + amount: 1, - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :trans_id => response.params['direct_response']['transaction_id'] + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + trans_id: response.params['direct_response']['transaction_id'] } ) assert_instance_of Response, response @@ -559,9 +559,9 @@ def test_should_create_customer_profile_transaction_for_void_request @gateway.expects(:ssl_post).returns(successful_create_customer_profile_transaction_response(:void)) assert response = @gateway.create_customer_profile_transaction_for_void( - :transaction => { - :trans_id => 1 - } + transaction: { + trans_id: 1 + } ) assert_instance_of Response, response assert_success response @@ -573,11 +573,11 @@ def test_should_create_customer_profile_transaction_for_refund_request @gateway.expects(:ssl_post).returns(successful_create_customer_profile_transaction_response(:refund)) assert response = @gateway.create_customer_profile_transaction_for_refund( - :transaction => { - :trans_id => 1, - :amount => '1.00', - :credit_card_number_masked => 'XXXX1234' - } + transaction: { + trans_id: 1, + amount: '1.00', + credit_card_number_masked: 'XXXX1234' + } ) assert_instance_of Response, response assert_success response @@ -588,21 +588,21 @@ def test_should_create_customer_profile_transaction_for_refund_request def test_should_create_customer_profile_transaction_passing_recurring_flag response = stub_comms do @gateway.create_customer_profile_transaction( - :transaction => { - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :type => :auth_capture, - :order => { - :invoice_number => '1234', - :description => 'Test Order Description', - :purchase_order_number => '4321' + transaction: { + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + type: :auth_capture, + order: { + invoice_number: '1234', + description: 'Test Order Description', + purchase_order_number: '4321' }, - :amount => @amount, - :card_code => '123', - :recurring_billing => true + amount: @amount, + card_code: '123', + recurring_billing: true } ) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match %r{true}, data end.respond_with(successful_create_customer_profile_transaction_response(:auth_capture)) @@ -623,13 +623,13 @@ def test_full_or_masked_card_number def test_multiple_errors_when_creating_customer_profile @gateway.expects(:ssl_post).returns(unsuccessful_create_customer_profile_transaction_response_with_multiple_errors(:refund)) assert response = @gateway.create_customer_profile_transaction( - :transaction => { - :type => :refund, - :amount => 1, + transaction: { + type: :refund, + amount: 1, - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :trans_id => 1 + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + trans_id: 1 } ) assert_equal 'The transaction was unsuccessful.', response.message @@ -642,11 +642,11 @@ def get_auth_only_response @gateway.expects(:ssl_post).returns(successful_create_customer_profile_transaction_response(:auth_only)) assert response = @gateway.create_customer_profile_transaction( - :transaction => { - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :type => :auth_only, - :amount => @amount + transaction: { + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + type: :auth_only, + amount: @amount } ) assert_instance_of Response, response @@ -662,16 +662,16 @@ def get_and_validate_auth_capture_response @gateway.expects(:ssl_post).returns(successful_create_customer_profile_transaction_response(:auth_capture)) assert response = @gateway.create_customer_profile_transaction( - :transaction => { - :customer_profile_id => @customer_profile_id, - :customer_payment_profile_id => @customer_payment_profile_id, - :type => :auth_capture, - :order => { - :invoice_number => '1234', - :description => 'Test Order Description', - :purchase_order_number => '4321' + transaction: { + customer_profile_id: @customer_profile_id, + customer_payment_profile_id: @customer_payment_profile_id, + type: :auth_capture, + order: { + invoice_number: '1234', + description: 'Test Order Description', + purchase_order_number: '4321' }, - :amount => @amount + amount: @amount } ) assert_instance_of Response, response @@ -1003,16 +1003,16 @@ def successful_update_customer_shipping_address_response end SUCCESSFUL_DIRECT_RESPONSE = { - :auth_only => '1,1,1,This transaction has been approved.,Gw4NGI,Y,508223659,,,100.00,CC,auth_only,Up to 20 chars,,,,,,,,,,,Up to 255 Characters,,,,,,,,,,,,,,6E5334C13C78EA078173565FD67318E4,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,', - :capture_only => '1,1,1,This transaction has been approved.,,Y,508223660,,,100.00,CC,capture_only,Up to 20 chars,,,,,,,,,,,Up to 255 Characters,,,,,,,,,,,,,,6E5334C13C78EA078173565FD67318E4,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,', - :auth_capture => '1,1,1,This transaction has been approved.,d1GENk,Y,508223661,32968c18334f16525227,Store purchase,1.00,CC,auth_capture,,Longbob,Longsen,,,,,,,,,,,,,,,,,,,,,,,269862C030129C1173727CC10B1935ED,M,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,', - :void => '1,1,1,This transaction has been approved.,nnCMEx,P,2149222068,1245879759,,0.00,CC,void,1245879759,,,,,,,K1C2N6,,,,,,,,,,,,,,,,,,F240D65BB27ADCB8C80410B92342B22C,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,', - :refund => '1,1,1,This transaction has been approved.,nnCMEx,P,2149222068,1245879759,,0.00,CC,refund,1245879759,,,,,,,K1C2N6,,,,,,,,,,,,,,,,,,F240D65BB27ADCB8C80410B92342B22C,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,', - :prior_auth_capture => '1,1,1,This transaction has been approved.,VR0lrD,P,2149227870,1245958544,,1.00,CC,prior_auth_capture,1245958544,,,,,,,K1C2N6,,,,,,,,,,,,,,,,,,0B8BFE0A0DE6FDB69740ED20F79D04B0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,', - :auth_capture_version_3_1 => '1,1,1,This transaction has been approved.,CSYM0K,Y,2163585627,1234,Test Order Description,100.00,CC,auth_capture,Up to 20 chars,,,Widgets Inc,1234 My Street,Ottawa,ON,K1C2N6,CA,,,Up to 255 Characters,,,,,,,,,,,,,4321,02DFBD7934AD862AB16688D44F045D31,,2,,,,,,,,,,,XXXX4242,Visa,,,,,,,,,,,,,,,,' + auth_only: '1,1,1,This transaction has been approved.,Gw4NGI,Y,508223659,,,100.00,CC,auth_only,Up to 20 chars,,,,,,,,,,,Up to 255 Characters,,,,,,,,,,,,,,6E5334C13C78EA078173565FD67318E4,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,', + capture_only: '1,1,1,This transaction has been approved.,,Y,508223660,,,100.00,CC,capture_only,Up to 20 chars,,,,,,,,,,,Up to 255 Characters,,,,,,,,,,,,,,6E5334C13C78EA078173565FD67318E4,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,', + auth_capture: '1,1,1,This transaction has been approved.,d1GENk,Y,508223661,32968c18334f16525227,Store purchase,1.00,CC,auth_capture,,Longbob,Longsen,,,,,,,,,,,,,,,,,,,,,,,269862C030129C1173727CC10B1935ED,M,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,', + void: '1,1,1,This transaction has been approved.,nnCMEx,P,2149222068,1245879759,,0.00,CC,void,1245879759,,,,,,,K1C2N6,,,,,,,,,,,,,,,,,,F240D65BB27ADCB8C80410B92342B22C,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,', + refund: '1,1,1,This transaction has been approved.,nnCMEx,P,2149222068,1245879759,,0.00,CC,refund,1245879759,,,,,,,K1C2N6,,,,,,,,,,,,,,,,,,F240D65BB27ADCB8C80410B92342B22C,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,', + prior_auth_capture: '1,1,1,This transaction has been approved.,VR0lrD,P,2149227870,1245958544,,1.00,CC,prior_auth_capture,1245958544,,,,,,,K1C2N6,,,,,,,,,,,,,,,,,,0B8BFE0A0DE6FDB69740ED20F79D04B0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,', + auth_capture_version_3_1: '1,1,1,This transaction has been approved.,CSYM0K,Y,2163585627,1234,Test Order Description,100.00,CC,auth_capture,Up to 20 chars,,,Widgets Inc,1234 My Street,Ottawa,ON,K1C2N6,CA,,,Up to 255 Characters,,,,,,,,,,,,,4321,02DFBD7934AD862AB16688D44F045D31,,2,,,,,,,,,,,XXXX4242,Visa,,,,,,,,,,,,,,,,' } UNSUCCESSUL_DIRECT_RESPONSE = { - :refund => '3,2,54,The referenced transaction does not meet the criteria for issuing a credit.,,P,0,,,1.00,CC,credit,1245952682,,,Widgets Inc,1245952682 My Street,Ottawa,ON,K1C2N6,CA,,,bob1245952682@email.com,,,,,,,,,,,,,,207BCBBF78E85CF174C87AE286B472D2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,447250,406104' + refund: '3,2,54,The referenced transaction does not meet the criteria for issuing a credit.,,P,0,,,1.00,CC,credit,1245952682,,,Widgets Inc,1245952682 My Street,Ottawa,ON,K1C2N6,CA,,,bob1245952682@email.com,,,,,,,,,,,,,,207BCBBF78E85CF174C87AE286B472D2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,447250,406104' } def successful_create_customer_profile_transaction_response(transaction_type) diff --git a/test/unit/gateways/authorize_net_test.rb b/test/unit/gateways/authorize_net_test.rb index 9c444ad6b3a..ebeaf01876c 100644 --- a/test/unit/gateways/authorize_net_test.rb +++ b/test/unit/gateways/authorize_net_test.rb @@ -17,7 +17,7 @@ def setup @credit_card = credit_card @check = check @apple_pay_payment_token = ActiveMerchant::Billing::ApplePayPaymentToken.new( - {data: 'encoded_payment_data'}, + { data: 'encoded_payment_data' }, payment_instrument_name: 'SomeBank Visa', payment_network: 'Visa', transaction_identifier: 'transaction123' @@ -76,7 +76,7 @@ def test_add_swipe_data_with_bad_data @credit_card.track_data = BAD_TRACK_DATA stub_comms do @gateway.purchase(@amount, @credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_nil doc.at_xpath('//track1') assert_nil doc.at_xpath('//track2') @@ -89,7 +89,7 @@ def test_add_swipe_data_with_track_1 @credit_card.track_data = TRACK1_DATA stub_comms do @gateway.purchase(@amount, @credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_equal '%B378282246310005^LONGSON/LONGBOB^1705101130504392?', doc.at_xpath('//track1').content assert_nil doc.at_xpath('//track2') @@ -102,7 +102,7 @@ def test_add_swipe_data_with_track_2 @credit_card.track_data = TRACK2_DATA stub_comms do @gateway.purchase(@amount, @credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_nil doc.at_xpath('//track1') assert_equal ';4111111111111111=1803101000020000831?', doc.at_xpath('//track2').content @@ -116,7 +116,7 @@ def test_retail_market_type_device_type_included_in_swipe_transactions_with_vali @credit_card.track_data = track stub_comms do @gateway.purchase(@amount, @credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_nil doc.at_xpath('//retail') end @@ -127,7 +127,7 @@ def test_retail_market_type_device_type_included_in_swipe_transactions_with_vali @credit_card.track_data = track stub_comms do @gateway.purchase(@amount, @credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_not_nil doc.at_xpath('//retail') assert_equal '2', doc.at_xpath('//retail/marketType').content @@ -141,8 +141,8 @@ def test_device_type_used_from_options_if_included_with_valid_track_data [TRACK1_DATA, TRACK2_DATA].each do |track| @credit_card.track_data = track stub_comms do - @gateway.purchase(@amount, @credit_card, {device_type: 1}) - end.check_request do |endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, { device_type: 1 }) + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_not_nil doc.at_xpath('//retail') assert_equal '2', doc.at_xpath('//retail/marketType').content @@ -156,7 +156,7 @@ def test_market_type_not_included_for_apple_pay_or_echeck [@check, @apple_pay_payment_token].each do |payment| stub_comms do @gateway.purchase(@amount, payment) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_nil doc.at_xpath('//retail') end @@ -168,7 +168,7 @@ def test_moto_market_type_included_when_card_is_entered_manually @credit_card.manual_entry = true stub_comms do @gateway.purchase(@amount, @credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_not_nil doc.at_xpath('//retail') assert_equal '1', doc.at_xpath('//retail/marketType').content @@ -179,7 +179,7 @@ def test_moto_market_type_included_when_card_is_entered_manually def test_market_type_can_be_specified stub_comms do @gateway.purchase(@amount, @credit_card, market_type: 0) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_equal '0', doc.at_xpath('//retail/marketType').content end @@ -189,7 +189,7 @@ def test_market_type_can_be_specified def test_successful_echeck_authorization response = stub_comms do @gateway.authorize(@amount, @check) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_not_nil doc.at_xpath('//payment/bankAccount') assert_equal '244183602', doc.at_xpath('//routingNumber').content @@ -207,12 +207,13 @@ def test_successful_echeck_authorization assert_equal '508141794', response.authorization.split('#')[0] end - def test_successful_echeck_purchase + def test_successful_echeck_purchase_with_checking_account_type response = stub_comms do @gateway.purchase(@amount, @check) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_not_nil doc.at_xpath('//payment/bankAccount') + assert_equal 'checking', doc.at_xpath('//accountType').content assert_equal '244183602', doc.at_xpath('//routingNumber').content assert_equal '15378535', doc.at_xpath('//accountNumber').content assert_equal 'Bank of Elbonia', doc.at_xpath('//bankName').content @@ -228,10 +229,27 @@ def test_successful_echeck_purchase assert_equal '508141795', response.authorization.split('#')[0] end + def test_successful_echeck_purchase_with_savings_account_type + savings_account = check(account_type: 'savings') + response = stub_comms do + @gateway.purchase(@amount, savings_account) + end.check_request do |_endpoint, data, _headers| + parse(data) do |doc| + assert_not_nil doc.at_xpath('//payment/bankAccount') + assert_equal 'savings', doc.at_xpath('//accountType').content + end + end.respond_with(successful_purchase_response) + + assert response + assert_instance_of Response, response + assert_success response + assert_equal '508141795', response.authorization.split('#')[0] + end + def test_echeck_passing_recurring_flag response = stub_comms do @gateway.purchase(@amount, @check, recurring: true) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_equal settings_from_doc(parse(data))['recurringBilling'], 'true' end.respond_with(successful_purchase_response) @@ -248,7 +266,7 @@ def test_failed_echeck_authorization def test_successful_apple_pay_authorization response = stub_comms do @gateway.authorize(@amount, @apple_pay_payment_token) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_equal @gateway.class::APPLE_PAY_DATA_DESCRIPTOR, doc.at_xpath('//opaqueData/dataDescriptor').content assert_equal Base64.strict_encode64(@apple_pay_payment_token.payment_data.to_json), doc.at_xpath('//opaqueData/dataValue').content @@ -264,7 +282,7 @@ def test_successful_apple_pay_authorization def test_successful_apple_pay_purchase response = stub_comms do @gateway.purchase(@amount, @apple_pay_payment_token) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_equal @gateway.class::APPLE_PAY_DATA_DESCRIPTOR, doc.at_xpath('//opaqueData/dataDescriptor').content assert_equal Base64.strict_encode64(@apple_pay_payment_token.payment_data.to_json), doc.at_xpath('//opaqueData/dataValue').content @@ -310,7 +328,7 @@ def test_successful_purchase def test_successful_purchase_with_utf_character stub_comms do @gateway.purchase(@amount, credit_card('4000100011112224', last_name: 'Wåhlin')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/Wåhlin/, data) end.respond_with(successful_purchase_response) end @@ -318,7 +336,7 @@ def test_successful_purchase_with_utf_character def test_passes_partial_auth stub_comms do @gateway.purchase(@amount, credit_card, disable_partial_auth: true) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/allowPartialAuth<\/settingName>/, data) assert_match(/false<\/settingValue>/, data) end.respond_with(successful_purchase_response) @@ -327,14 +345,14 @@ def test_passes_partial_auth def test_passes_email_customer stub_comms do @gateway.purchase(@amount, credit_card, email_customer: true) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/emailCustomer<\/settingName>/, data) assert_match(/true<\/settingValue>/, data) end.respond_with(successful_purchase_response) stub_comms do @gateway.purchase(@amount, credit_card, email_customer: false) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/emailCustomer<\/settingName>/, data) assert_match(/false<\/settingValue>/, data) end.respond_with(successful_purchase_response) @@ -343,7 +361,7 @@ def test_passes_email_customer def test_passes_header_email_receipt stub_comms do @gateway.purchase(@amount, credit_card, header_email_receipt: 'yet another field') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/headerEmailReceipt<\/settingName>/, data) assert_match(/yet another field<\/settingValue>/, data) end.respond_with(successful_purchase_response) @@ -352,7 +370,7 @@ def test_passes_header_email_receipt def test_passes_level_3_options stub_comms do @gateway.purchase(@amount, credit_card, @options.merge(@level_3_options)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(//, data) assert_match(/#{@level_3_options[:summary_commodity_code]}<\/summaryCommodityCode>/, data) assert_match(/<\/order>/, data) @@ -366,7 +384,7 @@ def test_passes_level_3_options def test_passes_line_items stub_comms do @gateway.purchase(@amount, credit_card, @options.merge(@additional_options)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(//, data) assert_match(//, data) assert_match(/#{@additional_options[:line_items][0][:item_id]}<\/itemId>/, data) @@ -387,7 +405,7 @@ def test_passes_line_items def test_passes_level_3_line_items stub_comms do @gateway.purchase(@amount, credit_card, @options.merge(@level_3_line_item_options)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(//, data) assert_match(//, data) assert_match(/#{@level_3_line_item_options[:line_items][0][:item_id]}<\/itemId>/, data) @@ -456,7 +474,7 @@ def test_successful_purchase_using_stored_card_and_custom_delimiter @gateway.expects(:ssl_post).returns(successful_purchase_using_stored_card_response_with_pipe_delimiter) - response = @gateway.purchase(@amount, store.authorization, {delimiter: '|', description: 'description, with, commas'}) + response = @gateway.purchase(@amount, store.authorization, { delimiter: '|', description: 'description, with, commas' }) assert_success response assert_equal '2235700270#XXXX2224#cim_purchase', response.authorization @@ -467,6 +485,23 @@ def test_successful_purchase_using_stored_card_and_custom_delimiter assert_equal 'description, with, commas', response.params['order_description'] end + def test_successful_purchase_using_stored_card_and_custom_delimiter_with_quotes + @gateway.expects(:ssl_post).returns(successful_store_response) + store = @gateway.store(@credit_card, @options) + assert_success store + + @gateway.expects(:ssl_post).returns(successful_purchase_using_stored_card_response_with_pipe_delimiter_and_quotes) + + response = @gateway.purchase(@amount, store.authorization, { delimiter: '|', description: 'description, with, commas' }) + assert_success response + + assert_equal '12345667#XXXX1111#cim_purchase', response.authorization + assert_equal 'Y', response.avs_result['code'] + assert response.avs_result['street_match'] + assert response.avs_result['postal_match'] + assert_equal 'Street address and 5-digit postal code match.', response.avs_result['message'] + end + def test_failed_purchase_using_stored_card @gateway.expects(:ssl_post).returns(successful_store_response) store = @gateway.store(@credit_card, @options) @@ -504,6 +539,59 @@ def test_successful_authorize_and_capture_using_stored_card assert_equal 'This transaction has been approved.', capture.message end + def test_successful_auth_with_initial_stored_credential + stored_credential_params = { + initial_transaction: true, + reason_type: 'unscheduled', + initiator: 'merchant', + network_transaction_id: nil + } + auth = stub_comms do + @gateway.authorize(@amount, @credit_card, @options.merge({ stored_credential: stored_credential_params })) + end.check_request do |_endpoint, data, _headers| + doc = parse(data) + assert_equal 'true', doc.at_xpath('//processingOptions/isFirstSubsequentAuth').content + end.respond_with(successful_authorize_response) + assert_success auth + assert auth.authorization + end + + def test_successful_auth_with_installment_stored_credential + stored_credential_params = { + initial_transaction: false, + reason_type: 'installment', + initiator: 'merchant', + network_transaction_id: '0123' + } + auth = stub_comms do + @gateway.authorize(@amount, @credit_card, @options.merge({ stored_credential: stored_credential_params })) + end.check_request do |_endpoint, data, _headers| + doc = parse(data) + assert_equal 'true', doc.at_xpath('//processingOptions/isSubsequentAuth').content + end.respond_with(successful_authorize_response) + assert_success auth + assert auth.authorization + end + + def test_successful_auth_with_recurring_stored_credential + stored_credential_params = { + initial_transaction: false, + reason_type: 'recurring', + initiator: 'merchant', + network_transaction_id: '0123' + } + auth = stub_comms do + @gateway.authorize(@amount, @credit_card, @options.merge({ stored_credential: stored_credential_params })) + end.check_request do |_endpoint, data, _headers| + doc = parse(data) + assert_equal 'true', doc.at_xpath('//processingOptions/isSubsequentAuth').content + assert_equal 'recurringBilling', doc.at_xpath('//transactionSettings/setting/settingName').content + assert_equal 'true', doc.at_xpath('//transactionSettings/setting/settingValue').content + end.respond_with(successful_authorize_response) + assert_success auth + assert auth.authorization + end + def test_failed_authorize_using_stored_card @gateway.expects(:ssl_post).returns(successful_store_response) store = @gateway.store(@credit_card, @options) @@ -675,7 +763,7 @@ def test_failed_store def test_successful_unstore response = stub_comms do @gateway.unstore('35959426#32506918#cim_store') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| doc = parse(data) assert_equal '35959426', doc.at_xpath('//deleteCustomerProfileRequest/customerProfileId').content end.respond_with(successful_unstore_response) @@ -715,8 +803,8 @@ def test_failed_store_new_payment_profile def test_address stub_comms do - @gateway.authorize(@amount, @credit_card, billing_address: {address1: '164 Waverley Street', country: 'US', state: 'CO', phone: '(555)555-5555', fax: '(555)555-4444'}) - end.check_request do |endpoint, data, headers| + @gateway.authorize(@amount, @credit_card, billing_address: { address1: '164 Waverley Street', country: 'US', state: 'CO', phone: '(555)555-5555', fax: '(555)555-4444' }) + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_equal 'CO', doc.at_xpath('//billTo/state').content, data assert_equal '164 Waverley Street', doc.at_xpath('//billTo/address').content, data @@ -730,7 +818,7 @@ def test_address def test_address_with_empty_billing_address stub_comms do @gateway.authorize(@amount, @credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_equal '', doc.at_xpath('//billTo/address').content, data assert_equal '', doc.at_xpath('//billTo/city').content, data @@ -743,8 +831,8 @@ def test_address_with_empty_billing_address def test_address_with_address2_present stub_comms do - @gateway.authorize(@amount, @credit_card, billing_address: {address1: '164 Waverley Street', address2: 'Apt 1234', country: 'US', state: 'CO', phone: '(555)555-5555', fax: '(555)555-4444'}) - end.check_request do |endpoint, data, headers| + @gateway.authorize(@amount, @credit_card, billing_address: { address1: '164 Waverley Street', address2: 'Apt 1234', country: 'US', state: 'CO', phone: '(555)555-5555', fax: '(555)555-4444' }) + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_equal 'CO', doc.at_xpath('//billTo/state').content, data assert_equal '164 Waverley Street Apt 1234', doc.at_xpath('//billTo/address').content, data @@ -757,8 +845,8 @@ def test_address_with_address2_present def test_address_north_america_with_defaults stub_comms do - @gateway.authorize(@amount, @credit_card, billing_address: {address1: '164 Waverley Street', country: 'US'}) - end.check_request do |endpoint, data, headers| + @gateway.authorize(@amount, @credit_card, billing_address: { address1: '164 Waverley Street', country: 'US' }) + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_equal 'NC', doc.at_xpath('//billTo/state').content, data assert_equal '164 Waverley Street', doc.at_xpath('//billTo/address').content, data @@ -769,8 +857,8 @@ def test_address_north_america_with_defaults def test_address_outsite_north_america stub_comms do - @gateway.authorize(@amount, @credit_card, billing_address: {address1: '164 Waverley Street', country: 'DE'}) - end.check_request do |endpoint, data, headers| + @gateway.authorize(@amount, @credit_card, billing_address: { address1: '164 Waverley Street', country: 'DE' }) + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_equal 'n/a', doc.at_xpath('//billTo/state').content, data assert_equal '164 Waverley Street', doc.at_xpath('//billTo/address').content, data @@ -781,8 +869,8 @@ def test_address_outsite_north_america def test_address_outsite_north_america_with_address2_present stub_comms do - @gateway.authorize(@amount, @credit_card, billing_address: {address1: '164 Waverley Street', address2: 'Apt 1234', country: 'DE'}) - end.check_request do |endpoint, data, headers| + @gateway.authorize(@amount, @credit_card, billing_address: { address1: '164 Waverley Street', address2: 'Apt 1234', country: 'DE' }) + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_equal 'n/a', doc.at_xpath('//billTo/state').content, data assert_equal '164 Waverley Street Apt 1234', doc.at_xpath('//billTo/address').content, data @@ -794,7 +882,7 @@ def test_address_outsite_north_america_with_address2_present def test_duplicate_window stub_comms do @gateway.purchase(@amount, @credit_card, duplicate_window: 0) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_equal settings_from_doc(parse(data))['duplicateWindow'], '0' end.respond_with(successful_purchase_response) end @@ -813,7 +901,7 @@ def test_duplicate_window_class_attribute_deprecated def test_add_cardholder_authentication_value stub_comms do @gateway.purchase(@amount, @credit_card, cardholder_authentication_value: 'E0Mvq8AAABEiMwARIjNEVWZ3iJk=', authentication_indicator: '2') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_equal 'E0Mvq8AAABEiMwARIjNEVWZ3iJk=', doc.at_xpath('//cardholderAuthentication/cardholderAuthenticationValue').content assert_equal '2', doc.at_xpath('//cardholderAuthentication/authenticationIndicator').content @@ -826,7 +914,7 @@ def test_alternative_three_d_secure_options three_d_secure_opts = { cavv: 'E0Mvq8AAABEiMwARIjNEVWZ3iJk=', eci: '2' } stub_comms do @gateway.purchase(@amount, @credit_card, three_d_secure: three_d_secure_opts) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_equal 'E0Mvq8AAABEiMwARIjNEVWZ3iJk=', doc.at_xpath('//cardholderAuthentication/cardholderAuthenticationValue').content assert_equal '2', doc.at_xpath('//cardholderAuthentication/authenticationIndicator').content @@ -845,7 +933,7 @@ def test_prioritize_authentication_value_params authentication_indicator: '2', three_d_secure: three_d_secure_opts ) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_equal 'E0Mvq8AAABEiMwARIjNEVWZ3iJk=', doc.at_xpath('//cardholderAuthentication/cardholderAuthenticationValue').content assert_equal '2', doc.at_xpath('//cardholderAuthentication/authenticationIndicator').content @@ -857,7 +945,7 @@ def test_prioritize_authentication_value_params def test_capture_passing_extra_info response = stub_comms do @gateway.capture(50, '123456789', description: 'Yo', order_id: 'Sweetness') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_not_nil doc.at_xpath('//order/description'), data assert_equal 'Yo', doc.at_xpath('//order/description').content, data @@ -880,7 +968,7 @@ def test_successful_refund def test_successful_bank_refund response = stub_comms do @gateway.refund(50, '12345667', account_type: 'checking', routing_number: '123450987', account_number: '12345667', first_name: 'Louise', last_name: 'Belcher') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_equal 'checking', doc.at_xpath('//transactionRequest/payment/bankAccount/accountType').content assert_equal '123450987', doc.at_xpath('//transactionRequest/payment/bankAccount/routingNumber').content @@ -894,7 +982,7 @@ def test_successful_bank_refund def test_refund_passing_extra_info response = stub_comms do @gateway.refund(50, '123456789', card_number: @credit_card.number, first_name: 'Bob', last_name: 'Smith', zip: '12345', order_id: '1', description: 'Refund for order 1') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_equal 'Bob', doc.at_xpath('//billTo/firstName').content, data assert_equal 'Smith', doc.at_xpath('//billTo/lastName').content, data @@ -935,11 +1023,11 @@ def test_failed_credit end def test_supported_countries - assert_equal 4, (['US', 'CA', 'AU', 'VA'] & AuthorizeNetGateway.supported_countries).size + assert_equal 3, (%w[US CA AU] & AuthorizeNetGateway.supported_countries).size end def test_supported_card_types - assert_equal [:visa, :master, :american_express, :discover, :diners_club, :jcb, :maestro], AuthorizeNetGateway.supported_cardtypes + assert_equal %i[visa master american_express discover diners_club jcb maestro], AuthorizeNetGateway.supported_cardtypes end def test_failure_without_response_reason_text @@ -1002,7 +1090,7 @@ def test_solution_id_is_added_to_post_data_parameters @gateway.class.application_id = 'A1000000' stub_comms do @gateway.authorize(@amount, @credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| doc = parse(data) assert_equal 'A1000000', fields_from_doc(doc)['x_solution_id'], data assert_equal '1.00', doc.at_xpath('//transactionRequest/amount').content @@ -1025,7 +1113,7 @@ def assert_no_has_customer_id(data) def test_include_cust_id_for_numeric_values stub_comms do @gateway.purchase(@amount, @credit_card, customer: '123') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_not_nil doc.at_xpath('//customer/id'), data assert_equal '123', doc.at_xpath('//customer/id').content, data @@ -1037,7 +1125,7 @@ def test_include_cust_id_for_numeric_values def test_include_cust_id_for_word_character_values stub_comms do @gateway.purchase(@amount, @credit_card, customer: '4840_TT') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_not_nil doc.at_xpath('//customer/id'), data assert_equal '4840_TT', doc.at_xpath('//customer/id').content, data @@ -1049,7 +1137,7 @@ def test_include_cust_id_for_word_character_values def test_dont_include_cust_id_for_email_addresses stub_comms do @gateway.purchase(@amount, @credit_card, customer: 'bob@test.com') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| doc = parse(data) assert !doc.at_xpath('//customer/id'), data assert_equal '1.00', doc.at_xpath('//transactionRequest/amount').content @@ -1059,7 +1147,7 @@ def test_dont_include_cust_id_for_email_addresses def test_dont_include_cust_id_for_phone_numbers stub_comms do @gateway.purchase(@amount, @credit_card, customer: '111-123-1231') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| doc = parse(data) assert !doc.at_xpath('//customer/id'), data assert_equal '1.00', doc.at_xpath('//transactionRequest/amount').content @@ -1079,7 +1167,7 @@ def test_includes_shipping_name_when_different_from_billing_name stub_comms do @gateway.purchase(@amount, card, options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_equal 'billing', doc.at_xpath('//billTo/firstName').text assert_equal 'name', doc.at_xpath('//billTo/lastName').text @@ -1104,7 +1192,7 @@ def test_includes_shipping_name_when_passed_as_options stub_comms do @gateway.purchase(@amount, card, options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_equal 'billing', doc.at_xpath('//billTo/firstName').text assert_equal 'name', doc.at_xpath('//billTo/lastName').text @@ -1117,8 +1205,7 @@ def test_includes_shipping_name_when_passed_as_options def test_truncation card = credit_card('4242424242424242', first_name: 'a' * 51, - last_name: 'a' * 51 - ) + last_name: 'a' * 51) options = { order_id: 'a' * 21, @@ -1144,7 +1231,7 @@ def test_truncation stub_comms do @gateway.purchase(@amount, card, options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_truncated(data, 20, '//refId') assert_truncated(data, 255, '//description') assert_address_truncated(data, 50, 'firstName') @@ -1164,7 +1251,7 @@ def test_invalid_cvv card = credit_card(@credit_card.number, { verification_value: cvv }) stub_comms do @gateway.purchase(@amount, card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) { |doc| assert_nil doc.at_xpath('//cardCode') } end.respond_with(successful_purchase_response) end @@ -1174,7 +1261,7 @@ def test_card_number_truncation card = credit_card(@credit_card.number + '0123456789') stub_comms do @gateway.purchase(@amount, card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_equal @credit_card.number, doc.at_xpath('//cardNumber').text end @@ -1191,12 +1278,11 @@ def test_supports_scrubbing? def test_successful_apple_pay_authorization_with_network_tokenization credit_card = network_tokenization_credit_card('4242424242424242', - :payment_cryptogram => '111111111100cryptogram' - ) + payment_cryptogram: '111111111100cryptogram') response = stub_comms do @gateway.authorize(@amount, credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_equal credit_card.payment_cryptogram, doc.at_xpath('//creditCard/cryptogram').content assert_equal credit_card.number, doc.at_xpath('//creditCard/cardNumber').content @@ -1211,12 +1297,11 @@ def test_successful_apple_pay_authorization_with_network_tokenization def test_failed_apple_pay_authorization_with_network_tokenization_not_supported credit_card = network_tokenization_credit_card('4242424242424242', - :payment_cryptogram => '111111111100cryptogram' - ) + payment_cryptogram: '111111111100cryptogram') response = stub_comms do @gateway.authorize(@amount, credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_equal credit_card.payment_cryptogram, doc.at_xpath('//creditCard/cryptogram').content assert_equal credit_card.number, doc.at_xpath('//creditCard/cardNumber').content @@ -1229,7 +1314,7 @@ def test_failed_apple_pay_authorization_with_network_tokenization_not_supported def test_supports_network_tokenization_true response = stub_comms do @gateway.supports_network_tokenization? - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_equal 'authOnlyTransaction', doc.at_xpath('//transactionType').content assert_equal '0.01', doc.at_xpath('//amount').content @@ -1244,7 +1329,7 @@ def test_supports_network_tokenization_true def test_supports_network_tokenization_false response = stub_comms do @gateway.supports_network_tokenization? - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_equal 'authOnlyTransaction', doc.at_xpath('//transactionType').content assert_equal '0.01', doc.at_xpath('//amount').content @@ -1357,7 +1442,7 @@ def assert_address_truncated(data, expected_size, field) end def successful_purchase_response - <<-eos + <<-XML - eos + XML end def fraud_review_response - <<-eos + <<-XML - eos + XML end def address_not_provided_avs_response - <<-eos + <<-XML - eos + XML end def no_match_cvv_response - <<-eos + <<-XML - eos + XML end def no_match_avs_response - <<-eos + <<-XML - eos + XML end def failed_purchase_response - <<-eos + <<-XML @@ -1584,11 +1669,11 @@ def failed_purchase_response - eos + XML end def no_message_response - <<-eos + <<-XML @@ -1620,11 +1705,11 @@ def no_message_response - eos + XML end def successful_purchase_response_test_mode - <<-eos + <<-XML - eos + XML end def successful_authorize_response - <<-eos + <<-XML @@ -1703,11 +1788,11 @@ def successful_authorize_response - eos + XML end def failed_authorize_response - <<-eos + <<-XML @@ -1749,11 +1834,11 @@ def failed_authorize_response - eos + XML end def successful_capture_response - <<-eos + <<-XML @@ -1784,11 +1869,11 @@ def successful_capture_response - eos + XML end def already_actioned_capture_response - <<-eos + <<-XML @@ -1819,11 +1904,11 @@ def already_actioned_capture_response - eos + XML end def failed_capture_response - <<-eos + <<-XML Error @@ -1852,11 +1937,11 @@ def failed_capture_response - eos + XML end def successful_refund_response - <<-eos + <<-XML @@ -1886,11 +1971,11 @@ def successful_refund_response - eos + XML end def failed_refund_response - <<-eos + <<-XML @@ -1920,11 +2005,11 @@ def failed_refund_response - eos + XML end def successful_void_response - <<-eos + <<-XML @@ -1955,11 +2040,11 @@ def successful_void_response - eos + XML end def failed_void_response - <<-eos + <<-XML @@ -1991,11 +2076,11 @@ def failed_void_response - eos + XML end def successful_credit_response - <<-eos + <<-XML 1 @@ -2032,11 +2117,11 @@ def successful_credit_response - eos + XML end def failed_credit_response - <<-eos + <<-XML 1 @@ -2073,11 +2158,11 @@ def failed_credit_response - eos + XML end def successful_store_response - <<-eos + <<-XML @@ -2094,11 +2179,11 @@ def successful_store_response - eos + XML end def failed_store_response - <<-eos + <<-XML @@ -2112,11 +2197,11 @@ def failed_store_response - eos + XML end def successful_unstore_response - <<-eos + <<-XML @@ -2127,11 +2212,11 @@ def successful_unstore_response - eos + XML end def failed_unstore_response - <<-eos + <<-XML @@ -2142,11 +2227,11 @@ def failed_unstore_response - eos + XML end def successful_store_new_payment_profile_response - <<-eos + <<-XML @@ -2159,11 +2244,11 @@ def successful_store_new_payment_profile_response 38392170 34896759 - eos + XML end def failed_store_new_payment_profile_response - <<-eos + <<-XML @@ -2176,11 +2261,11 @@ def failed_store_new_payment_profile_response 38392767 34897359 - eos + XML end def successful_purchase_using_stored_card_response - <<-eos + <<-XML 1 @@ -2193,11 +2278,11 @@ def successful_purchase_using_stored_card_response 1,1,1,This transaction has been approved.,8HUT72,Y,2235700270,1,Store Purchase,1.01,CC,auth_capture,e385c780422f4bd182c4,Longbob,Longsen,,,,n/a,,,,,,,,,,,,,,,,,,,4A20EEAF89018FF075899DDB332E9D35,,2,,,,,,,,,,,XXXX2224,Visa,,,,,,,,,,,,,,,, - eos + XML end def successful_purchase_using_stored_card_response_with_pipe_delimiter - <<-eos + <<-XML 1 @@ -2210,11 +2295,15 @@ def successful_purchase_using_stored_card_response_with_pipe_delimiter 1|1|1|This transaction has been approved.|8HUT72|Y|2235700270|1|description, with, commas|1.01|CC|auth_capture|e385c780422f4bd182c4|Longbob|Longsen||||n/a|||||||||||||||||||4A20EEAF89018FF075899DDB332E9D35||2|||||||||||XXXX2224|Visa|||||||||||||||| - eos + XML + end + + def successful_purchase_using_stored_card_response_with_pipe_delimiter_and_quotes + "\xEF\xBB\xBF12345OkI00001Successful.\"1\"|\"1\"|\"1\"|\"This transaction has been approved.\"|\"001234\"|\"Y\"|\"12345667\"|\"654321\"|\"\"|\"39.95\"|\"CC\"|\"auth_capture\"|\"54321\"|\"Jane\"|\"Doe\"|\"\"|\"1 Main St.\"|\"Durham\"|\"NC\"|\"27707\"|\"US\"|\"\"|\"\"|\"test@example.com\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"XXXX1111\"|\"Visa\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"|\"\"" end def failed_purchase_using_stored_card_response - <<-eos + <<-XML 1 @@ -2227,11 +2316,11 @@ def failed_purchase_using_stored_card_response 3,1,6,The credit card number is invalid.,,P,0,1,Store Purchase,1.01,CC,auth_capture,2da01d7b583c706106e2,Longbob,Longsen,,,,n/a,,,,,,,,,,,,,,,,,,,13BA28EEA3593C13E2E3BC109D16E5D2,,,,,,,,,,,,,XXXX1222,,,,,,,,,,,,,,,,, - eos + XML end def successful_authorize_using_stored_card_response - <<-eos + <<-XML 1 @@ -2244,11 +2333,11 @@ def successful_authorize_using_stored_card_response 1,1,1,This transaction has been approved.,GGHQ5R,Y,2235700640,1,Store Purchase,1.01,CC,auth_only,0bde9d39f8eb9443f2af,Longbob,Longsen,,,,n/a,,,,,,,,,,,,,,,,,,,E47E5CA4F1239B00D39A7F8C147215D3,,2,,,,,,,,,,,XXXX2224,Visa,,,,,,,,,,,,,,,, - eos + XML end def failed_authorize_using_stored_card_response - <<-eos + <<-XML 1 @@ -2261,11 +2350,11 @@ def failed_authorize_using_stored_card_response 3,1,6,The credit card number is invalid.,,P,0,1,Store Purchase,1.01,CC,auth_only,f632442ce056f9f82ee9,Longbob,Longsen,,,,n/a,,,,,,,,,,,,,,,,,,,13BA28EEA3593C13E2E3BC109D16E5D2,,,,,,,,,,,,,XXXX1222,,,,,,,,,,,,,,,,, - eos + XML end def successful_capture_using_stored_card_response - <<-eos + <<-XML @@ -2278,11 +2367,11 @@ def successful_capture_using_stored_card_response 1,1,1,This transaction has been approved.,GGHQ5R,P,2235700640,1,,1.01,CC,prior_auth_capture,0bde9d39f8eb9443f2af,,,,,,,,,,,,,,,,,,,,,,,,,E47E5CA4F1239B00D39A7F8C147215D3,,,,,,,,,,,,,XXXX2224,Visa,,,,,,,,,,,,,,,, - eos + XML end def failed_capture_using_stored_card_response - <<-eos + <<-XML @@ -2295,11 +2384,11 @@ def failed_capture_using_stored_card_response 3,2,47,The amount requested for settlement cannot be greater than the original amount authorized.,,P,0,,,41.01,CC,prior_auth_capture,,,,,,,,,,,,,,,,,,,,,,,,,,8A556B125A1DA070AF5A84B798B7FBF7,,,,,,,,,,,,,,Visa,,,,,,,,,,,,,,,, - eos + XML end def failed_refund_using_stored_card_response - <<-eos + <<-XML 1 @@ -2311,11 +2400,11 @@ def failed_refund_using_stored_card_response - eos + XML end def successful_void_using_stored_card_response - <<-eos + <<-XML @@ -2328,11 +2417,11 @@ def successful_void_using_stored_card_response 1,1,1,This transaction has been approved.,3R9YE2,P,2235701141,1,,0.00,CC,void,becdb509b35a32c30e97,,,,,,,,,,,,,,,,,,,,,,,,,C3C4B846B9D5A37D14462C2BF5B924FD,,,,,,,,,,,,,XXXX2224,Visa,,,,,,,,,,,,,,,, - eos + XML end def failed_void_using_stored_card_response - <<-eos + <<-XML @@ -2345,11 +2434,11 @@ def failed_void_using_stored_card_response 1,1,310,This transaction has already been voided.,,P,0,,,0.00,CC,void,,,,,,,,,,,,,,,,,,,,,,,,,,FD9FAE70BEF461997A6C15D7D597658D,,,,,,,,,,,,,,Visa,,,,,,,,,,,,,,,, - eos + XML end def network_tokenization_not_supported_response - <<-eos + <<-XML @@ -2391,11 +2480,11 @@ def network_tokenization_not_supported_response - eos + XML end def credentials_are_legit_response - <<-eos + <<-XML @@ -2406,11 +2495,11 @@ def credentials_are_legit_response - eos + XML end def credentials_are_bogus_response - <<-eos + <<-XML @@ -2421,11 +2510,11 @@ def credentials_are_bogus_response - eos + XML end def failed_refund_for_unsettled_payment_response - <<-eos + <<-XML @@ -2457,6 +2546,6 @@ def failed_refund_for_unsettled_payment_response - eos + XML end end diff --git a/test/unit/gateways/axcessms_test.rb b/test/unit/gateways/axcessms_test.rb index e87a092498b..c4b0c9bfd12 100644 --- a/test/unit/gateways/axcessms_test.rb +++ b/test/unit/gateways/axcessms_test.rb @@ -21,12 +21,12 @@ def setup ip: '0.0.0.0', mode: @mode, billing_address: { - :address1 => '10 Marklar St', - :address2 => 'Musselburgh', - :city => 'Dunedin', - :zip => '9013', - :state => 'Otago', - :country => 'NZ' + address1: '10 Marklar St', + address2: 'Musselburgh', + city: 'Dunedin', + zip: '9013', + state: 'Otago', + country: 'NZ' } } end @@ -106,13 +106,13 @@ def test_failed_void @gateway.expects(:ssl_post).returns(failed_void_response) response = @gateway.refund(@amount - 30, 'authorization', @options) assert_failure response - assert_equal 'Reference Error - reversal needs at least one successful transaction of type (CP or DB or RB or PA)', response.message + assert_equal 'Reference Error - reversal needs at least one successful transaction of type (CP or DB or RB or PA)', response.message end def test_authorize_using_reference_sets_proper_elements stub_comms do @gateway.authorize(@amount, 'MY_AUTHORIZE_VALUE', @options) - end.check_request do |endpoint, body, headers| + end.check_request do |_endpoint, body, _headers| assert_xpath_text(body, '//ReferenceID', 'MY_AUTHORIZE_VALUE') assert_no_match(//, body) end.respond_with(successful_authorize_response) @@ -121,7 +121,7 @@ def test_authorize_using_reference_sets_proper_elements def test_purchase_using_reference_sets_proper_elements stub_comms do @gateway.purchase(@amount, 'MY_AUTHORIZE_VALUE', @options) - end.check_request do |endpoint, body, headers| + end.check_request do |_endpoint, body, _headers| assert_xpath_text(body, '//ReferenceID', 'MY_AUTHORIZE_VALUE') assert_no_match(//, 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 4222e7b8e89..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 + { + "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 + { + "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 + { + "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 + { + "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 + { + "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 + { + "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' + { + "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 + { + "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 + { + "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 + { + "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 + { + "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 + { + "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 + { + "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 + { + "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 + { + "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 + { + "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..b28c2411e75 100644 --- a/test/unit/gateways/banwire_test.rb +++ b/test/unit/gateways/banwire_test.rb @@ -5,32 +5,33 @@ class BanwireTest < Test::Unit::TestCase def setup @gateway = BanwireGateway.new( - :login => 'desarrollo', - :currency => 'MXN') + login: 'desarrollo', + currency: 'MXN' + ) @credit_card = credit_card('5204164299999999', - :month => 11, - :year => 2012, - :verification_value => '999') + 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') + 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 +66,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 87ad0da5c0b..9b84e216b0c 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,14 @@ 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', @@ -108,7 +109,7 @@ def setup shopper_reference: 'John Smith', billing_address: address(), order_id: '123', - stored_credential: {reason_type: 'unscheduled'}, + stored_credential: { reason_type: 'unscheduled' }, three_ds_2: { channel: 'browser', browser_info: { @@ -139,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) @@ -154,7 +155,7 @@ def test_successful_authorize_with_house_number_and_street @gateway.authorize(@amount, @credit_card, @options_with_house_number_and_street) - end.check_request do |endpoint, data, headers| + 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) @@ -169,7 +170,7 @@ def test_successful_authorize_with_shipping_house_number_and_street @gateway.authorize(@amount, @credit_card, @options_with_shipping_house_number_and_shipping_street) - end.check_request do |endpoint, data, headers| + 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) @@ -196,7 +197,7 @@ def test_successful_authorize_with_extra_options shopper_statement: shopper_statement ) ) - end.check_request do |endpoint, data, headers| + 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) @@ -256,7 +257,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 @@ -267,7 +268,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) @@ -278,7 +279,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) @@ -288,7 +289,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 @@ -313,7 +314,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) @@ -327,9 +328,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) @@ -371,9 +372,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 @@ -382,9 +383,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 @@ -398,13 +399,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) @@ -597,5 +652,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..886a4479e1c 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) @@ -340,11 +341,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 +371,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 4f883818dd7..9e952cd6a56 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,21 +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]) @@ -40,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]) @@ -53,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]) @@ -66,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] @@ -76,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] @@ -88,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] @@ -96,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) @@ -121,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) @@ -133,8 +133,8 @@ 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', :doc_type => 'WEB'})) - 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) @@ -147,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) @@ -161,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) @@ -174,8 +174,8 @@ def test_deprecated_credit 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| + @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) @@ -183,11 +183,11 @@ def test_successful_credit_with_check 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 @@ -230,12 +230,11 @@ def test_successful_recurring 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 - ) + 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 assert_instance_of Response, response @@ -248,7 +247,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 diff --git a/test/unit/gateways/blue_snap_test.rb b/test/unit/gateways/blue_snap_test.rb index 541cc05a65d..1ea552b79f4 100644 --- a/test/unit/gateways/blue_snap_test.rb +++ b/test/unit/gateways/blue_snap_test.rb @@ -2,6 +2,16 @@ 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 @@ -10,6 +20,15 @@ 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: { @@ -30,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 @@ -40,6 +64,162 @@ 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: { @@ -58,6 +238,19 @@ def test_successful_purchase_with_unused_state_code 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) @@ -69,7 +262,7 @@ def test_successful_echeck_purchase 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| + 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) @@ -87,7 +280,7 @@ def test_successful_purchase_with_3ds_auth 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| + end.check_request do |_method, _url, data| assert_not_match(//, data) assert_not_match(//, data) assert_not_match(//, data) @@ -116,7 +309,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) @@ -127,7 +320,7 @@ def test_successful_authorize 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| + 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) @@ -153,7 +346,7 @@ def test_failed_authorize def test_successful_capture response = stub_comms(@gateway, :raw_ssl_request) do @gateway.capture(@amount, @credit_card, @options) - end.check_request do |method, url, data| + 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) @@ -165,7 +358,7 @@ def test_successful_capture 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| + end.check_request do |_method, _url, data| assert_match(/1.00<\/amount>/, data) assert_match(/USD<\/currency>/, data) end.respond_with(successful_capture_response) @@ -265,7 +458,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 @@ -291,12 +484,30 @@ def test_failed_forbidden_response 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 @@ -307,8 +518,33 @@ 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 + 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... @@ -400,6 +636,63 @@ 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 @@ -938,6 +1231,55 @@ def forbidden_response MockResponse.new(403, 'You are not authorized to perform this request due to inappropriate role permissions.') 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..4564a4d3096 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) @@ -125,71 +125,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..506b78c88cf 100644 --- a/test/unit/gateways/borgun_test.rb +++ b/test/unit/gateways/borgun_test.rb @@ -49,13 +49,30 @@ 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_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 +83,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 +100,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 +110,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 +118,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 diff --git a/test/unit/gateways/bpoint_test.rb b/test/unit/gateways/bpoint_test.rb index 3ee09b8c0e1..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,7 +135,7 @@ 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 @@ -133,7 +143,7 @@ def test_passing_biller_code 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| + 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) @@ -234,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 %( @@ -261,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 727fbd054d8..a154ab83b8d 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') @@ -96,7 +96,7 @@ def test_capture_transaction 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 +106,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 @@ -133,14 +133,14 @@ def test_user_agent_includes_activemerchant_version 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 +148,33 @@ 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_hold_in_escrow_can_be_specified @@ -182,7 +182,7 @@ 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_merchant_account_id_absent_if_not_provided @@ -195,61 +195,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 +257,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 +429,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 +446,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 +479,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 +510,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,46 +601,46 @@ 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_version_1 @@ -650,11 +650,11 @@ def test_three_d_secure_pass_thru_handling_version_1 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 @@ -672,7 +672,7 @@ def test_three_d_secure_pass_thru_handling_version_2 ))). returns(braintree_result) - @gateway.purchase(100, credit_card('41111111111111111111'), 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'), 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' }) end def test_three_d_secure_pass_thru_some_fields @@ -687,25 +687,45 @@ def test_three_d_secure_pass_thru_some_fields ))). returns(braintree_result) - @gateway.purchase(100, credit_card('41111111111111111111'), three_d_secure: {version: '2.0', cavv: 'cavv', eci: 'eci', ds_transaction_id: 'trans_id'}) + @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')) @@ -713,30 +733,37 @@ 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) + @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')) + 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) + 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')) + end.returns(braintree_result(cvv_response_code: 'B')) - response = @gateway.purchase(100, credit_card('41111111111111111111'), :skip_cvv => true) + 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'), account_type: 'credit') + end + def test_configured_logger_has_a_default # The default is actually provided by the Braintree gem, but we # assert its presence in order to show ActiveMerchant need not @@ -755,9 +782,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) @@ -774,9 +801,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) @@ -790,7 +817,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 @@ -799,8 +826,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 @@ -808,7 +835,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') @@ -820,102 +847,137 @@ 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')) + returns(braintree_result(id: 'transaction_id')) credit_card = network_tokenization_credit_card('4111111111111111', - :brand => 'visa', - :transaction_id => '123', - :eci => '05', - :payment_cryptogram => '111111111100cryptogram' - ) + 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 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, + 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' } ). - 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 => :android_pay, - :transaction_id => '1234567890' - ) + brand: 'visa', + eci: '05', + payment_cryptogram: '111111111100cryptogram', + source: :android_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 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, + 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' } ). - 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', + 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 @@ -924,7 +986,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? @@ -965,177 +1027,213 @@ 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 => '' - }) + 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)}) + @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 => '' - }) + 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')}) + @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' - }) + 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)}) + @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' - }) + 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')}) + @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 => '' - }) + 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)}) + @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 => '' - }) + 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')}) + @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' - }) + 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)}) + @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' - }) + 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')}) + @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 => '' - }) + 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)}) + @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 => '' - }) + 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')}) + @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' - }) + 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)}) + @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' - }) + 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')}) + @gateway.purchase(100, credit_card('41111111111111111111'), { test: true, order_id: '1', stored_credential: stored_credential(:merchant, :unscheduled, id: '123ABC') }) 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) @@ -1153,18 +1251,18 @@ def with_braintree_configuration_restoration(&block) 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 => '2020', - :cardholder_name => 'Longbob Longsen', + 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 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/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 c4736f57616..44e51252403 100644 --- a/test/unit/gateways/card_connect_test.rb +++ b/test/unit/gateways/card_connect_test.rb @@ -16,9 +16,19 @@ def setup } 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_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 +195,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) 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 917397db76b..97232894cbb 100644 --- a/test/unit/gateways/card_stream_test.rb +++ b/test/unit/gateways/card_stream_test.rb @@ -5,45 +5,49 @@ 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 - ) + 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_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' } + @amex = credit_card('374245455400001', + month: '12', + year: 2014, + verification_value: '4887', + brand: :american_express) + @declined_card = credit_card('4000300011112220', - :month => '9', - :year => '2014' - ) + month: '9', + year: '2014') end def test_successful_visacreditcard_authorization @@ -130,7 +134,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 +143,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 +151,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 +183,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 +211,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 +219,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 +227,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 +236,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 @@ -238,17 +250,25 @@ 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 +281,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,7 +296,7 @@ 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 @@ -340,16 +360,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 7ac004c8b0b..d9f3c0c2d29 100644 --- a/test/unit/gateways/cashnet_test.rb +++ b/test/unit/gateways/cashnet_test.rb @@ -55,7 +55,7 @@ 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 @@ -76,9 +76,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,7 +93,7 @@ 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) @@ -108,7 +108,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 +127,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 +136,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 +177,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\n

Object 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 + 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\n

Object 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\n

Object 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 + 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\n

Object 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_test.rb b/test/unit/gateways/cecabank_test.rb index 87ad7e20ab5..2641b1b6800 100644 --- a/test/unit/gateways/cecabank_test.rb +++ b/test/unit/gateways/cecabank_test.rb @@ -5,18 +5,18 @@ class CecabankTest < Test::Unit::TestCase def setup @gateway = CecabankGateway.new( - :merchant_id => '12345678', - :acquirer_bin => '12345678', - :terminal_id => '00000003', - :key => 'enc_key' + merchant_id: '12345678', + acquirer_bin: '12345678', + terminal_id: '00000003', + 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 141534eed8f..c76a2ddd433 100644 --- a/test/unit/gateways/checkout_v2_test.rb +++ b/test/unit/gateways/checkout_v2_test.rb @@ -18,7 +18,7 @@ def test_successful_purchase end.respond_with(successful_purchase_response) assert_success response - assert_equal 'pay_fj3xswqe3emuxckocjx6td73ni', response.authorization + assert_equal 'pay_bgv5tmah6fmuzcmcrcro6exe6m', response.authorization assert response.test? end @@ -41,6 +41,17 @@ def test_successful_purchase_includes_cvv_result assert_equal 'Y', response.cvv_result['code'] end + def test_successful_purchase_using_network_token + network_token = network_tokenization_credit_card({ source: :network_token }) + response = stub_comms do + @gateway.purchase(@amount, network_token) + 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_authorize_includes_avs_result response = stub_comms do @gateway.authorize(@amount, @credit_card) @@ -62,8 +73,8 @@ def test_successful_authorize_includes_cvv_result 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| + @gateway.purchase(@amount, @credit_card, { descriptor_city: 'london', descriptor_name: 'sherlock' }) + end.check_request do |_endpoint, data, _headers| assert_match(/"billing_descriptor\":{\"name\":\"sherlock\",\"city\":\"london\"}/, data) end.respond_with(successful_purchase_response) @@ -101,7 +112,7 @@ def test_successful_authorize_and_capture_with_additional_options previous_charge_id: 'pay_123' } @gateway.authorize(@amount, @credit_card, options) - end.check_request do |endpoint, data, headers| + end.check_request do |_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) @@ -120,10 +131,10 @@ def test_successful_authorize_and_capture_with_additional_options def test_moto_transaction_is_properly_set response = stub_comms do options = { - metadata: { manual_entry: true} + metadata: { manual_entry: true } } @gateway.authorize(@amount, @credit_card, options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{"payment_type":"MOTO"}, data) end.respond_with(successful_authorize_response) @@ -137,7 +148,7 @@ def test_3ds_passed callback_url: 'https://www.example.com' } @gateway.authorize(@amount, @credit_card, options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{"success_url"}, data) assert_match(%r{"failure_url"}, data) end.respond_with(successful_authorize_response) @@ -165,6 +176,7 @@ def test_successful_authorize_and_capture_with_3ds response = stub_comms do options = { execute_threed: true, + attempt_n3d: true, three_d_secure: { version: '1.0.2', eci: '05', @@ -256,7 +268,7 @@ def test_successful_refund end.respond_with(successful_purchase_response) assert_success response - assert_equal 'pay_fj3xswqe3emuxckocjx6td73ni', response.authorization + assert_equal 'pay_bgv5tmah6fmuzcmcrcro6exe6m', response.authorization refund = stub_comms do @gateway.refund(@amount, response.authorization) @@ -276,7 +288,7 @@ def test_failed_refund def test_successful_verify response = stub_comms 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 @@ -284,9 +296,9 @@ def test_successful_verify def test_failed_verify response = stub_comms 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_transcript_scrubbing @@ -299,7 +311,7 @@ def test_invalid_json end.respond_with(invalid_json_response) assert_failure response - assert_match %r{Unable to read error message}, 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 @@ -311,8 +323,17 @@ def test_error_code_returned assert_match(/request_invalid: card_expired/, response.error_code) end + def test_4xx_error_message + @gateway.expects(:ssl_post).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 private @@ -333,26 +354,16 @@ def post_scrubbed def successful_purchase_response %( - { - "id":"pay_fj3xswqe3emuxckocjx6td73ni", - "amount":200, - "currency":"USD", - "reference":"1", - "response_summary": "Approved", - "response_code":"10000", - "customer": { - "id": "cus_zvnv7gsblfjuxppycd7bx4erue", - "email": "longbob.longsen@example.com", - "name": "Sarah Mitchell" - }, - "source": { - "cvv_check":"Y", - "avs_check":"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 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 failed_purchase_response %( { @@ -511,6 +522,13 @@ def error_code_response ) 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"}}} @@ -522,4 +540,12 @@ 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..7c96c1c1308 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']) @@ -166,7 +166,7 @@ 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| + end.check_request do |_method, endpoint, _data, _headers| assert_match(/secure.na.tnspayments.com/, endpoint) end.respond_with(successful_capture_response) @@ -182,7 +182,7 @@ def test_asia_pacific_region_url response = stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, endpoint, _data, _headers| assert_match(/secure.ap.tnspayments.com/, endpoint) end.respond_with(successful_capture_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/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 a3403d44604..71a9a3368e4 100644 --- a/test/unit/gateways/credorax_test.rb +++ b/test/unit/gateways/credorax_test.rb @@ -22,8 +22,10 @@ def setup shipping_address: address(), order_id: '123', execute_threed: true, + three_ds_initiate: '03', + f23: '1', three_ds_challenge_window_size: '01', - stored_credential: {reason_type: 'unscheduled'}, + stored_credential: { reason_type: 'unscheduled' }, three_ds_2: { channel: 'browser', notification_url: 'www.example.com', @@ -44,13 +46,14 @@ def setup 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 @@ -74,11 +77,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 @@ -97,6 +101,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 @@ -109,21 +114,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 @@ -136,11 +143,12 @@ 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_failed_refund @@ -149,6 +157,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 @@ -159,6 +204,7 @@ def test_successful_credit assert_success response assert_equal '8a82944a53515706015359604c135301;;868f8b942fae639d28e27e8933d575d4;credit', response.authorization + assert_equal 'Succeeded', response.message assert response.test? end @@ -206,9 +252,11 @@ def test_adds_3d2_secure_fields 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_redirect_url=www.example.com/, data) assert_match(/3ds_challengewindowsize=01/, data) assert_match(/d5=unknown/, data) @@ -225,6 +273,38 @@ def test_adds_3d2_secure_fields 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_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 @@ -234,12 +314,13 @@ def test_adds_3d2_secure_fields end def test_purchase_adds_3d_secure_fields - options_with_3ds = @options.merge({eci: 'sample-eci', cavv: 'sample-cavv', xid: 'sample-xid'}) + 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| + 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 @@ -248,13 +329,34 @@ def test_purchase_adds_3d_secure_fields 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| - p data + end.check_request do |_endpoint, data, _headers| assert_match(/3ds_channel=03/, data) end.respond_with(successful_purchase_response) @@ -265,12 +367,13 @@ def test_3ds_channel_field_set_by_stored_credential_initiator end def test_authorize_adds_3d_secure_fields - options_with_3ds = @options.merge({eci: 'sample-eci', cavv: 'sample-cavv', xid: 'sample-xid'}) + 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| + 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 @@ -280,11 +383,11 @@ def test_authorize_adds_3d_secure_fields 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) @@ -295,7 +398,7 @@ def test_defaults_3d_secure_cavv_field_to_none_if_not_present end def test_adds_3ds2_fields_via_normalized_hash - version = '2.0' + version = '2' eci = '05' cavv = '637574652070757070792026206b697474656e73' ds_transaction_id = '97267598-FAE6-48F2-8083-C23433990FBC' @@ -310,15 +413,15 @@ def test_adds_3ds2_fields_via_normalized_hash stub_comms do @gateway.purchase(@amount, @credit_card, options_with_normalized_3ds) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/i8=#{eci}%3A#{cavv}%3Anone/, data) - assert_match(/3ds_version=#{version}/, 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.0' + version = '2.2.0' eci = '05' ds_transaction_id = '97267598-FAE6-48F2-8083-C23433990FBC' options_with_normalized_3ds = @options.merge( @@ -331,45 +434,55 @@ def test_adds_default_cavv_when_omitted_from_normalized_hash stub_comms do @gateway.purchase(@amount, @credit_card, options_with_normalized_3ds) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/i8=#{eci}%3Anone%3Anone/, data) - assert_match(/3ds_version=#{version}/, 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'}) + 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_authorize_adds_a9_field - options_with_3ds = @options.merge({transaction_type: '8'}) + 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| + 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'}) + 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| + 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 @@ -378,7 +491,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/a2=3/, data) end.respond_with(successful_purchase_response) end @@ -387,7 +500,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/h3=12345/, data) end.respond_with(successful_authorize_response) end @@ -400,7 +513,7 @@ def test_capture_adds_submerchant_id @options[:submerchant_id] = '12345' stub_comms do @gateway.capture(@amount, response.authorization, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/h3=12345/, data) end.respond_with(successful_capture_response) end @@ -413,7 +526,7 @@ def test_void_adds_submerchant_id @options[:submerchant_id] = '12345' stub_comms do @gateway.void(response.authorization, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/h3=12345/, data) end.respond_with(successful_void_response) end @@ -426,7 +539,7 @@ def test_refund_adds_submerchant_id @options[:submerchant_id] = '12345' stub_comms do @gateway.refund(@amount, response.authorization, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/h3=12345/, data) end.respond_with(successful_refund_response) end @@ -435,7 +548,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/h3=12345/, data) end.respond_with(successful_credit_response) end @@ -444,7 +557,7 @@ def test_supports_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 @@ -453,7 +566,7 @@ 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 @@ -462,7 +575,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/i2=abcdefghijkl/, data) end.respond_with(successful_authorize_response) end @@ -475,7 +588,7 @@ def test_capture_adds_billing_descriptor @options[:billing_descriptor] = 'abcdefghijkl' stub_comms do @gateway.capture(@amount, response.authorization, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/i2=abcdefghijkl/, data) end.respond_with(successful_capture_response) end @@ -488,7 +601,7 @@ def test_refund_adds_billing_descriptor @options[:billing_descriptor] = 'abcdefghijkl' stub_comms do @gateway.refund(@amount, response.authorization, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/i2=abcdefghijkl/, data) end.respond_with(successful_refund_response) end @@ -497,7 +610,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/i2=abcdefghijkl/, data) end.respond_with(successful_credit_response) end @@ -507,7 +620,7 @@ def test_purchase_adds_processor_fields @options[:processor_merchant_id] = '123' 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(/r1=TEST/, data) assert_match(/r2=123/, data) end.respond_with(successful_purchase_response) @@ -518,7 +631,7 @@ def test_authorize_adds_processor_fields @options[:processor_merchant_id] = '123' 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(/r1=TEST/, data) assert_match(/r2=123/, data) end.respond_with(successful_authorize_response) @@ -533,7 +646,7 @@ def test_capture_adds_processor_fields @options[:processor_merchant_id] = '123' stub_comms do @gateway.capture(@amount, response.authorization, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/r1=TEST/, data) assert_match(/r2=123/, data) end.respond_with(successful_capture_response) @@ -548,7 +661,7 @@ def test_void_adds_processor_fields @options[:processor_merchant_id] = '123' stub_comms do @gateway.void(response.authorization, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/r1=TEST/, data) assert_match(/r2=123/, data) end.respond_with(successful_void_response) @@ -563,7 +676,7 @@ def test_refund_adds_processor_fields @options[:processor_merchant_id] = '123' stub_comms do @gateway.refund(@amount, response.authorization, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/r1=TEST/, data) assert_match(/r2=123/, data) end.respond_with(successful_refund_response) @@ -574,17 +687,57 @@ def test_credit_adds_processor_fields @options[:processor_merchant_id] = '123' stub_comms do @gateway.credit(@amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| + 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_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| + end.check_request do |_endpoint, data, _headers| assert_match(/a9=9/, data) end.respond_with(successful_authorize_response) @@ -595,7 +748,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/a9=9/, data) end.respond_with(successful_authorize_response) @@ -606,7 +759,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/a9=1/, data) end.respond_with(successful_authorize_response) @@ -617,7 +770,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/a9=2/, data) end.respond_with(successful_authorize_response) @@ -628,7 +781,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/a9=9/, data) end.respond_with(successful_authorize_response) @@ -639,7 +792,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/a9=9/, data) end.respond_with(successful_authorize_response) @@ -650,7 +803,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/a9=8/, data) end.respond_with(successful_authorize_response) @@ -661,7 +814,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/a9=8/, data) end.respond_with(successful_authorize_response) @@ -672,7 +825,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/a9=9/, data) end.respond_with(successful_authorize_response) @@ -683,7 +836,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/a9=9/, data) end.respond_with(successful_authorize_response) @@ -694,7 +847,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/a9=8/, data) end.respond_with(successful_authorize_response) @@ -705,7 +858,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/a9=8/, data) end.respond_with(successful_authorize_response) @@ -716,7 +869,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/a9=2/, data) end.respond_with(successful_authorize_response) @@ -727,13 +880,48 @@ 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| + 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: 'JPY')) + 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 + private def stored_credential_options(*args, id: nil) @@ -786,6 +974,14 @@ 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' end diff --git a/test/unit/gateways/cyber_source_test.rb b/test/unit/gateways/cyber_source_test.rb index e0fb131d6ba..6de6047b715 100644 --- a/test/unit/gateways/cyber_source_test.rb +++ b/test/unit/gateways/cyber_source_test.rb @@ -8,49 +8,49 @@ 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') - @master_credit_card = credit_card('4111111111111111', :brand => 'master') - @elo_credit_card = credit_card('5067310000000010', :brand => 'elo') - @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') @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, + code: 'default', + description: 'Giant Walrus', + sku: 'WA323232323232323' }, { - :declared_value => @amount, - :quantity => 2, - :description => 'Marble Snowcone', - :sku => 'FAKE1232132113123' + declared_value: @amount, + quantity: 2, + description: 'Marble Snowcone', + sku: 'FAKE1232132113123' } ], - :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 } } @@ -90,7 +90,7 @@ def test_purchase_includes_customer_ip 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| + 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 @@ -98,15 +98,95 @@ def test_purchase_includes_issuer_additional_data 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| + end.check_request do |_endpoint, data, _headers| assert_match(/field2>CustomValue2.*field3>CustomValue3181537<\/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_merchant_descriptor + stub_comms do + @gateway.purchase(100, @credit_card, merchant_descriptor: 'Spreedly') + end.check_request do |_endpoint, data, _headers| + assert_match(/Spreedly<\/merchantDescriptor>/, 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| + 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 @@ -114,19 +194,35 @@ def test_authorize_includes_issuer_additional_data 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| + end.check_request do |_endpoint, data, _headers| assert_match(/field2>CustomValue2.*field3>CustomValue3181537<\/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| + 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_total_count + stub_comms do + @gateway.authorize(100, @credit_card, order_id: '1', installment_total_count: 5) + end.check_request do |_endpoint, data, _headers| + assert_match(/\s+5<\/totalCount>\s+<\/installment>/, data) + end.respond_with(successful_authorization_response) + end + def test_successful_check_purchase @gateway.expects(:ssl_post).returns(successful_purchase_response) @@ -140,7 +236,7 @@ def test_successful_check_purchase 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 @@ -148,20 +244,19 @@ def test_successful_pinless_debit_card_purchase 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) - assert response = @gateway.purchase(@amount, @credit_card, @options.merge( - ignore_avs: true - )) + options = @options.merge(ignore_avs: true) + assert response = @gateway.purchase(@amount, @credit_card, 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 @@ -170,35 +265,34 @@ 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 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 - )) + ignore_cvv: true + )) 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 - )) + ignore_cvv: false + )) assert_success response end @@ -263,6 +357,22 @@ 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_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) @@ -273,6 +383,14 @@ def test_successful_credit_card_capture_with_elo_request 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(/field2>CustomValue2.*field3>CustomValue3 generate_unique_id) + assert response = @gateway.unstore(response.authorization, order_id: generate_unique_id) assert response.success? assert response.test? end @@ -334,7 +452,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 @@ -373,6 +491,14 @@ def test_successful_credit_to_card_request assert_success(@gateway.credit(@amount, @credit_card, @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) @@ -382,22 +508,78 @@ def test_successful_credit_to_subscription_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(/field2>CustomValue2.*field3>CustomValue3\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(/field2>CustomValue2.*field3>CustomValue31.00<\/amount>), data end.respond_with(successful_update_subscription_response) end @@ -448,11 +630,10 @@ def test_unsuccessful_verify 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' - ) + brand: 'visa', + transaction_id: '123', + eci: '05', + payment_cryptogram: '111111111100cryptogram') response = stub_comms do @gateway.authorize(@amount, credit_card, @options) @@ -466,116 +647,196 @@ def test_successful_auth_with_network_tokenization_for_visa 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' - ) + brand: 'visa', + transaction_id: '123', + eci: '05', + payment_cryptogram: '111111111100cryptogram') response = stub_comms do @gateway.purchase(@amount, credit_card, @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 true end.returns(successful_purchase_response) credit_card = network_tokenization_credit_card('5555555555554444', - :brand => 'master', - :transaction_id => '123', - :eci => '05', - :payment_cryptogram => '111111111100cryptogram' - ) + brand: 'master', + transaction_id: '123', + eci: '05', + payment_cryptogram: '111111111100cryptogram') assert response = @gateway.authorize(@amount, credit_card, @options) assert_success response 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 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') - ) + 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_successful_auth_first_unscheduled_stored_cred - @gateway.stubs(:ssl_post).returns(successful_authorization_response) + def test_cof_first @options[:stored_credential] = { - :initiator => 'cardholder', - :reason_type => 'unscheduled', - :initial_transaction => true, - :network_transaction_id => '' + initiator: 'cardholder', + reason_type: '', + initial_transaction: true, + network_transaction_id: '' } - assert response = @gateway.authorize(@amount, @credit_card, @options) - assert_equal Response, response.class + @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? - assert response.test? end - def test_successful_auth_subsequent_unscheduled_stored_cred - @gateway.stubs(:ssl_post).returns(successful_authorization_response) + def test_cof_cit_auth @options[:stored_credential] = { - :initiator => 'merchant', - :reason_type => 'unscheduled', - :initial_transaction => false, - :network_transaction_id => '016150703802094' + initiator: 'cardholder', + reason_type: 'unscheduled', + initial_transaction: false, + network_transaction_id: '' } - assert response = @gateway.authorize(@amount, @credit_card, @options) - assert_equal Response, response.class + 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? - assert response.test? end - def test_successful_auth_first_recurring_stored_cred - @gateway.stubs(:ssl_post).returns(successful_authorization_response) + def test_cof_unscheduled_mit_auth @options[:stored_credential] = { - :initiator => 'cardholder', - :reason_type => 'recurring', - :initial_transaction => true, - :network_transaction_id => '' + initiator: 'merchant', + reason_type: 'unscheduled', + initial_transaction: false, + network_transaction_id: '016150703802094' } - assert response = @gateway.authorize(@amount, @credit_card, @options) - assert_equal Response, response.class + 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? - assert response.test? end - def test_successful_auth_subsequent_recurring_stored_cred - @gateway.stubs(:ssl_post).returns(successful_authorization_response) + def test_cof_installment_mit_auth @options[:stored_credential] = { - :initiator => 'merchant', - :reason_type => 'recurring', - :initial_transaction => false, - :network_transaction_id => '016150703802094' + initiator: 'merchant', + reason_type: 'installment', + initial_transaction: false, + network_transaction_id: '016150703802094' } - assert response = @gateway.authorize(@amount, @credit_card, @options) - assert_equal Response, response.class + 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(/\/, data) + assert_match(/\true/, data) + assert_match(/\016150703802094/, data) + assert_match(/\recurring/, data) + end.respond_with(successful_purchase_response) + assert response.success? + end + + def test_cof_first_with_overrides + @options[:stored_credential] = { + initiator: 'cardholder', + reason_type: '', + initial_transaction: true, + network_transaction_id: '' + } + @options[:stored_credential_overrides] = { + subsequent_auth: 'true', + subsequent_auth_first: 'false', + subsequent_auth_stored_credential: 'true', + subsequent_auth_transaction_id: '54321' + } + @options[:commerce_indicator] = 'internet' + response = stub_comms do + @gateway.authorize(@amount, @credit_card, @options) + end.check_request do |_endpoint, data, _headers| + assert_match(/\false/, data) + assert_match(/\true/, data) + assert_match(/\true/, data) + assert_match(/\54321/, data) + assert_match(/\internet/, data) + end.respond_with(successful_authorization_response) assert response.success? - assert response.test? end def test_nonfractional_currency_handling - @gateway.expects(:ssl_post).with do |host, request_body| + @gateway.expects(:ssl_post).with do |_host, request_body| assert_match %r(1), request_body assert_match %r(JPY), request_body true @@ -597,7 +858,7 @@ def test_malformed_xml_handling def test_3ds_enroll_response purchase = stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(payer_auth_enroll_service: true)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/\/, data) end.respond_with(threedeesecure_purchase_response) @@ -610,7 +871,7 @@ def test_3ds_enroll_response def test_3ds_validate_response validation = stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(payer_auth_validate_service: true, pares: 'ABC123')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/\/, data) assert_match(/\ABC123\<\/signedPARes\>/, data) end.respond_with(successful_threedeesecure_validate_response) @@ -618,13 +879,25 @@ def test_3ds_validate_response assert_success validation end + def test_adds_3ds_brand_based_commerce_indicator + %w(visa maestro master american_express jcb discover diners_club).each do |brand| + @credit_card.brand = brand + + stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(three_d_secure: { cavv: 'anything but empty' })) + end.check_request do |_endpoint, data, _headers| + assert_match(/commerceIndicator\>#{CyberSourceGateway::ECI_BRAND_MAPPING[brand.to_sym]}#{eci}/, data) assert_match(/#{cavv}/, data) assert_match(/#{version}/, data) @@ -654,13 +927,76 @@ def test_adds_3ds2_fields_via_normalized_hash end.respond_with(successful_purchase_response) end + def test_does_not_add_3ds2_fields_via_normalized_hash_when_cavv_and_commerce_indicator_absent + options = options_with_normalized_3ds(cavv: nil, commerce_indicator: nil) + stub_comms do + @gateway.purchase(@amount, @credit_card, options) + end.check_request do |_, data, _| + assert_not_match(/#{options[:three_d_secure][:eci]}#{options[:three_d_secure][:cavv]}#{options[:three_d_secure][:version]}#{options[:three_d_secure][:ds_transaction_id]}#{options[:three_d_secure][:authentication_response_status]}#{options[:three_d_secure][:cavv_algorithm]}#{options[:three_d_secure][:enrolled]}#{options[:commerce_indicator]}#{options[:three_d_secure][:eci]}#{options[:three_d_secure][:version]}#{options[:three_d_secure][:ds_transaction_id]}#{options[:three_d_secure][:authentication_response_status]}#{options[:three_d_secure][:cavv_algorithm]}#{options[:three_d_secure][:enrolled]}#{options[:three_d_secure][:eci]}#{options[:three_d_secure][:version]}#{options[:three_d_secure][:ds_transaction_id]}#{options[:three_d_secure][:authentication_response_status]}#{options[:three_d_secure][:cavv_algorithm]}#{options[:three_d_secure][:enrolled]}#{options[:commerce_indicator]}#{options[:three_d_secure][:eci]}#{options[:three_d_secure][:cavv]}#{options[:three_d_secure][:version]}#{options[:three_d_secure][:ds_transaction_id]}#{options[:three_d_secure][:authentication_response_status]}#{options[:three_d_secure][:cavv_algorithm]}#{options[:three_d_secure][:enrolled]}#{eci}/, data) assert_match(/#{cavv}/, data) assert_match(/#{version}/, data) @@ -687,6 +1023,100 @@ def test_adds_mastercard_3ds2_fields_via_normalized_hash end.respond_with(successful_purchase_response) end + def test_adds_mastercard_3ds2_default_collection_indicator + options_with_normalized_3ds = @options.merge( + three_d_secure: { + version: '2.0', + eci: '05', + cavv: '637574652070757070792026206b697474656e73', + ds_transaction_id: '97267598-FAE6-48F2-8083-C23433990FBC', + cavv_algorithm: 'vbv' + } + ) + + stub_comms do + @gateway.purchase(@amount, @master_credit_card, options_with_normalized_3ds) + end.check_request do |_endpoint, data, _headers| + assert_match(/2/, data) + end.respond_with(successful_purchase_response) + end + + def test_send_xid_for_3ds_1_regardless_of_cc_brand + options_with_normalized_3ds = @options.merge( + three_d_secure: { + eci: '05', + cavv: '637574652070757070792026206b697474656e73', + xid: 'this-is-an-xid', + ds_transaction_id: '97267598-FAE6-48F2-8083-C23433990FBC', + cavv_algorithm: 'vbv' + } + ) + + stub_comms do + @gateway.purchase(@amount, @elo_credit_card, options_with_normalized_3ds) + end.check_request do |_endpoint, data, _headers| + assert_match(/this-is-an-xid/, data) + end.respond_with(successful_purchase_response) + end + + def test_dont_send_cavv_as_xid_in_3ds2_for_mastercard + options_with_normalized_3ds = @options.merge( + three_d_secure: { + version: '2.0', + eci: '05', + cavv: '637574652070757070792026206b697474656e73', + xid: 'this-is-an-xid', + ds_transaction_id: '97267598-FAE6-48F2-8083-C23433990FBC', + cavv_algorithm: 'vbv' + } + ) + + stub_comms do + @gateway.purchase(@amount, @master_credit_card, options_with_normalized_3ds) + end.check_request do |_endpoint, data, _headers| + assert_match(/this-is-an-xid/, data) + end.respond_with(successful_purchase_response) + end + + def test_adds_cavv_as_xid_for_3ds2 + cavv = '637574652070757070792026206b697474656e73' + + options_with_normalized_3ds = @options.merge( + three_d_secure: { + version: '2.0', + eci: '05', + cavv: cavv, + ds_transaction_id: '97267598-FAE6-48F2-8083-C23433990FBC', + cavv_algorithm: 'vbv' + } + ) + + stub_comms do + @gateway.purchase(@amount, @credit_card, options_with_normalized_3ds) + end.check_request do |_endpoint, data, _headers| + assert_match(/#{cavv}/, data) + end.respond_with(successful_purchase_response) + end + + def test_does_not_add_cavv_as_xid_if_xid_is_present + options_with_normalized_3ds = @options.merge( + three_d_secure: { + version: '2.0', + eci: '05', + cavv: '637574652070757070792026206b697474656e73', + xid: 'this-is-an-xid', + ds_transaction_id: '97267598-FAE6-48F2-8083-C23433990FBC', + cavv_algorithm: 'vbv' + } + ) + + stub_comms do + @gateway.purchase(@amount, @credit_card, options_with_normalized_3ds) + end.check_request do |_endpoint, data, _headers| + assert_match(/this-is-an-xid/, data) + end.respond_with(successful_purchase_response) + end + def test_scrub assert_equal @gateway.scrub(pre_scrubbed), post_scrubbed end @@ -709,8 +1139,125 @@ def test_does_not_throw_on_invalid_xml assert_failure response end + def test_address_email_has_a_default_when_email_option_is_empty + stub_comms do + @gateway.authorize(100, @credit_card, email: '') + end.check_request do |_endpoint, data, _headers| + assert_match('null@cybersource.com', data) + end.respond_with(successful_capture_response) + end + + def test_country_code_sent_as_default_when_submitted_as_empty_string + stub_comms do + @gateway.authorize(100, @credit_card, billing_address: { country: '' }) + end.check_request do |_endpoint, data, _headers| + assert_match('US', data) + end.respond_with(successful_capture_response) + end + + def test_default_address_does_not_override_when_hash_keys_are_strings + stub_comms do + @gateway.authorize(100, @credit_card, billing_address: { + 'address1' => '221B Baker Street', + 'city' => 'London', + 'zip' => 'NW16XE', + 'country' => 'GB' + }) + end.check_request do |_endpoint, data, _headers| + assert_match('221B Baker Street', data) + assert_match('London', data) + assert_match('NW16XE', data) + assert_match('GB', data) + end.respond_with(successful_capture_response) + end + + def test_adds_application_id_as_partner_solution_id + partner_id = 'partner_id' + CyberSourceGateway.application_id = partner_id + + stub_comms do + @gateway.authorize(100, @credit_card, @options) + end.check_request do |_endpoint, data, _headers| + assert_match("#{partner_id}", data) + end.respond_with(successful_capture_response) + ensure + CyberSourceGateway.application_id = nil + end + + def test_partner_solution_id_position_follows_schema + partner_id = 'partner_id' + CyberSourceGateway.application_id = partner_id + + @options[:stored_credential] = { + initiator: 'cardholder', + reason_type: '', + initial_transaction: true, + network_transaction_id: '' + } + @options[:commerce_indicator] = 'internet' + + stub_comms do + @gateway.authorize(100, @credit_card, @options) + end.check_request do |_endpoint, data, _headers| + assert_match("\n#{partner_id}\ntrue\n\n", data) + end.respond_with(successful_capture_response) + ensure + CyberSourceGateway.application_id = nil + end + + def test_missing_field + @gateway.expects(:ssl_post).returns(missing_field_response) + + response = @gateway.purchase(@amount, credit_card, @options) + + assert_failure response + assert_equal 'c:billTo/c:country', response.params['missingField'] + end + + def test_invalid_field + @gateway.expects(:ssl_post).returns(invalid_field_response) + + response = @gateway.purchase(@amount, credit_card, @options) + + assert_failure response + assert_equal 'c:billTo/c:postalCode', response.params['invalidField'] + end + private + def options_with_normalized_3ds( + cavv: '637574652070757070792026206b697474656e73', + commerce_indicator: 'commerce_indicator' + ) + xid = 'Y2FyZGluYWxjb21tZXJjZWF1dGg=' + authentication_response_status = 'Y' + cavv_algorithm = 2 + collection_indicator = 2 + ds_transaction_id = '97267598-FAE6-48F2-8083-C23433990FBC' + eci = '05' + enrolled = 'Y' + version = '2.0' + @options.merge( + three_d_secure: { + version: version, + eci: eci, + xid: xid, + cavv: cavv, + ds_transaction_id: ds_transaction_id, + cavv_algorithm: cavv_algorithm, + enrolled: enrolled, + authentication_response_status: authentication_response_status + }, + commerce_indicator: commerce_indicator, + collection_indicator: collection_indicator + ).compact + end + + def supported_cc_brand_without_inferred_commerce_indicator + (ActiveMerchant::Billing::CyberSourceGateway.supported_cardtypes - + ActiveMerchant::Billing::CyberSourceGateway::ECI_BRAND_MAPPING.keys).first + end + def pre_scrubbed <<-PRE_SCRUBBED opening connection to ics2wstest.ic3.com:443... @@ -760,26 +1307,26 @@ def post_scrubbed end def successful_purchase_response - <<-XML - - -2008-01-15T21:42:03.343Zb0a6cf9aa07f1a8495f89c364bbd6a9a2004333231260008401927ACCEPT100Afvvj7Ke2Fmsbq0wHFE2sM6R4GAptYZ0jwPSA+R9PhkyhFTb0KRjoE4+ynthZrG6tMBwjAtTUSD1001.00123456YYMM2008-01-15T21:42:03Z00U + <<~XML + + + 2008-01-15T21:42:03.343Zb0a6cf9aa07f1a8495f89c364bbd6a9a2004333231260008401927ACCEPT100Afvvj7Ke2Fmsbq0wHFE2sM6R4GAptYZ0jwPSA+R9PhkyhFTb0KRjoE4+ynthZrG6tMBwjAtTUSD1001.00123456YYMM2008-01-15T21:42:03Z00U XML end def successful_authorization_response - <<-XML - - -2007-07-12T18:31:53.838ZTEST111111111111842651133440156177166ACCEPT100AP4JY+Or4xRonEAOERAyMzQzOTEzMEM0MFZaNUZCBgDH3fgJ8AEGAMfd+AnwAwzRpAAA7RT/USD1001.00004542AI72007-07-12T18:31:53Z10023439130C40VZ2FB + <<~XML + + + 2007-07-12T18:31:53.838ZTEST111111111111842651133440156177166ACCEPT100AP4JY+Or4xRonEAOERAyMzQzOTEzMEM0MFZaNUZCBgDH3fgJ8AEGAMfd+AnwAwzRpAAA7RT/USD1001.00004542AI72007-07-12T18:31:53Z10023439130C40VZ2FB XML end def unsuccessful_authorization_response - <<-XML - - -2008-01-15T21:50:41.580Za1efca956703a2a5037178a8a28f73572004338415330008402434REJECT231Afvvj7KfIgU12gooCFE2/DanQIApt+G1OgTSA+R9PTnyhFTb0KRjgFY+ynyIFNdoKKAghwgx231 + <<~XML + + + 2008-01-15T21:50:41.580Za1efca956703a2a5037178a8a28f73572004338415330008402434REJECT231Afvvj7KfIgU12gooCFE2/DanQIApt+G1OgTSA+R9PTnyhFTb0KRjgFY+ynyIFNdoKKAghwgx231 XML end @@ -842,10 +1389,10 @@ def unsuccessful_authorization_response_with_reply end def successful_tax_response - <<-XML - - -2007-07-11T18:27:56.314ZTEST111111111111841784762620176127166ACCEPT100AMYJY9fl62i+vx2OEQYAx9zv/9UBZAAA5h5D1001.000Madison000WI0537170 + <<~XML + + + 2007-07-11T18:27:56.314ZTEST111111111111841784762620176127166ACCEPT100AMYJY9fl62i+vx2OEQYAx9zv/9UBZAAA5h5D1001.000Madison000WI0537170 XML end @@ -874,30 +1421,30 @@ def successful_delete_subscription_response end def successful_capture_response - <<-XML - 2007-07-17T17:15:32.642Ztest11111111111111111846925324700976124593ACCEPT100AP4JZB883WKS/34BEZAzMTE1OTI5MVQzWE0wQjEzBTUt3wbOAQUy3D7oDgMMmvQAnQglGBP1002007-07-17T17:15:32Z1.0031159291T3XM2B13 + <<~XML + 2007-07-17T17:15:32.642Ztest11111111111111111846925324700976124593ACCEPT100AP4JZB883WKS/34BEZAzMTE1OTI5MVQzWE0wQjEzBTUt3wbOAQUy3D7oDgMMmvQAnQglGBP1002007-07-17T17:15:32Z1.0031159291T3XM2B13 XML end def successful_refund_response - <<-XML - - -2008-01-21T16:00:38.927ZTEST111111111112009312387810008401927ACCEPT100Af/vj7OzPmut/eogHFCrBiwYsWTJy1r127CpCn0KdOgyTZnzKwVYCmzPmVgr9ID5H1WGTSTKuj0i30IE4+zsz2d/QNzwBwAACCPAUSD1002008-01-21T16:00:38Z1.00010112295WW70TBOPSSP2 + <<~XML + + + 2008-01-21T16:00:38.927ZTEST111111111112009312387810008401927ACCEPT100Af/vj7OzPmut/eogHFCrBiwYsWTJy1r127CpCn0KdOgyTZnzKwVYCmzPmVgr9ID5H1WGTSTKuj0i30IE4+zsz2d/QNzwBwAACCPAUSD1002008-01-21T16:00:38Z1.00010112295WW70TBOPSSP2 XML end def successful_card_credit_response - <<-XML -\n\n2019-05-16T20:25:05.234Z329b25a4540e05c731a4fb16112e4c725580383051126990804008ACCEPT100Ahj/7wSTLoNfMt0KyZQoGxDdm1ctGjlmo0/RdCA4BUafouhAdpAfJHYQyaSZbpAdvSeAnJl0GvmW6FZMoUAA/SE0USD1002019-05-16T20:25:05Z1.007359449300012345678901201234567 + <<~XML + \n\n2019-05-16T20:25:05.234Z329b25a4540e05c731a4fb16112e4c725580383051126990804008ACCEPT100Ahj/7wSTLoNfMt0KyZQoGxDdm1ctGjlmo0/RdCA4BUafouhAdpAfJHYQyaSZbpAdvSeAnJl0GvmW6FZMoUAA/SE0USD1002019-05-16T20:25:05Z1.007359449300012345678901201234567 XML end def successful_subscription_credit_response - <<-XML - - -2008-01-21T16:00:38.927ZTEST111111111112009312387810008401927ACCEPT100Af/vj7OzPmut/eogHFCrBiwYsWTJy1r127CpCn0KdOgyTZnzKwVYCmzPmVgr9ID5H1WGTSTKuj0i30IE4+zsz2d/QNzwBwAACCPAUSD1002012-09-28T16:59:25Z1.00010112295WW70TBOPSSP2 + <<~XML + + + 2008-01-21T16:00:38.927ZTEST111111111112009312387810008401927ACCEPT100Af/vj7OzPmut/eogHFCrBiwYsWTJy1r127CpCn0KdOgyTZnzKwVYCmzPmVgr9ID5H1WGTSTKuj0i30IE4+zsz2d/QNzwBwAACCPAUSD1002012-09-28T16:59:25Z1.00010112295WW70TBOPSSP2 XML end @@ -910,58 +1457,83 @@ def successful_retrieve_subscription_response end def successful_validate_pinless_debit_card - <<-XML - - -2013-05-13T13:52:57.159Z64270133684531771310176056442ACCEPT100AhijbwSRj3pM2QqPs2j0Ip+xoJXIsAMPYZNJMq6PSbs5ATAA6z421002013-05-13T13:52:57ZY + <<~XML + + + 2013-05-13T13:52:57.159Z64270133684531771310176056442ACCEPT100AhijbwSRj3pM2QqPs2j0Ip+xoJXIsAMPYZNJMq6PSbs5ATAA6z421002013-05-13T13:52:57ZY XML end def successful_auth_reversal_response - <<-XML - - -2016-07-25T21:10:31.506Z296805293329eea14917a8d04c63a0c44694810311256262804010ACCEPT100Ahj//wSR/QMpn9U9RwRUIkG7Nm4cMm7KVRrS4tppCS5TonESgFLhgHRTp0gPkYP4ZNJMt0gO3pPFAnI/oGUyy27D1uIA+xVKUSD1001.001002016-07-25T21:10:31Z + <<~XML + + + 2016-07-25T21:10:31.506Z296805293329eea14917a8d04c63a0c44694810311256262804010ACCEPT100Ahj//wSR/QMpn9U9RwRUIkG7Nm4cMm7KVRrS4tppCS5TonESgFLhgHRTp0gPkYP4ZNJMt0gO3pPFAnI/oGUyy27D1uIA+xVKUSD1001.001002016-07-25T21:10:31Z XML end def successful_void_response - <<-XML - - -2016-07-25T20:50:50.583Zbb3b1bb530192c9dd20f121686c91c404694798504476543904007ACCEPT100Ahj//wSR/QLVu2z/GtIOIkG7Nm4bNW7KPRrRY0mvYS4YB0I7QFLgkgkAA0gAwfwyaSZbpAdvSeeBOR/QLVqII/qE+QAA3yVtUSD1002016-07-25T20:50:50Z1.00usd + <<~XML + + + 2016-07-25T20:50:50.583Zbb3b1bb530192c9dd20f121686c91c404694798504476543904007ACCEPT100Ahj//wSR/QLVu2z/GtIOIkG7Nm4bNW7KPRrRY0mvYS4YB0I7QFLgkgkAA0gAwfwyaSZbpAdvSeeBOR/QLVqII/qE+QAA3yVtUSD1002016-07-25T20:50:50Z1.00usd XML end def successful_nonfractional_authorization_response - <<-XML - - -2007-07-12T18:31:53.838ZTEST111111111111842651133440156177166ACCEPT100AP4JY+Or4xRonEAOERAyMzQzOTEzMEM0MFZaNUZCBgDH3fgJ8AEGAMfd+AnwAwzRpAAA7RT/JPY1001004542AI72007-07-12T18:31:53Z10023439130C40VZ2FB + <<~XML + + + 2007-07-12T18:31:53.838ZTEST111111111111842651133440156177166ACCEPT100AP4JY+Or4xRonEAOERAyMzQzOTEzMEM0MFZaNUZCBgDH3fgJ8AEGAMfd+AnwAwzRpAAA7RT/JPY1001004542AI72007-07-12T18:31:53Z10023439130C40VZ2FB + XML + end + + def authorization_review_response + <<~XML + + + 2007-07-12T18:31:53.838ZTEST111111111111842651133440156177166REVIEW480AP4JY+Or4xRonEAOERAyMzQzOTEzMEM0MFZaNUZCBgDH3fgJ8AEGAMfd+AnwAwzRpAAA7RT/USD1001.00004542AI72007-07-12T18:31:53Z10023439130C40VZ2FB XML end def malformed_xml_response - <<-XML - - -2008-01-15T21:42:03.343Zb0a6cf9aa07f1a8495f89c364bbd6a9a2004333231260008401927ACCEPT100Afvvj7Ke2Fmsbq0wHFE2sM6R4GAptYZ0jwPSA+R9PhkyhFTb0KRjoE4+ynthZrG6tMBwjAtTUSD1001.00123456YYMM2008-01-15T21:42:03Z00U

+ <<~XML + + + 2008-01-15T21:42:03.343Zb0a6cf9aa07f1a8495f89c364bbd6a9a2004333231260008401927ACCEPT100Afvvj7Ke2Fmsbq0wHFE2sM6R4GAptYZ0jwPSA+R9PhkyhFTb0KRjoE4+ynthZrG6tMBwjAtTUSD1001.00123456YYMM2008-01-15T21:42:03Z00U

XML end def threedeesecure_purchase_response - <<-XML - - -2017-10-17T20:39:27.392Z1a5ba4804da54b384c6e8a2d8057ea995082727663166909004012REJECT475AhjzbwSTE4kEGDR65zjsGwFLjtwzsJ0gXLJx6Xb0ky3SA7ek8AYA/A17475https://0eafstag.cardinalcommerce.com/EAFService/jsp/v1/redirecteNpVUe9PwjAQ/d6/ghA/r2tBYMvRBEUFFEKQEP1Yu1Om7gfdJoy/3nZsgk2a3Lveu757B+utRhw/oyo0CphjlskPbIXBsC25TvuPD/lkc3xn2d2R6y+3LWA5WuFOwA/qLExiwRzX4UAbSEwLrbYyzgVItbuZLkS353HWA1pDAhHq6Vgw3ule9/pAT5BALCMUqnwznZJCKwRaZQiopIhzXYpB1wXaAAKF/hbbPE8zn9L9fu9cUB2VREBtAQF6FrQsbJSZOQ9hIF7Xs1KNg6dVZzXdxGk0f1nc4+eslMfREKitIBDIHAV3WZ+Z2+Ku3/F8bjRXeQIysmrEFeOOa0yoIYHUfjQ6Icbt02XGTFRojbFqRmoQATykSYymxlD+YjPDWfntxBqrcusg8wbmWGcrXNFD4w3z2IkfVkZRy6H13mi9YhP9W/0vhyyqPw==1198888YTJycDdLR3RIVnpmMXNFejJyazA=<AuthProof><Time>2017 Oct 17 20:39:27</Time><DSUrl>https://csrtestcustomer34.cardinalcommerce.com/merchantacsfrontend/vereq.jsp?acqid=CYBS</DSUrl><VEReqProof><Message id="a2rp7KGtHVzf1sEz2rk0"><VEReq><version>1.0.2</version><pan>XXXXXXXXXXXX0002</pan><Merchant><acqBIN>469216</acqBIN><merID>1234567</merID></Merchant><Browser><deviceCategory>0</deviceCategory></Browser></VEReq></Message></VEReqProof><VEResProof><Message id="a2rp7KGtHVzf1sEz2rk0"><VERes><version>1.0.2</version><CH><enrolled>Y</enrolled><acctID>1198888</acctID></CH><url>https://testcustomer34.cardinalcommerce.com/merchantacsfrontend/pareq.jsp?vaa=b&amp;gold=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</url><protocol>ThreeDSecure</protocol></VERes></Message></VEResProof></AuthProof>YENROLLED + <<~XML + + + 2017-10-17T20:39:27.392Z1a5ba4804da54b384c6e8a2d8057ea995082727663166909004012REJECT475AhjzbwSTE4kEGDR65zjsGwFLjtwzsJ0gXLJx6Xb0ky3SA7ek8AYA/A17475https://0eafstag.cardinalcommerce.com/EAFService/jsp/v1/redirecteNpVUe9PwjAQ/d6/ghA/r2tBYMvRBEUFFEKQEP1Yu1Om7gfdJoy/3nZsgk2a3Lveu757B+utRhw/oyo0CphjlskPbIXBsC25TvuPD/lkc3xn2d2R6y+3LWA5WuFOwA/qLExiwRzX4UAbSEwLrbYyzgVItbuZLkS353HWA1pDAhHq6Vgw3ule9/pAT5BALCMUqnwznZJCKwRaZQiopIhzXYpB1wXaAAKF/hbbPE8zn9L9fu9cUB2VREBtAQF6FrQsbJSZOQ9hIF7Xs1KNg6dVZzXdxGk0f1nc4+eslMfREKitIBDIHAV3WZ+Z2+Ku3/F8bjRXeQIysmrEFeOOa0yoIYHUfjQ6Icbt02XGTFRojbFqRmoQATykSYymxlD+YjPDWfntxBqrcusg8wbmWGcrXNFD4w3z2IkfVkZRy6H13mi9YhP9W/0vhyyqPw==1198888YTJycDdLR3RIVnpmMXNFejJyazA=<AuthProof><Time>2017 Oct 17 20:39:27</Time><DSUrl>https://csrtestcustomer34.cardinalcommerce.com/merchantacsfrontend/vereq.jsp?acqid=CYBS</DSUrl><VEReqProof><Message id="a2rp7KGtHVzf1sEz2rk0"><VEReq><version>1.0.2</version><pan>XXXXXXXXXXXX0002</pan><Merchant><acqBIN>469216</acqBIN><merID>1234567</merID></Merchant><Browser><deviceCategory>0</deviceCategory></Browser></VEReq></Message></VEReqProof><VEResProof><Message id="a2rp7KGtHVzf1sEz2rk0"><VERes><version>1.0.2</version><CH><enrolled>Y</enrolled><acctID>1198888</acctID></CH><url>https://testcustomer34.cardinalcommerce.com/merchantacsfrontend/pareq.jsp?vaa=b&amp;gold=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</url><protocol>ThreeDSecure</protocol></VERes></Message></VEResProof></AuthProof>YENROLLED XML end def successful_threedeesecure_validate_response - <<-XML - - -2018-05-01T14:28:36.773Z23751b5aeb076ea5940c5b656284bf6a5251849164756591904009ACCEPT100Ahj//wSTHLQMXdtQnQUJGxDds0bNnDRoo0+VcdXMBUafKuOrnpAuWT9zDJpJlukB29J4YBpMctAxd21CdBQkwQ3gUSD10012.02831000YY2018-05-01T14:28:36Z00ZLIU5GM27GBP0110322000000E10000200000000000000120205011428360272225A4C495535474D32374742503833313030303030000159004400103232415050524F56414C00223134573031363135303730333830323039344730363400065649435241201002018-05-01T14:28:36Z12.02764668441000SuccessAAABAWFlmQAAAABjRWWZEEFgFz+=2vbv0505S2R4eGtHbEZqbnozeGhBRHJ6QzA=Y + <<~XML + + + 2018-05-01T14:28:36.773Z23751b5aeb076ea5940c5b656284bf6a5251849164756591904009ACCEPT100Ahj//wSTHLQMXdtQnQUJGxDds0bNnDRoo0+VcdXMBUafKuOrnpAuWT9zDJpJlukB29J4YBpMctAxd21CdBQkwQ3gUSD10012.02831000YY2018-05-01T14:28:36Z00ZLIU5GM27GBP0110322000000E10000200000000000000120205011428360272225A4C495535474D32374742503833313030303030000159004400103232415050524F56414C00223134573031363135303730333830323039344730363400065649435241201002018-05-01T14:28:36Z12.02764668441000SuccessAAABAWFlmQAAAABjRWWZEEFgFz+=2vbv0505S2R4eGtHbEZqbnozeGhBRHJ6QzA=Y + XML + end + + def missing_field_response + <<~XML + + + 2019-09-05T01:02:20.132Z9y2A7XGxMSOUqppiEXkiN8T38Jj5676453399086696204061REJECT101c:billTo/c:countryAhjz7wSTM7ido1SNM4cdGwFRfPELvH+kE/QkEg+jLpJlXR6RuUgJMmZ3E7RqkaZw46AAniPV101 + XML + end + + def invalid_field_response + <<~XML + + + 2019-09-05T14:10:46.665Z5676926465076767004068REJECT102c:billTo/c:postalCodeAhjzbwSTM78uTleCsJWkEAJRqivRidukDssiQgRm0ky3SA7oegDUiwLm + XML end diff --git a/test/unit/gateways/d_local_test.rb b/test/unit/gateways/d_local_test.rb index bb4d1df6aac..3946ea0003e 100644 --- a/test/unit/gateways/d_local_test.rb +++ b/test/unit/gateways/d_local_test.rb @@ -32,6 +32,18 @@ def test_failed_purchase assert_equal '300', response.error_code end + def test_purchase_with_installments + installments = '6' + installments_id = 'INS54434' + + stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(installments: installments, installments_id: installments_id)) + end.check_request do |_endpoint, data, _headers| + assert_equal installments, JSON.parse(data)['card']['installments'] + assert_equal installments_id, JSON.parse(data)['card']['installments_id'] + end.respond_with(successful_purchase_response) + end + def test_successful_authorize @gateway.expects(:ssl_post).returns(successful_authorize_response) @@ -50,14 +62,53 @@ def test_successful_authorize_without_address assert_equal 'D-15104-be03e883-3e6b-497d-840e-54c8b6209bc3', response.authorization end + def test_passing_billing_address + stub_comms(@gateway, :ssl_request) do + @gateway.authorize(@amount, @credit_card, @options) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(/"state\":\"ON\"/, data) + assert_match(/"city\":\"Ottawa\"/, data) + assert_match(/"zip_code\":\"K1C2N6\"/, data) + assert_match(/"street\":\"My Street\"/, data) + assert_match(/"number\":\"456\"/, data) + end.respond_with(successful_authorize_response) + end + + def test_passing_incomplete_billing_address + stub_comms(@gateway, :ssl_request) do + @gateway.authorize(@amount, @credit_card, @options.merge(billing_address: address(address1: 'Just a Street'))) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(/"state\":\"ON\"/, data) + assert_match(/"city\":\"Ottawa\"/, data) + assert_match(/"zip_code\":\"K1C2N6\"/, data) + assert_match(/"street\":\"Just a Street\"/, data) + end.respond_with(successful_authorize_response) + end + + def test_passing_nil_address_1 + stub_comms(@gateway, :ssl_request) do + @gateway.authorize(@amount, @credit_card, @options.merge(billing_address: address(address1: nil))) + end.check_request do |_method, _endpoint, data, _headers| + refute_match(/"street\"/, data) + end.respond_with(successful_authorize_response) + end + def test_passing_country_as_string stub_comms(@gateway, :ssl_request) do @gateway.authorize(@amount, @credit_card, @options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/"country\":\"CA\"/, data) end.respond_with(successful_authorize_response) end + def test_invalid_country + stub_comms(@gateway, :ssl_request) do + @gateway.authorize(@amount, @credit_card, @options.merge(billing_address: address(country: 'INVALID'))) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(/\"country\":null/, data) + end.respond_with(successful_authorize_response) + end + def test_failed_authorize @gateway.expects(:ssl_post).returns(failed_authorize_response) @@ -202,6 +253,10 @@ def successful_purchase_response '{"id":"D-15104-05b0ec0c-5a1e-470a-b342-eb5f20758ef7","amount":1.00,"currency":"BRL","payment_method_id":"CARD","payment_method_type":"CARD","payment_method_flow":"DIRECT","country":"BR","card":{"holder_name":"Longbob Longsen","expiration_month":9,"expiration_year":2019,"brand":"VI","last4":"1111","card_id":"CV-993903e4-0b33-48fd-8d9b-99fd6c3f0d1a"},"created_date":"2018-12-06T20:20:41.000+0000","approved_date":"2018-12-06T20:20:42.000+0000","status":"PAID","status_detail":"The payment was paid","status_code":"200","order_id":"15940ef43d39331bc64f31341f8ccd93"}' end + def successful_purchase_with_installments_response + '{"id":"D-4-e2227981-8ec8-48fd-8e9a-19fedb08d73a","amount":1000,"currency":"BRL","payment_method_id":"CARD","payment_method_type":"CARD","payment_method_flow":"DIRECT","country":"BR","card":{"holder_name":"Thiago Gabriel","expiration_month":10,"expiration_year":2040,"brand":"VI","last4":"1111"},"created_date":"2019-02-06T21:04:43.000+0000","approved_date":"2019-02-06T21:04:44.000+0000","status":"PAID","status_detail":"The payment was paid.","status_code":"200","order_id":"657434343","notification_url":"http://merchant.com/notifications"}' + end + def failed_purchase_response '{"id":"D-15104-c3027e67-21f8-4308-8c94-06c44ffcea67","amount":1.00,"currency":"BRL","payment_method_id":"CARD","payment_method_type":"CARD","payment_method_flow":"DIRECT","country":"BR","card":{"holder_name":"Longbob Longsen","expiration_month":9,"expiration_year":2019,"brand":"VI","last4":"1111","card_id":"CV-529b0bb1-8b8a-42f4-b5e4-d358ffb2c978"},"created_date":"2018-12-06T20:22:40.000+0000","status":"REJECTED","status_detail":"The payment was rejected.","status_code":"300","order_id":"7aa5cd3200f287fbac51dcee32184260"}' end diff --git a/test/unit/gateways/data_cash_test.rb b/test/unit/gateways/data_cash_test.rb index 9d8f8e8d46f..313f5ea71ea 100644 --- a/test/unit/gateways/data_cash_test.rb +++ b/test/unit/gateways/data_cash_test.rb @@ -3,8 +3,8 @@ class DataCashTest < Test::Unit::TestCase def setup @gateway = DataCashGateway.new( - :login => 'LOGIN', - :password => 'PASSWORD' + login: 'LOGIN', + password: 'PASSWORD' ) @credit_card = credit_card('4242424242424242') @@ -12,19 +12,19 @@ def setup @amount = 100 @address = { - :name => 'Mark McBride', - :address1 => 'Flat 12/3', - :address2 => '45 Main Road', - :city => 'London', - :state => 'None', - :country => 'GBR', - :zip => 'A987AA', - :phone => '(555)555-5555' + name: 'Mark McBride', + address1: 'Flat 12/3', + address2: '45 Main Road', + city: 'London', + state: 'None', + country: 'GBR', + zip: 'A987AA', + phone: '(555)555-5555' } @options = { - :order_id => generate_unique_id, - :billing_address => @address + order_id: generate_unique_id, + billing_address: @address } end @@ -83,7 +83,7 @@ def test_supported_countries end def test_supported_card_types - assert_equal [ :visa, :master, :american_express, :discover, :diners_club, :jcb, :maestro ], DataCashGateway.supported_cardtypes + assert_equal %i[visa master american_express discover diners_club jcb maestro], DataCashGateway.supported_cardtypes end def test_purchase_with_missing_order_id_option @@ -96,7 +96,7 @@ def test_authorize_with_missing_order_id_option def test_purchase_does_not_raise_exception_with_missing_billing_address @gateway.expects(:ssl_post).returns(successful_purchase_response) - assert @gateway.authorize(100, @credit_card, {:order_id => generate_unique_id }).is_a?(ActiveMerchant::Billing::Response) + assert @gateway.authorize(100, @credit_card, { order_id: generate_unique_id }).is_a?(ActiveMerchant::Billing::Response) end def test_continuous_authority_purchase_with_missing_continuous_authority_reference @@ -124,69 +124,69 @@ def test_capture_method_is_ecomm private def failed_purchase_response - <<-XML - - - NOT AUTHORISED - Mastercard - Japan - - 4500203037300784 - 85613a50952067796b1c6ab61c2cac - TEST - DECLINED - 7 - - + <<~XML + + + NOT AUTHORISED + Mastercard + Japan + + 4500203037300784 + 85613a50952067796b1c6ab61c2cac + TEST + DECLINED + 7 + + XML end def successful_purchase_response - <<-XML - - - - - notprovided - - matched - ACCEPTED - - notprovided - - 123456789 - Visa - United Kingdom - - 4400200050664928 - 2d24cc91284c1ed5c65d8821f1e752c7 - TEST - ACCEPTED - 1 - - + <<~XML + + + + + notprovided + + matched + ACCEPTED + + notprovided + + 123456789 + Visa + United Kingdom + + 4400200050664928 + 2d24cc91284c1ed5c65d8821f1e752c7 + TEST + ACCEPTED + 1 + + XML end def successful_purchase_using_continuous_authority_response - <<-XML - - - 123456789 - VISA Debit - United Kingdom - Barclays Bank PLC - - - Using account ref 4500203037301241. CONT_AUTH transaction complete - - 4400200050664928 - 3fc2b05ab38b70f0eb3a6b6d35c0de - TEST - ACCEPTED - 1 - - + <<~XML + + + 123456789 + VISA Debit + United Kingdom + Barclays Bank PLC + + + Using account ref 4500203037301241. CONT_AUTH transaction complete + + 4400200050664928 + 3fc2b05ab38b70f0eb3a6b6d35c0de + TEST + ACCEPTED + 1 + + XML end @@ -196,62 +196,62 @@ def test_transcript_scrubbing end def pre_scrub - <<-RAW -opening connection to testserver.datacash.com:443... -opened -starting SSL for testserver.datacash.com:443... -SSL established -<- "POST /Transaction 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: testserver.datacash.com\r\nContent-Length: 1067\r\n\r\n" -<- "\n\n \n 99626800\n 9YM3DjUa6\n \n \n \n auth\n \n 4539792100000003\n 03/20\n \n 444\n \n \n \n \n \n \n \n \n \n d36e05ce3604313963854fca858d11\n 1.98\n ecomm\n \n \n\n" --> "HTTP/1.1 200 OK\r\n" --> "Date: Wed, 03 Jan 2018 21:24:38 GMT\r\n" --> "Server: Apache\r\n" --> "Connection: close\r\n" --> "Transfer-Encoding: chunked\r\n" --> "Content-Type: text/plain; charset=iso-8859-1\r\n" --> "\r\n" --> "559\r\n" -reading 1369 bytes... --> "" --> "\n\n \n \n \n notchecked\n \n matched\n ACCEPTED\n \n notchecked\n \n 698899\n VISA Debit\n United Kingdom\n Barclays Bank PLC\n 00\n Approved or completed successfully\n D4B1B0558173CAE56E87293F9E9E899C8002F7B6\n \n RBS\n 4700204504678897\n d36e05ce3604313963854fca858d11\n 99626800\n TEST\n ACCEPTED\n 1\n \n\n\n" -read 1369 bytes -reading 2 bytes... --> "" --> "\r\n" -read 2 bytes --> "0\r\n" --> "\r\n" -Conn close + <<~RAW + opening connection to testserver.datacash.com:443... + opened + starting SSL for testserver.datacash.com:443... + SSL established + <- "POST /Transaction 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: testserver.datacash.com\r\nContent-Length: 1067\r\n\r\n" + <- "\n\n \n 99626800\n 9YM3DjUa6\n \n \n \n auth\n \n 4539792100000003\n 03/20\n \n 444\n \n \n \n \n \n \n \n \n \n d36e05ce3604313963854fca858d11\n 1.98\n ecomm\n \n \n\n" + -> "HTTP/1.1 200 OK\r\n" + -> "Date: Wed, 03 Jan 2018 21:24:38 GMT\r\n" + -> "Server: Apache\r\n" + -> "Connection: close\r\n" + -> "Transfer-Encoding: chunked\r\n" + -> "Content-Type: text/plain; charset=iso-8859-1\r\n" + -> "\r\n" + -> "559\r\n" + reading 1369 bytes... + -> "" + -> "\n\n \n \n \n notchecked\n \n matched\n ACCEPTED\n \n notchecked\n \n 698899\n VISA Debit\n United Kingdom\n Barclays Bank PLC\n 00\n Approved or completed successfully\n D4B1B0558173CAE56E87293F9E9E899C8002F7B6\n \n RBS\n 4700204504678897\n d36e05ce3604313963854fca858d11\n 99626800\n TEST\n ACCEPTED\n 1\n \n\n\n" + read 1369 bytes + reading 2 bytes... + -> "" + -> "\r\n" + read 2 bytes + -> "0\r\n" + -> "\r\n" + Conn close RAW end def post_scrub - <<-SCRUBBED -opening connection to testserver.datacash.com:443... -opened -starting SSL for testserver.datacash.com:443... -SSL established -<- "POST /Transaction 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: testserver.datacash.com\r\nContent-Length: 1067\r\n\r\n" -<- "\n\n \n 99626800\n [FILTERED]\n \n \n \n auth\n \n [FILTERED]\n 03/20\n \n [FILTERED]\n \n \n \n \n \n \n \n \n \n d36e05ce3604313963854fca858d11\n 1.98\n ecomm\n \n \n\n" --> "HTTP/1.1 200 OK\r\n" --> "Date: Wed, 03 Jan 2018 21:24:38 GMT\r\n" --> "Server: Apache\r\n" --> "Connection: close\r\n" --> "Transfer-Encoding: chunked\r\n" --> "Content-Type: text/plain; charset=iso-8859-1\r\n" --> "\r\n" --> "559\r\n" -reading 1369 bytes... --> "" --> "\n\n \n \n \n notchecked\n \n matched\n ACCEPTED\n \n notchecked\n \n 698899\n VISA Debit\n United Kingdom\n Barclays Bank PLC\n 00\n Approved or completed successfully\n D4B1B0558173CAE56E87293F9E9E899C8002F7B6\n \n RBS\n 4700204504678897\n d36e05ce3604313963854fca858d11\n 99626800\n TEST\n ACCEPTED\n 1\n \n\n\n" -read 1369 bytes -reading 2 bytes... --> "" --> "\r\n" -read 2 bytes --> "0\r\n" --> "\r\n" -Conn close + <<~SCRUBBED + opening connection to testserver.datacash.com:443... + opened + starting SSL for testserver.datacash.com:443... + SSL established + <- "POST /Transaction 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: testserver.datacash.com\r\nContent-Length: 1067\r\n\r\n" + <- "\n\n \n 99626800\n [FILTERED]\n \n \n \n auth\n \n [FILTERED]\n 03/20\n \n [FILTERED]\n \n \n \n \n \n \n \n \n \n d36e05ce3604313963854fca858d11\n 1.98\n ecomm\n \n \n\n" + -> "HTTP/1.1 200 OK\r\n" + -> "Date: Wed, 03 Jan 2018 21:24:38 GMT\r\n" + -> "Server: Apache\r\n" + -> "Connection: close\r\n" + -> "Transfer-Encoding: chunked\r\n" + -> "Content-Type: text/plain; charset=iso-8859-1\r\n" + -> "\r\n" + -> "559\r\n" + reading 1369 bytes... + -> "" + -> "\n\n \n \n \n notchecked\n \n matched\n ACCEPTED\n \n notchecked\n \n 698899\n VISA Debit\n United Kingdom\n Barclays Bank PLC\n 00\n Approved or completed successfully\n D4B1B0558173CAE56E87293F9E9E899C8002F7B6\n \n RBS\n 4700204504678897\n d36e05ce3604313963854fca858d11\n 99626800\n TEST\n ACCEPTED\n 1\n \n\n\n" + read 1369 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/decidir_test.rb b/test/unit/gateways/decidir_test.rb index de23333bfc4..3e822f28bcb 100644 --- a/test/unit/gateways/decidir_test.rb +++ b/test/unit/gateways/decidir_test.rb @@ -35,16 +35,85 @@ def test_successful_purchase_with_options card_holder_birthday: '01011980', card_holder_identification_type: 'dni', card_holder_identification_number: '123456', - installments: 12 + establishment_name: 'Heavenly Buffaloes', + device_unique_identifier: '111', + fraud_detection: { + send_to_cs: false, + channel: 'Web', + dispatch_method: 'Store Pick Up', + csmdds: [ + { + code: 17, + description: 'Campo MDD17' + } + ], + device_unique_id: '111' + }, + installments: 12, + site_id: '99999999' } response = stub_comms(@gateway_for_purchase, :ssl_request) do @gateway_for_purchase.purchase(@amount, @credit_card, @options.merge(options)) - end.check_request do |method, endpoint, data, headers| - assert data =~ /card_holder_door_number/, '1234' - assert data =~ /card_holder_birthday/, '01011980' - assert data =~ /type/, 'dni' - assert data =~ /number/, '123456' + end.check_request do |_method, _endpoint, data, _headers| + assert data =~ /"card_holder_door_number":1234/ + assert data =~ /"card_holder_birthday":"01011980"/ + assert data =~ /"type":"dni"/ + assert data =~ /"number":"123456"/ + assert data =~ /"establishment_name":"Heavenly Buffaloes"/ + assert data =~ /"site_id":"99999999"/ + assert data =~ /"device_unique_identifier":"111"/ + assert data =~ /"fraud_detection":{"send_to_cs":false,"channel":"Web","dispatch_method":"Store Pick Up","csmdds":\[{"code":17,"description":"Campo MDD17"}\],"device_unique_id":"111"}/ + end.respond_with(successful_purchase_response) + + assert_equal 7719132, response.authorization + assert_equal 'approved', response.message + assert response.test? + end + + def test_successful_purchase_with_aggregate_data + options = { + aggregate_data: { + indicator: 1, + identification_number: '308103480', + bill_to_pay: 'test1', + bill_to_refund: 'test2', + merchant_name: 'Heavenly Buffaloes', + street: 'Sesame', + number: '123', + postal_code: '22001', + category: 'yum', + channel: '005', + geographic_code: 'C1234', + city: 'Ciudad de Buenos Aires', + merchant_id: 'dec_agg', + province: 'Buenos Aires', + country: 'Argentina', + merchant_email: 'merchant@mail.com', + merchant_phone: '2678433111' + } + } + + response = stub_comms(@gateway_for_purchase, :ssl_request) do + @gateway_for_purchase.purchase(@amount, @credit_card, @options.merge(options)) + end.check_request do |_method, _endpoint, data, _headers| + assert data =~ /"aggregate_data":{"indicator":1/ + assert data =~ /"identification_number":"308103480"/ + assert data =~ /"bill_to_pay":"test1"/ + assert data =~ /"bill_to_refund":"test2"/ + assert data =~ /"merchant_name":"Heavenly Buffaloes"/ + assert data =~ /"street":"Sesame"/ + assert data =~ /"number":"123"/ + assert data =~ /"postal_code":"22001"/ + assert data =~ /"category":"yum"/ + assert data =~ /"channel":"005"/ + assert data =~ /"geographic_code":"C1234"/ + assert data =~ /"city":"Ciudad de Buenos Aires"/ + assert data =~ /"merchant_id":"dec_agg"/ + assert data =~ /"province":"Buenos Aires"/ + assert data =~ /"country":"Argentina"/ + assert data =~ /"merchant_email":"merchant@mail.com"/ + assert data =~ /"merchant_phone":"2678433111"/ end.respond_with(successful_purchase_response) assert_equal 7719132, response.authorization @@ -57,7 +126,7 @@ def test_failed_purchase response = @gateway_for_purchase.purchase(@amount, @credit_card, @options) assert_failure response - assert_equal 'TARJETA INVALIDA', response.message + assert_equal 'TARJETA INVALIDA | invalid_number', response.message assert_match Gateway::STANDARD_ERROR_CODE[:invalid_number], response.error_code end @@ -76,6 +145,22 @@ def test_failed_purchase_with_preauth_mode end end + def test_failed_purchase_error_response + @gateway_for_purchase.expects(:ssl_request).returns(unique_error_response) + + response = @gateway_for_purchase.purchase(@amount, @credit_card, @options) + assert_failure response + assert_match 'invalid_request_error | invalid_param | payment_type', response.error_code + end + + def test_failed_purchase_error_response_with_error_code + @gateway_for_purchase.expects(:ssl_request).returns(error_response_with_error_code) + + response = @gateway_for_purchase.purchase(@amount, @credit_card, @options) + assert_failure response + assert_match '14, invalid_number', response.error_code + end + def test_successful_authorize @gateway_for_auth.expects(:ssl_request).returns(successful_authorize_response) @@ -94,7 +179,7 @@ def test_failed_authorize assert_failure response assert_equal 7719358, response.authorization - assert_equal 'TARJETA INVALIDA', response.message + assert_equal 'TARJETA INVALIDA | invalid_number', response.message assert response.test? end @@ -158,7 +243,7 @@ def test_successful_refund def test_partial_refund @gateway_for_purchase.expects(:ssl_request).returns(partial_refund_response) - response = @gateway_for_purchase.refund(@amount-1, 81932, @options) + response = @gateway_for_purchase.refund(@amount - 1, 81932, @options) assert_success response assert_equal 81932, response.authorization @@ -225,7 +310,7 @@ def test_failed_verify response = @gateway_for_auth.verify(@credit_card, @options) assert_failure response - assert_equal 'TARJETA INVALIDA', response.message + assert_equal 'TARJETA INVALIDA | invalid_number', response.message assert response.test? end @@ -246,6 +331,24 @@ def test_payment_method_id_with_visa assert_equal 1, post[:payment_method_id] end + def test_payment_method_id_with_mastercard + post = {} + @gateway_for_purchase.send(:add_auth_purchase_params, post, @amount, credit_card('5299910010000015'), @options) + assert_equal 104, post[:payment_method_id] + end + + def test_payment_method_id_with_amex + post = {} + @gateway_for_purchase.send(:add_auth_purchase_params, post, @amount, credit_card('373953192351004'), @options) + assert_equal 65, post[:payment_method_id] + end + + def test_payment_method_id_with_diners + post = {} + @gateway_for_purchase.send(:add_auth_purchase_params, post, @amount, credit_card('36463664750005'), @options) + assert_equal 8, post[:payment_method_id] + end + def test_payment_method_id_with_cabal post = {} credit_card = credit_card('5896570000000008') @@ -260,6 +363,53 @@ def test_payment_method_id_with_naranja assert_equal 24, post[:payment_method_id] end + def test_payment_method_id_with_visa_debit + visa_debit_card = credit_card('4517721004856075') + debit_options = @options.merge(debit: true) + + stub_comms(@gateway_for_purchase, :ssl_request) do + @gateway_for_purchase.purchase(@amount, visa_debit_card, debit_options) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(/"payment_method_id":31/, data) + end.respond_with(successful_purchase_response) + end + + def test_payment_method_id_with_mastercard_debit + # currently lacking a valid MasterCard debit card number, so using the MasterCard credit card number + mastercard = credit_card('5299910010000015') + debit_options = @options.merge(debit: true) + + stub_comms(@gateway_for_purchase, :ssl_request) do + @gateway_for_purchase.purchase(@amount, mastercard, debit_options) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(/"payment_method_id":105/, data) + end.respond_with(successful_purchase_response) + end + + def test_payment_method_id_with_maestro_debit + # currently lacking a valid Maestro debit card number, so using a generated test card number + maestro_card = credit_card('6759649826438453') + debit_options = @options.merge(debit: true) + + stub_comms(@gateway_for_purchase, :ssl_request) do + @gateway_for_purchase.purchase(@amount, maestro_card, debit_options) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(/"payment_method_id":106/, data) + end.respond_with(successful_purchase_response) + end + + def test_payment_method_id_with_cabal_debit + # currently lacking a valid Cabal debit card number, so using the Cabal credit card number + cabal_card = credit_card('5896570000000008') + debit_options = @options.merge(debit: true) + + stub_comms(@gateway_for_purchase, :ssl_request) do + @gateway_for_purchase.purchase(@amount, cabal_card, debit_options) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(/"payment_method_id":108/, data) + end.respond_with(successful_purchase_response) + end + private def pre_scrubbed @@ -281,7 +431,7 @@ def pre_scrubbed -> "Via: kong/0.8.3\r\n" -> "\r\n" reading 659 bytes... - -> "{\"id\":7721017,\"site_transaction_id\":\"d5972b68-87d5-46fd-8d3d-b2512902b9af\",\"payment_method_id\":1,\"card_brand\":\"Visa\",\"amount\":100,\"currency\":\"ars\",\"status\":\"approved\",\"status_details\":{\"ticket\":\"7297\",\"card_authorization_code\":\"153842\",\"address_validation_code\":\"VTE0011\",\"error\":null},\"date\":\"2019-06-24T15:38Z\",\"customer\":null,\"bin\":\"450799\",\"installments\":1,\"first_installment_expiration_date\":null,\"payment_type\":\"single\",\"sub_payments\":[],\"site_id\":\"99999999\",\"fraud_detection\":null,\"aggregate_data\":null,\"establishment_name\":null,\"spv\":null,\"confirmed\":null,\"pan\":\"345425f15b2c7c4584e0044357b6394d7e\",\"customer_token\":null,\"card_data\":\"/tokens/7721017\"}" + -> "{\"id\":7721017,\"site_transaction_id\":\"d5972b68-87d5-46fd-8d3d-b2512902b9af\",\"payment_method_id\":1,\"card_brand\":\"Visa\",\"amount\":100,\"currency\":\"ars\",\"status\":\"approved\",\"status_details\":{\"ticket\":\"7297\",\"card_authorization_code\":\"153842\",\"address_validation_code\":\"VTE0011\",\"error\":null},\"date\":\"2019-06-24T15:38Z\",\"customer\":null,\"bin\":\"450799\",\"installments\":1,\"first_installment_expiration_date\":null,\"payment_type\":\"single\",\"sub_payments\":[],\"site_id\":\"99999999\",\"fraud_detection\":{\"status\":null},\"aggregate_data\":null,\"establishment_name\":\"Heavenly Buffaloes\",\"spv\":null,\"confirmed\":null,\"pan\":\"345425f15b2c7c4584e0044357b6394d7e\",\"customer_token\":null,\"card_data\":\"/tokens/7721017\"}" read 659 bytes Conn close ) @@ -306,7 +456,7 @@ def post_scrubbed -> "Via: kong/0.8.3\r\n" -> "\r\n" reading 659 bytes... - -> "{\"id\":7721017,\"site_transaction_id\":\"d5972b68-87d5-46fd-8d3d-b2512902b9af\",\"payment_method_id\":1,\"card_brand\":\"Visa\",\"amount\":100,\"currency\":\"ars\",\"status\":\"approved\",\"status_details\":{\"ticket\":\"7297\",\"card_authorization_code\":\"153842\",\"address_validation_code\":\"VTE0011\",\"error\":null},\"date\":\"2019-06-24T15:38Z\",\"customer\":null,\"bin\":\"450799\",\"installments\":1,\"first_installment_expiration_date\":null,\"payment_type\":\"single\",\"sub_payments\":[],\"site_id\":\"99999999\",\"fraud_detection\":null,\"aggregate_data\":null,\"establishment_name\":null,\"spv\":null,\"confirmed\":null,\"pan\":\"345425f15b2c7c4584e0044357b6394d7e\",\"customer_token\":null,\"card_data\":\"/tokens/7721017\"}" + -> "{\"id\":7721017,\"site_transaction_id\":\"d5972b68-87d5-46fd-8d3d-b2512902b9af\",\"payment_method_id\":1,\"card_brand\":\"Visa\",\"amount\":100,\"currency\":\"ars\",\"status\":\"approved\",\"status_details\":{\"ticket\":\"7297\",\"card_authorization_code\":\"153842\",\"address_validation_code\":\"VTE0011\",\"error\":null},\"date\":\"2019-06-24T15:38Z\",\"customer\":null,\"bin\":\"450799\",\"installments\":1,\"first_installment_expiration_date\":null,\"payment_type\":\"single\",\"sub_payments\":[],\"site_id\":\"99999999\",\"fraud_detection\":{\"status\":null},\"aggregate_data\":null,\"establishment_name\":\"Heavenly Buffaloes\",\"spv\":null,\"confirmed\":null,\"pan\":\"345425f15b2c7c4584e0044357b6394d7e\",\"customer_token\":null,\"card_data\":\"/tokens/7721017\"}" read 659 bytes Conn close ) @@ -314,7 +464,7 @@ def post_scrubbed def successful_purchase_response %( - {"id":7719132,"site_transaction_id":"ebcb2db7-7aab-4f33-a7d1-6617a5749fce","payment_method_id":1,"card_brand":"Visa","amount":100,"currency":"ars","status":"approved","status_details":{"ticket":"7156","card_authorization_code":"174838","address_validation_code":"VTE0011","error":null},"date":"2019-06-21T17:48Z","customer":null,"bin":"450799","installments":1,"first_installment_expiration_date":null,"payment_type":"single","sub_payments":[],"site_id":"99999999","fraud_detection":null,"aggregate_data":null,"establishment_name":null,"spv":null,"confirmed":null,"pan":"345425f15b2c7c4584e0044357b6394d7e","customer_token":null,"card_data":"/tokens/7719132"} + {"id":7719132,"site_transaction_id":"ebcb2db7-7aab-4f33-a7d1-6617a5749fce","payment_method_id":1,"card_brand":"Visa","amount":100,"currency":"ars","status":"approved","status_details":{"ticket":"7156","card_authorization_code":"174838","address_validation_code":"VTE0011","error":null},"date":"2019-06-21T17:48Z","customer":null,"bin":"450799","installments":1,"establishment_name":"Heavenly Buffaloes","first_installment_expiration_date":null,"payment_type":"single","sub_payments":[],"site_id":"99999999","fraud_detection":{"status":null},"aggregate_data":null,"establishment_name":null,"spv":null,"confirmed":null,"pan":"345425f15b2c7c4584e0044357b6394d7e","customer_token":null,"card_data":"/tokens/7719132"} ) end @@ -388,4 +538,16 @@ def failed_void_response {"error_type":"not_found_error","entity_name":"","id":""} ) end + + def unique_error_response + %{ + {\"error\":{\"error_type\":\"invalid_request_error\",\"validation_errors\":[{\"code\":\"invalid_param\",\"param\":\"payment_type\"}]}} + } + end + + def error_response_with_error_code + %{ + {\"error\":{\"type\":\"invalid_number\",\"reason\":{\"id\":14,\"description\":\"TARJETA INVALIDA\",\"additional_description\":\"\"}}} + } + end end diff --git a/test/unit/gateways/dibs_test.rb b/test/unit/gateways/dibs_test.rb index af127ba0be8..0f639e4df34 100644 --- a/test/unit/gateways/dibs_test.rb +++ b/test/unit/gateways/dibs_test.rb @@ -62,7 +62,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(/1066662996/, data) end.respond_with(successful_capture_response) @@ -97,7 +97,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(/1066662996/, data) end.respond_with(successful_void_response) @@ -107,7 +107,7 @@ def test_successful_void 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) @@ -124,7 +124,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(/1066662996/, data) end.respond_with(successful_refund_response) diff --git a/test/unit/gateways/digitzs_test.rb b/test/unit/gateways/digitzs_test.rb index 99b57ddc432..ef5b67a844b 100644 --- a/test/unit/gateways/digitzs_test.rb +++ b/test/unit/gateways/digitzs_test.rb @@ -38,8 +38,8 @@ def test_successful_purchase def test_successful_card_split_purchase response = stub_comms do @gateway.purchase(@amount, @credit_card, @options_with_split) - end.check_request do |endpoint, data, headers| - if data =~ /"cardSplit"/ + end.check_request do |_endpoint, data, _headers| + if /"cardSplit"/.match?(data) assert_match(%r(split), data) assert_match(%r("merchantId":"spreedly-susanswidg-32270590-2095203-148657924"), data) end @@ -52,8 +52,8 @@ def test_successful_card_split_purchase def test_successful_token_split_purchase response = stub_comms do @gateway.purchase(@amount, @credit_card, @options_with_split) - end.check_request do |endpoint, data, headers| - if data =~ /"tokenSplit"/ + end.check_request do |_endpoint, data, _headers| + if /"tokenSplit"/.match?(data) assert_match(%r(split), data) assert_match(%r("merchantId":"spreedly-susanswidg-32270590-2095203-148657924"), data) end @@ -103,7 +103,7 @@ def test_successful_store_creates_new_customer @gateway.expects(:ssl_get).returns(customer_id_exists_response) @gateway.expects(:ssl_post).times(3).returns(successful_app_token_response, successful_create_customer_response, successful_token_response) - assert response = @gateway.store(@credit_card, @options.merge({customer_id: 'pre_existing_customer_id'})) + assert response = @gateway.store(@credit_card, @options.merge({ customer_id: 'pre_existing_customer_id' })) assert_success response assert_equal 'spreedly-susanswidg-32268973-2091076-148408385-2894006614343495-148710226|c0302d83-a694-4bec-9086-d1886b9eefd9-148710226', response.authorization end diff --git a/test/unit/gateways/ebanx_test.rb b/test/unit/gateways/ebanx_test.rb index c5e93bc8e13..0b0bb76b24a 100644 --- a/test/unit/gateways/ebanx_test.rb +++ b/test/unit/gateways/ebanx_test.rb @@ -54,11 +54,20 @@ def test_successful_capture response = @gateway.capture(@amount, 'authorization', @options) assert_success response - - assert_equal 'Sandbox - Test credit card, transaction captured', response.message + assert_equal '5dee94502bd59660b801c441ad5a703f2c4123f5fc892ccb', response.authorization + assert_equal 'Accepted', response.message assert response.test? end + def test_failed_partial_capture + @gateway.expects(:ssl_request).returns(failed_partial_capture_response) + + response = @gateway.capture(@amount, 'authorization', @options.merge(include_capture_amount: true)) + assert_failure response + assert_equal 'BP-CAP-11', response.error_code + assert_equal 'Partial capture not available', response.message + end + def test_failed_capture @gateway.expects(:ssl_request).returns(failed_capture_response) @@ -157,7 +166,7 @@ def test_scrub def pre_scrubbed %q( - request_body={\"integration_key\":\"1231000\",\"operation\":\"request\",\"payment\":{\"amount_total\":\"1.00\",\"currency_code\":\"USD\",\"merchant_payment_code\":\"2bed75b060e936834e354d944aeaa892\",\"name\":\"Longbob Longsen\",\"email\":\"unspecified@example.com\",\"document\":\"853.513.468-93\",\"payment_type_code\":\"visa\",\"creditcard\":{\"card_number\":\"4111111111111111\",\"card_name\":\"Longbob Longsen\",\"card_due_date\":\"9/2018\",\"card_cvv\":\"123\"},\"address\":\"Rua E\",\"street_number\":\"1040\",\"city\":\"Maracana\u{fa}\",\"state\":\"CE\",\"zipcode\":\"61919-230\",\"country\":\"BR\",\"phone_number\":\"(555)555-5555\"}} + request_body={\"integration_key\":\"Ac1EwnH0ud2UIndICS37l0\",\"operation\":\"request\",\"payment\":{\"amount_total\":\"1.00\",\"currency_code\":\"USD\",\"merchant_payment_code\":\"2bed75b060e936834e354d944aeaa892\",\"name\":\"Longbob Longsen\",\"email\":\"unspecified@example.com\",\"document\":\"853.513.468-93\",\"payment_type_code\":\"visa\",\"creditcard\":{\"card_number\":\"4111111111111111\",\"card_name\":\"Longbob Longsen\",\"card_due_date\":\"9/2018\",\"card_cvv\":\"123\"},\"address\":\"Rua E\",\"street_number\":\"1040\",\"city\":\"Maracana\u{fa}\",\"state\":\"CE\",\"zipcode\":\"61919-230\",\"country\":\"BR\",\"phone_number\":\"(555)555-5555\"}} ) end @@ -193,7 +202,13 @@ def failed_authorize_response def successful_capture_response %( - {"payment":{"hash":"592dd65824427e4f5f50564c118f399869637bfb30d54f5b","pin":"081043654","merchant_payment_code":"8424e3000d64d056fbd58639957dc1c4","order_number":null,"status":"CO","status_date":"2017-05-30 17:30:16","open_date":"2017-05-30 17:30:15","confirm_date":"2017-05-30 17:30:16","transfer_date":null,"amount_br":"3.31","amount_ext":"1.00","amount_iof":"0.01","currency_rate":"3.3000","currency_ext":"USD","due_date":"2017-06-02","instalments":"1","payment_type_code":"visa","transaction_status":{"acquirer":"EBANX","code":"OK","description":"Sandbox - Test credit card, transaction captured"},"pre_approved":true,"capture_available":false,"customer":{"document":"85351346893","email":"unspecified@example.com","name":"LONGBOB LONGSEN","birth_date":null}},"status":"SUCCESS"} + {"payment":{"hash":"5dee94502bd59660b801c441ad5a703f2c4123f5fc892ccb","pin":"675968133","country":"br","merchant_payment_code":"b98b2892b80771b9dadf2ebc482cb65d","order_number":null,"status":"CO","status_date":"2019-12-09 18:37:05","open_date":"2019-12-09 18:37:04","confirm_date":"2019-12-09 18:37:05","transfer_date":null,"amount_br":"4.19","amount_ext":"1.00","amount_iof":"0.02","currency_rate":"4.1700","currency_ext":"USD","due_date":"2019-12-12","instalments":"1","payment_type_code":"visa","details":{"billing_descriptor":"DEMONSTRATION"},"transaction_status":{"acquirer":"EBANX","code":"OK","description":"Accepted"},"pre_approved":true,"capture_available":false,"customer":{"document":"85351346893","email":"unspecified@example.com","name":"LONGBOB LONGSEN","birth_date":null}},"status":"SUCCESS"} + ) + end + + def failed_partial_capture_response + %( + {"status":"ERROR", "status_code":"BP-CAP-11", "status_message":"Partial capture not available"} ) end diff --git a/test/unit/gateways/efsnet_test.rb b/test/unit/gateways/efsnet_test.rb index e437e2aa422..15c79aecf1f 100644 --- a/test/unit/gateways/efsnet_test.rb +++ b/test/unit/gateways/efsnet_test.rb @@ -1,16 +1,15 @@ require 'test_helper' class EfsnetTest < Test::Unit::TestCase - def setup @gateway = EfsnetGateway.new( - :login => 'LOGIN', - :password => 'PASSWORD' + login: 'LOGIN', + password: 'PASSWORD' ) @credit_card = credit_card('4242424242424242') @amount = 100 - @options = { :order_id => 1, :billing_address => address } + @options = { order_id: 1, billing_address: address } end def test_successful_purchase @@ -36,28 +35,28 @@ def test_unsuccessful_purchase def test_credit @gateway.expects(:ssl_post).with(anything, regexp_matches(/AccountNumber>#{@credit_card.number}<\/AccountNumber/), anything).returns('') - @gateway.credit(@amount, @credit_card, :order_id => 5) + @gateway.credit(@amount, @credit_card, order_id: 5) end def test_deprecated_credit @gateway.expects(:ssl_post).with(anything, regexp_matches(/transaction_id<\/OriginalTransactionID>/), anything).returns('') assert_deprecation_warning(Gateway::CREDIT_DEPRECATION_MESSAGE) do - @gateway.credit(@amount, 'transaction_id', :order_id => 5) + @gateway.credit(@amount, 'transaction_id', order_id: 5) end end def test_refund @gateway.expects(:ssl_post).with(anything, regexp_matches(/transaction_id<\/OriginalTransactionID>/), anything).returns('') - @gateway.refund(@amount, 'transaction_id', :order_id => 5) + @gateway.refund(@amount, 'transaction_id', order_id: 5) end def test_authorize_is_valid_xml params = { - :order_id => 'order1', - :transaction_amount => '1.01', - :account_number => '4242424242424242', - :expiration_month => '12', - :expiration_year => '2029', + order_id: 'order1', + transaction_amount: '1.01', + account_number: '4242424242424242', + expiration_month: '12', + expiration_year: '2029' } assert data = @gateway.send(:post_data, :credit_card_authorize, params) @@ -66,10 +65,10 @@ def test_authorize_is_valid_xml def test_settle_is_valid_xml params = { - :order_id => 'order1', - :transaction_amount => '1.01', - :original_transaction_amount => '1.01', - :original_transaction_id => '1', + order_id: 'order1', + transaction_amount: '1.01', + original_transaction_amount: '1.01', + original_transaction_id: '1' } assert data = @gateway.send(:post_data, :credit_card_settle, params) @@ -93,48 +92,48 @@ def test_cvv_result private def successful_purchase_response - <<-XML - - - - 0 - 00 - APPROVED - 100018347764 - N - M - 123456 - 123456 - 080117 - 163222 - 1 - XXXXXXXXXXXX2224 - 1.00 - - + <<~XML + + + + 0 + 00 + APPROVED + 100018347764 + N + M + 123456 + 123456 + 080117 + 163222 + 1 + XXXXXXXXXXXX2224 + 1.00 + + XML end def unsuccessful_purchase_response - <<-XML - - - - 256 - 04 - DECLINED - 100018347784 - N - - - - 080117 - 163946 - 1 - XXXXXXXXXXXX2224 - 1.56 - - + <<~XML + + + + 256 + 04 + DECLINED + 100018347784 + N + + + + 080117 + 163946 + 1 + XXXXXXXXXXXX2224 + 1.56 + + XML end end diff --git a/test/unit/gateways/elavon_test.rb b/test/unit/gateways/elavon_test.rb index 8900990d879..81919fe7959 100644 --- a/test/unit/gateways/elavon_test.rb +++ b/test/unit/gateways/elavon_test.rb @@ -5,25 +5,25 @@ class ElavonTest < Test::Unit::TestCase def setup @gateway = ElavonGateway.new( - :login => 'login', - :user => 'user', - :password => 'password' - ) + login: 'login', + user: 'user', + password: 'password' + ) @multi_currency_gateway = ElavonGateway.new( - :login => 'login', - :user => 'user', - :password => 'password', - :multi_currency => true - ) + login: 'login', + user: 'user', + password: 'password', + multi_currency: true + ) @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 @@ -32,7 +32,7 @@ def test_successful_purchase assert response = @gateway.purchase(@amount, @credit_card, @options) assert_success response - assert_equal '123456;00000000-0000-0000-0000-00000000000', response.authorization + assert_equal '093840;180820AD3-27AEE6EF-8CA7-4811-8D1F-E420C3B5041E', response.authorization assert response.test? end @@ -43,8 +43,8 @@ def test_successful_authorization assert_instance_of Response, response assert_success response - assert_equal '123456;00000000-0000-0000-0000-00000000000', response.authorization - assert_equal 'APPROVED', response.message + assert_equal '259404;150920ED4-3EB7A2DF-A5A7-48E6-97B6-D98A9DC0BD59', response.authorization + assert_equal 'APPROVAL', response.message assert response.test? end @@ -58,44 +58,44 @@ def test_failed_authorization def test_successful_capture @gateway.expects(:ssl_post).returns(successful_capture_response) - authorization = '123456;00000000-0000-0000-0000-00000000000' + authorization = '070213;110820ED4-23CA2F2B-A88C-40E1-AC46-9219F800A520' - assert response = @gateway.capture(@amount, authorization, :credit_card => @credit_card) + assert response = @gateway.capture(@amount, authorization, credit_card: @credit_card) assert_instance_of Response, response assert_success response - assert_equal '123456;00000000-0000-0000-0000-00000000000', response.authorization + assert_equal '070213;110820ED4-23CA2F2B-A88C-40E1-AC46-9219F800A520', response.authorization assert_equal 'APPROVAL', response.message assert response.test? end def test_successful_capture_with_auth_code @gateway.expects(:ssl_post).returns(successful_capture_response) - authorization = '123456;00000000-0000-0000-0000-00000000000' + authorization = '070213;110820ED4-23CA2F2B-A88C-40E1-AC46-9219F800A520' assert response = @gateway.capture(@amount, authorization) assert_instance_of Response, response assert_success response - assert_equal '123456;00000000-0000-0000-0000-00000000000', response.authorization + assert_equal '070213;110820ED4-23CA2F2B-A88C-40E1-AC46-9219F800A520', response.authorization assert_equal 'APPROVAL', response.message assert response.test? end def test_successful_capture_with_additional_options - authorization = '123456;00000000-0000-0000-0000-00000000000' + authorization = '070213;110820ED4-23CA2F2B-A88C-40E1-AC46-9219F800A520' response = stub_comms do - @gateway.capture(@amount, authorization, :test_mode => true, :partial_shipment_flag => true) - end.check_request do |endpoint, data, headers| - assert_match(/ssl_transaction_type=CCCOMPLETE/, data) - assert_match(/ssl_test_mode=TRUE/, data) - assert_match(/ssl_partial_shipment_flag=Y/, data) + @gateway.capture(@amount, authorization, test_mode: true, partial_shipment_flag: true) + end.check_request do |_endpoint, data, _headers| + assert_match(/CCCOMPLETE<\/ssl_transaction_type>/, data) + assert_match(/TRUE<\/ssl_test_mode>/, data) + assert_match(/Y<\/ssl_partial_shipment_flag>/, data) end.respond_with(successful_capture_response) assert_instance_of Response, response assert_success response - assert_equal '123456;00000000-0000-0000-0000-00000000000', response.authorization + assert_equal '070213;110820ED4-23CA2F2B-A88C-40E1-AC46-9219F800A520', response.authorization assert_equal 'APPROVAL', response.message assert response.test? end @@ -104,8 +104,7 @@ def test_successful_purchase_with_ip response = stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(ip: '203.0.113.0')) end.check_request do |_endpoint, data, _headers| - parsed = CGI.parse(data) - assert_equal ['203.0.113.0'], parsed['ssl_cardholder_ip'] + assert_match(/203.0.113.0/, data) end.respond_with(successful_purchase_response) assert_success response @@ -115,8 +114,37 @@ def test_successful_authorization_with_ip response = stub_comms do @gateway.authorize(@amount, @credit_card, @options.merge(ip: '203.0.113.0')) end.check_request do |_endpoint, data, _headers| - parsed = CGI.parse(data) - assert_equal ['203.0.113.0'], parsed['ssl_cardholder_ip'] + assert_match(/203.0.113.0<\/ssl_cardholder_ip>/, data) + end.respond_with(successful_authorization_response) + + assert_success response + end + + def test_successful_purchase_with_dynamic_dba + response = stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(dba: 'MANYMAG*BAKERS MONTHLY')) + end.check_request do |_endpoint, data, _headers| + assert_match(/MANYMAG\*BAKERS MONTHLY<\/ssl_dynamic_dba>/, data) + end.respond_with(successful_purchase_response) + + assert_success response + end + + def test_successful_purchase_with_unscheduled + response = stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(merchant_initiated_unscheduled: 'Y')) + end.check_request do |_endpoint, data, _headers| + assert_match(/Y<\/ssl_merchant_initiated_unscheduled>/, data) + end.respond_with(successful_purchase_response) + + assert_success response + end + + def test_successful_authorization_with_dynamic_dba + response = stub_comms do + @gateway.authorize(@amount, @credit_card, @options.merge(dba: 'MANYMAG*BAKERS MONTHLY')) + end.check_request do |_endpoint, data, _headers| + assert_match(/MANYMAG\*BAKERS MONTHLY<\/ssl_dynamic_dba>/, data) end.respond_with(successful_authorization_response) assert_success response @@ -124,9 +152,9 @@ def test_successful_authorization_with_ip def test_successful_purchase_with_multi_currency response = stub_comms(@multi_currency_gateway) do - @multi_currency_gateway.purchase(@amount, @credit_card, @options.merge(currency: 'EUR')) - end.check_request do |endpoint, data, headers| - assert_match(/ssl_transaction_currency=EUR/, data) + @multi_currency_gateway.purchase(@amount, @credit_card, @options.merge(currency: 'JPY')) + end.check_request do |_endpoint, data, _headers| + assert_match(/JPY<\/ssl_transaction_currency>/, data) end.respond_with(successful_purchase_with_multi_currency_response) assert_success response @@ -135,7 +163,7 @@ def test_successful_purchase_with_multi_currency def test_successful_purchase_without_multi_currency response = stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(currency: 'EUR', multi_currency: false)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_no_match(/ssl_transaction_currency=EUR/, data) end.respond_with(successful_purchase_response) @@ -146,7 +174,7 @@ def test_failed_capture @gateway.expects(:ssl_post).returns(failed_authorization_response) authorization = '123456INVALID;00000000-0000-0000-0000-00000000000' - assert response = @gateway.capture(@amount, authorization, :credit_card => @credit_card) + assert response = @gateway.capture(@amount, authorization, credit_card: @credit_card) assert_instance_of Response, response assert_failure response end @@ -188,28 +216,20 @@ def test_unsuccessful_refund assert response = @gateway.refund(123, '456') assert_failure response - assert_equal 'The refund amount exceeds the original transaction amount.', response.message + assert_equal 'The amount exceeded the original transaction amount. Amount must be equal or lower than the original transaction amount.', response.message end def test_successful_verify response = stub_comms do @gateway.verify(@credit_card) - end.respond_with(successful_authorization_response, successful_void_response) - assert_success response - end - - def test_successful_verify_failed_void - response = stub_comms do - @gateway.verify(@credit_card, @options) - end.respond_with(successful_authorization_response, failed_void_response) + end.respond_with(successful_verify_response) assert_success response - assert_equal 'APPROVED', response.message end def test_unsuccessful_verify response = stub_comms do @gateway.verify(@credit_card, @options) - end.respond_with(failed_authorization_response, successful_void_response) + end.respond_with(failed_verify_response) assert_failure response assert_equal 'The Credit Card Number supplied in the authorization request appears to be invalid.', response.message end @@ -219,25 +239,25 @@ def test_invalid_login assert response = @gateway.purchase(@amount, @credit_card, @options) - assert_equal '7000', response.params['result'] - assert_equal 'The VirtualMerchant ID and/or User ID supplied in the authorization request is invalid.', response.message + assert_equal '4025', response.params['errorCode'] + assert_equal 'The credentials supplied in the authorization request are invalid.', response.message assert_failure response end def test_supported_card_types - assert_equal [:visa, :master, :american_express, :discover], ElavonGateway.supported_cardtypes + assert_equal %i[visa master american_express discover], ElavonGateway.supported_cardtypes end def test_avs_result @gateway.expects(:ssl_post).returns(successful_purchase_response) response = @gateway.purchase(@amount, @credit_card) - assert_equal 'X', response.avs_result['code'] + assert_equal 'M', response.avs_result['code'] end def test_cvv_result @gateway.expects(:ssl_post).returns(successful_purchase_response) response = @gateway.purchase(@amount, @credit_card) - assert_equal 'P', response.cvv_result['code'] + assert_equal 'M', response.cvv_result['code'] end def test_successful_store @@ -245,7 +265,7 @@ def test_successful_store assert response = @gateway.store(@credit_card, @options) assert_success response - assert_equal '7595301425001111', response.params['token'] + assert_equal '4421912014039990', response.params['token'] assert response.test? end @@ -279,7 +299,7 @@ def test_stripping_non_word_characters_from_zip @options[:billing_address][:zip] = bad_zip - @gateway.expects(:commit).with(anything, anything, has_entries(:avs_zip => stripped_zip), anything) + @gateway.expects(:commit).with(includes("#{stripped_zip}")) @gateway.purchase(@amount, @credit_card, @options) end @@ -287,18 +307,222 @@ def test_stripping_non_word_characters_from_zip def test_zip_codes_with_letters_are_left_intact @options[:billing_address][:zip] = '.K1%Z_5E3-' - @gateway.expects(:commit).with(anything, anything, has_entries(:avs_zip => 'K1Z5E3'), anything) + @gateway.expects(:commit).with(includes('K1Z5E3')) @gateway.purchase(@amount, @credit_card, @options) end + def test_strip_ampersands + stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(shipping_address: { address1: 'Bats & Cats' })) + end.check_request do |_endpoint, data, _headers| + refute_match(/&/, data) + end.respond_with(successful_purchase_response) + end + + def test_split_full_network_transaction_id + oar_data = '010012318808182231420000047554200000000000093840023122123188' + ps2000_data = 'A8181831435010530042VE' + network_transaction_id = "#{oar_data}|#{ps2000_data}" + stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(stored_credential: { network_transaction_id: network_transaction_id })) + end.check_request do |_endpoint, data, _headers| + assert_match(/#{oar_data}<\/ssl_oar_data>/, data) + assert_match(/#{ps2000_data}<\/ssl_ps2000_data>/, data) + end.respond_with(successful_purchase_response) + end + + def test_oar_only_network_transaction_id + oar_data = '010012318808182231420000047554200000000000093840023122123188' + ps2000_data = nil + network_transaction_id = "#{oar_data}|#{ps2000_data}" + stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(stored_credential: { network_transaction_id: network_transaction_id })) + end.check_request do |_endpoint, data, _headers| + assert_match(/#{oar_data}<\/ssl_oar_data>/, data) + refute_match(//, data) + end.respond_with(successful_purchase_response) + end + + def test_ps2000_only_network_transaction_id + oar_data = nil + ps2000_data = 'A8181831435010530042VE' + network_transaction_id = "#{oar_data}|#{ps2000_data}" + stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(stored_credential: { network_transaction_id: network_transaction_id })) + end.check_request do |_endpoint, data, _headers| + refute_match(//, data) + assert_match(/#{ps2000_data}<\/ssl_ps2000_data>/, data) + end.respond_with(successful_purchase_response) + end + + def test_oar_transaction_id_without_pipe + oar_data = '010012318808182231420000047554200000000000093840023122123188' + stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(stored_credential: { network_transaction_id: oar_data })) + end.check_request do |_endpoint, data, _headers| + assert_match(/#{oar_data}<\/ssl_oar_data>/, data) + refute_match(//, data) + end.respond_with(successful_purchase_response) + end + + def test_ps2000_transaction_id_without_pipe + ps2000_data = 'A8181831435010530042VE' + stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(stored_credential: { network_transaction_id: ps2000_data })) + end.check_request do |_endpoint, data, _headers| + refute_match(//, data) + assert_match(/#{ps2000_data}<\/ssl_ps2000_data>/, data) + end.respond_with(successful_purchase_response) + end + def test_custom_fields_in_request stub_comms do - @gateway.purchase(@amount, @credit_card, @options.merge(:customer_number => '123', :custom_fields => {:a_key => 'a value'})) - end.check_request do |endpoint, data, headers| - assert_match(/customer_number=123/, data) - assert_match(/a_key/, data) - refute_match(/ssl_a_key/, data) + @gateway.purchase(@amount, @credit_card, @options.merge(customer_number: '123', custom_fields: { a_key: 'a value' })) + end.check_request do |_endpoint, data, _headers| + assert_match(/123<\/ssl_customer_number>/, data) + assert_match(/a value<\/a_key>/, data) + end.respond_with(successful_purchase_response) + end + + def test_truncate_special_characters + first_name = 'Ricky ™ Martínez įncogníto' + credit_card = @credit_card + credit_card.first_name = first_name + + stub_comms do + @gateway.purchase(@amount, credit_card, @options) + end.check_request do |_endpoint, data, _headers| + check = 'Ricky ™ Martínez ' + assert_match(/#{check}/, data) + end.respond_with(successful_purchase_response) + end + + def test_level_3_fields_in_request + level_3_data = { + customer_code: 'bob', + salestax: '3.45', + salestax_indicator: 'Y', + level3_indicator: 'Y', + ship_to_zip: '12345', + ship_to_country: 'US', + shipping_amount: '1234', + ship_from_postal_code: '54321', + discount_amount: '5', + duty_amount: '2', + national_tax_indicator: '0', + national_tax_amount: '10', + order_date: '280810', + other_tax: '3', + summary_commodity_code: '123', + merchant_vat_number: '222', + customer_vat_number: '333', + freight_tax_amount: '4', + vat_invoice_number: '26', + tracking_number: '45', + shipping_company: 'UFedzon', + other_fees: '2', + line_items: [ + { + description: 'thing', + product_code: '23', + commodity_code: '444', + quantity: '15', + unit_of_measure: 'kropogs', + unit_cost: '4.5', + discount_indicator: 'Y', + tax_indicator: 'Y', + discount_amount: '1', + tax_rate: '8.25', + tax_amount: '12', + tax_type: 'state', + extended_total: '500', + total: '525', + alternative_tax: '111' + }, + { + description: 'thing2', + product_code: '23', + commodity_code: '444', + quantity: '15', + unit_of_measure: 'kropogs', + unit_cost: '4.5', + discount_indicator: 'Y', + tax_indicator: 'Y', + discount_amount: '1', + tax_rate: '8.25', + tax_amount: '12', + tax_type: 'state', + extended_total: '500', + total: '525', + alternative_tax: '111' + } + ] + } + + options = @options.merge(level_3_data: level_3_data) + stub_comms do + @gateway.purchase(@amount, @credit_card, options) + end.check_request do |_endpoint, data, _headers| + assert_match(/bob/, data) + assert_match(/3.45/, data) + assert_match(/Y/, data) + assert_match(/Y/, data) + assert_match(/12345/, data) + assert_match(/US/, data) + assert_match(/1234/, data) + assert_match(/54321/, data) + assert_match(/5/, data) + assert_match(/2/, data) + assert_match(/0/, data) + assert_match(/10/, data) + assert_match(/280810/, data) + assert_match(/3/, data) + assert_match(/123/, data) + assert_match(/222/, data) + assert_match(/333/, data) + assert_match(/4/, data) + assert_match(/26/, data) + assert_match(/45/, data) + assert_match(/UFedzon/, data) + assert_match(/2/, data) + assert_match(//, data) + assert_match(//, data) + assert_match(//, data) + assert_match(//, data) + assert_match(//, data) + assert_match(//, data) + assert_match(//, data) + assert_match(//, data) + assert_match(//, data) + assert_match(//, data) + assert_match(//, data) + assert_match(//, data) + assert_match(//, data) + assert_match(//, data) + assert_match(//, data) + end.respond_with(successful_purchase_response) + end + + def test_shipping_address_in_request + shipping_address = { + address1: '733 Foster St.', + city: 'Durham', + state: 'NC', + phone: '8887277750', + country: 'USA', + zip: '27701' + } + options = @options.merge(shipping_address: shipping_address) + stub_comms do + @gateway.purchase(@amount, @credit_card, options) + end.check_request do |_endpoint, data, _headers| + assert_match(/733 Foster St./, data) + assert_match(/Durham/, data) + assert_match(/NC/, data) + assert_match(/8887277750/, data) + assert_match(/USA/, data) + assert_match(/27701/, data) end.respond_with(successful_purchase_response) end @@ -310,206 +534,434 @@ def test_transcript_scrubbing private def successful_purchase_response - "ssl_card_number=42********4242 - ssl_exp_date=0910 - ssl_amount=1.00 - ssl_invoice_number= - ssl_description=Test Transaction - ssl_result=0 - ssl_result_message=APPROVED - ssl_txn_id=00000000-0000-0000-0000-00000000000 - ssl_approval_code=123456 - ssl_cvv2_response=P - ssl_avs_response=X - ssl_account_balance=0.00 - ssl_txn_time=08/07/2009 09:54:18 PM" + <<-XML + + + 00 + Longsen + Widgets Inc + (555)555-5555 + 41**********9990 + + 010012318808182231420000047554200000000000093840023122123188 + 0 + 180820AD3-27AEE6EF-8CA7-4811-8D1F-E420C3B5041E + M + 093840 + paul@domain.com + 100.00 + K1C2N6 + 08/18/2020 06:31:42 PM + 0921 + VISA + + Apt 1 + CA + CREDITCARD + AUTHONLY + + 456 My Street + 0.00 + A8181831435010530042VE + ON + Ottawa + APPROVAL + Longbob + + M + VM + + XML end def successful_purchase_with_multi_currency_response - "ssl_card_number=42********4242 - ssl_exp_date=0910 - ssl_amount=1.00 - ssl_invoice_number= - ssl_description=Test Transaction - ssl_result=0 - ssl_result_message=APPROVED - ssl_txn_id=00000000-0000-0000-0000-00000000000 - ssl_approval_code=123456 - ssl_cvv2_response=P - ssl_avs_response=X - ssl_account_balance=0.00 - ssl_transaction_currency=EUR - ssl_txn_time=08/07/2009 09:54:18 PM" + <<-XML + + + 00 + + 41**********9990 + + 010012316708182238060000047554200000000000093864023122123167 + 0 + 180820ED3-1DD371B9-64DF-4902-B377-EBD095E6DAF0 + + M + 093864 + + 100 + JPY + 08/18/2020 06:38:06 PM + + 0921 + VISA + + CREDITCARD + + SALE + + 0.00 + + 0.00 + A8181838065010780213VE + APPROVAL + + + + VM + + XML end def successful_refund_response - "ssl_card_number=42*****2222 - ssl_exp_date= - ssl_amount=1.00 - ssl_customer_code= - ssl_invoice_number= - ssl_description= - ssl_company= - ssl_first_name= - ssl_last_name= - ssl_avs_address= - ssl_address2= - ssl_city= - ssl_state= - ssl_avs_zip= - ssl_country= - ssl_phone= - ssl_email= - ssl_result=0 - ssl_result_message=APPROVAL - ssl_txn_id=AA49315-C3D2B7BA-237C-1168-405A-CD5CAF928B0C - ssl_approval_code= - ssl_cvv2_response= - ssl_avs_response= - ssl_account_balance=0.00 - ssl_txn_time=08/21/2012 05:43:46 PM" + <<-XML + + + 00 + Longsen + Widgets Inc + (555)555-5555 + 41**********9990 + + 0 + 180820AD3-4BACDE38-63F3-427D-BFC1-1B3EB046056B + + 094012 + paul@domain.com + 100.00 + K1C2N6 + 08/18/2020 07:04:49 PM + 0921 + VISA + + Apt 1 + + CA + CREDITCARD + RETURN + + 456 My Street + 0.00 + ON + Ottawa + APPROVAL + Longbob + + + VM + + XML end def successful_void_response - "ssl_card_number=42*****2222 - ssl_exp_date=0913 - ssl_amount=1.00 - ssl_invoice_number= - ssl_description= - ssl_company= - ssl_first_name= - ssl_last_name= - ssl_avs_address= - ssl_address2= - ssl_city= - ssl_state= - ssl_avs_zip= - ssl_country= - ssl_phone= - ssl_email= - ssl_result=0 - ssl_result_message=APPROVAL - ssl_txn_id=AA49315-F04216E3-E556-E2E0-ADE9-4186A5F69105 - ssl_approval_code= - ssl_cvv2_response= - ssl_avs_response= - ssl_account_balance=1.00 - ssl_txn_time=08/21/2012 05:37:19 PM" + <<-XML + + + Longsen + + Widgets Inc + (555)555-5555 + 41**********9990 + 0 + 180820AD3-2E02E02D-A1FB-4926-A957-3930D3F7B869 + paul@domain.com + 100.00 + K1C2N6 + 08/18/2020 06:56:27 PM + 0921 + VISA + Apt 1 + + CA + CREDITCARD + DELETE + + 456 My Street + ON + Ottawa + APPROVAL + Longbob + + VM + + XML + end + + def successful_verify_response + <<-XML + + + 85 + CARDVERIFICATION + 41**********9990 + 010012309508182257450000047554200000000000093964023122123095 + 0 + 180820ED4-85DA9146-51AB-4FEC-8004-91C607047E5C + M + 093964 + 456 My Street + K1C2N6 + 08/18/2020 06:57:45 PM + 0.00 + A8181857455011610042VE + 0921 + APPROVAL + VISA + CREDITCARD + M + VM + + XML end def failed_purchase_response - "errorCode=5000 - errorName=Credit Card Number Invalid - errorMessage=The Credit Card Number supplied in the authorization request appears to be invalid." + <<-XML + + + 5000 + Credit Card Number Invalid + The Credit Card Number supplied in the authorization request appears to be invalid. + + XML end def failed_refund_response - "errorCode=5091 - errorName=Invalid Refund Amount - errorMessage=The refund amount exceeds the original transaction amount." + <<-XML + + + 5091 + Invalid amount + The amount exceeded the original transaction amount. Amount must be equal or lower than the original transaction amount. + + XML end def failed_void_response - "errorCode=5040 - errorName=Invalid Transaction ID - errorMessage=The transaction ID is invalid for this transaction type" + <<-XML + + + 5040 + Invalid Transaction ID + The transaction ID is invalid for this transaction type + + XML + end + + def failed_verify_response + <<-XML + + + 5000 + Credit Card Number Invalid + The Credit Card Number supplied in the authorization request appears to be invalid. + + XML end def invalid_login_response - <<-RESPONSE - ssl_result=7000\r - ssl_result_message=The VirtualMerchant ID and/or User ID supplied in the authorization request is invalid.\r - RESPONSE + <<-XML + + + 4025 + Invalid Credentials + The credentials supplied in the authorization request are invalid. + + XML end def successful_authorization_response - "ssl_card_number=42********4242 - ssl_exp_date=0910 - ssl_amount=1.00 - ssl_invoice_number= - ssl_description=Test Transaction - ssl_result=0 - ssl_result_message=APPROVED - ssl_txn_id=00000000-0000-0000-0000-00000000000 - ssl_approval_code=123456 - ssl_cvv2_response=P - ssl_avs_response=X - ssl_account_balance=0.00 - ssl_txn_time=08/07/2009 09:56:11 PM" + <<-XML + + + 00 + AUTHONLY + 41**********9990 + + 010012312309152159540000047554200000000000259404025921123123 + 0 + 150920ED4-3EB7A2DF-A5A7-48E6-97B6-D98A9DC0BD59 + M + 259404 + + 100.00 + 09/15/2020 05:59:54 PM + 0.00 + A9151759546571260030VE + 0921 + APPROVAL + VISA + + 3 + CREDITCARD + + M + 01 + + XML end def failed_authorization_response - "errorCode=5000 - errorName=Credit Card Number Invalid - errorMessage=The Credit Card Number supplied in the authorization request appears to be invalid." + <<-XML + + + 5000 + Credit Card Number Invalid + The Credit Card Number supplied in the authorization request appears to be invalid. + + XML end def successful_capture_response - "ssl_card_number=42********4242 - ssl_exp_date=0910 - ssl_amount=1.00 - ssl_customer_code= - ssl_salestax= - ssl_invoice_number= - ssl_result=0 - ssl_result_message=APPROVAL - ssl_txn_id=00000000-0000-0000-0000-00000000000 - ssl_approval_code=123456 - ssl_cvv2_response=P - ssl_avs_response=X - ssl_account_balance=0.00 - ssl_txn_time=08/07/2009 09:56:11 PM" + <<~XML + + Longsen + Widgets Inc + (555)555-5555 + 41**********9990 + + 0 + 110820ED4-23CA2F2B-A88C-40E1-AC46-9219F800A520 + + 070213 + paul@domain.com + 100.00 + K1C2N6 + 08/11/2020 10:08:14 PM + 0921 + VISA + + Apt 1 + CA + CREDITCARD + FORCE + + 456 My Street + 0.00 + ON + Ottawa + APPROVAL + Longbob + + + VM + + XML end def failed_capture_response - "errorCode=5040 - errorName=Invalid Transaction ID - errorMessage=The transaction ID is invalid for this transaction type" + <<-XML + + + 5004 + Invalid Approval Code + The FORCE Approval Code supplied in the authorization request appears to be invalid or blank. The FORCE Approval Code must be 6 or less alphanumeric characters. + + XML end def successful_store_response - "ssl_transaction_type=CCGETTOKEN - ssl_result=0 - ssl_token=7595301425001111 - ssl_card_number=41**********1111 - ssl_token_response=SUCCESS - ssl_add_token_response=Card Updated - vu_aamc_id=" + <<-XML + + + Longsen + Widgets Inc + (555)555-5555 + 41**********9990 + 0 + + + + paul@domain.com + K1C2N6 + 08/18/2020 07:01:16 PM + 0921 + VISA + Apt 1 + SUCCESS + CA + CREDITCARD + GETTOKEN + + 456 My Street + + 0.00 + ON + Ottawa + + Longbob + + + 4421912014039990 + Card Updated + + XML end def failed_store_response - "errorCode=5000 - errorName=Credit Card Number Invalid - errorMessage=The Credit Card Number supplied in the authorization request appears to be invalid." + <<-XML + + + 5000 + Credit Card Number Invalid + The Credit Card Number supplied in the authorization request appears to be invalid. + + XML end def successful_update_response - "ssl_token=7595301425001111 - ssl_card_type=VISA - ssl_card_number=************1111 - ssl_exp_date=1015 - ssl_company= - ssl_customer_id= - ssl_first_name=John - ssl_last_name=Doe - ssl_avs_address= - ssl_address2= - ssl_avs_zip= - ssl_city= - ssl_state= - ssl_country= - ssl_phone= - ssl_email= - ssl_description= - ssl_user_id=webpage - ssl_token_response=SUCCESS - ssl_result=0" + <<-XML + + + 4421912014039990 + VISA + ************9990 + 1021 + Widgets Inc + + Longbob + Longsen + 456 My Street + Apt 1 + Ottawa + ON + K1C2N6 + CA + (555)555-5555 + paul@domain.com + + webpage + SUCCESS + 0 + + XML end def failed_update_response - "errorCode=5000 - errorName=Credit Card Number Invalid - errorMessage=The Credit Card Number supplied in the authorization request appears to be invalid." + <<-XML + + + 4421912014039990 + VISA + ************9990 + 1021 + Widgets Inc + + Longbob + Longsen + 456 My Street + Apt 1 + Ottawa + ON + K1C2N6 + CA + (555)555-5555 + paul@domain.com + + apiuser + Failed + 1 + + XML end def pre_scrub @@ -518,35 +970,38 @@ def pre_scrub opened starting SSL for api.demo.convergepay.com:443... SSL established -<- "POST /VirtualMerchantDemo/process.do 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: api.demo.convergepay.com\r\nContent-Length: 616\r\n\r\n" -<- "ssl_merchant_id=000127&ssl_pin=IERAOBEE5V0D6Q3Q6R51TG89XAIVGEQ3LGLKMKCKCVQBGGGAU7FN627GPA54P5HR&ssl_show_form=false&ssl_result_format=ASCII&ssl_user_id=ssltest&ssl_invoice_number=&ssl_description=Test+Transaction&ssl_card_number=4124939999999990&ssl_exp_date=0919&ssl_cvv2cvc2=123&ssl_cvv2cvc2_indicator=1&ssl_first_name=Longbob&ssl_last_name=Longsen&ssl_avs_address=456+My+Street&ssl_address2=Apt+1&ssl_avs_zip=K1C2N6&ssl_city=Ottawa&ssl_state=ON&ssl_company=Widgets+Inc&ssl_phone=%28555%29555-5555&ssl_country=CA&ssl_email=paul%40domain.com&ssl_cardholder_ip=203.0.113.0&ssl_amount=1.00&ssl_transaction_type=CCSALE" +<- "POST /VirtualMerchantDemo/processxml.do HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept: application/xml\r\nConnection: close\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nUser-Agent: Ruby\r\nHost: api.demo.convergepay.com\r\nContent-Length: 1026\r\n\r\n" +<- "xmldata=\n 2020701\n apiuser\n ULV2VQJXA5UR19KFXZ8TUWEFWMFY5MYXJVVOS8JN69EWV8XTN8Y0HYCR8B11DIUU\n CCSALE\n 100\n 4124939999999990\n 0921\n 123\n 1\n Longbob\n Longsen\n \n Test Transaction\n 456 My Street\n Apt 1\n K1C2N6\n Ottawa\n ON\n Widgets Inc\n (555)555-5555\n CA\n paul@domain.com\n N\n\n" -> "HTTP/1.1 200 OK\r\n" --> "Date: Wed, 03 Jan 2018 21:40:26 GMT\r\n" --> "Pragma: no-cache\r\n" --> "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n" +-> "Date: Tue, 15 Sep 2020 23:09:31 GMT\r\n" +-> "Server: Apache\r\n" +-> "X-Frame-Options: SAMEORIGIN\r\n" +-> "Strict-Transport-Security: max-age=31536000; includeSubDomains; preload\r\n" -> "Expires: 0\r\n" --> "Content-Disposition: inline; filename=response.txt\r\n" +-> "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n" -> "AuthApproved: true\r\n" +-> "Pragma: no-cache\r\n" +-> "X-Frame-Options: SAMEORIGIN\r\n" +-> "Content-Security-Policy: frame-ancestors 'self'\r\n" +-> "Content-Disposition: inline; filename=response.xml\r\n" +-> "CPID: ED4-dff741a6-df1a-463c-920e-2e4842eda7bf\r\n" -> "AuthResponse: AA\r\n" --> "Set-Cookie: JSESSIONID=00007wKfJV3-JFME8QiC_RCDjuI:14j4qkv92; HTTPOnly; Path=/; Secure\r\n" --> "Set-Cookie: JSESSIONID=0000uW6woWZ84eAJunhFLfJz8hS:14j4qkv92; HTTPOnly; Path=/; Secure\r\n" +-> "Content-Type: text/xml\r\n" +-> "Set-Cookie: JSESSIONID=UtM16S1VJSFsHChVlcYvM0cGVDWHMW1XD0vZ5T47.svplknxcnvrgdapp02; path=/VirtualMerchantDemo; secure; HttpOnly\r\n" -> "Connection: close\r\n" --> "Content-Type: text/plain\r\n" --> "Content-Language: en-US\r\n" --> "Content-Encoding: gzip\r\n" -> "Transfer-Encoding: chunked\r\n" -> "\r\n" --> "1A5 \r\n" -reading 421 bytes... --> "\x1F\x8B\b\x00\x00\x00\x00\x00\x00\x03MR\xEFk\xDB0\x10\xFD\xDE\xBF\xC2\x1F\xB7\x81[\xC9\xB1\x1D\xBB \x98\x7FtP\xD66!+\xDBGs\xB1o\x99\xC0\x96\x84%{q\xFF\xFA\xC9R\x12f\x10\xDC\xBDw\xBEw\xEF8\xAD\xFB\xA6\x85\xB1k\xC44\x1Cqd1\xFDr\xFB\xF2<'w\xDA\x16\xE0Y5\x1D\x18d$\xA7\xB9C`\x90\x930\x8C\xDE\x13_\xA1\xA1Gm\xE0\xCC\\\xC6\xC5,y\x8B\xD7\x9E\x0E\x130\xA0\x8FV9\x1Fu\xA8`4\xD3\x88\xBE\xFB\xDD;WM\xE1;\xFBJ9\xA8\x1E\r\x97\xE2Rp\x05A,\xEC\x17\xEFNht\xF0,Z\x87\xFF\xE6\xA36^\xE6E\x8A\xD3Q\x1E\x1D\xDC\xC3\xFF\xA8F\xE1P\x98u\x03]7\xA2\xD6,N\xD2\xE0u\t~\x98\x11\xD1x\xD63\x11+\x94\t\xA8W\xE5fa;c\xE0/\xB8\xDC\x9A\xB5\x03\xED\xDEn\xDD>\xB8b\xDFi\x15\xBD\xA5\xBE~u1.\xAC*\\\xAA\xFEH\x81\xECS\x92$\x9F\xED\v\xEDK\x1C\x8E\x03\xF0\x9E)\x98\xFA\xAF\x9D\xB4\xB1\xB8\xB7\xF6\x1Cc\a\x98z\xC3\xFCz}\xD2\fv(8!+\xF6\xFB\xC3\xEEg\xF1\xE28s\x16\r\xEF\x18\xD9\x10J\xB3\x82&!\xA9\xD3:O\xF3*|\x8A\xEA2\x8C\xB34\t\xB3o\xDB$,\xD3\xA2,\xB3tC\xB7E\xE9\xFE\x04\xA5F9\xC3:l\x87,\xDEnI\x1C9\xA2\x9D\xE7h\xD5TR\xE8\xCB\xD6W\x8B7\xE4\xE2\xBAu&\x9B#\xF4 Z{\x1C\xD7cX'2\xDCn\x9C\xD0\a\xB2y\x88\b\xCD\x02\x12?\xC6\xE41\xDA\x06\xFBW/\xB1\xDE\x9CY\x14\xB2\xEA\xF0T?\xBFW\xC5\xA1\xFE\aC\x85\x1DS\x8C\x02\x00\x00" -read 421 bytes +-> "44b\r\n" +reading 1099 bytes... +-> "\n00SALE41**********99900100123443091523092800000475542000000000002598490259231234430150920ED4-48E1CA31-F2C5-411B-9543-AEA81EFB81B9M259849100.0009/15/2020 07:09:28 PM0.00A9151909286574590030VE0921APPROVALVISA3CREDITCARDM01" +read 1099 bytes reading 2 bytes... -> "\r\n" read 2 bytes -> "0\r\n" -> "\r\n" Conn close -}} + } end def post_scrub @@ -555,34 +1010,37 @@ def post_scrub opened starting SSL for api.demo.convergepay.com:443... SSL established -<- "POST /VirtualMerchantDemo/process.do 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: api.demo.convergepay.com\r\nContent-Length: 616\r\n\r\n" -<- "ssl_merchant_id=000127&ssl_pin=[FILTERED]&ssl_show_form=false&ssl_result_format=ASCII&ssl_user_id=ssltest&ssl_invoice_number=&ssl_description=Test+Transaction&ssl_card_number=[FILTERED]&ssl_exp_date=0919&ssl_cvv2cvc2=[FILTERED]&ssl_cvv2cvc2_indicator=1&ssl_first_name=Longbob&ssl_last_name=Longsen&ssl_avs_address=456+My+Street&ssl_address2=Apt+1&ssl_avs_zip=K1C2N6&ssl_city=Ottawa&ssl_state=ON&ssl_company=Widgets+Inc&ssl_phone=%28555%29555-5555&ssl_country=CA&ssl_email=paul%40domain.com&ssl_cardholder_ip=203.0.113.0&ssl_amount=1.00&ssl_transaction_type=CCSALE" +<- "POST /VirtualMerchantDemo/processxml.do HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept: application/xml\r\nConnection: close\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nUser-Agent: Ruby\r\nHost: api.demo.convergepay.com\r\nContent-Length: 1026\r\n\r\n" +<- "xmldata=\n 2020701\n apiuser\n [FILTERED]\n CCSALE\n 100\n [FILTERED]\n 0921\n [FILTERED]\n 1\n Longbob\n Longsen\n \n Test Transaction\n 456 My Street\n Apt 1\n K1C2N6\n Ottawa\n ON\n Widgets Inc\n (555)555-5555\n CA\n paul@domain.com\n N\n\n" -> "HTTP/1.1 200 OK\r\n" --> "Date: Wed, 03 Jan 2018 21:40:26 GMT\r\n" --> "Pragma: no-cache\r\n" --> "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n" +-> "Date: Tue, 15 Sep 2020 23:09:31 GMT\r\n" +-> "Server: Apache\r\n" +-> "X-Frame-Options: SAMEORIGIN\r\n" +-> "Strict-Transport-Security: max-age=31536000; includeSubDomains; preload\r\n" -> "Expires: 0\r\n" --> "Content-Disposition: inline; filename=response.txt\r\n" +-> "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n" -> "AuthApproved: true\r\n" +-> "Pragma: no-cache\r\n" +-> "X-Frame-Options: SAMEORIGIN\r\n" +-> "Content-Security-Policy: frame-ancestors 'self'\r\n" +-> "Content-Disposition: inline; filename=response.xml\r\n" +-> "CPID: ED4-dff741a6-df1a-463c-920e-2e4842eda7bf\r\n" -> "AuthResponse: AA\r\n" --> "Set-Cookie: JSESSIONID=00007wKfJV3-JFME8QiC_RCDjuI:14j4qkv92; HTTPOnly; Path=/; Secure\r\n" --> "Set-Cookie: JSESSIONID=0000uW6woWZ84eAJunhFLfJz8hS:14j4qkv92; HTTPOnly; Path=/; Secure\r\n" +-> "Content-Type: text/xml\r\n" +-> "Set-Cookie: JSESSIONID=UtM16S1VJSFsHChVlcYvM0cGVDWHMW1XD0vZ5T47.svplknxcnvrgdapp02; path=/VirtualMerchantDemo; secure; HttpOnly\r\n" -> "Connection: close\r\n" --> "Content-Type: text/plain\r\n" --> "Content-Language: en-US\r\n" --> "Content-Encoding: gzip\r\n" -> "Transfer-Encoding: chunked\r\n" -> "\r\n" --> "1A5 \r\n" -reading 421 bytes... --> "\x1F\x8B\b\x00\x00\x00\x00\x00\x00\x03MR\xEFk\xDB0\x10\xFD\xDE\xBF\xC2\x1F\xB7\x81[\xC9\xB1\x1D\xBB \x98\x7FtP\xD66!+\xDBGs\xB1o\x99\xC0\x96\x84%{q\xFF\xFA\xC9R\x12f\x10\xDC\xBDw\xBEw\xEF8\xAD\xFB\xA6\x85\xB1k\xC44\x1Cqd1\xFDr\xFB\xF2<'w\xDA\x16\xE0Y5\x1D\x18d$\xA7\xB9C`\x90\x930\x8C\xDE\x13_\xA1\xA1Gm\xE0\xCC\\\xC6\xC5,y\x8B\xD7\x9E\x0E\x130\xA0\x8FV9\x1Fu\xA8`4\xD3\x88\xBE\xFB\xDD;WM\xE1;\xFBJ9\xA8\x1E\r\x97\xE2Rp\x05A,\xEC\x17\xEFNht\xF0,Z\x87\xFF\xE6\xA36^\xE6E\x8A\xD3Q\x1E\x1D\xDC\xC3\xFF\xA8F\xE1P\x98u\x03]7\xA2\xD6,N\xD2\xE0u\t~\x98\x11\xD1x\xD63\x11+\x94\t\xA8W\xE5fa;c\xE0/\xB8\xDC\x9A\xB5\x03\xED\xDEn\xDD>\xB8b\xDFi\x15\xBD\xA5\xBE~u1.\xAC*\\\xAA\xFEH\x81\xECS\x92$\x9F\xED\v\xEDK\x1C\x8E\x03\xF0\x9E)\x98\xFA\xAF\x9D\xB4\xB1\xB8\xB7\xF6\x1Cc\a\x98z\xC3\xFCz}\xD2\fv(8!+\xF6\xFB\xC3\xEEg\xF1\xE28s\x16\r\xEF\x18\xD9\x10J\xB3\x82&!\xA9\xD3:O\xF3*|\x8A\xEA2\x8C\xB34\t\xB3o\xDB$,\xD3\xA2,\xB3tC\xB7E\xE9\xFE\x04\xA5F9\xC3:l\x87,\xDEnI\x1C9\xA2\x9D\xE7h\xD5TR\xE8\xCB\xD6W\x8B7\xE4\xE2\xBAu&\x9B#\xF4 Z{\x1C\xD7cX'2\xDCn\x9C\xD0\a\xB2y\x88\b\xCD\x02\x12?\xC6\xE41\xDA\x06\xFBW/\xB1\xDE\x9CY\x14\xB2\xEA\xF0T?\xBFW\xC5\xA1\xFE\aC\x85\x1DS\x8C\x02\x00\x00" -read 421 bytes +-> "44b\r\n" +reading 1099 bytes... +-> "\n00SALE[FILTERED]0100123443091523092800000475542000000000002598490259231234430150920ED4-48E1CA31-F2C5-411B-9543-AEA81EFB81B9M259849100.0009/15/2020 07:09:28 PM0.00A9151909286574590030VE0921APPROVALVISA3CREDITCARDM01" +read 1099 bytes reading 2 bytes... -> "\r\n" read 2 bytes -> "0\r\n" -> "\r\n" Conn close -}} + } end end diff --git a/test/unit/gateways/element_test.rb b/test/unit/gateways/element_test.rb index 253cfcdccbf..68962ee7cee 100644 --- a/test/unit/gateways/element_test.rb +++ b/test/unit/gateways/element_test.rb @@ -1,6 +1,8 @@ require 'test_helper' class ElementTest < Test::Unit::TestCase + include CommStub + def setup @gateway = ElementGateway.new(account_id: '', account_token: '', application_id: '', acceptor_id: '', application_name: '', application_version: '') @credit_card = credit_card @@ -128,32 +130,109 @@ def test_failed_void end def test_successful_verify - @gateway.expects(:ssl_post).times(2).returns(successful_authorize_response, successful_void_response) + @gateway.expects(:ssl_post).returns(successful_verify_response) response = @gateway.verify(@credit_card, @options) assert_success response end - def test_successful_verify_with_failed_void - @gateway.expects(:ssl_post).times(2).returns(successful_authorize_response, failed_void_response) + def test_handles_error_response + @gateway.expects(:ssl_post).returns(error_response) + + response = @gateway.purchase(@amount, @credit_card, @options) + assert_equal response.message, 'TargetNamespace required' + assert_failure response + end + + def test_successful_purchase_with_card_present_code + response = stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(card_present_code: 'Present')) + end.check_request do |_endpoint, data, _headers| + assert_match 'Present', data + end.respond_with(successful_purchase_response) - response = @gateway.verify(@credit_card, @options) assert_success response end - def test_failed_verify - @gateway.expects(:ssl_post).returns(failed_authorize_response) + def test_successful_purchase_with_payment_type + response = stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(payment_type: 'NotUsed')) + end.check_request do |_endpoint, data, _headers| + assert_match 'NotUsed', data + end.respond_with(successful_purchase_response) - response = @gateway.verify(@credit_card, @options) - assert_failure response + assert_success response end - def test_handles_error_response - @gateway.expects(:ssl_post).returns(error_response) + def test_successful_purchase_with_submission_type + response = stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(submission_type: 'NotUsed')) + end.check_request do |_endpoint, data, _headers| + assert_match 'NotUsed', data + end.respond_with(successful_purchase_response) - response = @gateway.purchase(@amount, @credit_card, @options) - assert_equal response.message, 'TargetNamespace required' - assert_failure response + assert_success response + end + + def test_successful_purchase_with_duplicate_check_disable_flag + response = stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(duplicate_check_disable_flag: true)) + end.check_request do |_endpoint, data, _headers| + assert_match 'True', data + end.respond_with(successful_purchase_response) + + assert_success response + + response = stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(duplicate_check_disable_flag: 'true')) + end.check_request do |_endpoint, data, _headers| + assert_match 'True', data + end.respond_with(successful_purchase_response) + + assert_success response + + response = stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(duplicate_check_disable_flag: false)) + end.check_request do |_endpoint, data, _headers| + assert_match 'False', data + end.respond_with(successful_purchase_response) + + assert_success response + + response = stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(duplicate_check_disable_flag: 'xxx')) + end.check_request do |_endpoint, data, _headers| + assert_match 'False', data + end.respond_with(successful_purchase_response) + + assert_success response + + response = stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(duplicate_check_disable_flag: 'False')) + end.check_request do |_endpoint, data, _headers| + assert_match 'False', data + end.respond_with(successful_purchase_response) + + assert_success response + + # when duplicate_check_disable_flag is NOT passed, should not be in XML at all + response = stub_comms do + @gateway.purchase(@amount, @credit_card) + end.check_request do |_endpoint, data, _headers| + assert_no_match %r(False), data + end.respond_with(successful_purchase_response) + + assert_success response + end + + def test_successful_purchase_with_terminal_id + response = stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(terminal_id: '02')) + end.check_request do |_endpoint, data, _headers| + assert_match '02', data + end.respond_with(successful_purchase_response) + + assert_success response end def test_scrub @@ -164,104 +243,110 @@ def test_scrub private def pre_scrubbed - <<-XML -\n\n \n \n \n 1013963\n 683EED8A1A357EB91575A168E74482A74836FD72B1AD11B41B29B473CA9D65B9FE067701\n 3928907\n \n \n 5211\n Spreedly\n 1\n \n \n 4000100011112224\n 09\n 16\n Longbob Longsen\n 123\n \n \n 1.00\n Default\n \n \n 01\n UseDefault\n UseDefault\n UseDefault\n UseDefault\n UseDefault\n UseDefault\n UseDefault\n \n

\n 456 My Street\n Apt 1\n Ottawa\n ON\n K1C2N6\n
\n \n
\n
\n + <<~XML + \n\n \n \n \n 1013963\n 683EED8A1A357EB91575A168E74482A74836FD72B1AD11B41B29B473CA9D65B9FE067701\n 3928907\n \n \n 5211\n Spreedly\n 1\n \n \n 4000100011112224\n 09\n 16\n Longbob Longsen\n 123\n \n \n 1.00\n Default\n \n \n 01\n UseDefault\n UseDefault\n UseDefault\n UseDefault\n UseDefault\n UseDefault\n UseDefault\n \n
\n 456 My Street\n Apt 1\n Ottawa\n ON\n K1C2N6\n
\n
\n
\n
\n XML end def post_scrubbed - <<-XML -\n\n \n \n \n 1013963\n [FILTERED]\n 3928907\n \n \n 5211\n Spreedly\n 1\n \n \n [FILTERED]\n 09\n 16\n Longbob Longsen\n [FILTERED]\n \n \n 1.00\n Default\n \n \n 01\n UseDefault\n UseDefault\n UseDefault\n UseDefault\n UseDefault\n UseDefault\n UseDefault\n \n
\n 456 My Street\n Apt 1\n Ottawa\n ON\n K1C2N6\n
\n
\n
\n
\n + <<~XML + \n\n \n \n \n 1013963\n [FILTERED]\n 3928907\n \n \n 5211\n Spreedly\n 1\n \n \n [FILTERED]\n 09\n 16\n Longbob Longsen\n [FILTERED]\n \n \n 1.00\n Default\n \n \n 01\n UseDefault\n UseDefault\n UseDefault\n UseDefault\n UseDefault\n UseDefault\n UseDefault\n \n
\n 456 My Street\n Apt 1\n Ottawa\n ON\n K1C2N6\n
\n
\n
\n
\n XML end def error_response - <<-XML -103TargetNamespace required + <<~XML + 103TargetNamespace required XML end def successful_purchase_response - <<-XML -0Approved20151201104518UTC-05:00000APRegularTotals1962962.00FullBatchCurrentDefaultNMVisa2005831886000045SystemDefaultaVb001234567810425c0425d5e00FalseFalseFalseFalseNULL_PROCESSOR_TESTApproved1False1.00DefaultUnknownCreditCardNullNull
456 My StreetK1C2N6
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull
+ <<~XML + 0Approved20151201104518UTC-05:00000APRegularTotals1962962.00FullBatchCurrentDefaultNMVisa2005831886000045SystemDefaultaVb001234567810425c0425d5e00FalseFalseFalseFalseNULL_PROCESSOR_TESTApproved1False1.00DefaultUnknownCreditCardNullNull
456 My StreetK1C2N6
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull
XML end def successful_purchase_with_echeck_response - <<-XML -0Success20151202090320UTC-05:000Transaction ProcessedRegularTotalsFullBatchCurrentDefault2005838412347520966b3df3e93051b5dc85c355a54e3012c2SystemDefaultFalseFalseFalseFalseNULL_PROCESSOR_TESTPending10FalseDefaultUnknownCreditCardNullNull
456 My StreetK1C2N6
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull
+ <<~XML + 0Success20151202090320UTC-05:000Transaction ProcessedRegularTotalsFullBatchCurrentDefault2005838412347520966b3df3e93051b5dc85c355a54e3012c2SystemDefaultFalseFalseFalseFalseNULL_PROCESSOR_TESTPending10FalseDefaultUnknownCreditCardNullNull
456 My StreetK1C2N6
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull
XML end def successful_purchase_with_payment_account_token_response - <<-XML -0Approved20151202090144UTC-05:00000APRegularTotals11552995.00FullBatchCurrentDefaultNVisa2005838405000001c0d498aa3c2c07169d13a989a7af91af5bc4e6a0SystemDefaultaVb001234567810425c0425d5e00FalseFalseFalseFalseNULL_PROCESSOR_TESTApproved1False1.00DefaultUnknownC875D86C-5913-487D-822E-76B27E2C2A4ECreditCard147b0b90f74faac13afb618fdabee3a4e75bf03bNullNull
456 My StreetK1C2N6
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull
+ <<~XML + 0Approved20151202090144UTC-05:00000APRegularTotals11552995.00FullBatchCurrentDefaultNVisa2005838405000001c0d498aa3c2c07169d13a989a7af91af5bc4e6a0SystemDefaultaVb001234567810425c0425d5e00FalseFalseFalseFalseNULL_PROCESSOR_TESTApproved1False1.00DefaultUnknownC875D86C-5913-487D-822E-76B27E2C2A4ECreditCard147b0b90f74faac13afb618fdabee3a4e75bf03bNullNull
456 My StreetK1C2N6
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull
XML end def failed_purchase_with_echeck_response - <<-XML -101CardNumber Required20151202090342UTC-05:00RegularTotals1FullBatchCurrentDefault8fe3b762a2a4344d938c32be31f36e354fb28ee3SystemDefaultFalseFalseFalseFalseNULL_PROCESSOR_TESTFalseDefaultUnknownCreditCardNullNull
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull + <<~XML + 101CardNumber Required20151202090342UTC-05:00RegularTotals1FullBatchCurrentDefault8fe3b762a2a4344d938c32be31f36e354fb28ee3SystemDefaultFalseFalseFalseFalseNULL_PROCESSOR_TESTFalseDefaultUnknownCreditCardNullNull
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull XML end def failed_purchase_with_payment_account_token_response - <<-XML -103PAYMENT ACCOUNT NOT FOUND20151202090245UTC-05:00RegularTotals1FullBatchCurrentDefault564bd4943761a37bdbb3f201faa56faa091781b5SystemDefaultFalseFalseFalseFalseNULL_PROCESSOR_TESTFalseDefaultUnknownasdfCreditCardNullNull
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull + <<~XML + 103PAYMENT ACCOUNT NOT FOUND20151202090245UTC-05:00RegularTotals1FullBatchCurrentDefault564bd4943761a37bdbb3f201faa56faa091781b5SystemDefaultFalseFalseFalseFalseNULL_PROCESSOR_TESTFalseDefaultUnknownasdfCreditCardNullNull
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull XML end def failed_purchase_response - <<-XML -20Declined20151201104817UTC-05:00007DECLINEDRegularTotals1FullBatchCurrentDefaultNMVisa2005831909SystemDefaultaVb001234567810425c0425d5e00FalseFalseFalseFalseNULL_PROCESSOR_TESTDeclined2FalseDefaultUnknownCreditCardNullNull
456 My StreetK1C2N6
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull
+ <<~XML + 20Declined20151201104817UTC-05:00007DECLINEDRegularTotals1FullBatchCurrentDefaultNMVisa2005831909SystemDefaultaVb001234567810425c0425d5e00FalseFalseFalseFalseNULL_PROCESSOR_TESTDeclined2FalseDefaultUnknownCreditCardNullNull
456 My StreetK1C2N6
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull
XML end def successful_authorize_response - <<-XML -0Approved20151201120220UTC-05:00000APRegularTotals1FullBatchCurrentDefaultNMVisa2005832533000002SystemDefaultaVb001234567810425c0425d5e00FalseFalseFalseFalseNULL_PROCESSOR_TESTAuthorized5False1.00DefaultUnknownCreditCardNullNull
456 My StreetK1C2N6
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull
+ <<~XML + 0Approved20151201120220UTC-05:00000APRegularTotals1FullBatchCurrentDefaultNMVisa2005832533000002SystemDefaultaVb001234567810425c0425d5e00FalseFalseFalseFalseNULL_PROCESSOR_TESTAuthorized5False1.00DefaultUnknownCreditCardNullNull
456 My StreetK1C2N6
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull
XML end def failed_authorize_response - <<-XML -20Declined20151201120315UTC-05:00007DECLINEDRegularTotals1FullBatchCurrentDefaultNMVisa2005832537SystemDefaultaVb001234567810425c0425d5e00FalseFalseFalseFalseNULL_PROCESSOR_TESTDeclined2FalseDefaultUnknownCreditCardNullNull
456 My StreetK1C2N6
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull
+ <<~XML + 20Declined20151201120315UTC-05:00007DECLINEDRegularTotals1FullBatchCurrentDefaultNMVisa2005832537SystemDefaultaVb001234567810425c0425d5e00FalseFalseFalseFalseNULL_PROCESSOR_TESTDeclined2FalseDefaultUnknownCreditCardNullNull
456 My StreetK1C2N6
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull
XML end def successful_capture_response - <<-XML -0Success20151201120222UTC-05:00000APRegularTotals1972963.00FullBatchCurrentDefaultVisa2005832535000002SystemDefaultaVb001234567810425c0425d5e00FalseFalseFalseFalseNULL_PROCESSOR_TESTApproved1FalseDefaultUnknownCreditCardNullNull
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull + <<~XML + 0Success20151201120222UTC-05:00000APRegularTotals1972963.00FullBatchCurrentDefaultVisa2005832535000002SystemDefaultaVb001234567810425c0425d5e00FalseFalseFalseFalseNULL_PROCESSOR_TESTApproved1FalseDefaultUnknownCreditCardNullNull
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull XML end def failed_capture_response - <<-XML -101TransactionID requiredUTC-05:00RegularTotalsFullBatchCurrentDefaultSystemDefaultFalseFalseFalseFalseFalseDefaultUnknownCreditCardNullNull
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull + <<~XML + 101TransactionID requiredUTC-05:00RegularTotalsFullBatchCurrentDefaultSystemDefaultFalseFalseFalseFalseFalseDefaultUnknownCreditCardNullNull
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull XML end def successful_refund_response - <<-XML -0Approved20151201120437UTC-05:00000APRegularTotals1992963.00FullBatchCurrentDefaultVisa2005832540000004SystemDefaultFalseFalseFalseFalseNULL_PROCESSOR_TESTApproved1FalseDefaultUnknownCreditCardNullNull
456 My StreetK1C2N6
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull
+ <<~XML + 0Approved20151201120437UTC-05:00000APRegularTotals1992963.00FullBatchCurrentDefaultVisa2005832540000004SystemDefaultFalseFalseFalseFalseNULL_PROCESSOR_TESTApproved1FalseDefaultUnknownCreditCardNullNull
456 My StreetK1C2N6
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull
XML end def failed_refund_response - <<-XML -101TransactionID requiredUTC-05:00RegularTotalsFullBatchCurrentDefaultSystemDefaultFalseFalseFalseFalseFalseDefaultUnknownCreditCardNullNull
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull + <<~XML + 101TransactionID requiredUTC-05:00RegularTotalsFullBatchCurrentDefaultSystemDefaultFalseFalseFalseFalseFalseDefaultUnknownCreditCardNullNull
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull XML end def successful_void_response - <<-XML -0Success20151201120516UTC-05:00006REVERSEDRegularTotalsFullBatchCurrentDefaultVisa2005832551000005SystemDefaultaVb001234567810425c0425d5e00FalseFalseFalseFalseNULL_PROCESSOR_TESTSuccess8FalseDefaultUnknownCreditCardNullNull
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull + <<~XML + 0Success20151201120516UTC-05:00006REVERSEDRegularTotalsFullBatchCurrentDefaultVisa2005832551000005SystemDefaultaVb001234567810425c0425d5e00FalseFalseFalseFalseNULL_PROCESSOR_TESTSuccess8FalseDefaultUnknownCreditCardNullNull
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull XML end def failed_void_response - <<-XML -101TransactionAmount requiredUTC-05:00RegularTotalsFullBatchCurrentDefaultSystemDefaultFalseFalseFalseFalseFalseDefaultUnknownCreditCardNullNull
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull + <<~XML + 101TransactionAmount requiredUTC-05:00RegularTotalsFullBatchCurrentDefaultSystemDefaultFalseFalseFalseFalseFalseDefaultUnknownCreditCardNullNull
OneTimeFutureFalseActiveCheckingPersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefaultNull + XML + end + + def successful_verify_response + <<~XML + 0Success20200505094556UTC-05:00000APRegularTotalsFullBatchCurrentNVisa400010481381541SystemDefaultFalseFalseFalseFalseNULL_PROCESSOR_TESTSuccess8FalseDefaultUnknownNotUsedNotUsedCreditCardNullNull
456 My StreetK1C2N6
OneTimeFutureFalseActivePersonalNullNullFalseFalseFalseNotUsedUnknownUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultUseDefaultRegularNotUsedDefaultUnusedUnusedNoAdjustmentsFalseNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNotSpecifiedLedgerBalancePositiveNonParticipantDefaultDefault
XML end end diff --git a/test/unit/gateways/epay_test.rb b/test/unit/gateways/epay_test.rb index c232cc16661..cfebf4b8447 100644 --- a/test/unit/gateways/epay_test.rb +++ b/test/unit/gateways/epay_test.rb @@ -5,12 +5,12 @@ def setup Base.mode = :test @gateway = EpayGateway.new( - :login => '10100111001', - :password => 'http://example.com' + login: '10100111001', + password: 'http://example.com' ) @credit_card = credit_card - @options = {three_d_secure: { eci: '7', xid: '123', cavv: '456', version: '2', ds_transaction_id: '798' }} + @options = { three_d_secure: { eci: '7', xid: '123', cavv: '456', version: '2', ds_transaction_id: '798' } } end def test_successful_purchase @@ -122,13 +122,13 @@ def test_deprecated_credit def test_authorize_sends_order_number @gateway.expects(:raw_ssl_request).with(anything, anything, regexp_matches(/orderid=1234/), anything).returns(valid_authorize_response) - @gateway.authorize(100, '123', :order_id => '#1234') + @gateway.authorize(100, '123', order_id: '#1234') end def test_purchase_sends_order_number @gateway.expects(:raw_ssl_request).with(anything, anything, regexp_matches(/orderid=1234/), anything).returns(valid_authorize_response) - @gateway.purchase(100, '123', :order_id => '#1234') + @gateway.purchase(100, '123', order_id: '#1234') end def test_transcript_scrubbing diff --git a/test/unit/gateways/evo_ca_test.rb b/test/unit/gateways/evo_ca_test.rb index f2fe062e658..75b4513fa67 100644 --- a/test/unit/gateways/evo_ca_test.rb +++ b/test/unit/gateways/evo_ca_test.rb @@ -2,19 +2,19 @@ class EvoCaTest < Test::Unit::TestCase def setup - @gateway = EvoCaGateway.new(:username => 'demo', :password => 'password') + @gateway = EvoCaGateway.new(username: 'demo', password: 'password') @credit_card = credit_card @amount = 100 @options = { - :order_id => '1', - :billing_address => address, - :description => 'Store Purchase', - :tracking_number => '123456789-0', - :shipping_carrier => 'fedex', - :email => 'evo@example.com', - :ip => '127.0.0.1' + order_id: '1', + billing_address: address, + description: 'Store Purchase', + tracking_number: '123456789-0', + shipping_carrier: 'fedex', + email: 'evo@example.com', + ip: '127.0.0.1' } end @@ -84,7 +84,7 @@ def test_successful_void def test_successful_update @gateway.expects(:ssl_post).returns(successful_update_response) - assert response = @gateway.update('1812639342', :tracking_number => '1234', :shipping_carrier => 'fedex') + assert response = @gateway.update('1812639342', tracking_number: '1234', shipping_carrier: 'fedex') assert_success response assert_equal '1812639342', response.authorization end @@ -99,7 +99,7 @@ def test_successful_refund def test_add_address result = {} - @gateway.send(:add_address, result, :address => {:address1 => '123 Main Street', :country => 'CA', :state => 'BC'}) + @gateway.send(:add_address, result, address: { address1: '123 Main Street', country: 'CA', state: 'BC' }) assert_equal %w{address1 address2 city company country firstname lastname phone state zip}, result.stringify_keys.keys.sort assert_equal 'BC', result[:state] assert_equal '123 Main Street', result[:address1] @@ -109,7 +109,7 @@ def test_add_address def test_add_shipping_address result = {} - @gateway.send(:add_address, result, :shipping_address => {:address1 => '123 Main Street', :country => 'CA', :state => 'BC'}) + @gateway.send(:add_address, result, shipping_address: { address1: '123 Main Street', country: 'CA', state: 'BC' }) assert_equal %w{shipping_address1 shipping_address2 shipping_city shipping_company shipping_country shipping_firstname shipping_lastname shipping_state shipping_zip}, result.stringify_keys.keys.sort assert_equal 'BC', result[:shipping_state] assert_equal '123 Main Street', result[:shipping_address1] diff --git a/test/unit/gateways/eway_managed_test.rb b/test/unit/gateways/eway_managed_test.rb index 02666e0bc71..a920ac70c67 100644 --- a/test/unit/gateways/eway_managed_test.rb +++ b/test/unit/gateways/eway_managed_test.rb @@ -4,10 +4,10 @@ class EwayManagedTest < Test::Unit::TestCase def setup Base.mode = :test - @gateway = EwayManagedGateway.new(:username => 'username', :login => 'login', :password => 'password') + @gateway = EwayManagedGateway.new(username: 'username', login: 'login', password: 'password') - @valid_card='4444333322221111' - @valid_customer_id='9876543211000' + @valid_card = '4444333322221111' + @valid_customer_id = '9876543211000' @credit_card = credit_card(@valid_card) @declined_card = credit_card('4444111111111111') @@ -15,60 +15,60 @@ def setup @amount = 100 @options = { - :billing_address => { - :address1 => '1234 My Street', - :address2 => 'Apt 1', - :company => 'Widgets Inc', - :city => 'Ottawa', - :state => 'ON', - :zip => 'K1C2N6', - :country => 'au', - :title => 'Mr.', - :phone => '(555)555-5555' + billing_address: { + address1: '1234 My Street', + address2: 'Apt 1', + company: 'Widgets Inc', + city: 'Ottawa', + state: 'ON', + zip: 'K1C2N6', + country: 'au', + title: 'Mr.', + phone: '(555)555-5555' }, - :email => 'someguy1232@fakeemail.net', - :order_id => '1000', - :customer => 'mycustomerref', - :description => 'My Description', - :invoice => 'invoice-4567' + email: 'someguy1232@fakeemail.net', + order_id: '1000', + customer: 'mycustomerref', + description: 'My Description', + invoice: 'invoice-4567' } end def test_should_require_billing_address_on_store assert_raise ArgumentError do - @gateway.store(@credit_card, { }) + @gateway.store(@credit_card, {}) end assert_raise ArgumentError do - @gateway.store(@credit_card, { :billing_address => {} }) + @gateway.store(@credit_card, { billing_address: {} }) end assert_raise ArgumentError do - @gateway.store(@credit_card, { :billing_address => { :title => 'Mr.' } }) + @gateway.store(@credit_card, { billing_address: { title: 'Mr.' } }) end assert_raise ArgumentError do - @gateway.store(@credit_card, { :billing_address => { :country => 'au' } }) + @gateway.store(@credit_card, { billing_address: { country: 'au' } }) end assert_nothing_raised do @gateway.expects(:ssl_post).returns(successful_store_response) - @gateway.store(@credit_card, { :billing_address => { :title => 'Mr.', :country => 'au' } }) + @gateway.store(@credit_card, { billing_address: { title: 'Mr.', country: 'au' } }) end end def test_should_require_billing_address_on_update assert_raise ArgumentError do - @gateway.update(@valid_customer_id, @credit_card, { }) + @gateway.update(@valid_customer_id, @credit_card, {}) end assert_raise ArgumentError do - @gateway.update(@valid_customer_id, @credit_card, { :billing_address => {} }) + @gateway.update(@valid_customer_id, @credit_card, { billing_address: {} }) end assert_raise ArgumentError do - @gateway.update(@valid_customer_id, @credit_card, { :billing_address => { :title => 'Mr.' } }) + @gateway.update(@valid_customer_id, @credit_card, { billing_address: { title: 'Mr.' } }) end assert_raise ArgumentError do - @gateway.update(@valid_customer_id, @credit_card, { :billing_address => { :country => 'au' } }) + @gateway.update(@valid_customer_id, @credit_card, { billing_address: { country: 'au' } }) end assert_nothing_raised do @gateway.expects(:ssl_post).returns(successful_update_response) - @gateway.update(@valid_customer_id, @credit_card, { :billing_address => { :title => 'Mr.', :country => 'au' } }) + @gateway.update(@valid_customer_id, @credit_card, { billing_address: { title: 'Mr.', country: 'au' } }) end end @@ -85,7 +85,7 @@ def test_successful_purchase end def test_expected_request_on_purchase - @gateway.expects(:ssl_post).with { |endpoint, data, headers| + @gateway.expects(:ssl_post).with { |_endpoint, data, _headers| # Compare the actual and expected XML documents, by converting them to Hashes first expected = Hash.from_xml(expected_purchase_request) actual = Hash.from_xml(data) @@ -101,7 +101,7 @@ def test_purchase_invoice_reference_comes_from_order_id_or_invoice options[:order_id] = 'order_id' options.delete(:invoice) - @gateway.expects(:ssl_post).with { |endpoint, data, headers| + @gateway.expects(:ssl_post).with { |_endpoint, data, _headers| request_hash = Hash.from_xml(data) request_hash['Envelope']['Body']['ProcessPayment']['invoiceReference'] == 'order_id' }.returns(successful_purchase_response) @@ -111,7 +111,7 @@ def test_purchase_invoice_reference_comes_from_order_id_or_invoice options[:invoice] = 'invoice' options.delete(:order_id) - @gateway.expects(:ssl_post).with { |endpoint, data, headers| + @gateway.expects(:ssl_post).with { |_endpoint, data, _headers| request_hash = Hash.from_xml(data) request_hash['Envelope']['Body']['ProcessPayment']['invoiceReference'] == 'invoice' }.returns(successful_purchase_response) @@ -121,7 +121,7 @@ def test_purchase_invoice_reference_comes_from_order_id_or_invoice options[:order_id] = 'order_id' options[:invoice] = 'invoice' - @gateway.expects(:ssl_post).with { |endpoint, data, headers| + @gateway.expects(:ssl_post).with { |_endpoint, data, _headers| request_hash = Hash.from_xml(data) request_hash['Envelope']['Body']['ProcessPayment']['invoiceReference'] == 'order_id' }.returns(successful_purchase_response) @@ -148,7 +148,7 @@ def test_successful_store end def test_expected_request_on_store - @gateway.expects(:ssl_post).with { |endpoint, data, headers| + @gateway.expects(:ssl_post).with { |_endpoint, data, _headers| # Compare the actual and expected XML documents, by converting them to Hashes first expected = Hash.from_xml(expected_store_request) actual = Hash.from_xml(data) @@ -164,7 +164,7 @@ def test_email_on_store_may_come_from_options_root_or_billing_address options.delete(:email) options[:billing_address][:email] = 'email+billing@example.com' - @gateway.expects(:ssl_post).with { |endpoint, data, headers| + @gateway.expects(:ssl_post).with { |_endpoint, data, _headers| request_hash = Hash.from_xml(data) request_hash['Envelope']['Body']['CreateCustomer']['Email'] == 'email+billing@example.com' }.returns(successful_store_response) @@ -174,7 +174,7 @@ def test_email_on_store_may_come_from_options_root_or_billing_address options[:billing_address].delete(:email) options[:email] = 'email+root@example.com' - @gateway.expects(:ssl_post).with { |endpoint, data, headers| + @gateway.expects(:ssl_post).with { |_endpoint, data, _headers| request_hash = Hash.from_xml(data) request_hash['Envelope']['Body']['CreateCustomer']['Email'] == 'email+root@example.com' }.returns(successful_store_response) @@ -184,7 +184,7 @@ def test_email_on_store_may_come_from_options_root_or_billing_address options[:billing_address][:email] = 'email+billing@example.com' options[:email] = 'email+root@example.com' - @gateway.expects(:ssl_post).with { |endpoint, data, headers| + @gateway.expects(:ssl_post).with { |_endpoint, data, _headers| request_hash = Hash.from_xml(data) request_hash['Envelope']['Body']['CreateCustomer']['Email'] == 'email+billing@example.com' }.returns(successful_store_response) @@ -198,7 +198,7 @@ def test_customer_ref_on_store_may_come_from_options_root_or_billing_address options.delete(:customer) options[:billing_address][:customer_ref] = 'customer_ref+billing' - @gateway.expects(:ssl_post).with { |endpoint, data, headers| + @gateway.expects(:ssl_post).with { |_endpoint, data, _headers| request_hash = Hash.from_xml(data) request_hash['Envelope']['Body']['CreateCustomer']['CustomerRef'] == 'customer_ref+billing' }.returns(successful_store_response) @@ -208,7 +208,7 @@ def test_customer_ref_on_store_may_come_from_options_root_or_billing_address options[:billing_address].delete(:customer_ref) options[:customer] = 'customer_ref+root' - @gateway.expects(:ssl_post).with { |endpoint, data, headers| + @gateway.expects(:ssl_post).with { |_endpoint, data, _headers| request_hash = Hash.from_xml(data) request_hash['Envelope']['Body']['CreateCustomer']['CustomerRef'] == 'customer_ref+root' }.returns(successful_store_response) @@ -218,7 +218,7 @@ def test_customer_ref_on_store_may_come_from_options_root_or_billing_address options[:billing_address][:customer_ref] = 'customer_ref+billing' options[:customer] = 'customer_ref+root' - @gateway.expects(:ssl_post).with { |endpoint, data, headers| + @gateway.expects(:ssl_post).with { |_endpoint, data, _headers| request_hash = Hash.from_xml(data) request_hash['Envelope']['Body']['CreateCustomer']['CustomerRef'] == 'customer_ref+billing' }.returns(successful_store_response) @@ -246,7 +246,7 @@ def test_successful_retrieve end def test_expected_retrieve_response - @gateway.expects(:ssl_post).with { |endpoint, data, headers| + @gateway.expects(:ssl_post).with { |_endpoint, data, _headers| # Compare the actual and expected XML documents, by converting them to Hashes first expected = Hash.from_xml(expected_retrieve_request) actual = Hash.from_xml(data) @@ -262,53 +262,53 @@ def test_default_currency private def successful_purchase_response - <<-XML - - - - - - 00,Transaction Approved(Test Gateway) - True - 123456 - 100 - 123456 - - - - + <<~XML + + + + + + 00,Transaction Approved(Test Gateway) + True + 123456 + 100 + 123456 + + + + XML end def unsuccessful_authorization_response - <<-XML -soap:SenderLogin failed + <<~XML + soap:SenderLogin failed XML end def successful_store_response - <<-XML - - - - - 1234567 - - - + <<~XML + + + + + 1234567 + + + XML end def successful_update_response - <<-XML - - - - - true - - - + <<~XML + + + + + true + + + XML end @@ -322,8 +322,8 @@ def successful_retrieve_response #{@credit_card.first_name} #{@credit_card.last_name} #{@credit_card.number} - #{sprintf("%.2i", @credit_card.month)} - #{sprintf("%.4i", @credit_card.year)[-2..-1]} + #{sprintf('%.2i', @credit_card.month)} + #{sprintf('%.4i', @credit_card.year)[-2..-1]} @@ -333,66 +333,66 @@ def successful_retrieve_response # Documented here: https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?op=CreateCustomer def expected_store_request - <<-XML - - - - - login - username - password - - - - - Mr. - #{@credit_card.first_name} - #{@credit_card.last_name} -
#{@options[:billing_address][:address1]}
- #{@options[:billing_address][:city]} - #{@options[:billing_address][:state]} - #{@options[:billing_address][:company]} - #{@options[:billing_address][:zip]} - #{@options[:billing_address][:country]} - #{@options[:email]} - - #{@options[:billing_address][:phone]} - - #{@options[:customer]} - - #{@options[:description]} - - #{@credit_card.number} - #{@credit_card.first_name} #{@credit_card.last_name} - #{sprintf("%.2i", @credit_card.month)} - #{sprintf("%.4i", @credit_card.year)[-2..-1]} -
-
-
+ <<~XML + + + + + login + username + password + + + + + Mr. + #{@credit_card.first_name} + #{@credit_card.last_name} +
#{@options[:billing_address][:address1]}
+ #{@options[:billing_address][:city]} + #{@options[:billing_address][:state]} + #{@options[:billing_address][:company]} + #{@options[:billing_address][:zip]} + #{@options[:billing_address][:country]} + #{@options[:email]} + + #{@options[:billing_address][:phone]} + + #{@options[:customer]} + + #{@options[:description]} + + #{@credit_card.number} + #{@credit_card.first_name} #{@credit_card.last_name} + #{sprintf('%.2i', @credit_card.month)} + #{sprintf('%.4i', @credit_card.year)[-2..-1]} +
+
+
XML end # Documented here: https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?op=CreateCustomer def expected_purchase_request - <<-XML - - - - - login - username - password - - - - - #{@valid_customer_id} - #{@amount} - #{@options[:order_id] || @options[:invoice]} - #{@options[:description]} - - - + <<~XML + + + + + login + username + password + + + + + #{@valid_customer_id} + #{@amount} + #{@options[:order_id] || @options[:invoice]} + #{@options[:description]} + + + XML end diff --git a/test/unit/gateways/eway_rapid_test.rb b/test/unit/gateways/eway_rapid_test.rb index 790b839228e..4ed739ca9a4 100644 --- a/test/unit/gateways/eway_rapid_test.rb +++ b/test/unit/gateways/eway_rapid_test.rb @@ -6,8 +6,8 @@ class EwayRapidTest < Test::Unit::TestCase def setup ActiveMerchant::Billing::EwayRapidGateway.partner_id = nil @gateway = EwayRapidGateway.new( - :login => 'login', - :password => 'password' + login: 'login', + password: 'password' ) @credit_card = credit_card @@ -58,7 +58,7 @@ def test_successful_purchase def test_purchase_passes_customer_data_from_payment_method_when_no_address_is_provided stub_comms do @gateway.purchase(@amount, @credit_card, { email: @email }) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_customer_data_passed( data, @credit_card.first_name, @@ -71,7 +71,7 @@ def test_purchase_passes_customer_data_from_payment_method_when_no_address_is_pr def test_purchase_passes_customer_data_from_billing_address stub_comms do @gateway.purchase(@amount, @credit_card, { billing_address: @address, email: @email }) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_customer_data_passed( data, @address[:name].split[0], @@ -85,7 +85,7 @@ def test_purchase_passes_customer_data_from_billing_address def test_purchase_passes_customer_data_from_address stub_comms do @gateway.purchase(@amount, @credit_card, { address: @address, email: @email }) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_customer_data_passed( data, @address[:name].split[0], @@ -99,21 +99,62 @@ def test_purchase_passes_customer_data_from_address def test_purchase_passes_shipping_data stub_comms do @gateway.purchase(@amount, @credit_card, { shipping_address: @shipping_address, email: @email }) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_shipping_data_passed(data, @shipping_address, @email) end.respond_with(successful_purchase_response) end + def test_purchase_3ds1_data + eci = '05' + cavv = 'AgAAAAAA4n1uzQPRaATeQAAAAAA=' + xid = 'AAAAAAAA4n1uzQPRaATeQAAAAAA=' + authentication_response_status = 'Y' + options_with_3ds1 = { + eci: eci, + cavv: cavv, + xid: xid, + authentication_response_status: authentication_response_status + } + + stub_comms do + @gateway.purchase(@amount, @credit_card, { three_d_secure: options_with_3ds1 }) + end.check_request do |_endpoint, data, _headers| + assert_3ds_data_passed(data, options_with_3ds1) + end.respond_with(successful_purchase_response) + end + + def test_purchase_3ds2_data + eci = '05' + cavv = 'AgAAAAAA4n1uzQPRaATeQAAAAAA=' + authentication_response_status = 'Y' + version = '2.1.0' + ds_transaction_id = '8fe2e850-a028-407e-9a18-c8cf7598ca10' + + options_with_3ds2 = { + version: version, + eci: eci, + cavv: cavv, + ds_transaction_id: ds_transaction_id, + authentication_response_status: authentication_response_status + } + + stub_comms do + @gateway.purchase(@amount, @credit_card, { three_d_secure: options_with_3ds2 }) + end.check_request do |_endpoint, data, _headers| + assert_3ds_data_passed(data, options_with_3ds2) + end.respond_with(successful_purchase_response) + end + def test_localized_currency stub_comms do - @gateway.purchase(100, @credit_card, :currency => 'CAD') - end.check_request do |endpoint, data, headers| + @gateway.purchase(100, @credit_card, currency: 'CAD') + end.check_request do |_endpoint, data, _headers| assert_match '"TotalAmount":"100"', data end.respond_with(successful_purchase_response) stub_comms do - @gateway.purchase(100, @credit_card, :currency => 'JPY') - end.check_request do |endpoint, data, headers| + @gateway.purchase(100, @credit_card, currency: 'JPY') + end.check_request do |_endpoint, data, _headers| assert_match '"TotalAmount":"1"', data end.respond_with(successful_purchase_response) end @@ -154,44 +195,43 @@ def test_failed_purchase_with_multiple_messages def test_purchase_with_all_options response = stub_comms do @gateway.purchase(200, @credit_card, - :transaction_type => 'CustomTransactionType', - :redirect_url => 'http://awesomesauce.com', - :ip => '0.0.0.0', - :application_id => 'Woohoo', - :partner_id => 'SomePartner', - :description => 'The Really Long Description More Than Sixty Four Characters Gets Truncated', - :order_id => 'orderid1', - :invoice => 'I1234', - :currency => 'INR', - :email => 'jim@example.com', - :billing_address => { - :title => 'Mr.', - :name => 'Jim Awesome Smith', - :company => 'Awesome Co', - :address1 => '1234 My Street', - :address2 => 'Apt 1', - :city => 'Ottawa', - :state => 'ON', - :zip => 'K1C2N6', - :country => 'CA', - :phone => '(555)555-5555', - :fax => '(555)555-6666' + transaction_type: 'CustomTransactionType', + redirect_url: 'http://awesomesauce.com', + ip: '0.0.0.0', + application_id: 'Woohoo', + partner_id: 'SomePartner', + description: 'The Really Long Description More Than Sixty Four Characters Gets Truncated', + order_id: 'orderid1', + invoice: 'I1234', + currency: 'INR', + email: 'jim@example.com', + billing_address: { + title: 'Mr.', + name: 'Jim Awesome Smith', + company: 'Awesome Co', + address1: '1234 My Street', + address2: 'Apt 1', + city: 'Ottawa', + state: 'ON', + zip: 'K1C2N6', + country: 'CA', + phone: '(555)555-5555', + fax: '(555)555-6666' }, - :shipping_address => { - :title => 'Ms.', - :name => 'Baker', - :company => 'Elsewhere Inc.', - :address1 => '4321 Their St.', - :address2 => 'Apt 2', - :city => 'Chicago', - :state => 'IL', - :zip => '60625', - :country => 'US', - :phone => '1115555555', - :fax => '1115556666' - } - ) - end.check_request do |endpoint, data, headers| + shipping_address: { + title: 'Ms.', + name: 'Baker', + company: 'Elsewhere Inc.', + address1: '4321 Their St.', + address2: 'Apt 2', + city: 'Chicago', + state: 'IL', + zip: '60625', + country: 'US', + phone: '1115555555', + fax: '1115556666' + }) + end.check_request do |_endpoint, data, _headers| assert_match(%r{"TransactionType":"CustomTransactionType"}, data) assert_match(%r{"RedirectUrl":"http://awesomesauce.com"}, data) assert_match(%r{"CustomerIP":"0.0.0.0"}, data) @@ -241,7 +281,7 @@ def test_partner_id_class_attribute ActiveMerchant::Billing::EwayRapidGateway.partner_id = 'SomePartner' stub_comms do @gateway.purchase(200, @credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{"PartnerID":"SomePartner"}, data) end.respond_with(successful_purchase_response) end @@ -250,7 +290,7 @@ def test_partner_id_params_overrides_class_attribute ActiveMerchant::Billing::EwayRapidGateway.partner_id = 'SomePartner' stub_comms do @gateway.purchase(200, @credit_card, partner_id: 'OtherPartner') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{"PartnerID":"OtherPartner"}, data) end.respond_with(successful_purchase_response) end @@ -258,7 +298,7 @@ def test_partner_id_params_overrides_class_attribute def test_partner_id_is_omitted_when_not_set stub_comms do @gateway.purchase(200, @credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_no_match(%r{"PartnerID":}, data) end.respond_with(successful_purchase_response) end @@ -267,7 +307,7 @@ def test_partner_id_truncates_to_50_characters partner_string = 'EWay Rapid PartnerID is capped at 50 characters and will truncate if it is too long.' stub_comms do @gateway.purchase(200, @credit_card, partner_id: partner_string) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{"PartnerID":"#{partner_string.slice(0, 50)}"}, data) end.respond_with(successful_purchase_response) end @@ -285,7 +325,7 @@ def test_successful_authorize def test_authorize_passes_customer_data_from_payment_method_when_no_address_is_provided stub_comms do @gateway.authorize(@amount, @credit_card, { email: @email }) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_customer_data_passed( data, @credit_card.first_name, @@ -298,7 +338,7 @@ def test_authorize_passes_customer_data_from_payment_method_when_no_address_is_p def test_authorize_passes_customer_data_from_billing_address stub_comms do @gateway.authorize(@amount, @credit_card, { billing_address: @address, email: @email }) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_customer_data_passed( data, @address[:name].split[0], @@ -312,7 +352,7 @@ def test_authorize_passes_customer_data_from_billing_address def test_authorize_passes_customer_data_from_address stub_comms do @gateway.authorize(@amount, @credit_card, { address: @address, email: @email }) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_customer_data_passed( data, @address[:name].split[0], @@ -326,7 +366,7 @@ def test_authorize_passes_customer_data_from_address def test_authorize_passes_shipping_data stub_comms do @gateway.authorize(@amount, @credit_card, { shipping_address: @shipping_address, email: @email }) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_shipping_data_passed(data, @shipping_address, @email) end.respond_with(successful_authorize_response) end @@ -383,20 +423,20 @@ def test_failed_void def test_successful_store response = stub_comms do - @gateway.store(@credit_card, :billing_address => { - :title => 'Mr.', - :name => 'Jim Awesome Smith', - :company => 'Awesome Co', - :address1 => '1234 My Street', - :address2 => 'Apt 1', - :city => 'Ottawa', - :state => 'ON', - :zip => 'K1C2N6', - :country => 'CA', - :phone => '(555)555-5555', - :fax => '(555)555-6666' - }) - end.check_request do |endpoint, data, headers| + @gateway.store(@credit_card, billing_address: { + title: 'Mr.', + name: 'Jim Awesome Smith', + company: 'Awesome Co', + address1: '1234 My Street', + address2: 'Apt 1', + city: 'Ottawa', + state: 'ON', + zip: 'K1C2N6', + country: 'CA', + phone: '(555)555-5555', + fax: '(555)555-6666' + }) + end.check_request do |_endpoint, data, _headers| assert_match '"Method":"CreateTokenCustomer"', data end.respond_with(successful_store_response) @@ -409,7 +449,7 @@ def test_successful_store def test_store_passes_customer_data_from_billing_address stub_comms do @gateway.store(@credit_card, { billing_address: @address, email: @email }) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_customer_data_passed( data, @address[:name].split[0], @@ -426,14 +466,14 @@ def test_store_passes_shipping_data @credit_card, { shipping_address: @shipping_address, billing_address: @address, email: @email } ) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_shipping_data_passed(data, @shipping_address, @email) end.respond_with(successful_store_response) end def test_failed_store response = stub_comms do - @gateway.store(@credit_card, :billing_address => {}) + @gateway.store(@credit_card, billing_address: {}) end.respond_with(failed_store_response) assert_failure response @@ -445,7 +485,7 @@ def test_failed_store def test_successful_update response = stub_comms do @gateway.update('faketoken', nil) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match '"Method":"UpdateTokenCustomer"', data end.respond_with(successful_update_response) @@ -458,7 +498,7 @@ def test_successful_update def test_update_passes_customer_data_from_payment_method_when_no_address_is_provided stub_comms do @gateway.update('token', @credit_card, { email: @email }) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_customer_data_passed( data, @credit_card.first_name, @@ -471,7 +511,7 @@ def test_update_passes_customer_data_from_payment_method_when_no_address_is_prov def test_update_passes_customer_data_from_billing_address stub_comms do @gateway.update('token', @credit_card, { billing_address: @address, email: @email }) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_customer_data_passed( data, @address[:name].split[0], @@ -485,7 +525,7 @@ def test_update_passes_customer_data_from_billing_address def test_update_passes_customer_data_from_address stub_comms do @gateway.update('token', @credit_card, { address: @address, email: @email }) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_customer_data_passed( data, @address[:name].split[0], @@ -499,7 +539,7 @@ def test_update_passes_customer_data_from_address def test_update_passes_shipping_data stub_comms do @gateway.update('token', @credit_card, { shipping_address: @shipping_address, email: @email }) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_shipping_data_passed(data, @shipping_address, @email) end.respond_with(successful_update_response) end @@ -507,7 +547,7 @@ def test_update_passes_shipping_data def test_successful_refund response = stub_comms do @gateway.refund(@amount, '1234567') - end.check_request do |endpoint, data, headers| + end.check_request do |endpoint, data, _headers| assert_match %r{Transaction\/1234567\/Refund$}, endpoint json = JSON.parse(data) assert_equal '100', json['Refund']['TotalAmount'] @@ -534,7 +574,7 @@ def test_failed_refund def test_successful_stored_card_purchase response = stub_comms do @gateway.purchase(100, 'the_customer_token', transaction_type: 'MOTO') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match '"Method":"TokenPayment"', data assert_match '"TransactionType":"MOTO"', data end.respond_with(successful_store_purchase_response) @@ -548,7 +588,7 @@ def test_successful_stored_card_purchase def test_verification_results response = stub_comms do @gateway.purchase(100, @credit_card) - end.respond_with(successful_purchase_response(:verification_status => 'Valid')) + end.respond_with(successful_purchase_response(verification_status: 'Valid')) assert_success response assert_equal 'M', response.cvv_result['code'] @@ -556,7 +596,7 @@ def test_verification_results response = stub_comms do @gateway.purchase(100, @credit_card) - end.respond_with(successful_purchase_response(:verification_status => 'Invalid')) + end.respond_with(successful_purchase_response(verification_status: 'Invalid')) assert_success response assert_equal 'N', response.cvv_result['code'] @@ -564,7 +604,7 @@ def test_verification_results response = stub_comms do @gateway.purchase(100, @credit_card) - end.respond_with(successful_purchase_response(:verification_status => 'Unchecked')) + end.respond_with(successful_purchase_response(verification_status: 'Unchecked')) assert_success response assert_equal 'P', response.cvv_result['code'] @@ -599,6 +639,18 @@ def assert_customer_data_passed(data, first_name, last_name, email, address = ni end end + def assert_3ds_data_passed(data, threedsoption) + parsed_data = JSON.parse(data) + threeds = parsed_data['PaymentInstrument']['ThreeDSecureAuth'] + + assert_equal threeds['Cryptogram'], threedsoption[:cavv] + assert_equal threeds['ECI'], threedsoption[:eci] + assert_equal threeds['XID'], threedsoption[:xid] + assert_equal threeds['AuthStatus'], threedsoption[:authentication_response_status] + assert_equal threeds['dsTransactionId'], threedsoption[:ds_transaction_id] + assert_equal threeds['Version'], threedsoption[:version] + end + def assert_shipping_data_passed(data, address, email) parsed_data = JSON.parse(data) shipping = parsed_data['ShippingAddress'] diff --git a/test/unit/gateways/eway_test.rb b/test/unit/gateways/eway_test.rb index 5c1059163e5..898567d50b6 100644 --- a/test/unit/gateways/eway_test.rb +++ b/test/unit/gateways/eway_test.rb @@ -3,7 +3,7 @@ class EwayTest < Test::Unit::TestCase def setup @gateway = EwayGateway.new( - :login => '87654321' + login: '87654321' ) @amount = 100 @@ -11,17 +11,17 @@ def setup @credit_card = credit_card('4646464646464646') @options = { - :order_id => '1230123', - :email => 'bob@testbob.com', - :billing_address => { - :address1 => '1234 First St.', - :address2 => 'Apt. 1', - :city => 'Melbourne', - :state => 'ACT', - :country => 'AU', - :zip => '12345' + order_id: '1230123', + email: 'bob@testbob.com', + billing_address: { + address1: '1234 First St.', + address2: 'Apt. 1', + city: 'Melbourne', + state: 'ACT', + country: 'AU', + zip: '12345' }, - :description => 'purchased items' + description: 'purchased items' } end diff --git a/test/unit/gateways/exact_test.rb b/test/unit/gateways/exact_test.rb index 664f3d27ebf..5a1257add89 100644 --- a/test/unit/gateways/exact_test.rb +++ b/test/unit/gateways/exact_test.rb @@ -2,15 +2,15 @@ class ExactTest < Test::Unit::TestCase def setup - @gateway = ExactGateway.new(:login => 'A00427-01', - :password => 'testus') + @gateway = ExactGateway.new(login: 'A00427-01', + password: 'testus') @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 @@ -49,8 +49,8 @@ def test_failed_purchase end def test_expdate - assert_equal('%02d%s' % [ @credit_card.month, - @credit_card.year.to_s[-2..-1] ], + assert_equal('%02d%s' % [@credit_card.month, + @credit_card.year.to_s[-2..-1]], @gateway.send(:expdate, @credit_card)) end @@ -63,11 +63,11 @@ def test_soap_fault end def test_supported_countries - assert_equal ['CA', 'US'], ExactGateway.supported_countries + assert_equal %w[CA US], ExactGateway.supported_countries end def test_supported_card_types - assert_equal [:visa, :master, :american_express, :jcb, :discover], ExactGateway.supported_cardtypes + assert_equal %i[visa master american_express jcb discover], ExactGateway.supported_cardtypes end def test_avs_result @@ -87,120 +87,120 @@ def test_cvv_result private def successful_purchase_response - <<-RESPONSE -A00427-01#######00104242424242424242106625152ET17000909Longbob Longsen123100001Store Purchase0Processed by: -E-xact Transaction Gateway :- Version 8.4.0 B19b -Copyright 2006 -{34:2652}0falsetrue00Transaction Normal00VER UNAVAILABLE 377UM200801181700E-xact ConnectionShopSuite 400 - 1152 Mainland St.VancouverBCCanadaV6B 4X2www.e-xact.com========== TRANSACTION RECORD ========= + <<~RESPONSE + A00427-01#######00104242424242424242106625152ET17000909Longbob Longsen123100001Store Purchase0Processed by: + E-xact Transaction Gateway :- Version 8.4.0 B19b + Copyright 2006 + {34:2652}0falsetrue00Transaction Normal00VER UNAVAILABLE 377UM200801181700E-xact ConnectionShopSuite 400 - 1152 Mainland St.VancouverBCCanadaV6B 4X2www.e-xact.com========== TRANSACTION RECORD ========= -E-xact ConnectionShop -Suite 400 - 1152 Mainland St. -Vancouver, BC V6B 4X2 -www.e-xact.com + E-xact ConnectionShop + Suite 400 - 1152 Mainland St. + Vancouver, BC V6B 4X2 + www.e-xact.com -TYPE: Purchase + TYPE: Purchase -ACCT: Visa $1.00 USD + ACCT: Visa $1.00 USD -CARD NUMBER : ############4242 -TRANS. REF. : 1 -CARD HOLDER : Longbob Longsen -EXPIRY DATE : xx/xx -DATE/TIME : 18 Jan 08 14:17:00 -REFERENCE # : 5999 377 M -AUTHOR.# : ET1700 + CARD NUMBER : ############4242 + TRANS. REF. : 1 + CARD HOLDER : Longbob Longsen + EXPIRY DATE : xx/xx + DATE/TIME : 18 Jan 08 14:17:00 + REFERENCE # : 5999 377 M + AUTHOR.# : ET1700 - Approved - Thank You 00 + Approved - Thank You 00 -SIGNATURE + SIGNATURE -_______________________________________ + _______________________________________ - + RESPONSE end def successful_refund_response - <<-RESPONSE -A00427-01#######00104242424242424242106625152ET17000909Longbob Longsen123100001Store Purchase0Processed by: -E-xact Transaction Gateway :- Version 8.4.0 B19b -Copyright 2006 -{34:2652}0falsetrue00Transaction Normal00VER UNAVAILABLE 377UM200801181700E-xact ConnectionShopSuite 400 - 1152 Mainland St.VancouverBCCanadaV6B 4X2www.e-xact.com========== TRANSACTION RECORD ========= + <<~RESPONSE + A00427-01#######00104242424242424242106625152ET17000909Longbob Longsen123100001Store Purchase0Processed by: + E-xact Transaction Gateway :- Version 8.4.0 B19b + Copyright 2006 + {34:2652}0falsetrue00Transaction Normal00VER UNAVAILABLE 377UM200801181700E-xact ConnectionShopSuite 400 - 1152 Mainland St.VancouverBCCanadaV6B 4X2www.e-xact.com========== TRANSACTION RECORD ========= -E-xact ConnectionShop -Suite 400 - 1152 Mainland St. -Vancouver, BC V6B 4X2 -www.e-xact.com + E-xact ConnectionShop + Suite 400 - 1152 Mainland St. + Vancouver, BC V6B 4X2 + www.e-xact.com -TYPE: Refund + TYPE: Refund -ACCT: Visa $1.00 USD + ACCT: Visa $1.00 USD -CARD NUMBER : ############4242 -TRANS. REF. : 1 -CARD HOLDER : Longbob Longsen -EXPIRY DATE : xx/xx -DATE/TIME : 18 Jan 08 14:17:00 -REFERENCE # : 5999 377 M + CARD NUMBER : ############4242 + TRANS. REF. : 1 + CARD HOLDER : Longbob Longsen + EXPIRY DATE : xx/xx + DATE/TIME : 18 Jan 08 14:17:00 + REFERENCE # : 5999 377 M - Approved - Thank You 00 + Approved - Thank You 00 -SIGNATURE + SIGNATURE -Please retain this copy for your records. + Please retain this copy for your records. - ========================================= + ========================================= - + RESPONSE end def failed_purchase_response - <<-RESPONSE -A00427-01#######005013041111111111111111066246680909Longbob Longsen123100001Store Purchase0Processed by: -E-xact Transaction Gateway :- Version 8.4.0 B19b -Copyright 2006 -{34:2652}0falsefalse00Transaction Normal13AMOUNT ERR376UME-xact ConnectionShopSuite 400 - 1152 Mainland St.VancouverBCCanadaV6B 4X2www.e-xact.com========== TRANSACTION RECORD ========= + <<~RESPONSE + A00427-01#######005013041111111111111111066246680909Longbob Longsen123100001Store Purchase0Processed by: + E-xact Transaction Gateway :- Version 8.4.0 B19b + Copyright 2006 + {34:2652}0falsefalse00Transaction Normal13AMOUNT ERR376UME-xact ConnectionShopSuite 400 - 1152 Mainland St.VancouverBCCanadaV6B 4X2www.e-xact.com========== TRANSACTION RECORD ========= -E-xact ConnectionShop -Suite 400 - 1152 Mainland St. -Vancouver, BC V6B 4X2 -www.e-xact.com + E-xact ConnectionShop + Suite 400 - 1152 Mainland St. + Vancouver, BC V6B 4X2 + www.e-xact.com -TYPE: Purchase + TYPE: Purchase -ACCT: Visa $5,013.00 USD + ACCT: Visa $5,013.00 USD -CARD NUMBER : ############1111 -TRANS. REF. : 1 -CARD HOLDER : Longbob Longsen -EXPIRY DATE : xx/xx -DATE/TIME : 18 Jan 08 14:11:09 -REFERENCE # : 5999 376 M -AUTHOR.# : + CARD NUMBER : ############1111 + TRANS. REF. : 1 + CARD HOLDER : Longbob Longsen + EXPIRY DATE : xx/xx + DATE/TIME : 18 Jan 08 14:11:09 + REFERENCE # : 5999 376 M + AUTHOR.# : - Transaction not Approved 13 + Transaction not Approved 13 - + RESPONSE end def soap_fault_response - <<-RESPONSE - - - - - soap:Client - Unable to handle request without a valid action parameter. Please supply a valid soap action. - - - - + <<~RESPONSE + + + + + soap:Client + Unable to handle request without a valid action parameter. Please supply a valid soap action. + + + + RESPONSE end end diff --git a/test/unit/gateways/ezic_test.rb b/test/unit/gateways/ezic_test.rb index 5fa29b4004b..d79f3ece845 100644 --- a/test/unit/gateways/ezic_test.rb +++ b/test/unit/gateways/ezic_test.rb @@ -166,5 +166,4 @@ def failed_void_response def successful_authorize_raw_response MockResponse.succeeded(successful_authorize_response) end - end diff --git a/test/unit/gateways/fat_zebra_test.rb b/test/unit/gateways/fat_zebra_test.rb index 2bd96c1c19f..4e3e8a2b00f 100644 --- a/test/unit/gateways/fat_zebra_test.rb +++ b/test/unit/gateways/fat_zebra_test.rb @@ -5,17 +5,18 @@ class FatZebraTest < Test::Unit::TestCase def setup @gateway = FatZebraGateway.new( - :username => 'TEST', - :token => 'TEST' - ) + username: 'TEST', + token: 'TEST' + ) @credit_card = credit_card @amount = 100 @options = { - :order_id => rand(10000), - :billing_address => address, - :description => 'Store Purchase' + order_id: rand(10000), + billing_address: address, + description: 'Store Purchase', + extra: { card_on_file: false } } end @@ -30,11 +31,11 @@ def test_successful_purchase end def test_successful_purchase_with_metadata - @gateway.expects(:ssl_request).with { |method, url, body, headers| + @gateway.expects(:ssl_request).with { |_method, _url, body, _headers| body.match '"metadata":{"foo":"bar"}' }.returns(successful_purchase_response_with_metadata) - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:metadata => { 'foo' => 'bar' })) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(metadata: { 'foo' => 'bar' })) assert_success response assert_equal '001-P-12345AA|purchases', response.authorization @@ -42,7 +43,7 @@ def test_successful_purchase_with_metadata end def test_successful_purchase_with_token - @gateway.expects(:ssl_request).with { |method, url, body, headers| + @gateway.expects(:ssl_request).with { |_method, _url, body, _headers| body.match '"card_token":"e1q7dbj2"' }.returns(successful_purchase_response) @@ -54,7 +55,7 @@ def test_successful_purchase_with_token end def test_successful_purchase_with_token_string - @gateway.expects(:ssl_request).with { |method, url, body, headers| + @gateway.expects(:ssl_request).with { |_method, _url, body, _headers| body.match '"card_token":"e1q7dbj2"' }.returns(successful_purchase_response) @@ -66,11 +67,11 @@ def test_successful_purchase_with_token_string end def test_successful_multi_currency_purchase - @gateway.expects(:ssl_request).with { |method, url, body, headers| + @gateway.expects(:ssl_request).with { |_method, _url, body, _headers| body.match '"currency":"USD"' }.returns(successful_purchase_response) - assert response = @gateway.purchase(@amount, 'e1q7dbj2', @options.merge(:currency => 'USD')) + assert response = @gateway.purchase(@amount, 'e1q7dbj2', @options.merge(currency: 'USD')) assert_success response assert_equal '001-P-12345AA|purchases', response.authorization @@ -80,18 +81,18 @@ def test_successful_multi_currency_purchase def test_successful_purchase_with_recurring_flag stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, @credit_card, @options.merge(recurring: true)) - end.check_request do |method, endpoint, data, headers| - assert_match(%r("extra":{"ecm":"32"}), data) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(%r("extra":{"ecm":"32"), data) end.respond_with(successful_purchase_response) end def test_successful_purchase_with_descriptor - @gateway.expects(:ssl_request).with { |method, url, body, headers| + @gateway.expects(:ssl_request).with { |_method, _url, body, _headers| json = JSON.parse(body) json['extra']['name'] == 'Merchant' && json['extra']['location'] == 'Location' }.returns(successful_purchase_response) - assert response = @gateway.purchase(@amount, 'e1q7dbj2', @options.merge(:merchant => 'Merchant', :merchant_location => 'Location')) + assert response = @gateway.purchase(@amount, 'e1q7dbj2', @options.merge(merchant: 'Merchant', merchant_location: 'Location')) assert_success response assert_equal '001-P-12345AA|purchases', response.authorization @@ -99,7 +100,7 @@ def test_successful_purchase_with_descriptor end def test_successful_authorization - @gateway.expects(:ssl_request).with { |method, url, body, headers| + @gateway.expects(:ssl_request).with { |_method, _url, body, _headers| body.match '"capture":false' }.returns(successful_purchase_response) @@ -111,7 +112,7 @@ def test_successful_authorization end def test_successful_capture - @gateway.expects(:ssl_request).with { |method, url, body, headers| + @gateway.expects(:ssl_request).with { |_method, url, _body, _headers| url =~ %r[purchases/e1q7dbj2/capture\z] }.returns(successful_purchase_response) @@ -169,6 +170,26 @@ def test_unsuccessful_tokenization assert_failure response end + def test_successful_tokenization_without_cvv + credit_card = @credit_card + credit_card.verification_value = nil + @gateway.expects(:ssl_request).returns(successful_no_cvv_tokenize_response) + + assert response = @gateway.store(credit_card, recurring: true) + assert_success response + assert_equal 'ep3c05nzsqvft15wsf1z|credit_cards', response.authorization + end + + def test_unsuccessful_tokenization_without_cvv + credit_card = @credit_card + credit_card.verification_value = nil + @gateway.expects(:ssl_request).returns(failed_no_cvv_tokenize_response) + + assert response = @gateway.store(credit_card) + assert_failure response + assert_equal 'CVV is required', response.message + end + def test_successful_refund @gateway.expects(:ssl_request).returns(successful_refund_response) @@ -194,263 +215,296 @@ def test_scrub private def pre_scrubbed - <<-'PRE_SCRUBBED' -opening connection to gateway.sandbox.fatzebra.com.au:443... -opened -starting SSL for gateway.sandbox.fatzebra.com.au:443... -SSL established -<- "POST /v1.0/credit_cards HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAuthorization: Basic VEVTVDpURVNU\r\nUser-Agent: Fat Zebra v1.0/ActiveMerchant 1.56.0\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nConnection: close\r\nHost: gateway.sandbox.fatzebra.com.au\r\nContent-Length: 93\r\n\r\n" -<- "{\"card_number\":\"5123456789012346\",\"card_expiry\":\"5/2017\",\"cvv\":\"111\",\"card_holder\":\"Foo Bar\"}" --> "HTTP/1.1 200 OK\r\n" --> "Content-Type: application/json; charset=utf-8\r\n" --> "Connection: close\r\n" --> "Status: 200 OK\r\n" --> "Cache-control: no-store\r\n" --> "Pragma: no-cache\r\n" --> "X-Request-Id: 3BA78272_F214_AC10001D_01BB_566A58EC_222F1D_49F4\r\n" --> "X-Runtime: 0.142463\r\n" --> "Date: Fri, 11 Dec 2015 05:02:36 GMT\r\n" --> "X-Rack-Cache: invalidate, pass\r\n" --> "X-Sandbox: true\r\n" --> "X-Backend-Server: app-3\r\n" --> "\r\n" -reading all... --> "{\"successful\":true,\"response\":{\"token\":\"nkk9rhwu\",\"card_holder\":\"Foo Bar\",\"card_number\":\"512345XXXXXX2346\",\"card_expiry\":\"2017-05-31T23:59:59+10:00\",\"authorized\":true,\"transaction_count\":0},\"errors\":[],\"test\":true}" -read 214 bytes -Conn close + <<~'PRE_SCRUBBED' + opening connection to gateway.sandbox.fatzebra.com.au:443... + opened + starting SSL for gateway.sandbox.fatzebra.com.au:443... + SSL established + <- "POST /v1.0/credit_cards HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAuthorization: Basic VEVTVDpURVNU\r\nUser-Agent: Fat Zebra v1.0/ActiveMerchant 1.56.0\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nConnection: close\r\nHost: gateway.sandbox.fatzebra.com.au\r\nContent-Length: 93\r\n\r\n" + <- "{\"card_number\":\"5123456789012346\",\"card_expiry\":\"5/2017\",\"cvv\":\"111\",\"card_holder\":\"Foo Bar\"}" + -> "HTTP/1.1 200 OK\r\n" + -> "Content-Type: application/json; charset=utf-8\r\n" + -> "Connection: close\r\n" + -> "Status: 200 OK\r\n" + -> "Cache-control: no-store\r\n" + -> "Pragma: no-cache\r\n" + -> "X-Request-Id: 3BA78272_F214_AC10001D_01BB_566A58EC_222F1D_49F4\r\n" + -> "X-Runtime: 0.142463\r\n" + -> "Date: Fri, 11 Dec 2015 05:02:36 GMT\r\n" + -> "X-Rack-Cache: invalidate, pass\r\n" + -> "X-Sandbox: true\r\n" + -> "X-Backend-Server: app-3\r\n" + -> "\r\n" + reading all... + -> "{\"successful\":true,\"response\":{\"token\":\"nkk9rhwu\",\"card_holder\":\"Foo Bar\",\"card_number\":\"512345XXXXXX2346\",\"card_expiry\":\"2017-05-31T23:59:59+10:00\",\"authorized\":true,\"transaction_count\":0},\"errors\":[],\"test\":true}" + read 214 bytes + Conn close PRE_SCRUBBED end def post_scrubbed - <<-'POST_SCRUBBED' -opening connection to gateway.sandbox.fatzebra.com.au:443... -opened -starting SSL for gateway.sandbox.fatzebra.com.au:443... -SSL established -<- "POST /v1.0/credit_cards HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAuthorization: Basic [FILTERED]\r\nUser-Agent: Fat Zebra v1.0/ActiveMerchant 1.56.0\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nConnection: close\r\nHost: gateway.sandbox.fatzebra.com.au\r\nContent-Length: 93\r\n\r\n" -<- "{\"card_number\":\"[FILTERED]\",\"card_expiry\":\"5/2017\",\"cvv\":\"[FILTERED]\",\"card_holder\":\"Foo Bar\"}" --> "HTTP/1.1 200 OK\r\n" --> "Content-Type: application/json; charset=utf-8\r\n" --> "Connection: close\r\n" --> "Status: 200 OK\r\n" --> "Cache-control: no-store\r\n" --> "Pragma: no-cache\r\n" --> "X-Request-Id: 3BA78272_F214_AC10001D_01BB_566A58EC_222F1D_49F4\r\n" --> "X-Runtime: 0.142463\r\n" --> "Date: Fri, 11 Dec 2015 05:02:36 GMT\r\n" --> "X-Rack-Cache: invalidate, pass\r\n" --> "X-Sandbox: true\r\n" --> "X-Backend-Server: app-3\r\n" --> "\r\n" -reading all... --> "{\"successful\":true,\"response\":{\"token\":\"nkk9rhwu\",\"card_holder\":\"Foo Bar\",\"card_number\":\"[FILTERED]\",\"card_expiry\":\"2017-05-31T23:59:59+10:00\",\"authorized\":true,\"transaction_count\":0},\"errors\":[],\"test\":true}" -read 214 bytes -Conn close + <<~'POST_SCRUBBED' + opening connection to gateway.sandbox.fatzebra.com.au:443... + opened + starting SSL for gateway.sandbox.fatzebra.com.au:443... + SSL established + <- "POST /v1.0/credit_cards HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAuthorization: Basic [FILTERED]\r\nUser-Agent: Fat Zebra v1.0/ActiveMerchant 1.56.0\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nConnection: close\r\nHost: gateway.sandbox.fatzebra.com.au\r\nContent-Length: 93\r\n\r\n" + <- "{\"card_number\":\"[FILTERED]\",\"card_expiry\":\"5/2017\",\"cvv\":\"[FILTERED]\",\"card_holder\":\"Foo Bar\"}" + -> "HTTP/1.1 200 OK\r\n" + -> "Content-Type: application/json; charset=utf-8\r\n" + -> "Connection: close\r\n" + -> "Status: 200 OK\r\n" + -> "Cache-control: no-store\r\n" + -> "Pragma: no-cache\r\n" + -> "X-Request-Id: 3BA78272_F214_AC10001D_01BB_566A58EC_222F1D_49F4\r\n" + -> "X-Runtime: 0.142463\r\n" + -> "Date: Fri, 11 Dec 2015 05:02:36 GMT\r\n" + -> "X-Rack-Cache: invalidate, pass\r\n" + -> "X-Sandbox: true\r\n" + -> "X-Backend-Server: app-3\r\n" + -> "\r\n" + reading all... + -> "{\"successful\":true,\"response\":{\"token\":\"nkk9rhwu\",\"card_holder\":\"Foo Bar\",\"card_number\":\"[FILTERED]\",\"card_expiry\":\"2017-05-31T23:59:59+10:00\",\"authorized\":true,\"transaction_count\":0},\"errors\":[],\"test\":true}" + read 214 bytes + Conn close POST_SCRUBBED end # Place raw successful response from gateway here def successful_purchase_response { - :successful => true, - :response => { - :authorization => 55355, - :id => '001-P-12345AA', - :card_number => 'XXXXXXXXXXXX1111', - :card_holder => 'John Smith', - :card_expiry => '10/2011', - :card_token => 'a1bhj98j', - :amount => 349, - :decimal_amount => 3.49, - :successful => true, - :message => 'Approved', - :reference => 'ABC123', - :currency => 'AUD', - :transaction_id => '001-P-12345AA', - :settlement_date => '2011-07-01', - :transaction_date => '2011-07-01T12:00:00+11:00', - :response_code => '08', - :captured => true, - :captured_amount => 349, - :rrn => '000000000000', - :cvv_match => 'U', - :metadata => { - }, + successful: true, + response: { + authorization: 55355, + id: '001-P-12345AA', + card_number: 'XXXXXXXXXXXX1111', + card_holder: 'John Smith', + card_expiry: '10/2011', + card_token: 'a1bhj98j', + amount: 349, + decimal_amount: 3.49, + successful: true, + message: 'Approved', + reference: 'ABC123', + currency: 'AUD', + transaction_id: '001-P-12345AA', + settlement_date: '2011-07-01', + transaction_date: '2011-07-01T12:00:00+11:00', + response_code: '08', + captured: true, + captured_amount: 349, + rrn: '000000000000', + cvv_match: 'U', + metadata: { + } }, - :test => true, - :errors => [] + test: true, + errors: [] }.to_json end def successful_purchase_response_with_metadata { - :successful => true, - :response => { - :authorization => 55355, - :id => '001-P-12345AA', - :card_number => 'XXXXXXXXXXXX1111', - :card_holder => 'John Smith', - :card_expiry => '2011-10-31', - :card_token => 'a1bhj98j', - :amount => 349, - :decimal_amount => 3.49, - :successful => true, - :message => 'Approved', - :reference => 'ABC123', - :currency => 'AUD', - :transaction_id => '001-P-12345AA', - :settlement_date => '2011-07-01', - :transaction_date => '2011-07-01T12:00:00+11:00', - :response_code => '08', - :captured => true, - :captured_amount => 349, - :rrn => '000000000000', - :cvv_match => 'U', - :metadata => { - 'foo' => 'bar', - }, + successful: true, + response: { + authorization: 55355, + id: '001-P-12345AA', + card_number: 'XXXXXXXXXXXX1111', + card_holder: 'John Smith', + card_expiry: '2011-10-31', + card_token: 'a1bhj98j', + amount: 349, + decimal_amount: 3.49, + successful: true, + message: 'Approved', + reference: 'ABC123', + currency: 'AUD', + transaction_id: '001-P-12345AA', + settlement_date: '2011-07-01', + transaction_date: '2011-07-01T12:00:00+11:00', + response_code: '08', + captured: true, + captured_amount: 349, + rrn: '000000000000', + cvv_match: 'U', + metadata: { + 'foo' => 'bar' + } }, - :test => true, - :errors => [] + test: true, + errors: [] }.to_json end def declined_purchase_response { - :successful => true, - :response => { - :authorization => 0, - :id => '001-P-12345AB', - :card_number => 'XXXXXXXXXXXX1111', - :card_holder => 'John Smith', - :card_expiry => '10/2011', - :amount => 100, - :authorized => false, - :reference => 'ABC123', - :decimal_amount => 1.0, - :successful => false, - :message => 'Card Declined - check with issuer', - :currency => 'AUD', - :transaction_id => '001-P-12345AB', - :settlement_date => nil, - :transaction_date => '2011-07-01T12:00:00+11:00', - :response_code => '01', - :captured => false, - :captured_amount => 0, - :rrn => '000000000001', - :cvv_match => 'U', - :metadata => { - } + successful: true, + response: { + authorization: 0, + id: '001-P-12345AB', + card_number: 'XXXXXXXXXXXX1111', + card_holder: 'John Smith', + card_expiry: '10/2011', + amount: 100, + authorized: false, + reference: 'ABC123', + decimal_amount: 1.0, + successful: false, + message: 'Card Declined - check with issuer', + currency: 'AUD', + transaction_id: '001-P-12345AB', + settlement_date: nil, + transaction_date: '2011-07-01T12:00:00+11:00', + response_code: '01', + captured: false, + captured_amount: 0, + rrn: '000000000001', + cvv_match: 'U', + metadata: { + } }, - :test => true, - :errors => [] + test: true, + errors: [] }.to_json end def successful_refund_response { - :successful => true, - :response => { - :authorization => 1339973263, - :id => '003-R-7MNIUMY6', - :amount => 10, - :refunded => 'Approved', - :message => 'Approved', - :card_holder => 'Harry Smith', - :card_number => 'XXXXXXXXXXXX4444', - :card_expiry => '2013-05-31', - :card_type => 'MasterCard', - :transaction_id => '003-R-7MNIUMY6', - :reference => '18280', - :currency => 'USD', - :successful => true, - :transaction_date => '2013-07-01T12:00:00+11:00', - :response_code => '08', - :settlement_date => '2013-07-01', - :metadata => { + successful: true, + response: { + authorization: 1339973263, + id: '003-R-7MNIUMY6', + amount: 10, + refunded: 'Approved', + message: 'Approved', + card_holder: 'Harry Smith', + card_number: 'XXXXXXXXXXXX4444', + card_expiry: '2013-05-31', + card_type: 'MasterCard', + transaction_id: '003-R-7MNIUMY6', + reference: '18280', + currency: 'USD', + successful: true, + transaction_date: '2013-07-01T12:00:00+11:00', + response_code: '08', + settlement_date: '2013-07-01', + metadata: { }, - :standalone => false, - :rrn => '000000000002', + standalone: false, + rrn: '000000000002' }, - :errors => [ - ], - :test => true + errors: [], + test: true }.to_json end def unsuccessful_refund_response { - :successful => false, - :response => { - :authorization => nil, - :id => nil, - :amount => nil, - :refunded => nil, - :message => nil, - :card_holder => 'Matthew Savage', - :card_number => 'XXXXXXXXXXXX4444', - :card_expiry => '2013-05-31', - :card_type => 'MasterCard', - :transaction_id => nil, - :successful => false + successful: false, + response: { + authorization: nil, + id: nil, + amount: nil, + refunded: nil, + message: nil, + card_holder: 'Matthew Savage', + card_number: 'XXXXXXXXXXXX4444', + card_expiry: '2013-05-31', + card_type: 'MasterCard', + transaction_id: nil, + successful: false }, - :errors => [ + errors: [ "Reference can't be blank" ], - :test => true + test: true }.to_json end def successful_tokenize_response { - :successful => true, - :response => { - :token => 'e1q7dbj2', - :card_holder => 'Bob Smith', - :card_number => 'XXXXXXXXXXXX2346', - :card_expiry => '2013-05-31T23:59:59+10:00', - :authorized => true, - :transaction_count => 0 + successful: true, + response: { + token: 'e1q7dbj2', + card_holder: 'Bob Smith', + card_number: 'XXXXXXXXXXXX2346', + card_expiry: '2013-05-31T23:59:59+10:00', + authorized: true, + transaction_count: 0 }, - :errors => [], - :test => true + errors: [], + test: true }.to_json end def failed_tokenize_response { - :successful => false, - :response => { - :token => nil, - :card_holder => 'Bob ', - :card_number => '512345XXXXXX2346', - :card_expiry => nil, - :authorized => false, - :transaction_count => 10 + successful: false, + response: { + token: nil, + card_holder: 'Bob ', + card_number: '512345XXXXXX2346', + card_expiry: nil, + authorized: false, + transaction_count: 10 }, - :errors => [ + errors: [ "Expiry date can't be blank" ], - :test => false + test: false + }.to_json + end + + def successful_no_cvv_tokenize_response + { + successful: true, + response: { + token: 'ep3c05nzsqvft15wsf1z', + card_holder: 'Bob ', + card_number: '512345XXXXXX2346', + card_expiry: nil, + authorized: true, + transaction_count: 0 + }, + errors: [], + test: false + }.to_json + end + + def failed_no_cvv_tokenize_response + { + successful: false, + response: { + token: nil, + card_holder: 'Bob ', + card_number: '512345XXXXXX2346', + card_expiry: nil, + authorized: false, + transaction_count: 0 + }, + errors: [ + 'CVV is required' + ], + test: false }.to_json end # Place raw failed response from gateway here def failed_purchase_response { - :successful => false, - :response => {}, - :test => true, - :errors => ['Invalid Card Number'] + successful: false, + response: {}, + test: true, + errors: ['Invalid Card Number'] }.to_json end def missing_data_response { - :successful => false, - :response => {}, - :test => true, - :errors => ['Card Number is required'] + successful: false, + response: {}, + test: true, + errors: ['Card Number is required'] }.to_json end end diff --git a/test/unit/gateways/federated_canada_test.rb b/test/unit/gateways/federated_canada_test.rb index d3ca5956ae8..c54a6c7e006 100644 --- a/test/unit/gateways/federated_canada_test.rb +++ b/test/unit/gateways/federated_canada_test.rb @@ -3,24 +3,24 @@ class FederatedCanadaTest < Test::Unit::TestCase def setup @gateway = FederatedCanadaGateway.new( - :login => 'demo', - :password => 'password' - ) + login: 'demo', + password: 'password' + ) @credit_card = credit_card('4111111111111111') @credit_card.verification_value = '999' @amount = 100 @options = { - :order_id => '1', - :billing_address => address, - :description => 'Store Purchase' + order_id: '1', + billing_address: address, + description: 'Store Purchase' } end def test_successful_authorization @gateway.expects(:ssl_post).returns(successful_authorization_response) - options = {:billing_address => {:address1 => '888', :address2 => 'apt 13', :country => 'CA', :state => 'SK', :city => 'Big Beaver', :zip => '77777'}} + options = { billing_address: { address1: '888', address2: 'apt 13', country: 'CA', state: 'SK', city: 'Big Beaver', zip: '77777' } } assert response = @gateway.authorize(@amount, @credit_card, options) assert_instance_of Response, response assert_success response @@ -47,8 +47,8 @@ def test_unsuccessful_request def test_add_address result = {} - @gateway.send(:add_address, result, :billing_address => {:address1 => '123 Happy Town Road', :address2 => 'apt 13', :country => 'CA', :state => 'SK', :phone => '1234567890'}) - assert_equal ['address1', 'address2', 'city', 'company', 'country', 'phone', 'state', 'zip'], result.stringify_keys.keys.sort + @gateway.send(:add_address, result, billing_address: { address1: '123 Happy Town Road', address2: 'apt 13', country: 'CA', state: 'SK', phone: '1234567890' }) + assert_equal %w[address1 address2 city company country phone state zip], result.stringify_keys.keys.sort assert_equal 'SK', result[:state] assert_equal '123 Happy Town Road', result[:address1] assert_equal 'apt 13', result[:address2] @@ -57,13 +57,13 @@ def test_add_address def test_add_invoice result = {} - @gateway.send(:add_invoice, result, :order_id => '#1001', :description => 'This is a great order') + @gateway.send(:add_invoice, result, order_id: '#1001', description: 'This is a great order') assert_equal '#1001', result[:orderid] assert_equal 'This is a great order', result[:orderdescription] end def test_purchase_is_valid_csv - params = {:amount => @amount} + params = { amount: @amount } @gateway.send(:add_creditcard, params, @credit_card) assert data = @gateway.send(:post_data, 'auth', params) @@ -71,7 +71,7 @@ def test_purchase_is_valid_csv end def test_purchase_meets_minimum_requirements - params = {:amount => @amount} + params = { amount: @amount } @gateway.send(:add_creditcard, params, @credit_card) assert data = @gateway.send(:post_data, 'auth', params) minimum_requirements.each do |key| @@ -80,8 +80,8 @@ def test_purchase_meets_minimum_requirements end def test_expdate_formatting - assert_equal '0909', @gateway.send(:expdate, credit_card('4111111111111111', :month => '9', :year => '2009')) - assert_equal '0711', @gateway.send(:expdate, credit_card('4111111111111111', :month => '7', :year => '2011')) + assert_equal '0909', @gateway.send(:expdate, credit_card('4111111111111111', month: '9', year: '2009')) + assert_equal '0711', @gateway.send(:expdate, credit_card('4111111111111111', month: '7', year: '2011')) end def test_supported_countries @@ -89,7 +89,7 @@ def test_supported_countries end def test_supported_card_types - assert_equal @gateway.supported_cardtypes, [:visa, :master, :american_express, :discover] + assert_equal @gateway.supported_cardtypes, %i[visa master american_express discover] end def test_avs_result diff --git a/test/unit/gateways/finansbank_test.rb b/test/unit/gateways/finansbank_test.rb index 5d9752b3f23..2f7e1cfabbd 100644 --- a/test/unit/gateways/finansbank_test.rb +++ b/test/unit/gateways/finansbank_test.rb @@ -7,18 +7,18 @@ def setup @original_kcode = nil @gateway = FinansbankGateway.new( - :login => 'login', - :password => 'password', - :client_id => 'client_id' + login: 'login', + password: 'password', + client_id: 'client_id' ) @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 @@ -122,228 +122,228 @@ def test_failed_credit private def successful_purchase_response - <<-EOF - - 1 - 1 - Approved - 123456 - 123456 - 00 - 123456 - - - EOF + <<~XML + + 1 + 1 + Approved + 123456 + 123456 + 00 + 123456 + + + XML end def failed_purchase_response - <<-EOF - - 1 - 2 - Declined - - 123456 - 12 - 123456 - Not enough credit - - EOF + <<~XML + + 1 + 2 + Declined + + 123456 + 12 + 123456 + Not enough credit + + XML end def successful_authorize_response - <<-EOF - - 1 - 1 - Approved - 794573 - 305219419620 - 00 - 13052TpOI06012476 - - - 411 - 20130221 19:41:14 - - ISLEMINIZ ONAYLANDI - 00 - 000 - N - - - EOF + <<~XML + + 1 + 1 + Approved + 794573 + 305219419620 + 00 + 13052TpOI06012476 + + + 411 + 20130221 19:41:14 + + ISLEMINIZ ONAYLANDI + 00 + 000 + N + + + XML end def successful_capture_response - <<-EOF - - 1 - 1 - Approved - 794573 - 305219419622 - 00 - 13052TpPH06012485 - - - 411 - 20130221 19:41:15 - - 00 - - - EOF + <<~XML + + 1 + 1 + Approved + 794573 + 305219419622 + 00 + 13052TpPH06012485 + + + 411 + 20130221 19:41:15 + + 00 + + + XML end def capture_without_authorize_response - <<-EOF - - - - Error - - - 99 - 13052TtZF06012712 - PostAuth sadece iliskili bir PreAuth icin yapilabilir. - - - 20130221 19:45:25 - CORE-2115 - 992115 - - - EOF + <<~XML + + + + Error + + + 99 + 13052TtZF06012712 + PostAuth sadece iliskili bir PreAuth icin yapilabilir. + + + 20130221 19:45:25 + CORE-2115 + 992115 + + + XML end def successful_void_response - <<-EOF - - 1 - 1 - Approved - 794573 - 402310197597 - 00 - 14023KVGD18549 - - - 1363 - 20140123 10:21:05 - - 00 - - - EOF + <<~XML + + 1 + 1 + Approved + 794573 + 402310197597 + 00 + 14023KVGD18549 + + + 1363 + 20140123 10:21:05 + + 00 + + + XML end def failed_void_response - <<-EOF - - - - Error - - - 99 - 14023KvNI18702 - İptal edilmeye uygun satış işlemi bulunamadı. - - - 20140123 10:47:13 - CORE-2008 - 992008 - - - EOF + <<~XML + + + + Error + + + 99 + 14023KvNI18702 + İptal edilmeye uygun satış işlemi bulunamadı. + + + 20140123 10:47:13 + CORE-2008 + 992008 + + + XML end def success_refund_response - <<-EOF - - 1 - 1 - Approved - 811778 - 402410197809 - 00 - 14024KACE13836 - - - 1364 - 20140124 10:00:02 - - 000000001634 - 000000001634 - 00 - 3 - - - EOF + <<~XML + + 1 + 1 + Approved + 811778 + 402410197809 + 00 + 14024KACE13836 + + + 1364 + 20140124 10:00:02 + + 000000001634 + 000000001634 + 00 + 3 + + + XML end def failed_refund_response - <<-EOF - - - - Error - - - 99 - 14024KEwH13882 - Iade yapilamaz, siparis gunsonuna girmemis. - - - 20140124 10:04:48 - CORE-2508 - 992508 - - - EOF + <<~XML + + + + Error + + + 99 + 14024KEwH13882 + Iade yapilamaz, siparis gunsonuna girmemis. + + + 20140124 10:04:48 + CORE-2508 + 992508 + + + XML end def success_credit_response - <<-EOF - - ORDER-14024KUGB13953 - ORDER-14024KUGB13953 - Approved - 718160 - 402410197818 - 00 - 14024KUGD13955 - - - 1364 - 20140124 10:20:06 - - 00 - 3 - - - EOF + <<~XML + + ORDER-14024KUGB13953 + ORDER-14024KUGB13953 + Approved + 718160 + 402410197818 + 00 + 14024KUGD13955 + + + 1364 + 20140124 10:20:06 + + 00 + 3 + + + XML end def failed_credit_response - <<-EOF - - - - Error - - - 99 - 14024KUtG13966 - Kredi karti numarasi gecerli formatta degil. - - - 20140124 10:20:45 - CORE-2012 - 992012 - - - EOF + <<~XML + + + + Error + + + 99 + 14024KUtG13966 + Kredi karti numarasi gecerli formatta degil. + + + 20140124 10:20:45 + CORE-2012 + 992012 + + + XML end end diff --git a/test/unit/gateways/first_pay_test.rb b/test/unit/gateways/first_pay_test.rb index b761e884938..0db2ce8680a 100644 --- a/test/unit/gateways/first_pay_test.rb +++ b/test/unit/gateways/first_pay_test.rb @@ -21,7 +21,7 @@ def setup 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(/1234<\/FIELD>/, data) assert_match(/a91c38c3-7d7f-4d29-acc7-927b4dca0dbe<\/FIELD>/, data) assert_match(/sale<\/FIELD>/, data) @@ -62,7 +62,7 @@ def test_failed_purchase def test_successful_authorize 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(/1234<\/FIELD>/, data) assert_match(/a91c38c3-7d7f-4d29-acc7-927b4dca0dbe<\/FIELD>/, data) assert_match(/auth<\/FIELD>/, data) @@ -101,7 +101,7 @@ def test_failed_authorize def test_successful_capture response = stub_comms do @gateway.capture(@amount, '47920') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/1234<\/FIELD>/, data) assert_match(/a91c38c3-7d7f-4d29-acc7-927b4dca0dbe<\/FIELD>/, data) assert_match(/settle<\/FIELD>/, data) @@ -129,7 +129,7 @@ def test_failed_capture def test_successful_refund response = stub_comms do @gateway.refund(@amount, '47925') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/1234<\/FIELD>/, data) assert_match(/a91c38c3-7d7f-4d29-acc7-927b4dca0dbe<\/FIELD>/, data) assert_match(/credit<\/FIELD>/, data) @@ -157,7 +157,7 @@ def test_failed_refund def test_successful_void response = stub_comms do @gateway.void('47934') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/1234<\/FIELD>/, data) assert_match(/a91c38c3-7d7f-4d29-acc7-927b4dca0dbe<\/FIELD>/, data) assert_match(/void<\/FIELD>/, data) @@ -188,7 +188,7 @@ def test_recurring_payments @options[:recurring_type] = 'monthly' 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{1}, data) assert_match(%r{01/01/1900}, data) assert_match(%r{02/02/1901}, data) diff --git a/test/unit/gateways/firstdata_e4_test.rb b/test/unit/gateways/firstdata_e4_test.rb index a244a13df53..21a0a0da180 100755 --- a/test/unit/gateways/firstdata_e4_test.rb +++ b/test/unit/gateways/firstdata_e4_test.rb @@ -7,16 +7,16 @@ class FirstdataE4Test < Test::Unit::TestCase def setup @gateway = FirstdataE4Gateway.new( - :login => 'A00427-01', - :password => 'testus' + login: 'A00427-01', + password: 'testus' ) @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' } @authorization = 'ET1700;106625152;4738' end @@ -42,7 +42,7 @@ def test_successful_purchase end def test_successful_purchase_with_specified_currency - options_with_specified_currency = @options.merge({currency: 'GBP'}) + options_with_specified_currency = @options.merge({ currency: 'GBP' }) @gateway.expects(:ssl_post).returns(successful_purchase_with_specified_currency_response) assert response = @gateway.purchase(@amount, @credit_card, options_with_specified_currency) assert_success response @@ -61,7 +61,7 @@ def test_successful_purchase_with_token end def test_successful_purchase_with_specified_currency_and_token - options_with_specified_currency = @options.merge({currency: 'GBP'}) + options_with_specified_currency = @options.merge({ currency: 'GBP' }) @gateway.expects(:ssl_post).returns(successful_purchase_with_specified_currency_response) assert response = @gateway.purchase(@amount, '8938737759041111;visa;Longbob;Longsen;9;2014', options_with_specified_currency) @@ -82,7 +82,7 @@ def test_successful_refund end def test_successful_refund_with_specified_currency - options_with_specified_currency = @options.merge({currency: 'GBP'}) + options_with_specified_currency = @options.merge({ currency: 'GBP' }) @gateway.expects(:ssl_post).returns(successful_refund_with_specified_currency_response) assert response = @gateway.refund(@amount, @authorization, options_with_specified_currency) assert_success response @@ -136,11 +136,11 @@ def test_no_transaction end def test_supported_countries - assert_equal ['CA', 'US'], FirstdataE4Gateway.supported_countries + assert_equal %w[CA US], FirstdataE4Gateway.supported_countries end def test_supported_cardtypes - assert_equal [:visa, :master, :american_express, :jcb, :discover], FirstdataE4Gateway.supported_cardtypes + assert_equal %i[visa master american_express jcb discover], FirstdataE4Gateway.supported_cardtypes end def test_avs_result @@ -160,15 +160,24 @@ def test_cvv_result def test_requests_include_verification_string 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 '456 My Street|K1C2N6|Ottawa|ON|CA', data end.respond_with(successful_purchase_response) end + def test_requests_scrub_newline_and_return_characters_from_verification_string_components + stub_comms do + options_with_newline_and_return_characters_in_address = @options.merge({ billing_address: address({ address1: "123 My\nStreet", address2: "K1C2N6\r", city: "Ottawa\r\n" }) }) + @gateway.purchase(@amount, @credit_card, options_with_newline_and_return_characters_in_address) + end.check_request do |_endpoint, data, _headers| + assert_match '123 My Street|K1C2N6|Ottawa|ON|CA', data + end.respond_with(successful_purchase_response) + end + def test_tax_fields_are_sent stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(tax1_amount: 830, tax1_number: 'Br59a')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match '830', data assert_match 'Br59a', data end.respond_with(successful_purchase_response) @@ -177,7 +186,7 @@ def test_tax_fields_are_sent def test_customer_ref_is_sent stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(customer: '932')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match '932', data end.respond_with(successful_purchase_response) end @@ -185,7 +194,7 @@ def test_customer_ref_is_sent def test_eci_default_value 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 '07', data end.respond_with(successful_purchase_response) end @@ -196,7 +205,7 @@ def test_eci_numeric_padding 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 '05', data end.respond_with(successful_purchase_response) @@ -205,7 +214,7 @@ def test_eci_numeric_padding 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 '05', data end.respond_with(successful_purchase_response) end @@ -213,7 +222,7 @@ def test_eci_numeric_padding def test_eci_option_value stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(eci: '05')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match '05', data end.respond_with(successful_purchase_response) end @@ -287,7 +296,7 @@ def test_requests_include_card_authentication_data stub_comms do @gateway.purchase(@amount, @credit_card, options_with_authentication_data) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match '06', data assert_match 'SAMPLECAVV', data assert_match 'SAMPLEXID', data @@ -309,7 +318,7 @@ def test_add_swipe_data_with_creditcard stub_comms do @gateway.purchase(@amount, @credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match 'Track Data', data assert_match 'R', data end.respond_with(successful_purchase_response) @@ -394,780 +403,780 @@ def post_scrub end def successful_purchase_response - <<-RESPONSE - - - AD1234-56 - - 00 - 47.38 - - ############1111 - 106625152 - - - - ET1700 - 0913 - Fred Burfle - - 773 - 0 - - - - - - - - - - - - 77 - - - - 1.1.1.10 - - false - true - 00 - Transaction Normal - 100 - Approved - - 000040 - U - M - 3146117 - - USD - - false - Friendly Inc DEMO0983 - 123 King St - Toronto - Ontario - Canada - L7Z 3K8 - - 8938737759041111 - =========== TRANSACTION RECORD ========== -Friendly Inc DEMO0983 -123 King St -Toronto, ON L7Z 3K8 -Canada - - -TYPE: Purchase - -ACCT: Visa $ 47.38 USD - -CARD NUMBER : ############1111 -DATE/TIME : 28 Sep 12 07:54:48 -REFERENCE # : 000040 M -AUTHOR. # : ET120454 -TRANS. REF. : 77 - - Approved - Thank You 100 - - -Please retain this copy for your records. - -Cardholder will pay above amount to card -issuer pursuant to cardholder agreement. -========================================= - + <<~RESPONSE + + + AD1234-56 + + 00 + 47.38 + + ############1111 + 106625152 + + + + ET1700 + 0913 + Fred Burfle + + 773 + 0 + + + + + + + + + + + + 77 + + + + 1.1.1.10 + + false + true + 00 + Transaction Normal + 100 + Approved + + 000040 + U + M + 3146117 + + USD + + false + Friendly Inc DEMO0983 + 123 King St + Toronto + Ontario + Canada + L7Z 3K8 + + 8938737759041111 + =========== TRANSACTION RECORD ========== + Friendly Inc DEMO0983 + 123 King St + Toronto, ON L7Z 3K8 + Canada + + + TYPE: Purchase + + ACCT: Visa $ 47.38 USD + + CARD NUMBER : ############1111 + DATE/TIME : 28 Sep 12 07:54:48 + REFERENCE # : 000040 M + AUTHOR. # : ET120454 + TRANS. REF. : 77 + + Approved - Thank You 100 + + + Please retain this copy for your records. + + Cardholder will pay above amount to card + issuer pursuant to cardholder agreement. + ========================================= + RESPONSE end def successful_purchase_with_specified_currency_response - <<-RESPONSE - - - AD1234-56 - - 00 - 47.38 - - ############1111 - 106625152 - - - - ET1700 - 0913 - Fred Burfle - - 773 - 0 - - - - - - - - - - - - 77 - - - - 1.1.1.10 - - false - true - 00 - Transaction Normal - 100 - Approved - - 000040 - U - M - 3146117 - - GBP - - false - Friendly Inc DEMO0983 - 123 King St - Toronto - Ontario - Canada - L7Z 3K8 - - 8938737759041111 - =========== TRANSACTION RECORD ========== -Friendly Inc DEMO0983 -123 King St -Toronto, ON L7Z 3K8 -Canada - - -TYPE: Purchase - -ACCT: Visa £ 47.38 GBP - -CARD NUMBER : ############1111 -DATE/TIME : 28 Sep 12 07:54:48 -REFERENCE # : 000040 M -AUTHOR. # : ET120454 -TRANS. REF. : 77 - - Approved - Thank You 100 - - -Please retain this copy for your records. - -Cardholder will pay above amount to card -issuer pursuant to cardholder agreement. -========================================= - + <<~RESPONSE + + + AD1234-56 + + 00 + 47.38 + + ############1111 + 106625152 + + + + ET1700 + 0913 + Fred Burfle + + 773 + 0 + + + + + + + + + + + + 77 + + + + 1.1.1.10 + + false + true + 00 + Transaction Normal + 100 + Approved + + 000040 + U + M + 3146117 + + GBP + + false + Friendly Inc DEMO0983 + 123 King St + Toronto + Ontario + Canada + L7Z 3K8 + + 8938737759041111 + =========== TRANSACTION RECORD ========== + Friendly Inc DEMO0983 + 123 King St + Toronto, ON L7Z 3K8 + Canada + + + TYPE: Purchase + + ACCT: Visa £ 47.38 GBP + + CARD NUMBER : ############1111 + DATE/TIME : 28 Sep 12 07:54:48 + REFERENCE # : 000040 M + AUTHOR. # : ET120454 + TRANS. REF. : 77 + + Approved - Thank You 100 + + + Please retain this copy for your records. + + Cardholder will pay above amount to card + issuer pursuant to cardholder agreement. + ========================================= + RESPONSE end def successful_purchase_response_without_transarmor - <<-RESPONSE - - - AD1234-56 - - 00 - 47.38 - - ############1111 - 106625152 - - - - ET1700 - 0913 - Fred Burfle - - 773 - 0 - - - - - - - - - - - - 77 - - - - 1.1.1.10 - - false - true - 00 - Transaction Normal - 100 - Approved - - 000040 - U - M - 3146117 - - USD - - false - Friendly Inc DEMO0983 - 123 King St - Toronto - Ontario - Canada - L7Z 3K8 - - - =========== TRANSACTION RECORD ========== -Friendly Inc DEMO0983 -123 King St -Toronto, ON L7Z 3K8 -Canada - - -TYPE: Purchase - -ACCT: Visa $ 47.38 USD - -CARD NUMBER : ############1111 -DATE/TIME : 28 Sep 12 07:54:48 -REFERENCE # : 000040 M -AUTHOR. # : ET120454 -TRANS. REF. : 77 - - Approved - Thank You 100 - - -Please retain this copy for your records. - -Cardholder will pay above amount to card -issuer pursuant to cardholder agreement. -========================================= - + <<~RESPONSE + + + AD1234-56 + + 00 + 47.38 + + ############1111 + 106625152 + + + + ET1700 + 0913 + Fred Burfle + + 773 + 0 + + + + + + + + + + + + 77 + + + + 1.1.1.10 + + false + true + 00 + Transaction Normal + 100 + Approved + + 000040 + U + M + 3146117 + + USD + + false + Friendly Inc DEMO0983 + 123 King St + Toronto + Ontario + Canada + L7Z 3K8 + + + =========== TRANSACTION RECORD ========== + Friendly Inc DEMO0983 + 123 King St + Toronto, ON L7Z 3K8 + Canada + + + TYPE: Purchase + + ACCT: Visa $ 47.38 USD + + CARD NUMBER : ############1111 + DATE/TIME : 28 Sep 12 07:54:48 + REFERENCE # : 000040 M + AUTHOR. # : ET120454 + TRANS. REF. : 77 + + Approved - Thank You 100 + + + Please retain this copy for your records. + + Cardholder will pay above amount to card + issuer pursuant to cardholder agreement. + ========================================= + RESPONSE end def successful_refund_response - <<-RESPONSE - - - AD1234-56 - - 34 - 123 - - ############1111 - 888 - - - - ET112216 - 0913 - Fred Burfle - - - 0 - - - - - - - - - - - - - - - - 1.1.1.10 - - false - true - 00 - Transaction Normal - 100 - Approved - - 000041 - - I - 9176784 - - USD - - false - Friendly Inc DEMO0983 - 123 King St - Toronto - Ontario - Canada - L7Z 3K8 - - =========== TRANSACTION RECORD ========== -Friendly Inc DEMO0983 -123 King St -Toronto, ON L7Z 3K8 -Canada - - -TYPE: Refund - -ACCT: Visa $ 23.69 USD - -CARD NUMBER : ############1111 -DATE/TIME : 28 Sep 12 08:31:23 -REFERENCE # : 000041 M -AUTHOR. # : ET112216 -TRANS. REF. : - - Approved - Thank You 100 - - -Please retain this copy for your records. - -========================================= - + <<~RESPONSE + + + AD1234-56 + + 34 + 123 + + ############1111 + 888 + + + + ET112216 + 0913 + Fred Burfle + + + 0 + + + + + + + + + + + + + + + + 1.1.1.10 + + false + true + 00 + Transaction Normal + 100 + Approved + + 000041 + + I + 9176784 + + USD + + false + Friendly Inc DEMO0983 + 123 King St + Toronto + Ontario + Canada + L7Z 3K8 + + =========== TRANSACTION RECORD ========== + Friendly Inc DEMO0983 + 123 King St + Toronto, ON L7Z 3K8 + Canada + + + TYPE: Refund + + ACCT: Visa $ 23.69 USD + + CARD NUMBER : ############1111 + DATE/TIME : 28 Sep 12 08:31:23 + REFERENCE # : 000041 M + AUTHOR. # : ET112216 + TRANS. REF. : + + Approved - Thank You 100 + + + Please retain this copy for your records. + + ========================================= + RESPONSE end def successful_refund_with_specified_currency_response - <<-RESPONSE - - - AD1234-56 - - 34 - 123 - - ############1111 - 888 - - - - ET112216 - 0913 - Fred Burfle - - - 0 - - - - - - - - - - - - - - - - 1.1.1.10 - - false - true - 00 - Transaction Normal - 100 - Approved - - 000041 - - I - 9176784 - - GBP - - false - Friendly Inc DEMO0983 - 123 King St - Toronto - Ontario - Canada - L7Z 3K8 - - =========== TRANSACTION RECORD ========== -Friendly Inc DEMO0983 -123 King St -Toronto, ON L7Z 3K8 -Canada - - -TYPE: Refund - -ACCT: Visa £ 23.69 GBP - -CARD NUMBER : ############1111 -DATE/TIME : 28 Sep 12 08:31:23 -REFERENCE # : 000041 M -AUTHOR. # : ET112216 -TRANS. REF. : - - Approved - Thank You 100 - - -Please retain this copy for your records. - -========================================= - + <<~RESPONSE + + + AD1234-56 + + 34 + 123 + + ############1111 + 888 + + + + ET112216 + 0913 + Fred Burfle + + + 0 + + + + + + + + + + + + + + + + 1.1.1.10 + + false + true + 00 + Transaction Normal + 100 + Approved + + 000041 + + I + 9176784 + + GBP + + false + Friendly Inc DEMO0983 + 123 King St + Toronto + Ontario + Canada + L7Z 3K8 + + =========== TRANSACTION RECORD ========== + Friendly Inc DEMO0983 + 123 King St + Toronto, ON L7Z 3K8 + Canada + + + TYPE: Refund + + ACCT: Visa £ 23.69 GBP + + CARD NUMBER : ############1111 + DATE/TIME : 28 Sep 12 08:31:23 + REFERENCE # : 000041 M + AUTHOR. # : ET112216 + TRANS. REF. : + + Approved - Thank You 100 + + + Please retain this copy for your records. + + ========================================= + RESPONSE end def failed_purchase_response - <<-RESPONSE - - - AD1234-56 - - 00 - 5013.0 - - ############1111 - 555555 - - - - - 0911 - Fred Burfle - - 773 - 0 - - - - - - - - - - - - 77 - - - - 1.1.1.10 - - - 0 - - false - false - 00 - Transaction Normal - 605 - Invalid Expiration Date - - 000033 - - - - - USD - - false - Friendly Inc DEMO0983 - 123 King St - Toronto - Ontario - Canada - L7Z 3K8 - - =========== TRANSACTION RECORD ========== -Friendly Inc DEMO0983 -123 King St -Toronto, ON L7Z 3K8 -Canada - - -TYPE: Purchase -ACCT: Visa $ 5,013.00 USD -CARD NUMBER : ############1111 -DATE/TIME : 25 Sep 12 07:27:00 -REFERENCE # : 000033 M -AUTHOR. # : -TRANS. REF. : 77 -Transaction not approved 605 -Please retain this copy for your records. -========================================= - + <<~RESPONSE + + + AD1234-56 + + 00 + 5013.0 + + ############1111 + 555555 + + + + + 0911 + Fred Burfle + + 773 + 0 + + + + + + + + + + + + 77 + + + + 1.1.1.10 + + + 0 + + false + false + 00 + Transaction Normal + 605 + Invalid Expiration Date + + 000033 + + + + + USD + + false + Friendly Inc DEMO0983 + 123 King St + Toronto + Ontario + Canada + L7Z 3K8 + + =========== TRANSACTION RECORD ========== + Friendly Inc DEMO0983 + 123 King St + Toronto, ON L7Z 3K8 + Canada + + + TYPE: Purchase + ACCT: Visa $ 5,013.00 USD + CARD NUMBER : ############1111 + DATE/TIME : 25 Sep 12 07:27:00 + REFERENCE # : 000033 M + AUTHOR. # : + TRANS. REF. : 77 + Transaction not approved 605 + Please retain this copy for your records. + ========================================= + RESPONSE end def successful_verify_response - <<-RESPONSE - - - AD2552-05 - - 05 - 0.0 - - ############4242 - 25101911 - - - - ET184931 - 0915 - Longbob Longsen - 1234 My Street|K1C2N6|Ottawa|ON|CA - 123 - 0 - - - - - - - - - - - - 1 - - Store Purchase - - 75.182.123.244 - - false - true - 00 - Transaction Normal - 100 - Approved - - 000040 - 1 - M - 7228838 - - USD - - false - FriendlyInc - 123 Main Street - Durham - North Carolina - United States - 27592 - - - Visa - - - - - false - =========== TRANSACTION RECORD ========== -FriendlyInc DEMO0 -123 Main Street -Durham, NC 27592 -United States - - -TYPE: Auth Only - -ACCT: Visa $ 0.00 USD - -CARDHOLDER NAME : Longbob Longsen -CARD NUMBER : ############4242 -DATE/TIME : 04 Jul 14 14:21:52 -REFERENCE # : 000040 M -AUTHOR. # : ET184931 -TRANS. REF. : 1 - - Approved - Thank You 100 - - -Please retain this copy for your records. - -Cardholder will pay above amount to card -issuer pursuant to cardholder agreement. -========================================= - + <<~RESPONSE + + + AD2552-05 + + 05 + 0.0 + + ############4242 + 25101911 + + + + ET184931 + 0915 + Longbob Longsen + 1234 My Street|K1C2N6|Ottawa|ON|CA + 123 + 0 + + + + + + + + + + + + 1 + + Store Purchase + + 75.182.123.244 + + false + true + 00 + Transaction Normal + 100 + Approved + + 000040 + 1 + M + 7228838 + + USD + + false + FriendlyInc + 123 Main Street + Durham + North Carolina + United States + 27592 + + + Visa + + + + + false + =========== TRANSACTION RECORD ========== + FriendlyInc DEMO0 + 123 Main Street + Durham, NC 27592 + United States + + + TYPE: Auth Only + + ACCT: Visa $ 0.00 USD + + CARDHOLDER NAME : Longbob Longsen + CARD NUMBER : ############4242 + DATE/TIME : 04 Jul 14 14:21:52 + REFERENCE # : 000040 M + AUTHOR. # : ET184931 + TRANS. REF. : 1 + + Approved - Thank You 100 + + + Please retain this copy for your records. + + Cardholder will pay above amount to card + issuer pursuant to cardholder agreement. + ========================================= + RESPONSE end def no_transaction_response - yamlexcep = <<-RESPONSE ---- !ruby/exception:ActiveMerchant::ResponseError -message: Failed with 400 Bad Request -message: -response: !ruby/object:Net::HTTPBadRequest - body: "Malformed request: Transaction Type is missing." - body_exist: true - code: "400" - header: - connection: - - Close - content-type: - - text/html; charset=utf-8 - server: - - Apache - date: - - Fri, 28 Sep 2012 18:21:37 GMT - content-length: - - "47" - status: - - "400" - cache-control: - - no-cache - http_version: "1.1" - message: Bad Request - read: true - socket: + yamlexcep = <<~RESPONSE + --- !ruby/exception:ActiveMerchant::ResponseError + message: Failed with 400 Bad Request + message: + response: !ruby/object:Net::HTTPBadRequest + body: "Malformed request: Transaction Type is missing." + body_exist: true + code: "400" + header: + connection: + - Close + content-type: + - text/html; charset=utf-8 + server: + - Apache + date: + - Fri, 28 Sep 2012 18:21:37 GMT + content-length: + - "47" + status: + - "400" + cache-control: + - no-cache + http_version: "1.1" + message: Bad Request + read: true + socket: RESPONSE YAML.safe_load(yamlexcep, ['Net::HTTPBadRequest', 'ActiveMerchant::ResponseError']) end def bad_credentials_response - yamlexcep = <<-RESPONSE ---- !ruby/exception:ActiveMerchant::ResponseError -message: -response: !ruby/object:Net::HTTPUnauthorized - code: '401' - message: Authorization Required - body: Unauthorized Request. Bad or missing credentials. - read: true - header: - cache-control: - - no-cache - content-type: - - text/html; charset=utf-8 - date: - - Tue, 30 Dec 2014 23:28:32 GMT - server: - - Apache - status: - - '401' - x-rack-cache: - - invalidate, pass - x-request-id: - - 4157e21cc5620a95ead8d2025b55bdf4 - x-ua-compatible: - - IE=Edge,chrome=1 - content-length: - - '49' - connection: - - Close - body_exist: true - http_version: '1.1' - socket: + yamlexcep = <<~RESPONSE + --- !ruby/exception:ActiveMerchant::ResponseError + message: + response: !ruby/object:Net::HTTPUnauthorized + code: '401' + message: Authorization Required + body: Unauthorized Request. Bad or missing credentials. + read: true + header: + cache-control: + - no-cache + content-type: + - text/html; charset=utf-8 + date: + - Tue, 30 Dec 2014 23:28:32 GMT + server: + - Apache + status: + - '401' + x-rack-cache: + - invalidate, pass + x-request-id: + - 4157e21cc5620a95ead8d2025b55bdf4 + x-ua-compatible: + - IE=Edge,chrome=1 + content-length: + - '49' + connection: + - Close + body_exist: true + http_version: '1.1' + socket: RESPONSE YAML.safe_load(yamlexcep, ['Net::HTTPUnauthorized', 'ActiveMerchant::ResponseError']) end def successful_void_response - <<-RESPONSE - - - AD1234-56 - - 33 - 11.45 - - ############1111 - 987123 - - - - ET112112 - 0913 - Fred Burfle - - - 0 - - - - - - - - - - - - - - - - 1.1.1.10 - - - 0 - - false - true - 00 - Transaction Normal - 100 - Approved - - 000166 - - I - 2046743 - - USD - - false - FreshBooks DEMO0785 - 35 Golden Ave - Toronto - Ontario - Canada - M6R 2J5 - -=========== TRANSACTION RECORD ========== -FreshBooks DEMO0785 -35 Golden Ave -Toronto, ON M6R 2J5 -Canada - - -TYPE: Void - -ACCT: Visa $ 47.38 USD - -CARD NUMBER : ############1111 -DATE/TIME : 15 Nov 12 08:20:36 -REFERENCE # : 000166 M -AUTHOR. # : ET112112 -TRANS. REF. : - -Approved - Thank You 100 - - -Please retain this copy for your records. - -Cardholder will pay above amount to card -issuer pursuant to cardholder agreement. -========================================= - + <<~RESPONSE + + + AD1234-56 + + 33 + 11.45 + + ############1111 + 987123 + + + + ET112112 + 0913 + Fred Burfle + + + 0 + + + + + + + + + + + + + + + + 1.1.1.10 + + + 0 + + false + true + 00 + Transaction Normal + 100 + Approved + + 000166 + + I + 2046743 + + USD + + false + FreshBooks DEMO0785 + 35 Golden Ave + Toronto + Ontario + Canada + M6R 2J5 + + =========== TRANSACTION RECORD ========== + FreshBooks DEMO0785 + 35 Golden Ave + Toronto, ON M6R 2J5 + Canada + + + TYPE: Void + + ACCT: Visa $ 47.38 USD + + CARD NUMBER : ############1111 + DATE/TIME : 15 Nov 12 08:20:36 + REFERENCE # : 000166 M + AUTHOR. # : ET112112 + TRANS. REF. : + + Approved - Thank You 100 + + + Please retain this copy for your records. + + Cardholder will pay above amount to card + issuer pursuant to cardholder agreement. + ========================================= + RESPONSE end end diff --git a/test/unit/gateways/firstdata_e4_v27_test.rb b/test/unit/gateways/firstdata_e4_v27_test.rb index 6cdb1522596..02f982bb551 100644 --- a/test/unit/gateways/firstdata_e4_v27_test.rb +++ b/test/unit/gateways/firstdata_e4_v27_test.rb @@ -7,18 +7,18 @@ class FirstdataE4V27Test < Test::Unit::TestCase def setup @gateway = FirstdataE4V27Gateway.new( - :login => 'A00427-01', - :password => 'testus', - :key_id => '12345', - :hmac_key => 'hexkey' + login: 'A00427-01', + password: 'testus', + key_id: '12345', + hmac_key: 'hexkey' ) @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' } @authorization = 'ET1700;106625152;4738' end @@ -51,8 +51,21 @@ def test_successful_purchase_with_token def test_successful_purchase_with_wallet response = stub_comms do - @gateway.purchase(@amount, @credit_card, @options.merge!({wallet_provider_id: 4})) - end.check_request do |endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, @options.merge!({ wallet_provider_id: 3 })) + end.check_request do |_endpoint, data, _headers| + assert_match(/WalletProviderID>341UnewC/, data) end.respond_with(successful_purchase_response_with_stored_credentials) assert_success response @@ -138,11 +152,11 @@ def test_no_transaction end def test_supported_countries - assert_equal ['CA', 'US'], FirstdataE4V27Gateway.supported_countries + assert_equal %w[CA US], FirstdataE4V27Gateway.supported_countries end def test_supported_cardtypes - assert_equal [:visa, :master, :american_express, :jcb, :discover], FirstdataE4V27Gateway.supported_cardtypes + assert_equal %i[visa master american_express jcb discover], FirstdataE4V27Gateway.supported_cardtypes end def test_avs_result @@ -162,15 +176,24 @@ def test_cvv_result def test_request_includes_address 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 '
456 My StreetApt 1OttawaONK1C2N6CA
', data end.respond_with(successful_purchase_response) end + def test_requests_scrub_newline_and_return_characters_from_verification_string_components + stub_comms do + options_with_newline_and_return_characters_in_address = @options.merge({ billing_address: address({ address1: "456 My\nStreet", address2: nil, city: "Ottawa\r\n", state: 'ON', country: 'CA', zip: 'K1C2N6' }) }) + @gateway.purchase(@amount, @credit_card, options_with_newline_and_return_characters_in_address) + end.check_request do |_endpoint, data, _headers| + assert_match '
456 My StreetOttawaONK1C2N6CA
', data + end.respond_with(successful_purchase_response) + end + def test_tax_fields_are_sent stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(tax1_amount: 830, tax1_number: 'Br59a')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match '830', data assert_match 'Br59a', data end.respond_with(successful_purchase_response) @@ -179,7 +202,7 @@ def test_tax_fields_are_sent def test_customer_ref_is_sent stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(customer: '932')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match '932', data end.respond_with(successful_purchase_response) end @@ -187,7 +210,7 @@ def test_customer_ref_is_sent def test_eci_default_value 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 '07', data end.respond_with(successful_purchase_response) end @@ -198,7 +221,7 @@ def test_eci_numeric_padding 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 '05', data end.respond_with(successful_purchase_response) @@ -207,7 +230,7 @@ def test_eci_numeric_padding 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 '05', data end.respond_with(successful_purchase_response) end @@ -215,7 +238,7 @@ def test_eci_numeric_padding def test_eci_option_value stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(eci: '05')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match '05', data end.respond_with(successful_purchase_response) end @@ -245,13 +268,13 @@ def test_network_tokenization_requests_with_discover '6011111111111117', brand: 'discover', transaction_id: '123', - eci: '05', + eci: '04', payment_cryptogram: 'whatever_the_cryptogram_is' ) @gateway.purchase(@amount, credit_card, @options) end.check_request do |_, data, _| - assert_match '04', data + assert_match '05', data assert_match '123', data assert_match 'whatever_the_cryptogram_is', data assert_xml_valid_to_wsdl(data) @@ -289,7 +312,7 @@ def test_requests_include_card_authentication_data stub_comms do @gateway.purchase(@amount, @credit_card, options_with_authentication_data) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match '06', data assert_match 'SAMPLECAVV', data assert_match 'SAMPLEXID', data @@ -310,7 +333,7 @@ def test_add_swipe_data_with_creditcard stub_comms do @gateway.purchase(@amount, @credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match 'Track Data', data assert_match 'R', data end.respond_with(successful_purchase_response) @@ -409,701 +432,701 @@ def post_scrub end def successful_purchase_response - <<-RESPONSE - - - AD1234-56 - - 00 - 47.38 - - ############1111 - 106625152 - - - - ET1700 - 0913 - Fred Burfle - 0 - - - - - - - - - - - - 77 - - - - 1.1.1.10 - - false - true - 00 - Transaction Normal - 100 - Approved - - 000040 - U - M - 3146117 - - USD - - false - Friendly Inc DEMO0983 - 123 King St - Toronto - Ontario - Canada - L7Z 3K8 - - 8938737759041111 - =========== TRANSACTION RECORD ========== -Friendly Inc DEMO0983 -123 King St -Toronto, ON L7Z 3K8 -Canada - - -TYPE: Purchase - -ACCT: Visa $ 47.38 USD - -CARD NUMBER : ############1111 -DATE/TIME : 28 Sep 12 07:54:48 -REFERENCE # : 000040 M -AUTHOR. # : ET120454 -TRANS. REF. : 77 - - Approved - Thank You 100 - - -Please retain this copy for your records. - -Cardholder will pay above amount to card -issuer pursuant to cardholder agreement. -========================================= -
- 456 My Street - Apt 1 - Ottawa - ON - K1C2N6 - CA -
-
+ <<~RESPONSE + + + AD1234-56 + + 00 + 47.38 + + ############1111 + 106625152 + + + + ET1700 + 0913 + Fred Burfle + 0 + + + + + + + + + + + + 77 + + + + 1.1.1.10 + + false + true + 00 + Transaction Normal + 100 + Approved + + 000040 + U + M + 3146117 + + USD + + false + Friendly Inc DEMO0983 + 123 King St + Toronto + Ontario + Canada + L7Z 3K8 + + 8938737759041111 + =========== TRANSACTION RECORD ========== + Friendly Inc DEMO0983 + 123 King St + Toronto, ON L7Z 3K8 + Canada + + + TYPE: Purchase + + ACCT: Visa $ 47.38 USD + + CARD NUMBER : ############1111 + DATE/TIME : 28 Sep 12 07:54:48 + REFERENCE # : 000040 M + AUTHOR. # : ET120454 + TRANS. REF. : 77 + + Approved - Thank You 100 + + + Please retain this copy for your records. + + Cardholder will pay above amount to card + issuer pursuant to cardholder agreement. + ========================================= +
+ 456 My Street + Apt 1 + Ottawa + ON + K1C2N6 + CA +
+
RESPONSE end def successful_purchase_response_with_stored_credentials - <<-RESPONSE - - - AD1234-56 - - 00 - 47.38 - - ############1111 - 106625152 - - - - ET1700 - 0913 - Fred Burfle - 0 - - - - - - - - - - - - 77 - - - - 1.1.1.10 - - false - true - 00 - Transaction Normal - 100 - Approved - - 000040 - U - M - 3146117 - - USD - - false - Friendly Inc DEMO0983 - 123 King St - Toronto - Ontario - Canada - L7Z 3K8 - - 8938737759041111 - =========== TRANSACTION RECORD ========== -Friendly Inc DEMO0983 -123 King St -Toronto, ON L7Z 3K8 -Canada - - -TYPE: Purchase - -ACCT: Visa $ 47.38 USD - -CARD NUMBER : ############1111 -DATE/TIME : 28 Sep 12 07:54:48 -REFERENCE # : 000040 M -AUTHOR. # : ET120454 -TRANS. REF. : 77 - - Approved - Thank You 100 - - -Please retain this copy for your records. - -Cardholder will pay above amount to card -issuer pursuant to cardholder agreement. -========================================= -
- 456 My Street - Apt 1 - Ottawa - ON - K1C2N6 - CA -
- - 1 - U - 732602247202501 - -
+ <<~RESPONSE + + + AD1234-56 + + 00 + 47.38 + + ############1111 + 106625152 + + + + ET1700 + 0913 + Fred Burfle + 0 + + + + + + + + + + + + 77 + + + + 1.1.1.10 + + false + true + 00 + Transaction Normal + 100 + Approved + + 000040 + U + M + 3146117 + + USD + + false + Friendly Inc DEMO0983 + 123 King St + Toronto + Ontario + Canada + L7Z 3K8 + + 8938737759041111 + =========== TRANSACTION RECORD ========== + Friendly Inc DEMO0983 + 123 King St + Toronto, ON L7Z 3K8 + Canada + + + TYPE: Purchase + + ACCT: Visa $ 47.38 USD + + CARD NUMBER : ############1111 + DATE/TIME : 28 Sep 12 07:54:48 + REFERENCE # : 000040 M + AUTHOR. # : ET120454 + TRANS. REF. : 77 + + Approved - Thank You 100 + + + Please retain this copy for your records. + + Cardholder will pay above amount to card + issuer pursuant to cardholder agreement. + ========================================= +
+ 456 My Street + Apt 1 + Ottawa + ON + K1C2N6 + CA +
+ + 1 + U + 732602247202501 + +
RESPONSE end def successful_purchase_response_without_transarmor - <<-RESPONSE - - - AD1234-56 - - 00 - 47.38 - - ############1111 - 106625152 - - - - ET1700 - 0913 - Fred Burfle - 0 - - - - - - - - - - - - 77 - - - - 1.1.1.10 - - false - true - 00 - Transaction Normal - 100 - Approved - - 000040 - U - M - 3146117 - - USD - - false - Friendly Inc DEMO0983 - 123 King St - Toronto - Ontario - Canada - L7Z 3K8 - - - =========== TRANSACTION RECORD ========== -Friendly Inc DEMO0983 -123 King St -Toronto, ON L7Z 3K8 -Canada - - -TYPE: Purchase - -ACCT: Visa $ 47.38 USD - -CARD NUMBER : ############1111 -DATE/TIME : 28 Sep 12 07:54:48 -REFERENCE # : 000040 M -AUTHOR. # : ET120454 -TRANS. REF. : 77 - - Approved - Thank You 100 - - -Please retain this copy for your records. - -Cardholder will pay above amount to card -issuer pursuant to cardholder agreement. -========================================= - + <<~RESPONSE + + + AD1234-56 + + 00 + 47.38 + + ############1111 + 106625152 + + + + ET1700 + 0913 + Fred Burfle + 0 + + + + + + + + + + + + 77 + + + + 1.1.1.10 + + false + true + 00 + Transaction Normal + 100 + Approved + + 000040 + U + M + 3146117 + + USD + + false + Friendly Inc DEMO0983 + 123 King St + Toronto + Ontario + Canada + L7Z 3K8 + + + =========== TRANSACTION RECORD ========== + Friendly Inc DEMO0983 + 123 King St + Toronto, ON L7Z 3K8 + Canada + + + TYPE: Purchase + + ACCT: Visa $ 47.38 USD + + CARD NUMBER : ############1111 + DATE/TIME : 28 Sep 12 07:54:48 + REFERENCE # : 000040 M + AUTHOR. # : ET120454 + TRANS. REF. : 77 + + Approved - Thank You 100 + + + Please retain this copy for your records. + + Cardholder will pay above amount to card + issuer pursuant to cardholder agreement. + ========================================= + RESPONSE end def successful_refund_response - <<-RESPONSE - - - AD1234-56 - - 34 - 123 - - ############1111 - 888 - - - - ET112216 - 0913 - Fred Burfle - 0 - - - - - - - - - - - - - - - - 1.1.1.10 - - false - true - 00 - Transaction Normal - 100 - Approved - - 000041 - - I - 9176784 - - USD - - false - Friendly Inc DEMO0983 - 123 King St - Toronto - Ontario - Canada - L7Z 3K8 - - =========== TRANSACTION RECORD ========== -Friendly Inc DEMO0983 -123 King St -Toronto, ON L7Z 3K8 -Canada - - -TYPE: Refund - -ACCT: Visa $ 23.69 USD - -CARD NUMBER : ############1111 -DATE/TIME : 28 Sep 12 08:31:23 -REFERENCE # : 000041 M -AUTHOR. # : ET112216 -TRANS. REF. : - - Approved - Thank You 100 - - -Please retain this copy for your records. - -========================================= - + <<~RESPONSE + + + AD1234-56 + + 34 + 123 + + ############1111 + 888 + + + + ET112216 + 0913 + Fred Burfle + 0 + + + + + + + + + + + + + + + + 1.1.1.10 + + false + true + 00 + Transaction Normal + 100 + Approved + + 000041 + + I + 9176784 + + USD + + false + Friendly Inc DEMO0983 + 123 King St + Toronto + Ontario + Canada + L7Z 3K8 + + =========== TRANSACTION RECORD ========== + Friendly Inc DEMO0983 + 123 King St + Toronto, ON L7Z 3K8 + Canada + + + TYPE: Refund + + ACCT: Visa $ 23.69 USD + + CARD NUMBER : ############1111 + DATE/TIME : 28 Sep 12 08:31:23 + REFERENCE # : 000041 M + AUTHOR. # : ET112216 + TRANS. REF. : + + Approved - Thank You 100 + + + Please retain this copy for your records. + + ========================================= + RESPONSE end def failed_purchase_response - <<-RESPONSE - - - AD1234-56 - - 00 - 5013.0 - - ############1111 - 555555 - - - - - 0911 - Fred Burfle - 0 - - - - - - - - - - - - 77 - - - - 1.1.1.10 - - - 0 - - false - false - 00 - Transaction Normal - 605 - Invalid Expiration Date - - 000033 - - - - - USD - - false - Friendly Inc DEMO0983 - 123 King St - Toronto - Ontario - Canada - L7Z 3K8 - - =========== TRANSACTION RECORD ========== -Friendly Inc DEMO0983 -123 King St -Toronto, ON L7Z 3K8 -Canada - - -TYPE: Purchase -ACCT: Visa $ 5,013.00 USD -CARD NUMBER : ############1111 -DATE/TIME : 25 Sep 12 07:27:00 -REFERENCE # : 000033 M -AUTHOR. # : -TRANS. REF. : 77 -Transaction not approved 605 -Please retain this copy for your records. -========================================= - + <<~RESPONSE + + + AD1234-56 + + 00 + 5013.0 + + ############1111 + 555555 + + + + + 0911 + Fred Burfle + 0 + + + + + + + + + + + + 77 + + + + 1.1.1.10 + + + 0 + + false + false + 00 + Transaction Normal + 605 + Invalid Expiration Date + + 000033 + + + + + USD + + false + Friendly Inc DEMO0983 + 123 King St + Toronto + Ontario + Canada + L7Z 3K8 + + =========== TRANSACTION RECORD ========== + Friendly Inc DEMO0983 + 123 King St + Toronto, ON L7Z 3K8 + Canada + + + TYPE: Purchase + ACCT: Visa $ 5,013.00 USD + CARD NUMBER : ############1111 + DATE/TIME : 25 Sep 12 07:27:00 + REFERENCE # : 000033 M + AUTHOR. # : + TRANS. REF. : 77 + Transaction not approved 605 + Please retain this copy for your records. + ========================================= + RESPONSE end def successful_verify_response - <<-RESPONSE - - - AD2552-05 - - 05 - 0.0 - - ############4242 - 25101911 - - - - ET184931 - 0915 - Longbob Longsen - 0 - - - - - - - - - - - - 1 - - Store Purchase - - 75.182.123.244 - - false - true - 00 - Transaction Normal - 100 - Approved - - 000040 - 1 - M - 7228838 - - USD - - false - FriendlyInc - 123 Main Street - Durham - North Carolina - United States - 27592 - - - Visa - - - - - false - =========== TRANSACTION RECORD ========== -FriendlyInc DEMO0 -123 Main Street -Durham, NC 27592 -United States - - -TYPE: Auth Only - -ACCT: Visa $ 0.00 USD - -CARDHOLDER NAME : Longbob Longsen -CARD NUMBER : ############4242 -DATE/TIME : 04 Jul 14 14:21:52 -REFERENCE # : 000040 M -AUTHOR. # : ET184931 -TRANS. REF. : 1 - - Approved - Thank You 100 - - -Please retain this copy for your records. - -Cardholder will pay above amount to card -issuer pursuant to cardholder agreement. -========================================= - + <<~RESPONSE + + + AD2552-05 + + 05 + 0.0 + + ############4242 + 25101911 + + + + ET184931 + 0915 + Longbob Longsen + 0 + + + + + + + + + + + + 1 + + Store Purchase + + 75.182.123.244 + + false + true + 00 + Transaction Normal + 100 + Approved + + 000040 + 1 + M + 7228838 + + USD + + false + FriendlyInc + 123 Main Street + Durham + North Carolina + United States + 27592 + + + Visa + + + + + false + =========== TRANSACTION RECORD ========== + FriendlyInc DEMO0 + 123 Main Street + Durham, NC 27592 + United States + + + TYPE: Auth Only + + ACCT: Visa $ 0.00 USD + + CARDHOLDER NAME : Longbob Longsen + CARD NUMBER : ############4242 + DATE/TIME : 04 Jul 14 14:21:52 + REFERENCE # : 000040 M + AUTHOR. # : ET184931 + TRANS. REF. : 1 + + Approved - Thank You 100 + + + Please retain this copy for your records. + + Cardholder will pay above amount to card + issuer pursuant to cardholder agreement. + ========================================= + RESPONSE end def no_transaction_response - yamlexcep = <<-RESPONSE ---- !ruby/exception:ActiveMerchant::ResponseError -message: Failed with 400 Bad Request -message: -response: !ruby/object:Net::HTTPBadRequest - body: "Malformed request: Transaction Type is missing." - body_exist: true - code: "400" - header: - connection: - - Close - content-type: - - text/html; charset=utf-8 - server: - - Apache - date: - - Fri, 28 Sep 2012 18:21:37 GMT - content-length: - - "47" - status: - - "400" - cache-control: - - no-cache - http_version: "1.1" - message: Bad Request - read: true - socket: + yamlexcep = <<~RESPONSE + --- !ruby/exception:ActiveMerchant::ResponseError + message: Failed with 400 Bad Request + message: + response: !ruby/object:Net::HTTPBadRequest + body: "Malformed request: Transaction Type is missing." + body_exist: true + code: "400" + header: + connection: + - Close + content-type: + - text/html; charset=utf-8 + server: + - Apache + date: + - Fri, 28 Sep 2012 18:21:37 GMT + content-length: + - "47" + status: + - "400" + cache-control: + - no-cache + http_version: "1.1" + message: Bad Request + read: true + socket: RESPONSE YAML.safe_load(yamlexcep, ['Net::HTTPBadRequest', 'ActiveMerchant::ResponseError']) end def bad_credentials_response - yamlexcep = <<-RESPONSE ---- !ruby/exception:ActiveMerchant::ResponseError -message: -response: !ruby/object:Net::HTTPUnauthorized - code: '401' - message: Authorization Required - body: Unauthorized Request. Bad or missing credentials. - read: true - header: - cache-control: - - no-cache - content-type: - - text/html; charset=utf-8 - date: - - Tue, 30 Dec 2014 23:28:32 GMT - server: - - Apache - status: - - '401' - x-rack-cache: - - invalidate, pass - x-request-id: - - 4157e21cc5620a95ead8d2025b55bdf4 - x-ua-compatible: - - IE=Edge,chrome=1 - content-length: - - '49' - connection: - - Close - body_exist: true - http_version: '1.1' - socket: + yamlexcep = <<~RESPONSE + --- !ruby/exception:ActiveMerchant::ResponseError + message: + response: !ruby/object:Net::HTTPUnauthorized + code: '401' + message: Authorization Required + body: Unauthorized Request. Bad or missing credentials. + read: true + header: + cache-control: + - no-cache + content-type: + - text/html; charset=utf-8 + date: + - Tue, 30 Dec 2014 23:28:32 GMT + server: + - Apache + status: + - '401' + x-rack-cache: + - invalidate, pass + x-request-id: + - 4157e21cc5620a95ead8d2025b55bdf4 + x-ua-compatible: + - IE=Edge,chrome=1 + content-length: + - '49' + connection: + - Close + body_exist: true + http_version: '1.1' + socket: RESPONSE YAML.safe_load(yamlexcep, ['Net::HTTPUnauthorized', 'ActiveMerchant::ResponseError']) end def successful_void_response - <<-RESPONSE - - - AD1234-56 - - 33 - 11.45 - - ############1111 - 987123 - - - - ET112112 - 0913 - Fred Burfle - 0 - - - - - - - - - - - - - - - - 1.1.1.10 - - - 0 - - false - true - 00 - Transaction Normal - 100 - Approved - - 000166 - - I - 2046743 - - USD - - false - FreshBooks DEMO0785 - 35 Golden Ave - Toronto - Ontario - Canada - M6R 2J5 - -=========== TRANSACTION RECORD ========== -FreshBooks DEMO0785 -35 Golden Ave -Toronto, ON M6R 2J5 -Canada - - -TYPE: Void - -ACCT: Visa $ 47.38 USD - -CARD NUMBER : ############1111 -DATE/TIME : 15 Nov 12 08:20:36 -REFERENCE # : 000166 M -AUTHOR. # : ET112112 -TRANS. REF. : - -Approved - Thank You 100 - - -Please retain this copy for your records. - -Cardholder will pay above amount to card -issuer pursuant to cardholder agreement. -========================================= - + <<~RESPONSE + + + AD1234-56 + + 33 + 11.45 + + ############1111 + 987123 + + + + ET112112 + 0913 + Fred Burfle + 0 + + + + + + + + + + + + + + + + 1.1.1.10 + + + 0 + + false + true + 00 + Transaction Normal + 100 + Approved + + 000166 + + I + 2046743 + + USD + + false + FreshBooks DEMO0785 + 35 Golden Ave + Toronto + Ontario + Canada + M6R 2J5 + + =========== TRANSACTION RECORD ========== + FreshBooks DEMO0785 + 35 Golden Ave + Toronto, ON M6R 2J5 + Canada + + + TYPE: Void + + ACCT: Visa $ 47.38 USD + + CARD NUMBER : ############1111 + DATE/TIME : 15 Nov 12 08:20:36 + REFERENCE # : 000166 M + AUTHOR. # : ET112112 + TRANS. REF. : + + Approved - Thank You 100 + + + Please retain this copy for your records. + + Cardholder will pay above amount to card + issuer pursuant to cardholder agreement. + ========================================= + RESPONSE end end diff --git a/test/unit/gateways/flo2cash_simple_test.rb b/test/unit/gateways/flo2cash_simple_test.rb index 627f6782e29..d6d2b580d6c 100644 --- a/test/unit/gateways/flo2cash_simple_test.rb +++ b/test/unit/gateways/flo2cash_simple_test.rb @@ -7,9 +7,9 @@ def setup Base.mode = :test @gateway = Flo2cashSimpleGateway.new( - :username => 'username', - :password => 'password', - :account_id => 'account_id' + username: 'username', + password: 'password', + account_id: 'account_id' ) @credit_card = credit_card @@ -19,7 +19,7 @@ def setup def test_successful_purchase response = stub_comms do @gateway.purchase(@amount, @credit_card, order_id: 'boom') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{boom}, data) end.respond_with(successful_purchase_response) @@ -50,7 +50,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(/P150200005007600/, data) end.respond_with(successful_refund_response) @@ -67,7 +67,7 @@ def test_empty_response_fails end def test_transcript_scrubbing - transcript = @gateway.scrub(successful_purchase_response) + transcript = @gateway.scrub(successful_purchase_response) assert_scrubbed(@credit_card.number, transcript) assert_scrubbed(@credit_card.verification_value, transcript) diff --git a/test/unit/gateways/flo2cash_test.rb b/test/unit/gateways/flo2cash_test.rb index 4564114db64..664a329739c 100644 --- a/test/unit/gateways/flo2cash_test.rb +++ b/test/unit/gateways/flo2cash_test.rb @@ -7,9 +7,9 @@ def setup Base.mode = :test @gateway = Flo2cashGateway.new( - :username => 'username', - :password => 'password', - :account_id => 'account_id' + username: 'username', + password: 'password', + account_id: 'account_id' ) @credit_card = credit_card @@ -19,7 +19,7 @@ def setup def test_successful_purchase response = stub_comms do @gateway.purchase(@amount, @credit_card, order_id: 'boom') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{boom}, data) end.respond_with(successful_authorize_response, successful_capture_response) @@ -50,7 +50,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(/P150100005006789/, data) end.respond_with(successful_capture_response) @@ -78,7 +78,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(/P150100005006789/, data) end.respond_with(successful_refund_response) @@ -95,7 +95,7 @@ def test_empty_response_fails end def test_transcript_scrubbing - transcript = @gateway.scrub(successful_authorize_response) + transcript = @gateway.scrub(successful_authorize_response) assert_scrubbed(@credit_card.number, transcript) assert_scrubbed(@credit_card.verification_value, transcript) diff --git a/test/unit/gateways/forte_test.rb b/test/unit/gateways/forte_test.rb index c7ca564cc65..2d3254244db 100644 --- a/test/unit/gateways/forte_test.rb +++ b/test/unit/gateways/forte_test.rb @@ -28,7 +28,7 @@ def test_successful_purchase def test_purchase_passes_options options = { order_id: '1' } - @gateway.expects(:commit).with(anything, has_entries(:order_number => '1')) + @gateway.expects(:commit).with(anything, has_entries(order_number: '1')) stub_comms(@gateway, :raw_ssl_request) do @gateway.purchase(@amount, @credit_card, options) @@ -61,6 +61,26 @@ def test_failed_purchase_with_echeck assert_equal 'INVALID CREDIT CARD NUMBER', response.message end + def test_successful_purchase_with_service_fee + response = stub_comms(@gateway, :raw_ssl_request) do + @gateway.purchase(@amount, @credit_card, @options) + end.respond_with(MockedResponse.new(successful_purchase_with_service_fee_response)) + assert_success response + + assert_equal '.5', response.params['service_fee_amount'] + assert response.test? + end + + def test_successful_purchase_with_xdata + response = stub_comms(@gateway, :raw_ssl_request) do + @gateway.purchase(@amount, @credit_card, @options) + end.respond_with(MockedResponse.new(successful_purchase_with_xdata_response)) + + assert_success response + (1..9).each { |n| assert_equal 'some customer metadata', response.params['xdata']["xdata_#{n}"] } + assert response.test? + end + def test_successful_authorize response = stub_comms(@gateway, :raw_ssl_request) do @gateway.authorize(@amount, @credit_card, @options) @@ -157,7 +177,7 @@ def test_handles_improper_padding @gateway = ForteGateway.new(location_id: ' improperly-padded ', account_id: ' account_id ', api_key: 'api_key', secret: 'secret') response = stub_comms(@gateway, :raw_ssl_request) do @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |type, url, parameters, headers| + end.check_request do |_type, url, _parameters, _headers| URI.parse(url) end.respond_with(MockedResponse.new(successful_purchase_response)) assert_success response @@ -171,7 +191,7 @@ def test_scrub private class MockedResponse - attr :code, :body + attr_reader :code, :body def initialize(body, code = 200) @code = code @body = body @@ -351,6 +371,97 @@ def failed_echeck_purchase_response ' end + def successful_purchase_with_service_fee_response + ' + { + "transaction_id":"trn_bb7687a7-3d3a-40c2-8fa9-90727a814249", + "account_id":"act_300111", + "location_id":"loc_176008", + "action":"sale", + "authorization_amount": 1.0, + "service_fee_amount": ".5", + "subtotal_amount": ".5", + "authorization_code":"123456", + "billing_address":{ + "first_name":"Jim", + "last_name":"Smith" + }, + "card": { + "name_on_card":"Longbob Longsen", + "masked_account_number":"****2224", + "expire_month":9, + "expire_year":2016, + "card_verification_value":"***", + "card_type":"visa" + }, + "response": { + "authorization_code":"123456", + "avs_result":"Y", + "cvv_code":"M", + "environment":"sandbox", + "response_type":"A", + "response_code":"A01", + "response_desc":"TEST APPROVAL" + }, + "links": { + "self":"https://sandbox.forte.net/API/v2/transactions/trn_bb7687a7-3d3a-40c2-8fa9-90727a814249", + "settlements":"https://sandbox.forte.net/API/v2/transactions/trn_bb7687a7-3d3a-40c2-8fa9-90727a814249/settlements" + } + } + ' + end + + def successful_purchase_with_xdata_response + ' + { + "transaction_id":"trn_bb7687a7-3d3a-40c2-8fa9-90727a814249", + "account_id":"act_300111", + "location_id":"loc_176008", + "action":"sale", + "authorization_amount": 1.0, + "service_fee_amount": ".5", + "subtotal_amount": ".5", + "authorization_code":"123456", + "billing_address":{ + "first_name":"Jim", + "last_name":"Smith" + }, + "xdata": { + "xdata_1": "some customer metadata", + "xdata_2": "some customer metadata", + "xdata_3": "some customer metadata", + "xdata_4": "some customer metadata", + "xdata_5": "some customer metadata", + "xdata_6": "some customer metadata", + "xdata_7": "some customer metadata", + "xdata_8": "some customer metadata", + "xdata_9": "some customer metadata" + }, + "card": { + "name_on_card":"Longbob Longsen", + "masked_account_number":"****2224", + "expire_month":9, + "expire_year":2016, + "card_verification_value":"***", + "card_type":"visa" + }, + "response": { + "authorization_code":"123456", + "avs_result":"Y", + "cvv_code":"M", + "environment":"sandbox", + "response_type":"A", + "response_code":"A01", + "response_desc":"TEST APPROVAL" + }, + "links": { + "self":"https://sandbox.forte.net/API/v2/transactions/trn_bb7687a7-3d3a-40c2-8fa9-90727a814249", + "settlements":"https://sandbox.forte.net/API/v2/transactions/trn_bb7687a7-3d3a-40c2-8fa9-90727a814249/settlements" + } + } + ' + end + def successful_authorize_response ' { diff --git a/test/unit/gateways/garanti_test.rb b/test/unit/gateways/garanti_test.rb index 8902737312b..cc3416e0f89 100644 --- a/test/unit/gateways/garanti_test.rb +++ b/test/unit/gateways/garanti_test.rb @@ -7,15 +7,15 @@ def setup @original_kcode = nil Base.mode = :test - @gateway = GarantiGateway.new(:login => 'a', :password => 'b', :terminal_id => 'c', :merchant_id => 'd') + @gateway = GarantiGateway.new(login: 'a', password: 'b', terminal_id: 'c', merchant_id: 'd') @credit_card = credit_card(4242424242424242) @amount = 1000 # 1000 cents, 10$ @options = { - :order_id => 'db4af18c5222503d845180350fbda516', - :billing_address => address, - :description => 'Store Purchase' + order_id: 'db4af18c5222503d845180350fbda516', + billing_address: address, + description: 'Store Purchase' } end @@ -58,11 +58,11 @@ def test_nil_normalization end def test_strip_invalid_xml_chars - xml = < Parse the First & but not this ˜ &x002a; -EOF +XML parsed_xml = @gateway.send(:strip_invalid_xml_chars, xml) assert REXML::Document.new(parsed_xml) @@ -75,71 +75,71 @@ def test_strip_invalid_xml_chars # Place raw successful response from gateway here def successful_purchase_response - <<-EOF - - - - db4af18c5222503d845180350fbda516 - - - - - HOST - 00 - 00 - Approved - - - - 035208609374 - 784260 - 000089 - 000008 - 20101218 08:56:39 - - Company Name & Another Name - - - - - - - - EOF + <<~XML + + + + db4af18c5222503d845180350fbda516 + + + + + HOST + 00 + 00 + Approved + + + + 035208609374 + 784260 + 000089 + 000008 + 20101218 08:56:39 + + Company Name & Another Name + + + + + + + + XML end # Place raw failed response from gateway here def failed_purchase_response - <<-EOF - - - - db4af18c5222503d845180350fbda516 - - - - - GVPS - 92 - 0651 - Declined - - ErrorId: 0651 - - - - - - 20101220 01:58:41 - - - - - - - - - - EOF + <<~XML + + + + db4af18c5222503d845180350fbda516 + + + + + GVPS + 92 + 0651 + Declined + + ErrorId: 0651 + + + + + + 20101220 01:58:41 + + + + + + + + + + XML end end diff --git a/test/unit/gateways/gateway_test.rb b/test/unit/gateways/gateway_test.rb index 1be0dd4931c..68d6d0a441e 100644 --- a/test/unit/gateways/gateway_test.rb +++ b/test/unit/gateways/gateway_test.rb @@ -10,11 +10,11 @@ def teardown end def test_should_detect_if_a_card_is_supported - Gateway.supported_cardtypes = [:visa, :bogus] - assert([:visa, :bogus].all? { |supported_cardtype| Gateway.supports?(supported_cardtype) }) + Gateway.supported_cardtypes = %i[visa bogus] + assert(%i[visa bogus].all? { |supported_cardtype| Gateway.supports?(supported_cardtype) }) Gateway.supported_cardtypes = [] - assert_false([:visa, :bogus].all? { |invalid_cardtype| Gateway.supports?(invalid_cardtype) }) + assert_false(%i[visa bogus].all? { |invalid_cardtype| Gateway.supports?(invalid_cardtype) }) end def test_should_validate_supported_countries @@ -54,12 +54,12 @@ def test_amount_style end def test_card_brand - credit_card = stub(:brand => 'visa') + credit_card = stub(brand: 'visa') assert_equal 'visa', Gateway.card_brand(credit_card) end def test_card_brand_using_type - credit_card = stub(:type => 'String') + credit_card = stub(type: 'String') assert_equal 'string', Gateway.card_brand(credit_card) end @@ -103,7 +103,7 @@ def test_localized_amount_returns_three_decimal_places_for_three_decimal_currenc end def test_split_names - assert_equal ['Longbob', 'Longsen'], @gateway.send(:split_names, 'Longbob Longsen') + assert_equal %w[Longbob Longsen], @gateway.send(:split_names, 'Longbob Longsen') end def test_split_names_with_single_name @@ -131,11 +131,11 @@ def test_should_not_allow_scrubbing_if_unsupported end def test_strip_invalid_xml_chars - xml = < Parse the First & but not this ˜ &x002a; -EOF + XML parsed_xml = @gateway.send(:strip_invalid_xml_chars, xml) assert REXML::Document.new(parsed_xml) @@ -147,7 +147,7 @@ def test_strip_invalid_xml_chars def test_add_field_to_post_if_present order_id = 'abc123' - post = { } + post = {} options = { order_id: order_id, do_not_add: 24 } @gateway.add_field_to_post_if_present(post, options, :order_id) @@ -160,10 +160,10 @@ def test_add_fields_to_post_if_present order_id = 'abc123' transaction_number = 500 - post = { } + post = {} options = { order_id: order_id, transaction_number: transaction_number, do_not_add: 24 } - @gateway.add_fields_to_post_if_present(post, options, [:order_id, :transaction_number]) + @gateway.add_fields_to_post_if_present(post, options, %i[order_id transaction_number]) assert_equal post[:order_id], order_id assert_equal post[:transaction_number], transaction_number diff --git a/test/unit/gateways/global_collect_test.rb b/test/unit/gateways/global_collect_test.rb index fd1d5bff1fc..f8ad5b486c0 100644 --- a/test/unit/gateways/global_collect_test.rb +++ b/test/unit/gateways/global_collect_test.rb @@ -16,6 +16,18 @@ def setup billing_address: address, description: 'Store Purchase' } + @options_3ds2 = @options.merge( + three_d_secure: { + version: '2.1.0', + eci: '05', + cavv: 'jJ81HADVRtXfCBATEp01CJUAAAA=', + xid: 'BwABBJQ1AgAAAAAgJDUCAAAAAAA=', + ds_transaction_id: '97267598-FAE6-48F2-8083-C23433990FBC', + acs_transaction_id: '13c701a3-5a88-4c45-89e9-ef65e50a8bf9', + cavv_algorithm: 1, + authentication_response_status: 'Y' + } + ) end def test_successful_authorize_and_capture @@ -28,13 +40,71 @@ def test_successful_authorize_and_capture capture = stub_comms do @gateway.capture(@accepted_amount, response.authorization) - end.check_request do |endpoint, data, headers| + end.check_request do |endpoint, _data, _headers| assert_match(/000000142800000000920000100001/, endpoint) end.respond_with(successful_capture_response) assert_success capture end + # When requires_approval is true (or not present), + # a `purchase` makes two calls (`auth` and `capture`). + def test_successful_purchase_with_requires_approval_true + stub_comms do + @gateway.purchase(@accepted_amount, @credit_card, @options.merge(requires_approval: true)) + end.check_request do |endpoint, data, headers| + end.respond_with(successful_authorize_response, successful_capture_response) + end + + # When requires_approval is false, a `purchase` makes one call (`auth`). + def test_successful_purchase_with_requires_approval_false + stub_comms do + @gateway.purchase(@accepted_amount, @credit_card, @options.merge(requires_approval: false)) + end.check_request do |_endpoint, data, _headers| + assert_equal false, JSON.parse(data)['cardPaymentMethodSpecificInput']['requiresApproval'] + end.respond_with(successful_authorize_response) + end + + def test_successful_purchase_airline_fields + options = @options.merge( + airline_data: { + code: 111, + name: 'Spreedly Airlines', + flight_date: '20190810', + passenger_name: 'Randi Smith', + flight_legs: [ + { arrival_airport: 'BDL', + origin_airport: 'RDU', + date: '20190810', + carrier_code: 'SA', + number: 596, + airline_class: 'ZZ' }, + { arrival_airport: 'RDU', + origin_airport: 'BDL', + date: '20190817', + carrier_code: 'SA', + number: 597, + airline_class: 'ZZ' } + ] + } + ) + stub_comms do + @gateway.purchase(@accepted_amount, @credit_card, options) + end.check_request do |_endpoint, data, _headers| + assert_equal 111, JSON.parse(data)['order']['additionalInput']['airlineData']['code'] + assert_equal '20190810', JSON.parse(data)['order']['additionalInput']['airlineData']['flightDate'] + assert_equal 2, JSON.parse(data)['order']['additionalInput']['airlineData']['flightLegs'].length + end.respond_with(successful_authorize_response, successful_capture_response) + end + + def test_purchase_passes_installments + stub_comms do + @gateway.purchase(@accepted_amount, @credit_card, @options.merge(number_of_installments: '3')) + end.check_request do |_endpoint, data, _headers| + assert_match(/"numberOfInstallments\":\"3\"/, data) + end.respond_with(successful_authorize_response, successful_capture_response) + end + def test_purchase_does_not_run_capture_if_authorize_auto_captured response = stub_comms do @gateway.purchase(@accepted_amount, @credit_card, @options) @@ -48,7 +118,7 @@ def test_purchase_does_not_run_capture_if_authorize_auto_captured def test_authorize_with_pre_authorization_flag response = stub_comms do @gateway.authorize(@accepted_amount, @credit_card, @options.merge(pre_authorization: true)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/PRE_AUTHORIZATION/, data) end.respond_with(successful_authorize_response) @@ -58,7 +128,7 @@ def test_authorize_with_pre_authorization_flag def test_authorize_without_pre_authorization_flag response = stub_comms do @gateway.authorize(@accepted_amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/FINAL_AUTHORIZATION/, data) end.respond_with(successful_authorize_response) @@ -82,7 +152,7 @@ def test_successful_authorization_with_extra_options response = stub_comms do @gateway.authorize(@accepted_amount, @credit_card, options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match %r("fraudFields":{"website":"www.example.com","giftMessage":"Happy Day!","customerIpAddress":"127.0.0.1"}), data assert_match %r("merchantReference":"123"), data assert_match %r("customer":{"personalInformation":{"name":{"firstName":"Longbob","surname":"Longsen"}},"merchantCustomerId":"123987","contactDetails":{"emailAddress":"example@example.com","phoneNumber":"\(555\)555-5555"},"billingAddress":{"street":"456 My Street","additionalInfo":"Apt 1","zip":"K1C2N6","city":"Ottawa","state":"ON","countryCode":"CA"}}}), data @@ -91,12 +161,48 @@ def test_successful_authorization_with_extra_options assert_success response end - def test_trucates_first_name_to_15_chars + def test_successful_authorize_with_3ds_auth + response = stub_comms do + @gateway.authorize(@accepted_amount, @credit_card, @options_3ds2) + end.check_request do |_endpoint, data, _headers| + assert_match(/"threeDSecure\":{\"externalCardholderAuthenticationData\":{/, data) + assert_match(/"eci\":\"05\"/, data) + assert_match(/"cavv\":\"jJ81HADVRtXfCBATEp01CJUAAAA=\"/, data) + assert_match(/"xid\":\"BwABBJQ1AgAAAAAgJDUCAAAAAAA=\"/, data) + assert_match(/"threeDSecureVersion\":\"2.1.0\"/, data) + assert_match(/"directoryServerTransactionId\":\"97267598-FAE6-48F2-8083-C23433990FBC\"/, data) + assert_match(/"acsTransactionId\":\"13c701a3-5a88-4c45-89e9-ef65e50a8bf9\"/, data) + assert_match(/"cavvAlgorithm\":1/, data) + assert_match(/"validationResult\":\"Y\"/, data) + end.respond_with(successful_authorize_with_3ds2_data_response) + + assert_success response + end + + def test_does_not_send_3ds_auth_when_empty + response = stub_comms do + @gateway.authorize(@accepted_amount, @credit_card, @options) + end.check_request do |_endpoint, data, _headers| + assert_not_match(/threeDSecure/, data) + assert_not_match(/externalCardholderAuthenticationData/, data) + assert_not_match(/cavv/, data) + assert_not_match(/xid/, data) + assert_not_match(/threeDSecureVersion/, data) + assert_not_match(/directoryServerTransactionId/, data) + assert_not_match(/acsTransactionId/, data) + assert_not_match(/cavvAlgorithm/, data) + assert_not_match(/validationResult/, data) + end.respond_with(successful_authorize_response) + + assert_success response + end + + def test_truncates_first_name_to_15_chars credit_card = credit_card('4567350000427977', { first_name: 'thisisaverylongfirstname' }) response = stub_comms do @gateway.authorize(@accepted_amount, credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/thisisaverylong/, data) end.respond_with(successful_authorize_response) @@ -105,7 +211,7 @@ def test_trucates_first_name_to_15_chars end def test_handles_blank_names - credit_card = credit_card('4567350000427977', { first_name: nil, last_name: nil}) + credit_card = credit_card('4567350000427977', { first_name: nil, last_name: nil }) response = stub_comms do @gateway.authorize(@accepted_amount, credit_card, @options) @@ -114,6 +220,24 @@ def test_handles_blank_names assert_success response end + def test_truncates_address_fields + response = stub_comms do + @gateway.purchase(@accepted_amount, @credit_card, { + billing_address: { + address1: '1234 Supercalifragilisticexpialidociousthiscantbemorethanfiftycharacters', + address2: 'Unit 6', + city: '‎Portland', + state: 'ME', + zip: '09901', + country: 'US' + } + }) + end.check_request do |_endpoint, data, _headers| + refute_match(/Supercalifragilisticexpialidociousthiscantbemorethanfiftycharacters/, data) + end.respond_with(successful_capture_response) + assert_success response + end + def test_failed_authorize response = stub_comms do @gateway.authorize(@rejected_amount, @declined_card, @options) @@ -141,7 +265,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(/000000142800000000920000100001/, endpoint) end.respond_with(successful_void_response) @@ -151,7 +275,7 @@ def test_successful_void 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/, endpoint) end.respond_with(failed_void_response) @@ -189,7 +313,7 @@ def test_successful_refund refund = stub_comms do @gateway.refund(@accepted_amount, capture.authorization) - end.check_request do |endpoint, data, headers| + end.check_request do |endpoint, _data, _headers| assert_match(/000000142800000000920000100001/, endpoint) end.respond_with(successful_refund_response) @@ -198,8 +322,8 @@ def test_successful_refund def test_refund_passes_currency_code stub_comms do - @gateway.refund(@accepted_amount, '000000142800000000920000100001', {currency: 'COP'}) - end.check_request do |endpoint, data, headers| + @gateway.refund(@accepted_amount, '000000142800000000920000100001', { currency: 'COP' }) + end.check_request do |_endpoint, data, _headers| assert_match(/"currencyCode\":\"COP\"/, data) end.respond_with(failed_refund_response) end @@ -359,7 +483,11 @@ def post_scrubbed end def successful_authorize_response - %({\n \"creationOutput\" : {\n \"additionalReference\" : \"00000014280000000092\",\n \"externalReference\" : \"000000142800000000920000100001\"\n },\n \"payment\" : {\n \"id\" : \"000000142800000000920000100001\",\n \"paymentOutput\" : {\n \"amountOfMoney\" : {\n \"amount\" : 100,\n \"currencyCode\" : \"USD\"\n },\n \"references\" : {\n \"paymentReference\" : \"0\"\n },\n \"paymentMethod\" : \"card\",\n \"cardPaymentMethodSpecificOutput\" : {\n \"paymentProductId\" : 1,\n \"authorisationCode\" : \"OK1131\",\n \"card\" : {\n \"cardNumber\" : \"************7977\",\n \"expiryDate\" : \"0917\"\n },\n \"fraudResults\" : {\n \"fraudServiceResult\" : \"no-advice\",\n \"avsResult\" : \"0\",\n \"cvvResult\" : \"0\"\n }\n }\n },\n \"status\" : \"PENDING_APPROVAL\",\n \"statusOutput\" : {\n \"isCancellable\" : true,\n \"statusCode\" : 600,\n \"statusCodeChangeDateTime\" : \"20160316205952\",\n \"isAuthorized\" : true\n }\n }\n}) + "{\n \"creationOutput\" : {\n \"additionalReference\" : \"00000014280000000092\",\n \"externalReference\" : \"000000142800000000920000100001\"\n },\n \"payment\" : {\n \"id\" : \"000000142800000000920000100001\",\n \"paymentOutput\" : {\n \"amountOfMoney\" : {\n \"amount\" : 4005,\n \"currencyCode\" : \"USD\"\n },\n \"references\" : {\n \"paymentReference\" : \"0\"\n },\n \"paymentMethod\" : \"card\",\n \"cardPaymentMethodSpecificOutput\" : {\n \"paymentProductId\" : 1,\n \"authorisationCode\" : \"OK1131\",\n \"fraudResults\" : {\n \"fraudServiceResult\" : \"no-advice\",\n \"avsResult\" : \"0\",\n \"cvvResult\" : \"0\"\n },\n \"card\" : {\n \"cardNumber\" : \"************7977\",\n \"expiryDate\" : \"0920\"\n }\n }\n },\n \"status\" : \"PENDING_APPROVAL\",\n \"statusOutput\" : {\n \"isCancellable\" : true,\n \"statusCategory\" : \"PENDING_MERCHANT\",\n \"statusCode\" : 600,\n \"statusCodeChangeDateTime\" : \"20191203162910\",\n \"isAuthorized\" : true,\n \"isRefundable\" : false\n }\n }\n}" + end + + def successful_authorize_with_3ds2_data_response + %({\"creationOutput\":{\"additionalReference\":\"00000021960000002279\",\"externalReference\":\"000000219600000022790000100001\"},\"payment\":{\"id\":\"000000219600000022790000100001\",\"paymentOutput\":{\"amountOfMoney\":{\"amount\":100,\"currencyCode\":\"USD\"},\"references\":{\"paymentReference\":\"0\"},\"paymentMethod\":\"card\",\"cardPaymentMethodSpecificOutput\":{\"paymentProductId\":1,\"authorisationCode\":\"OK1131\",\"fraudResults\":{\"fraudServiceResult\":\"no-advice\",\"avsResult\":\"0\",\"cvvResult\":\"0\"},\"threeDSecureResults\":{\"cavv\":\"jJ81HADVRtXfCBATEp01CJUAAAA=\",\"directoryServerTransactionId\":\"97267598-FAE6-48F2-8083-C23433990FBC\",\"eci\":\"5\",\"threeDSecureVersion\":\"2.1.0\"},\"card\":{\"cardNumber\":\"************7977\",\"expiryDate\":\"0921\"}}},\"status\":\"PENDING_APPROVAL\",\"statusOutput\":{\"isCancellable\":true,\"statusCategory\":\"PENDING_MERCHANT\",\"statusCode\":600,\"statusCodeChangeDateTime\":\"20201029212921\",\"isAuthorized\":true,\"isRefundable\":false}}}) end def failed_authorize_response @@ -367,7 +495,7 @@ def failed_authorize_response end def successful_capture_response - %({\n \"payment\" : {\n \"id\" : \"000000142800000000920000100001\",\n \"paymentOutput\" : {\n \"amountOfMoney\" : {\n \"amount\" : 100,\n \"currencyCode\" : \"USD\"\n },\n \"references\" : {\n \"paymentReference\" : \"0\"\n },\n \"paymentMethod\" : \"card\",\n \"cardPaymentMethodSpecificOutput\" : {\n \"paymentProductId\" : 1,\n \"authorisationCode\" : \"OK1131\",\n \"card\" : {\n \"cardNumber\" : \"************7977\",\n \"expiryDate\" : \"0917\"\n },\n \"fraudResults\" : {\n \"fraudServiceResult\" : \"no-advice\",\n \"avsResult\" : \"0\",\n \"cvvResult\" : \"0\"\n }\n }\n },\n \"status\" : \"CAPTURE_REQUESTED\",\n \"statusOutput\" : {\n \"isCancellable\" : true,\n \"statusCode\" : 800,\n \"statusCodeChangeDateTime\" : \"20160317191047\",\n \"isAuthorized\" : true\n }\n }\n}) + "{\n \"payment\" : {\n \"id\" : \"000000142800000000920000100001\",\n \"paymentOutput\" : {\n \"amountOfMoney\" : {\n \"amount\" : 4005,\n \"currencyCode\" : \"USD\"\n },\n \"references\" : {\n \"paymentReference\" : \"0\"\n },\n \"paymentMethod\" : \"card\",\n \"cardPaymentMethodSpecificOutput\" : {\n \"paymentProductId\" : 1,\n \"authorisationCode\" : \"OK1131\",\n \"fraudResults\" : {\n \"fraudServiceResult\" : \"no-advice\",\n \"avsResult\" : \"0\",\n \"cvvResult\" : \"0\"\n },\n \"card\" : {\n \"cardNumber\" : \"************7977\",\n \"expiryDate\" : \"0920\"\n }\n }\n },\n \"status\" : \"CAPTURE_REQUESTED\",\n \"statusOutput\" : {\n \"isCancellable\" : true,\n \"statusCategory\" : \"PENDING_CONNECT_OR_3RD_PARTY\",\n \"statusCode\" : 800,\n \"statusCodeChangeDateTime\" : \"20191203163030\",\n \"isAuthorized\" : true,\n \"isRefundable\" : false\n }\n }\n}" end def failed_capture_response diff --git a/test/unit/gateways/global_transport_test.rb b/test/unit/gateways/global_transport_test.rb index 560c8033025..637ace0ed49 100644 --- a/test/unit/gateways/global_transport_test.rb +++ b/test/unit/gateways/global_transport_test.rb @@ -9,7 +9,7 @@ def setup @options = { order_id: '1', - billing_address: address, + billing_address: address } end @@ -52,7 +52,7 @@ def test_successful_authorize_and_capture capture = stub_comms do @gateway.capture(100, response.authorization) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/PNRef=3648890/, data) end.respond_with(successful_capture_response) @@ -70,7 +70,7 @@ def test_successful_partial_authorize_and_capture capture = stub_comms do @gateway.capture(150, response.authorization) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/PNRef=8869269/, data) end.respond_with(successful_partial_capture_response) @@ -103,7 +103,7 @@ def test_successful_refund refund = stub_comms do @gateway.refund(100, response.authorization) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/PNRef=3648838/, data) end.respond_with(successful_refund_response) @@ -127,7 +127,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(/PNRef=3648838/, data) end.respond_with(successful_void_response) @@ -162,7 +162,7 @@ def test_failed_verify def test_truncation stub_comms do @gateway.purchase(100, credit_card, order_id: 'a' * 17) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/&InvNum=a{16}&/, data) end.respond_with(successful_purchase_response) end diff --git a/test/unit/gateways/hdfc_test.rb b/test/unit/gateways/hdfc_test.rb index 9913adedf19..935c0adf433 100644 --- a/test/unit/gateways/hdfc_test.rb +++ b/test/unit/gateways/hdfc_test.rb @@ -7,8 +7,8 @@ def setup Base.mode = :test @gateway = HdfcGateway.new( - :login => 'login', - :password => 'password' + login: 'login', + password: 'password' ) @credit_card = credit_card @@ -47,7 +47,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(/2441955352022771/, data) end.respond_with(successful_capture_response) @@ -64,7 +64,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(/849768440022761/, data) end.respond_with(successful_refund_response) @@ -74,45 +74,45 @@ def test_refund 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_currency stub_comms do - @gateway.purchase(@amount, @credit_card, :currency => 'INR') - end.check_request do |endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, currency: 'INR') + end.check_request do |_endpoint, data, _headers| assert_match(/currencycode>356 'AOA') + @gateway.purchase(@amount, @credit_card, currency: 'AOA') end end def test_passing_order_id stub_comms do - @gateway.purchase(@amount, @credit_card, :order_id => '932823723') - end.check_request do |endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, order_id: '932823723') + end.check_request do |_endpoint, data, _headers| assert_match(/932823723/, data) end.respond_with(successful_purchase_response) end def test_passing_description stub_comms do - @gateway.purchase(@amount, @credit_card, :description => 'Awesome Services By Us') - end.check_request do |endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, description: 'Awesome Services By Us') + end.check_request do |_endpoint, data, _headers| assert_match(/Awesome Services By Us/, data) end.respond_with(successful_purchase_response) end def test_escaping stub_comms do - @gateway.purchase(@amount, @credit_card, :order_id => 'a' * 41, :description => "This has 'Hack Characters' ~`!\#$%^=+|\\:'\",;<>{}[]() and non-Hack Characters -_@.") - end.check_request do |endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, order_id: 'a' * 41, description: "This has 'Hack Characters' ~`!\#$%^=+|\\:'\",;<>{}[]() and non-Hack Characters -_@.") + end.check_request do |_endpoint, data, _headers| assert_match(/>This has Hack Characters and non-Hack Characters -_@.#{"a" * 40} 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(/udf4>Jim Smith\nWidgets Inc\n456 My Street\nApt 1\nOttawa ON K1C2N6\nCA/, data) end.respond_with(successful_purchase_response) end def test_passing_phone_number 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(/udf3>555555-5555 address(:phone => nil)) - end.check_request do |endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, billing_address: address(phone: nil)) + end.check_request do |_endpoint, data, _headers| assert_no_match(/udf3/, data) end.respond_with(successful_purchase_response) end def test_passing_eci stub_comms do - @gateway.purchase(@amount, @credit_card, :eci => 22) - end.check_request do |endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, eci: 22) + end.check_request do |_endpoint, data, _headers| assert_match(/eci>22 '12'}) + @gateway = HpsGateway.new({ secret_api_key: '12' }) @credit_card = credit_card @amount = 100 + @check = check(account_number: '1357902468', routing_number: '122000030', number: '1234', account_type: 'SAVINGS') + @check_amount = 2000 @options = { order_id: '1', @@ -36,6 +38,40 @@ def test_successful_purchase_no_address assert_success response end + def test_successful_check_purchase + response = stub_comms(@gateway, :ssl_request) do + @gateway.purchase(@check_amount, @check, @options) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(/SALE<\/hps:CheckAction>/, data) + end.respond_with(successful_check_purchase_response) + + assert_success response + end + + def test_check_purchase_does_not_raise_no_method_error_when_account_type_missing + check = @check.dup + check.account_type = nil + response = stub_comms(@gateway, :ssl_request) do + @gateway.purchase(@check_amount, check, @options) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(/SALE<\/hps:CheckAction>/, data) + end.respond_with(successful_check_purchase_response) + + assert_success response + end + + def test_check_purchase_does_not_raise_no_method_error_when_account_holder_type_missing + check = @check.dup + check.account_holder_type = nil + response = stub_comms(@gateway, :ssl_request) do + @gateway.purchase(@check_amount, check, @options) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(/SALE<\/hps:CheckAction>/, data) + end.respond_with(successful_check_purchase_response) + + assert_success response + end + def test_failed_purchase @gateway.expects(:ssl_post).returns(failed_charge_response) @@ -106,6 +142,20 @@ def test_failed_refund assert_failure refund end + def test_successful_credit + @gateway.expects(:ssl_post).returns(successful_refund_response) + + credit = @gateway.credit(@amount, @credit_card) + assert_success credit + end + + def test_failed_credit + @gateway.expects(:ssl_post).returns(failed_refund_response) + + credit = @gateway.refund(@amount, @credit_card) + assert_failure credit + end + def test_successful_void @gateway.expects(:ssl_post).returns(successful_void_response) @@ -114,6 +164,16 @@ def test_successful_void assert_success void end + def test_successful_check_void + void = stub_comms(@gateway, :ssl_request) do + @gateway.void('169054', check_void: true) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(//, data) + end.respond_with(successful_check_void_response) + + assert_success void + end + def test_failed_void @gateway.expects(:ssl_post).returns(failed_refund_response) @@ -122,6 +182,18 @@ def test_failed_void assert_failure void end + def test_successful_recurring_purchase + stored_credential_params = { + reason_type: 'recurring' + } + + @gateway.expects(:ssl_post).returns(successful_charge_response) + + response = @gateway.purchase(@amount, @credit_card, @options.merge({ stored_credential: stored_credential_params })) + assert_instance_of Response, response + assert_success response + end + def test_successful_purchase_with_swipe_no_encryption @gateway.expects(:ssl_post).returns(successful_swipe_purchase_response) @@ -204,8 +276,7 @@ def test_successful_purchase_with_apple_pay_raw_cryptogram_with_eci payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', verification_value: nil, eci: '05', - source: :apple_pay - ) + source: :apple_pay) assert response = @gateway.purchase(@amount, credit_card, @options) assert_success response assert_equal 'Success', response.message @@ -218,8 +289,7 @@ def test_failed_purchase_with_apple_pay_raw_cryptogram_with_eci payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', verification_value: nil, eci: '05', - source: :apple_pay - ) + source: :apple_pay) assert response = @gateway.purchase(@amount, credit_card, @options) assert_failure response assert_equal 'The card was declined.', response.message @@ -231,8 +301,7 @@ def test_successful_purchase_with_apple_pay_raw_cryptogram_without_eci credit_card = network_tokenization_credit_card('4242424242424242', payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', verification_value: nil, - source: :apple_pay - ) + source: :apple_pay) assert response = @gateway.purchase(@amount, credit_card, @options) assert_success response assert_equal 'Success', response.message @@ -244,8 +313,7 @@ def test_failed_purchase_with_apple_pay_raw_cryptogram_without_eci credit_card = network_tokenization_credit_card('4242424242424242', payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', verification_value: nil, - source: :apple_pay - ) + source: :apple_pay) assert response = @gateway.purchase(@amount, credit_card, @options) assert_failure response assert_equal 'The card was declined.', response.message @@ -258,8 +326,7 @@ def test_successful_auth_with_apple_pay_raw_cryptogram_with_eci payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', verification_value: nil, eci: '05', - source: :apple_pay - ) + source: :apple_pay) assert response = @gateway.authorize(@amount, credit_card, @options) assert_success response assert_equal 'Success', response.message @@ -272,8 +339,7 @@ def test_failed_auth_with_apple_pay_raw_cryptogram_with_eci payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', verification_value: nil, eci: '05', - source: :apple_pay - ) + source: :apple_pay) assert response = @gateway.authorize(@amount, credit_card, @options) assert_failure response assert_equal 'The card was declined.', response.message @@ -285,8 +351,7 @@ def test_successful_auth_with_apple_pay_raw_cryptogram_without_eci credit_card = network_tokenization_credit_card('4242424242424242', payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', verification_value: nil, - source: :apple_pay - ) + source: :apple_pay) assert response = @gateway.authorize(@amount, credit_card, @options) assert_success response assert_equal 'Success', response.message @@ -298,8 +363,207 @@ def test_failed_auth_with_apple_pay_raw_cryptogram_without_eci credit_card = network_tokenization_credit_card('4242424242424242', payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', verification_value: nil, - source: :apple_pay - ) + source: :apple_pay) + assert response = @gateway.authorize(@amount, credit_card, @options) + assert_failure response + assert_equal 'The card was declined.', response.message + end + + def test_successful_purchase_with_android_pay_raw_cryptogram_with_eci + @gateway.expects(:ssl_post).returns(successful_charge_response) + + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + eci: '05', + source: :android_pay) + assert response = @gateway.purchase(@amount, credit_card, @options) + assert_success response + assert_equal 'Success', response.message + end + + def test_failed_purchase_with_android_pay_raw_cryptogram_with_eci + @gateway.expects(:ssl_post).returns(failed_charge_response_decline) + + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + eci: '05', + source: :android_pay) + assert response = @gateway.purchase(@amount, credit_card, @options) + assert_failure response + assert_equal 'The card was declined.', response.message + end + + def test_successful_purchase_with_android_pay_raw_cryptogram_without_eci + @gateway.expects(:ssl_post).returns(successful_charge_response) + + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + source: :android_pay) + assert response = @gateway.purchase(@amount, credit_card, @options) + assert_success response + assert_equal 'Success', response.message + end + + def test_failed_purchase_with_android_pay_raw_cryptogram_without_eci + @gateway.expects(:ssl_post).returns(failed_charge_response_decline) + + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + source: :android_pay) + assert response = @gateway.purchase(@amount, credit_card, @options) + assert_failure response + assert_equal 'The card was declined.', response.message + end + + def test_successful_auth_with_android_pay_raw_cryptogram_with_eci + @gateway.expects(:ssl_post).returns(successful_authorize_response) + + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + eci: '05', + source: :android_pay) + assert response = @gateway.authorize(@amount, credit_card, @options) + assert_success response + assert_equal 'Success', response.message + end + + def test_failed_auth_with_android_pay_raw_cryptogram_with_eci + @gateway.expects(:ssl_post).returns(failed_authorize_response_decline) + + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + eci: '05', + source: :android_pay) + assert response = @gateway.authorize(@amount, credit_card, @options) + assert_failure response + assert_equal 'The card was declined.', response.message + end + + def test_successful_auth_with_android_pay_raw_cryptogram_without_eci + @gateway.expects(:ssl_post).returns(successful_authorize_response) + + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + source: :android_pay) + assert response = @gateway.authorize(@amount, credit_card, @options) + assert_success response + assert_equal 'Success', response.message + end + + def test_failed_auth_with_android_pay_raw_cryptogram_without_eci + @gateway.expects(:ssl_post).returns(failed_authorize_response_decline) + + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + source: :android_pay) + assert response = @gateway.authorize(@amount, credit_card, @options) + assert_failure response + assert_equal 'The card was declined.', response.message + end + + def test_successful_purchase_with_google_pay_raw_cryptogram_with_eci + @gateway.expects(:ssl_post).returns(successful_charge_response) + + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + eci: '05', + source: :google_pay) + assert response = @gateway.purchase(@amount, credit_card, @options) + assert_success response + assert_equal 'Success', response.message + end + + def test_failed_purchase_with_google_pay_raw_cryptogram_with_eci + @gateway.expects(:ssl_post).returns(failed_charge_response_decline) + + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + eci: '05', + source: :google_pay) + assert response = @gateway.purchase(@amount, credit_card, @options) + assert_failure response + assert_equal 'The card was declined.', response.message + end + + def test_successful_purchase_with_google_pay_raw_cryptogram_without_eci + @gateway.expects(:ssl_post).returns(successful_charge_response) + + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + source: :google_pay) + assert response = @gateway.purchase(@amount, credit_card, @options) + assert_success response + assert_equal 'Success', response.message + end + + def test_failed_purchase_with_google_pay_raw_cryptogram_without_eci + @gateway.expects(:ssl_post).returns(failed_charge_response_decline) + + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + source: :google_pay) + assert response = @gateway.purchase(@amount, credit_card, @options) + assert_failure response + assert_equal 'The card was declined.', response.message + end + + def test_successful_auth_with_google_pay_raw_cryptogram_with_eci + @gateway.expects(:ssl_post).returns(successful_authorize_response) + + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + eci: '05', + source: :google_pay) + assert response = @gateway.authorize(@amount, credit_card, @options) + assert_success response + assert_equal 'Success', response.message + end + + def test_failed_auth_with_google_pay_raw_cryptogram_with_eci + @gateway.expects(:ssl_post).returns(failed_authorize_response_decline) + + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + eci: '05', + source: :google_pay) + assert response = @gateway.authorize(@amount, credit_card, @options) + assert_failure response + assert_equal 'The card was declined.', response.message + end + + def test_successful_auth_with_google_pay_raw_cryptogram_without_eci + @gateway.expects(:ssl_post).returns(successful_authorize_response) + + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + source: :google_pay) + assert response = @gateway.authorize(@amount, credit_card, @options) + assert_success response + assert_equal 'Success', response.message + end + + def test_failed_auth_with_google_pay_raw_cryptogram_without_eci + @gateway.expects(:ssl_post).returns(failed_authorize_response_decline) + + credit_card = network_tokenization_credit_card('4242424242424242', + payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + verification_value: nil, + source: :google_pay) assert response = @gateway.authorize(@amount, credit_card, @options) assert_failure response assert_equal 'The card was declined.', response.message @@ -310,16 +574,16 @@ def test_three_d_secure_visa @credit_card.brand = 'visa' options = { - :three_d_secure => { - :cavv => 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', - :eci => '05', - :xid => 'TTBCSkVTa1ZpbDI1bjRxbGk5ODE=' + three_d_secure: { + cavv: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + eci: '05', + xid: 'TTBCSkVTa1ZpbDI1bjRxbGk5ODE=' } } response = stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, @credit_card, options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/(.*)<\/hps:SecureECommerce>/, data) assert_match(/Visa 3DSecure<\/hps:PaymentDataSource>/, data) assert_match(/3DSecure<\/hps:TypeOfPaymentData>/, data) @@ -337,16 +601,16 @@ def test_three_d_secure_mastercard @credit_card.brand = 'master' options = { - :three_d_secure => { - :cavv => 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', - :eci => '05', - :xid => 'TTBCSkVTa1ZpbDI1bjRxbGk5ODE=' + three_d_secure: { + cavv: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + eci: '05', + xid: 'TTBCSkVTa1ZpbDI1bjRxbGk5ODE=' } } response = stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, @credit_card, options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/(.*)<\/hps:SecureECommerce>/, data) assert_match(/MasterCard 3DSecure<\/hps:PaymentDataSource>/, data) assert_match(/3DSecure<\/hps:TypeOfPaymentData>/, data) @@ -364,16 +628,16 @@ def test_three_d_secure_discover @credit_card.brand = 'discover' options = { - :three_d_secure => { - :cavv => 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', - :eci => '5', - :xid => 'TTBCSkVTa1ZpbDI1bjRxbGk5ODE=' + three_d_secure: { + cavv: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + eci: '5', + xid: 'TTBCSkVTa1ZpbDI1bjRxbGk5ODE=' } } response = stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, @credit_card, options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/(.*)<\/hps:SecureECommerce>/, data) assert_match(/Discover 3DSecure<\/hps:PaymentDataSource>/, data) assert_match(/3DSecure<\/hps:TypeOfPaymentData>/, data) @@ -391,16 +655,16 @@ def test_three_d_secure_amex @credit_card.brand = 'american_express' options = { - :three_d_secure => { - :cavv => 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', - :eci => '05', - :xid => 'TTBCSkVTa1ZpbDI1bjRxbGk5ODE=' + three_d_secure: { + cavv: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + eci: '05', + xid: 'TTBCSkVTa1ZpbDI1bjRxbGk5ODE=' } } response = stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, @credit_card, options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/(.*)<\/hps:SecureECommerce>/, data) assert_match(/AMEX 3DSecure<\/hps:PaymentDataSource>/, data) assert_match(/3DSecure<\/hps:TypeOfPaymentData>/, data) @@ -418,16 +682,16 @@ def test_three_d_secure_jcb @credit_card.brand = 'jcb' options = { - :three_d_secure => { - :cavv => 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', - :eci => '5', - :xid => 'TTBCSkVTa1ZpbDI1bjRxbGk5ODE=' + three_d_secure: { + cavv: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + eci: '5', + xid: 'TTBCSkVTa1ZpbDI1bjRxbGk5ODE=' } } response = stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, @credit_card, options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| refute_match(/(.*)<\/hps:SecureECommerce>/, data) refute_match(/(.*)<\/hps:PaymentDataSource>/, data) refute_match(/3DSecure<\/hps:TypeOfPaymentData>/, data) @@ -440,486 +704,575 @@ def test_three_d_secure_jcb assert_equal 'Success', response.message end + def test_successful_auth_with_stored_credentials + stored_credential_params = { + initial_transaction: false, + reason_type: 'recurring', + initiator: 'customer', + network_transaction_id: 12345 + } + + response = stub_comms(@gateway, :ssl_request) do + @gateway.purchase(@amount, @credit_card, @options.merge({ stored_credential: stored_credential_params })) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(/C<\/hps:CardOnFile>/, data) + assert_match(/12345<\/hps:CardBrandTxnId>/, data) + assert_match(/N<\/hps:OneTime>/, data) + end.respond_with(successful_charge_response) + + assert_success response + assert_equal 'Success', response.message + end + + def test_truncates_long_invoicenbr + response = stub_comms(@gateway, :ssl_request) do + @gateway.purchase(@check_amount, @check, @options.merge(order_id: '04863692e6b56aaed85760b3d0879afd18b980da0521f6454c007a838435e561')) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(/04863692e6b56aaed85760b3d0879afd18b980da0521f6454c007a838435<\/hps:InvoiceNbr>/, data) + end.respond_with(successful_check_purchase_response) + + assert_success response + assert_equal 'Success', response.message + end + private def successful_charge_response - <<-RESPONSE - - - - - -
- 95878 - 95881 - 2409000 - 15927453 - 0 - Success - 2014-03-14T15:40:25.4686202 -
- - - 00 - APPROVAL - 36987A - 0 - M - 407313649105 - ACCEPT - ACCEPT - Visa - AVS Not Requested. - Match. - - -
-
-
-
- RESPONSE + <<~XML + + + + + +
+ 95878 + 95881 + 2409000 + 15927453 + 0 + Success + 2014-03-14T15:40:25.4686202 +
+ + + 00 + APPROVAL + 36987A + 0 + M + 407313649105 + ACCEPT + ACCEPT + Visa + AVS Not Requested. + Match. + + +
+
+
+
+ XML + end + + def successful_check_purchase_response + <<~XML + + + + + +
+ 144379 + 144474 + 6407594 + 1284694345 + 0 + Success + 2020-01-13T15:11:24.735047 +
+ + + 0 + Transaction Approved. BatchID:31796 + + +
+
+
+
+ XML end def failed_charge_response - <<-RESPONSE - - - - - -
- 21229 - 21232 - 1525997 - 16099851 - 0 - Success - 2014-03-17T13:01:55.851307 -
- - - 02 - CALL - - 0 - 407613674802 - Visa - AVS Not Requested. - - -
-
-
-
- RESPONSE + <<~XML + + + + + +
+ 21229 + 21232 + 1525997 + 16099851 + 0 + Success + 2014-03-17T13:01:55.851307 +
+ + + 02 + CALL + + 0 + 407613674802 + Visa + AVS Not Requested. + + +
+
+
+
+ XML end def failed_charge_response_decline - <<-RESPONSE - - - - - -
- 21229 - 21232 - 1525997 - 16099851 - 0 - Success - 2014-03-17T13:01:55.851307 -
- - - 05 - DECLINE - - 0 - 407613674802 - Visa - AVS Not Requested. - - -
-
-
-
- RESPONSE + <<~XML + + + + + +
+ 21229 + 21232 + 1525997 + 16099851 + 0 + Success + 2014-03-17T13:01:55.851307 +
+ + + 05 + DECLINE + + 0 + 407613674802 + Visa + AVS Not Requested. + + +
+
+
+
+ XML end def successful_authorize_response - <<-RESPONSE - - - - - -
- 21229 - 21232 - 1525997 - 16072891 - 0 - Success - 2014-03-17T13:05:34.5819712 -
- - - 00 - APPROVAL - 43204A - 0 - M - 407613674895 - ACCEPT - ACCEPT - Visa - AVS Not Requested. - Match. - - -
-
-
-
- RESPONSE + <<~XML + + + + + +
+ 21229 + 21232 + 1525997 + 16072891 + 0 + Success + 2014-03-17T13:05:34.5819712 +
+ + + 00 + APPROVAL + 43204A + 0 + M + 407613674895 + ACCEPT + ACCEPT + Visa + AVS Not Requested. + Match. + + +
+
+
+
+ XML end def failed_authorize_response - <<-RESPONSE - - - - - -
- 21229 - 21232 - 1525997 - 16088893 - 0 - Success - 2014-03-17T13:06:45.449707 -
- - - 54 - EXPIRED CARD - - 0 - 407613674811 - Visa - AVS Not Requested. - - -
-
-
-
- RESPONSE + <<~XML + + + + + +
+ 21229 + 21232 + 1525997 + 16088893 + 0 + Success + 2014-03-17T13:06:45.449707 +
+ + + 54 + EXPIRED CARD + + 0 + 407613674811 + Visa + AVS Not Requested. + + +
+
+
+
+ XML end def failed_authorize_response_decline - <<-RESPONSE - - - - - -
- 21229 - 21232 - 1525997 - 16088893 - 0 - Success - 2014-03-17T13:06:45.449707 -
- - - 05 - DECLINE - - 0 - 407613674811 - Visa - AVS Not Requested. - - -
-
-
-
- RESPONSE + <<~XML + + + + + +
+ 21229 + 21232 + 1525997 + 16088893 + 0 + Success + 2014-03-17T13:06:45.449707 +
+ + + 05 + DECLINE + + 0 + 407613674811 + Visa + AVS Not Requested. + + +
+
+
+
+ XML end def successful_capture_response - <<-RESPONSE - - - - - -
- 21229 - 21232 - 1525997 - 17213037 - 0 - Success - 2014-05-16T14:45:48.9906929 -
- - - -
-
-
-
- RESPONSE + <<~XML + + + + + +
+ 21229 + 21232 + 1525997 + 17213037 + 0 + Success + 2014-05-16T14:45:48.9906929 +
+ + + +
+
+
+
+ XML end def failed_capture_response - <<-Response - - - - - -
- 21229 - 21232 - 1525997 - 16104055 - 3 - Transaction rejected because the referenced original transaction is invalid. Subject '216072899'. Original transaction not found. - 2014-03-17T14:20:32.355307 -
-
-
-
-
- Response + <<~XML + + + + + +
+ 21229 + 21232 + 1525997 + 16104055 + 3 + Transaction rejected because the referenced original transaction is invalid. Subject '216072899'. Original transaction not found. + 2014-03-17T14:20:32.355307 +
+
+
+
+
+ XML end def successful_refund_response - <<-RESPONSE - - - - - -
- 21229 - 21232 - 1525997 - - 16092738 - 0 - Success - 2014-03-17T13:31:42.0231712 -
- - - -
-
-
-
- RESPONSE + <<~XML + + + + + +
+ 21229 + 21232 + 1525997 + + 16092738 + 0 + Success + 2014-03-17T13:31:42.0231712 +
+ + + +
+
+
+
+ XML end def failed_refund_response - <<-RESPONSE - - - - - -
- 21229 - 21232 - 1525997 - - 16092766 - 3 - Transaction rejected because the referenced original transaction is invalid. - 2014-03-17T13:48:55.3203712 -
-
-
-
-
- RESPONSE + <<~XML + + + + + +
+ 21229 + 21232 + 1525997 + + 16092766 + 3 + Transaction rejected because the referenced original transaction is invalid. + 2014-03-17T13:48:55.3203712 +
+
+
+
+
+ XML end def successful_void_response - <<-RESPONSE - - - - - -
- 21229 - 21232 - 1525997 - 16092767 - 0 - Success - 2014-03-17T13:53:43.6863712 -
- - - -
-
-
-
- RESPONSE + <<~XML + + + + + +
+ 21229 + 21232 + 1525997 + 16092767 + 0 + Success + 2014-03-17T13:53:43.6863712 +
+ + + +
+
+
+
+ XML + end + + def successful_check_void_response + <<~XML + + + + + +
+ 144379 + 144474 + 6407594 + 1284696436 + 0 + Success + 2020-01-13T15:44:24.3568038 +
+ + + 0 + Transaction Approved. + + +
+
+
+
+ XML end def failed_void_response - <<-RESPONSE - - - - - -
- 21229 - 21232 - 1525997 - 16103858 - 3 - Transaction rejected because the referenced original transaction is invalid. Subject '169054'. Original transaction not found. - 2014-03-17T13:55:56.8947712 -
-
-
-
-
- RESPONSE + <<~XML + + + + + +
+ 21229 + 21232 + 1525997 + 16103858 + 3 + Transaction rejected because the referenced original transaction is invalid. Subject '169054'. Original transaction not found. + 2014-03-17T13:55:56.8947712 +
+
+
+
+
+ XML end def successful_swipe_purchase_response - <<-RESPONSE - - - - - -
- 95878 - 95881 - 2409000 - 17596558 - 0 - Success - 2014-05-26T10:27:30.4211513 -
- - - 00 - APPROVAL - 037677 - 0 - 414614470800 - ACCEPT - MC - AVS Not Requested. - - -
-
-
-
- RESPONSE + <<~XML + + + + + +
+ 95878 + 95881 + 2409000 + 17596558 + 0 + Success + 2014-05-26T10:27:30.4211513 +
+ + + 00 + APPROVAL + 037677 + 0 + 414614470800 + ACCEPT + MC + AVS Not Requested. + + +
+
+
+
+ XML end def failed_swipe_purchase_response - <<-RESPONSE - - - - - -
- 95878 - 95881 - 2409000 - 17602711 - 8 - Transaction was rejected because the track data could not be read. - 2014-05-26T10:42:44.5031513 -
-
-
-
-
- RESPONSE + <<~XML + + + + + +
+ 95878 + 95881 + 2409000 + 17602711 + 8 + Transaction was rejected because the track data could not be read. + 2014-05-26T10:42:44.5031513 +
+
+
+
+
+ XML end def successful_verify_response - <<-RESPONSE - - - - - -
- 95878 - 95881 - 2409000 - - 20153225 - 0 - Success - 2014-09-04T14:43:49.6015895 -
- - - 85 - CARD OK - 65557A - 0 - M - 424715929580 - Visa - AVS Not Requested. - Match. - - -
-
-
-
- RESPONSE + <<~XML + + + + + +
+ 95878 + 95881 + 2409000 + + 20153225 + 0 + Success + 2014-09-04T14:43:49.6015895 +
+ + + 85 + CARD OK + 65557A + 0 + M + 424715929580 + Visa + AVS Not Requested. + Match. + + +
+
+
+
+ XML end def failed_verify_response - <<-RESPONSE - - - - - -
- 95878 - 95881 - 2409000 - - 20155097 - 14 - Transaction rejected because the manually entered card number is invalid. - 2014-09-04T15:42:47.983634 -
-
-
-
-
- RESPONSE + <<~XML + + + + + +
+ 95878 + 95881 + 2409000 + + 20155097 + 14 + Transaction rejected because the manually entered card number is invalid. + 2014-09-04T15:42:47.983634 +
+
+
+
+
+ XML end def pre_scrub @@ -981,5 +1334,4 @@ def post_scrub Conn close } end - end diff --git a/test/unit/gateways/iats_payments_test.rb b/test/unit/gateways/iats_payments_test.rb index ac94ec90912..5cb3aa396d1 100644 --- a/test/unit/gateways/iats_payments_test.rb +++ b/test/unit/gateways/iats_payments_test.rb @@ -5,18 +5,31 @@ class IatsPaymentsTest < Test::Unit::TestCase def setup @gateway = IatsPaymentsGateway.new( - :agent_code => 'login', - :password => 'password', - :region => 'uk' + agent_code: 'login', + password: 'password', + region: 'uk' ) @amount = 100 @credit_card = credit_card @check = check + @address = { + name: 'Jim Smith', + address1: '456 My Street', + address2: 'Apt 1', + company: 'Widgets Inc', + city: 'Ottawa', + state: 'ON', + zip: 'K1C2N6', + country: 'CA', + phone: '555-555-5555', + fax: '(555)555-6666', + email: 'jimsmith@example.com' + } @options = { - :ip => '71.65.249.145', - :order_id => generate_unique_id, - :billing_address => address, - :description => 'Store purchase' + ip: '71.65.249.145', + order_id: generate_unique_id, + billing_address: @address, + description: 'Store purchase' } end @@ -38,9 +51,12 @@ def test_successful_purchase assert_match(/#{@options[:billing_address][:city]}<\/city>/, data) assert_match(/#{@options[:billing_address][:state]}<\/state>/, data) assert_match(/#{@options[:billing_address][:zip]}<\/zipCode>/, data) + assert_match(/#{@options[:billing_address][:phone]}<\/phone>/, data) + assert_match(/#{@options[:billing_address][:country]}<\/country>/, data) assert_match(/1.00<\/total>/, data) assert_match(/#{@options[:description]}<\/comment>/, data) - assert_equal endpoint, 'https://www.uk.iatspayments.com/NetGate/ProcessLink.asmx?op=ProcessCreditCardV1' + assert_match(/#{@options[:billing_address][:email]}<\/email>/, data) + assert_equal endpoint, 'https://www.uk.iatspayments.com/NetGate/ProcessLinkv3.asmx?op=ProcessCreditCard' assert_equal headers['Content-Type'], 'application/soap+xml; charset=utf-8' end.respond_with(successful_purchase_response) @@ -66,7 +82,7 @@ def test_successful_check_purchase response = stub_comms do @gateway.purchase(@amount, @check, @options) end.check_request do |endpoint, data, headers| - assert_match(/login<\/agentCode>/, data) assert_match(/password<\/password>/, data) assert_match(/#{@options[:ip]}<\/customerIPAddress>/, data) @@ -79,9 +95,12 @@ def test_successful_check_purchase assert_match(/#{@options[:billing_address][:city]}<\/city>/, data) assert_match(/#{@options[:billing_address][:state]}<\/state>/, data) assert_match(/#{@options[:billing_address][:zip]}<\/zipCode>/, data) + assert_match(/#{@options[:billing_address][:phone]}<\/phone>/, data) + assert_match(/#{@options[:billing_address][:country]}<\/country>/, data) assert_match(/1.00<\/total>/, data) + assert_match(/#{@options[:billing_address][:email]}<\/email>/, data) assert_match(/#{@options[:description]}<\/comment>/, data) - assert_equal endpoint, 'https://www.uk.iatspayments.com/NetGate/ProcessLink.asmx?op=ProcessACHEFTV1' + assert_equal endpoint, 'https://www.uk.iatspayments.com/NetGate/ProcessLinkv3.asmx?op=ProcessACHEFT' assert_equal headers['Content-Type'], 'application/soap+xml; charset=utf-8' end.respond_with(successful_check_purchase_response) @@ -92,6 +111,17 @@ def test_successful_check_purchase assert_equal 'Success', response.message end + def test_successful_purchase_with_customer_details + @options[:email] = 'jsmith2@example.com' + response = stub_comms do + @gateway.purchase(@amount, @credit_card, @options) + end.check_request do |_endpoint, data, _headers| + assert_match(/#{@options[:email]}<\/email>/, data) + end.respond_with(successful_purchase_response) + + assert response + end + def test_failed_check_purchase response = stub_comms do @gateway.purchase(@amount, @check, @options) @@ -107,7 +137,7 @@ def test_failed_check_purchase def test_successful_refund response = stub_comms do @gateway.refund(@amount, '1234', @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/1234<\/transactionId>/, data) assert_match(/-1.00<\/total>/, data) end.respond_with(successful_refund_response) @@ -121,13 +151,13 @@ def test_successful_check_refund response = stub_comms do @gateway.refund(@amount, 'ref|check', @options) end.check_request do |endpoint, data, headers| - assert_match(/login<\/agentCode>/, data) assert_match(/password<\/password>/, data) assert_match(/#{@options[:ip]}<\/customerIPAddress>/, data) assert_match(/-1.00<\/total>/, data) assert_match(/#{@options[:description]}<\/comment>/, data) - assert_equal endpoint, 'https://www.uk.iatspayments.com/NetGate/ProcessLink.asmx?op=ProcessACHEFTRefundWithTransactionIdV1' + assert_equal endpoint, 'https://www.uk.iatspayments.com/NetGate/ProcessLinkv3.asmx?op=ProcessACHEFTRefundWithTransactionId' assert_equal headers['Content-Type'], 'application/soap+xml; charset=utf-8' end.respond_with(successful_check_refund_response) @@ -153,7 +183,7 @@ def test_failed_check_refund def test_failed_refund response = stub_comms do @gateway.refund(@amount, '1234', @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/1234<\/transactionId>/, data) assert_match(/-1.00<\/total>/, data) end.respond_with(failed_refund_response) @@ -166,7 +196,7 @@ def test_failed_refund def test_successful_store response = stub_comms do @gateway.store(@credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/beginDate/, data) assert_match(/endDate/, data) assert_match(%r{#{@credit_card.number}}, data) @@ -180,6 +210,18 @@ def test_successful_store assert_equal 'Success', response.message end + def test_successful_purchase_with_customer_code + response = stub_comms do + @gateway.purchase(@amount, 'CustomerCode', @options) + end.check_request do |_endpoint, data, _headers| + assert_match(%r{CustomerCode}, data) + end.respond_with(successful_purchase_response) + + assert response + assert_success response + assert_equal 'Success', response.message + end + def test_failed_store response = stub_comms do @gateway.store(@credit_card, @options) @@ -193,7 +235,7 @@ def test_failed_store def test_successful_unstore response = stub_comms do @gateway.unstore('TheAuthorization', @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{TheAuthorization}, data) end.respond_with(successful_unstore_response) @@ -205,17 +247,17 @@ def test_successful_unstore def test_deprecated_options assert_deprecation_warning("The 'login' option is deprecated in favor of 'agent_code' and will be removed in a future version.") do @gateway = IatsPaymentsGateway.new( - :login => 'login', - :password => 'password' + login: 'login', + password: 'password' ) end 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(/login<\/agentCode>/, data) assert_match(/password<\/password>/, data) - assert_equal endpoint, 'https://www.iatspayments.com/NetGate/ProcessLink.asmx?op=ProcessCreditCardV1' + assert_equal endpoint, 'https://www.iatspayments.com/NetGate/ProcessLinkv3.asmx?op=ProcessCreditCard' end.respond_with(successful_purchase_response) assert_success response @@ -223,15 +265,15 @@ def test_deprecated_options def test_region_urls @gateway = IatsPaymentsGateway.new( - :agent_code => 'code', - :password => 'password', - :region => 'na' # North america + agent_code: 'code', + password: 'password', + region: 'na' # North america ) response = stub_comms do @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| - assert_equal endpoint, 'https://www.iatspayments.com/NetGate/ProcessLink.asmx?op=ProcessCreditCardV1' + end.check_request do |endpoint, _data, _headers| + assert_equal endpoint, 'https://www.iatspayments.com/NetGate/ProcessLinkv3.asmx?op=ProcessCreditCard' end.respond_with(successful_purchase_response) assert_success response @@ -264,196 +306,196 @@ def test_supports_scrubbing? private def successful_purchase_response - <<-XML - - - - - - - Success - - - OK - - 04/22/2014 - 04/23/2014 - A6DE6F24 - - - - - - + <<~XML + + + + + + + Success + + + OK + + 04/22/2014 + 04/23/2014 + A6DE6F24 + + + + + + XML end def failed_purchase_response - <<-XML - - - - - - - Success - - - REJECT: 15 - - 04/22/2014 - 04/23/2014 - A6DE6F24 - - - - - - + <<~XML + + + + + + + Success + + + REJECT: 15 + + 04/22/2014 + 04/23/2014 + A6DE6F24 + + + + + + XML end def successful_check_purchase_response - <<-XML - - - - - - - Success - - - OK: 555555 - - A7F8B8B3 - - - - - - + <<~XML + + + + + + + Success + + + OK: 555555 + + A7F8B8B3 + + + + + + XML end def failed_check_purchase_response - <<-XML - - - - - - - Success - - - REJECT: 40 - - - - - - - - + <<~XML + + + + + + + Success + + + REJECT: 40 + + + + + + + + XML end def successful_refund_response - <<-XML - - - - - - - Success - - - OK: 678594: - - 04/22/2014 - 04/23/2014 - A6DEA654 - - - - - - + <<~XML + + + + + + + Success + + + OK: 678594: + + 04/22/2014 + 04/23/2014 + A6DEA654 + + + + + + XML end def successful_check_refund_response - <<-XML - - - - - - - Success - - - OK: 555555 - - A7F8B8B3 - - - - - - + <<~XML + + + + + + + Success + + + OK: 555555 + + A7F8B8B3 + + + + + + XML end def failed_check_refund_response - <<-XML - - - - - - - Success - - - REJECT: 39 - - 06/11/2015 - 06/12/2015 - - - - - - - + <<~XML + + + + + + + Success + + + REJECT: 39 + + 06/11/2015 + 06/12/2015 + + + + + + + XML end def failed_refund_response - <<-XML - - - - - - - Success - - - REJECT: 15 - - 04/22/2014 - 04/23/2014 - A6DEA654 - - - - - - + <<~XML + + + + + + + Success + + + REJECT: 15 + + 04/22/2014 + 04/23/2014 + A6DEA654 + + + + + + XML end @@ -462,8 +504,8 @@ def successful_store_response - - + + Success @@ -472,8 +514,8 @@ def successful_store_response A12181132 - - + + XML @@ -484,8 +526,8 @@ def failed_store_response - - + + Success @@ -494,8 +536,8 @@ def failed_store_response - - + + XML @@ -506,8 +548,8 @@ def successful_unstore_response - - + + Success @@ -516,8 +558,8 @@ def successful_unstore_response "A12181132" is deleted - - + + XML @@ -528,16 +570,16 @@ def failed_connection_response - - + + Failure Server Error - - + + XML @@ -549,8 +591,8 @@ def pre_scrub opened starting SSL for www.iatspayments.com:443... SSL established - <- "POST /NetGate/ProcessLink.asmx?op=ProcessCreditCardV1 HTTP/1.1\r\nContent-Type: application/soap+xml; charset=utf-8\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: www.iatspayments.com\r\nContent-Length: 779\r\n\r\n" - <- "TEST88TEST8863b5dd7098e8e3a9ff9a6f0992fdb6d51.00LongbobLongsen422222222222222009/17123VISA
456 My Street
OttawaONK1C2N6Store purchase
" + <- "POST /NetGate/ProcessLink.asmx?op=ProcessCreditCard HTTP/1.1\r\nContent-Type: application/soap+xml; charset=utf-8\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: www.iatspayments.com\r\nContent-Length: 779\r\n\r\n" + <- "TEST88TEST8863b5dd7098e8e3a9ff9a6f0992fdb6d51.00LongbobLongsen422222222222222009/17123VISA
456 My Street
OttawaONK1C2N6Store purchase
" -> "HTTP/1.1 200 OK\r\n" -> "Cache-Control: private, max-age=0\r\n" -> "Content-Type: application/soap+xml; charset=utf-8\r\n" @@ -562,7 +604,7 @@ def pre_scrub -> "Via: 1.1 sjc1-10\r\n" -> "\r\n" reading 719 bytes... - -> "Success OK: 678594:\n 09/28/2016\n 09/29/2016\nA92E3B72\n" + -> "Success OK: 678594:\n 09/28/2016\n 09/29/2016\nA92E3B72\n" read 719 bytes Conn close XML @@ -574,8 +616,8 @@ def post_scrub opened starting SSL for www.iatspayments.com:443... SSL established - <- "POST /NetGate/ProcessLink.asmx?op=ProcessCreditCardV1 HTTP/1.1\r\nContent-Type: application/soap+xml; charset=utf-8\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: www.iatspayments.com\r\nContent-Length: 779\r\n\r\n" - <- "[FILTERED][FILTERED]63b5dd7098e8e3a9ff9a6f0992fdb6d51.00LongbobLongsen[FILTERED]09/17[FILTERED]VISA
456 My Street
OttawaONK1C2N6Store purchase
" + <- "POST /NetGate/ProcessLink.asmx?op=ProcessCreditCard HTTP/1.1\r\nContent-Type: application/soap+xml; charset=utf-8\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: www.iatspayments.com\r\nContent-Length: 779\r\n\r\n" + <- "[FILTERED][FILTERED]63b5dd7098e8e3a9ff9a6f0992fdb6d51.00LongbobLongsen[FILTERED]09/17[FILTERED]VISA
456 My Street
OttawaONK1C2N6Store purchase
" -> "HTTP/1.1 200 OK\r\n" -> "Cache-Control: private, max-age=0\r\n" -> "Content-Type: application/soap+xml; charset=utf-8\r\n" @@ -587,7 +629,7 @@ def post_scrub -> "Via: 1.1 sjc1-10\r\n" -> "\r\n" reading 719 bytes... - -> "Success OK: 678594:\n 09/28/2016\n 09/29/2016\nA92E3B72\n" + -> "Success OK: 678594:\n 09/28/2016\n 09/29/2016\nA92E3B72\n" read 719 bytes Conn close XML diff --git a/test/unit/gateways/in_context_paypal_express_test.rb b/test/unit/gateways/in_context_paypal_express_test.rb index 4e92dc3032a..30bf8efffcc 100644 --- a/test/unit/gateways/in_context_paypal_express_test.rb +++ b/test/unit/gateways/in_context_paypal_express_test.rb @@ -8,9 +8,9 @@ class InContextPaypalExpressTest < Test::Unit::TestCase def setup @gateway = InContextPaypalExpressGateway.new( - :login => 'cody', - :password => 'test', - :pem => 'PEM' + login: 'cody', + password: 'test', + pem: 'PEM' ) Base.mode = :test diff --git a/test/unit/gateways/inspire_test.rb b/test/unit/gateways/inspire_test.rb index b92b13ef34c..230db39427c 100644 --- a/test/unit/gateways/inspire_test.rb +++ b/test/unit/gateways/inspire_test.rb @@ -5,12 +5,12 @@ class InspireTest < Test::Unit::TestCase def setup @gateway = InspireGateway.new( - :login => 'LOGIN', - :password => 'PASSWORD' + login: 'LOGIN', + password: 'PASSWORD' ) @credit_card = credit_card('4242424242424242') @amount = 100 - @options = { :billing_address => address } + @options = { billing_address: address } end def test_successful_purchase @@ -60,8 +60,8 @@ def test_failed_refund def test_add_address result = {} - @gateway.send(:add_address, result, nil, :billing_address => {: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, nil, billing_address: { 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] @@ -72,14 +72,14 @@ def test_supported_countries end def test_supported_card_types - assert_equal [:visa, :master, :american_express], InspireGateway.supported_cardtypes + assert_equal %i[visa master american_express], InspireGateway.supported_cardtypes end 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 @@ -87,17 +87,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 diff --git a/test/unit/gateways/instapay_test.rb b/test/unit/gateways/instapay_test.rb index d70c9c52f72..bc58c48efea 100644 --- a/test/unit/gateways/instapay_test.rb +++ b/test/unit/gateways/instapay_test.rb @@ -2,7 +2,7 @@ class InstapayTest < Test::Unit::TestCase def setup - @gateway = InstapayGateway.new(:login => 'TEST0') + @gateway = InstapayGateway.new(login: 'TEST0') @credit_card = credit_card @amount = 100 end diff --git a/test/unit/gateways/ipp_test.rb b/test/unit/gateways/ipp_test.rb index 40b8035b37b..0174a7b7a93 100644 --- a/test/unit/gateways/ipp_test.rb +++ b/test/unit/gateways/ipp_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) @@ -90,122 +90,122 @@ 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 end diff --git a/test/unit/gateways/iridium_test.rb b/test/unit/gateways/iridium_test.rb index 055afb50653..865b183acac 100644 --- a/test/unit/gateways/iridium_test.rb +++ b/test/unit/gateways/iridium_test.rb @@ -1,18 +1,20 @@ require 'test_helper' class IridiumTest < Test::Unit::TestCase + include CommStub + def setup Base.mode = :test - @gateway = IridiumGateway.new(:login => 'login', :password => 'password') + @gateway = IridiumGateway.new(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 @@ -89,7 +91,7 @@ def test_override_currency @gateway.expects(:ssl_post). with(anything, all_of(regexp_matches(/Amount="400"/), regexp_matches(/CurrencyCode="484"/)), anything). returns(successful_purchase_response) - assert_success @gateway.purchase(400, @credit_card, @options.merge(:currency => 'MXN')) + assert_success @gateway.purchase(400, @credit_card, @options.merge(currency: 'MXN')) end def test_do_not_depend_on_expiry_date_class @@ -102,13 +104,21 @@ def test_do_not_depend_on_expiry_date_class def test_use_ducktyping_for_credit_card @gateway.expects(:ssl_post).returns(successful_purchase_response) - credit_card = stub(:number => '4242424242424242', :verification_value => '123', :name => 'Hans Tester', :year => 2012, :month => 1) + credit_card = stub(number: '4242424242424242', verification_value: '123', name: 'Hans Tester', year: 2012, month: 1) assert_nothing_raised do assert_success @gateway.purchase(@amount, credit_card, @options) end end + def test_nonfractional_currency_handling + stub_comms do + @gateway.authorize(14200, @credit_card, @options.merge(currency: 'JPY')) + end.check_request do |_endpoint, data, _headers| + assert_match(/0AuthCode: 608724608724PASSEDPASSEDPASSED POST_SCRUBBED end - end diff --git a/test/unit/gateways/itransact_test.rb b/test/unit/gateways/itransact_test.rb index 5f43bfc702f..46e019ebc95 100644 --- a/test/unit/gateways/itransact_test.rb +++ b/test/unit/gateways/itransact_test.rb @@ -3,21 +3,21 @@ class ItransactTest < Test::Unit::TestCase def setup @gateway = ItransactGateway.new( - :login => 'login', - :password => 'password', - :gateway_id => '09999' - ) + login: 'login', + password: 'password', + gateway_id: '09999' + ) @credit_card = credit_card @check = check @amount = 1014 # = $10.14 @options = { - :email => 'name@domain.com', - :order_id => '1', - :billing_address => address, - :description => 'Store Purchase', - :email_text => ['line1', 'line2', 'line3'] + email: 'name@domain.com', + order_id: '1', + billing_address: address, + description: 'Store Purchase', + email_text: %w[line1 line2 line3] } end @@ -67,5 +67,4 @@ def successful_check_purchase_response " ok20081216141214TRUE1.099999999991234 My StreetOttawaLongbobLongsenONK1C2N6CA(555)555-5555" end - end diff --git a/test/unit/gateways/iveri_test.rb b/test/unit/gateways/iveri_test.rb index 1269cd1ee53..329514fafa5 100644 --- a/test/unit/gateways/iveri_test.rb +++ b/test/unit/gateways/iveri_test.rb @@ -1,6 +1,8 @@ require 'test_helper' class IveriTest < Test::Unit::TestCase + include CommStub + def setup @gateway = IveriGateway.new(app_id: '123', cert_id: '321') @credit_card = credit_card('4242424242424242') @@ -100,20 +102,19 @@ def test_failed_void end def test_successful_verify - @gateway.expects(:ssl_post).returns(successful_verify_response) - - response = @gateway.verify(@credit_card, @options) + response = stub_comms do + @gateway.verify(@credit_card, @options) + end.respond_with(successful_authorize_response, failed_void_response) assert_success response - assert_equal '{F4337D04-B526-4A7E-A400-2A6DEADDCF57}|{5D5F8BF7-2D9D-42C3-AF32-08C5E62CD45E}|c0006d1d739905afc9e70beaf4194ea3', response.authorization - assert response.test? + assert_equal 'Succeeded', response.message end def test_failed_verify - @gateway.expects(:ssl_post).returns(failed_verify_response) - - response = @gateway.verify(credit_card('2121212121212121'), @options) + response = stub_comms do + @gateway.verify(credit_card('2121212121212121'), @options) + end.respond_with(failed_authorize_response, successful_void_response) assert_failure response - assert_equal '4', response.error_code + assert_equal 'Denied', response.message end def test_successful_verify_credentials @@ -184,370 +185,332 @@ def post_scrubbed end def successful_purchase_response - <<-XML -<V_XML Version="2.0" Direction="Response"> -<Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Debit" Mode="Test" RequestID="{F0568958-D10B-4093-A3BF-663168B06140}"> - <Result Status="0" AppServer="105IVERIAPPPR01" DBServer="105IVERIDBPR01" Gateway="Nedbank" AcquirerCode="00" /> - <Amount>100</Amount> - <AuthorisationCode>537473</AuthorisationCode> - <Currency>ZAR</Currency> - <ExpiryDate>092018</ExpiryDate> - <MerchantReference>48b63446223ce91451fc3c1641a9ec03</MerchantReference> - <Terminal>Default</Terminal> - <TransactionIndex>{5CEF96FD-960E-4EA5-811F-D02CE6E36A96}</TransactionIndex> - <MerchantName>iVeri Payment Technology</MerchantName> - <MerchantUSN>7771777</MerchantUSN> - <Acquirer>NBPostilionBICISONBSouthAfrica</Acquirer> - <AcquirerReference>70417:04077982</AcquirerReference> - <AcquirerDate>20170417</AcquirerDate> - <AcquirerTime>190433</AcquirerTime> - <DisplayAmount>R 1.00</DisplayAmount> - <BIN>4</BIN> - <Association>VISA</Association> - <CardType>Unknown CardType</CardType> - <Issuer>Unknown</Issuer> - <Jurisdiction>International</Jurisdiction> - <PANMode>Keyed,CVV</PANMode> - <ReconReference>04077982</ReconReference> - <CardHolderPresence>CardNotPresent</CardHolderPresence> - <MerchantAddress>MERCHANT ADDRESS</MerchantAddress> - <MerchantCity>Sandton</MerchantCity> - <MerchantCountryCode>ZA</MerchantCountryCode> - <MerchantCountry>South Africa</MerchantCountry> - <DistributorName>Nedbank</DistributorName> - <CCNumber>4242........4242</CCNumber> - <PAN>4242........4242</PAN> -</Transaction> -</V_XML> + <<~XML + <V_XML Version="2.0" Direction="Response"> + <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Debit" Mode="Test" RequestID="{F0568958-D10B-4093-A3BF-663168B06140}"> + <Result Status="0" AppServer="105IVERIAPPPR01" DBServer="105IVERIDBPR01" Gateway="Nedbank" AcquirerCode="00" /> + <Amount>100</Amount> + <AuthorisationCode>537473</AuthorisationCode> + <Currency>ZAR</Currency> + <ExpiryDate>092018</ExpiryDate> + <MerchantReference>48b63446223ce91451fc3c1641a9ec03</MerchantReference> + <Terminal>Default</Terminal> + <TransactionIndex>{5CEF96FD-960E-4EA5-811F-D02CE6E36A96}</TransactionIndex> + <MerchantName>iVeri Payment Technology</MerchantName> + <MerchantUSN>7771777</MerchantUSN> + <Acquirer>NBPostilionBICISONBSouthAfrica</Acquirer> + <AcquirerReference>70417:04077982</AcquirerReference> + <AcquirerDate>20170417</AcquirerDate> + <AcquirerTime>190433</AcquirerTime> + <DisplayAmount>R 1.00</DisplayAmount> + <BIN>4</BIN> + <Association>VISA</Association> + <CardType>Unknown CardType</CardType> + <Issuer>Unknown</Issuer> + <Jurisdiction>International</Jurisdiction> + <PANMode>Keyed,CVV</PANMode> + <ReconReference>04077982</ReconReference> + <CardHolderPresence>CardNotPresent</CardHolderPresence> + <MerchantAddress>MERCHANT ADDRESS</MerchantAddress> + <MerchantCity>Sandton</MerchantCity> + <MerchantCountryCode>ZA</MerchantCountryCode> + <MerchantCountry>South Africa</MerchantCountry> + <DistributorName>Nedbank</DistributorName> + <CCNumber>4242........4242</CCNumber> + <PAN>4242........4242</PAN> + </Transaction> + </V_XML> XML end def failed_purchase_response - <<-XML -<V_XML Version="2.0" Direction="Response"> - <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Debit" Mode="Test" RequestID="{B14C3834-72B9-4ACA-B362-B3C9EC96E8C0}"> - <Result Status="-1" Code="4" Description="Denied" Source="NBPostilionBICISONBSouthAfrica" AppServer="105IVERIAPPPR01" DBServer="105IVERIDBPR01" Gateway="Nedbank" AcquirerCode="05" AcquirerDescription="Do not Honour" /> - <Amount>100</Amount> - <Currency>ZAR</Currency> - <ExpiryDate>092018</ExpiryDate> - <MerchantReference>435a5d60b5fe874840c34e2e0504626b</MerchantReference> - <Terminal>Default</Terminal> - <TransactionIndex>{B35872A9-39C7-4DB8-9774-A5E34FFA519E}</TransactionIndex> - <MerchantName>iVeri Payment Technology</MerchantName> - <MerchantUSN>7771777</MerchantUSN> - <Acquirer>NBPostilionBICISONBSouthAfrica</Acquirer> - <AcquirerReference>70417:04077988</AcquirerReference> - <AcquirerDate>20170417</AcquirerDate> - <AcquirerTime>192038</AcquirerTime> - <DisplayAmount>R 1.00</DisplayAmount> - <BIN>2</BIN> - <Association>Unknown Association</Association> - <CardType>Unknown CardType</CardType> - <Issuer>Unknown</Issuer> - <Jurisdiction>Local</Jurisdiction> - <PANMode>Keyed,CVV</PANMode> - <ReconReference>04077988</ReconReference> - <CardHolderPresence>CardNotPresent</CardHolderPresence> - <MerchantAddress>MERCHANT ADDRESS</MerchantAddress> - <MerchantCity>Sandton</MerchantCity> - <MerchantCountryCode>ZA</MerchantCountryCode> - <MerchantCountry>South Africa</MerchantCountry> - <DistributorName>Nedbank</DistributorName> - <CCNumber>2121........2121</CCNumber> - <PAN>2121........2121</PAN> - </Transaction> -</V_XML> + <<~XML + <V_XML Version="2.0" Direction="Response"> + <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Debit" Mode="Test" RequestID="{B14C3834-72B9-4ACA-B362-B3C9EC96E8C0}"> + <Result Status="-1" Code="4" Description="Denied" Source="NBPostilionBICISONBSouthAfrica" AppServer="105IVERIAPPPR01" DBServer="105IVERIDBPR01" Gateway="Nedbank" AcquirerCode="05" AcquirerDescription="Do not Honour" /> + <Amount>100</Amount> + <Currency>ZAR</Currency> + <ExpiryDate>092018</ExpiryDate> + <MerchantReference>435a5d60b5fe874840c34e2e0504626b</MerchantReference> + <Terminal>Default</Terminal> + <TransactionIndex>{B35872A9-39C7-4DB8-9774-A5E34FFA519E}</TransactionIndex> + <MerchantName>iVeri Payment Technology</MerchantName> + <MerchantUSN>7771777</MerchantUSN> + <Acquirer>NBPostilionBICISONBSouthAfrica</Acquirer> + <AcquirerReference>70417:04077988</AcquirerReference> + <AcquirerDate>20170417</AcquirerDate> + <AcquirerTime>192038</AcquirerTime> + <DisplayAmount>R 1.00</DisplayAmount> + <BIN>2</BIN> + <Association>Unknown Association</Association> + <CardType>Unknown CardType</CardType> + <Issuer>Unknown</Issuer> + <Jurisdiction>Local</Jurisdiction> + <PANMode>Keyed,CVV</PANMode> + <ReconReference>04077988</ReconReference> + <CardHolderPresence>CardNotPresent</CardHolderPresence> + <MerchantAddress>MERCHANT ADDRESS</MerchantAddress> + <MerchantCity>Sandton</MerchantCity> + <MerchantCountryCode>ZA</MerchantCountryCode> + <MerchantCountry>South Africa</MerchantCountry> + <DistributorName>Nedbank</DistributorName> + <CCNumber>2121........2121</CCNumber> + <PAN>2121........2121</PAN> + </Transaction> + </V_XML> XML end def successful_authorize_response - <<-XML -<V_XML Version="2.0" Direction="Response"> - <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Authorisation" Mode="Test" RequestID="{B90D7CDB-C8E8-4477-BDF2-695F28137874}"> - <Result Status="0" AppServer="105IVERIAPPPR01" DBServer="105IVERIDBPR01" Gateway="Nedbank" AcquirerCode="00" /> - <Amount>100</Amount> - <AuthorisationCode>541267</AuthorisationCode> - <Currency>ZAR</Currency> - <ExpiryDate>092018</ExpiryDate> - <MerchantReference>23b4125c3b8e2777bffee52e196a863b</MerchantReference> - <Terminal>Default</Terminal> - <TransactionIndex>{EF0DC64E-2D00-4B6C-BDA0-2AD265391317}</TransactionIndex> - <MerchantName>iVeri Payment Technology</MerchantName> - <MerchantUSN>7771777</MerchantUSN> - <Acquirer>NBPostilionBICISONBSouthAfrica</Acquirer> - <AcquirerReference>70417:04078057</AcquirerReference> - <AcquirerDate>20170417</AcquirerDate> - <AcquirerTime>200747</AcquirerTime> - <DisplayAmount>R 1.00</DisplayAmount> - <BIN>4</BIN> - <Association>VISA</Association> - <CardType>Unknown CardType</CardType> - <Issuer>Unknown</Issuer> - <Jurisdiction>International</Jurisdiction> - <PANMode>Keyed,CVV</PANMode> - <ReconReference>04078057</ReconReference> - <CardHolderPresence>CardNotPresent</CardHolderPresence> - <MerchantAddress>MERCHANT ADDRESS</MerchantAddress> - <MerchantCity>Sandton</MerchantCity> - <MerchantCountryCode>ZA</MerchantCountryCode> - <MerchantCountry>South Africa</MerchantCountry> - <DistributorName>Nedbank</DistributorName> - <CCNumber>4242........4242</CCNumber> - <PAN>4242........4242</PAN> - </Transaction> -</V_XML> + <<~XML + <V_XML Version="2.0" Direction="Response"> + <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Authorisation" Mode="Test" RequestID="{B90D7CDB-C8E8-4477-BDF2-695F28137874}"> + <Result Status="0" AppServer="105IVERIAPPPR01" DBServer="105IVERIDBPR01" Gateway="Nedbank" AcquirerCode="00" /> + <Amount>100</Amount> + <AuthorisationCode>541267</AuthorisationCode> + <Currency>ZAR</Currency> + <ExpiryDate>092018</ExpiryDate> + <MerchantReference>23b4125c3b8e2777bffee52e196a863b</MerchantReference> + <Terminal>Default</Terminal> + <TransactionIndex>{EF0DC64E-2D00-4B6C-BDA0-2AD265391317}</TransactionIndex> + <MerchantName>iVeri Payment Technology</MerchantName> + <MerchantUSN>7771777</MerchantUSN> + <Acquirer>NBPostilionBICISONBSouthAfrica</Acquirer> + <AcquirerReference>70417:04078057</AcquirerReference> + <AcquirerDate>20170417</AcquirerDate> + <AcquirerTime>200747</AcquirerTime> + <DisplayAmount>R 1.00</DisplayAmount> + <BIN>4</BIN> + <Association>VISA</Association> + <CardType>Unknown CardType</CardType> + <Issuer>Unknown</Issuer> + <Jurisdiction>International</Jurisdiction> + <PANMode>Keyed,CVV</PANMode> + <ReconReference>04078057</ReconReference> + <CardHolderPresence>CardNotPresent</CardHolderPresence> + <MerchantAddress>MERCHANT ADDRESS</MerchantAddress> + <MerchantCity>Sandton</MerchantCity> + <MerchantCountryCode>ZA</MerchantCountryCode> + <MerchantCountry>South Africa</MerchantCountry> + <DistributorName>Nedbank</DistributorName> + <CCNumber>4242........4242</CCNumber> + <PAN>4242........4242</PAN> + </Transaction> + </V_XML> XML end def failed_authorize_response - <<-XML -<V_XML Version="2.0" Direction="Response"> - <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Authorisation" Mode="Test" RequestID="{3A1A29BE-288F-4FEE-8C15-B3BB8A207544}"> - <Result Status="-1" Code="4" Description="Denied" Source="NBPostilionBICISONBSouthAfrica" AppServer="105IVERIAPPPR01" DBServer="105IVERIDBPR01" Gateway="Nedbank" AcquirerCode="05" AcquirerDescription="Do not Honour" /> - <Amount>100</Amount> - <Currency>ZAR</Currency> - <ExpiryDate>092018</ExpiryDate> - <MerchantReference>3d12442ea042e78fd33057b7b50c76f7</MerchantReference> - <Terminal>Default</Terminal> - <TransactionIndex>{8AC33FB1-0D2E-42C7-A0DB-CF8B20279825}</TransactionIndex> - <MerchantName>iVeri Payment Technology</MerchantName> - <MerchantUSN>7771777</MerchantUSN> - <Acquirer>NBPostilionBICISONBSouthAfrica</Acquirer> - <AcquirerReference>70417:04078062</AcquirerReference> - <AcquirerDate>20170417</AcquirerDate> - <AcquirerTime>202648</AcquirerTime> - <DisplayAmount>R 1.00</DisplayAmount> - <BIN>2</BIN> - <Association>Unknown Association</Association> - <CardType>Unknown CardType</CardType> - <Issuer>Unknown</Issuer> - <Jurisdiction>Local</Jurisdiction> - <PANMode>Keyed,CVV</PANMode> - <ReconReference>04078062</ReconReference> - <CardHolderPresence>CardNotPresent</CardHolderPresence> - <MerchantAddress>MERCHANT ADDRESS</MerchantAddress> - <MerchantCity>Sandton</MerchantCity> - <MerchantCountryCode>ZA</MerchantCountryCode> - <MerchantCountry>South Africa</MerchantCountry> - <DistributorName>Nedbank</DistributorName> - <CCNumber>2121........2121</CCNumber> - <PAN>2121........2121</PAN> - </Transaction> -</V_XML> + <<~XML + <V_XML Version="2.0" Direction="Response"> + <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Authorisation" Mode="Test" RequestID="{3A1A29BE-288F-4FEE-8C15-B3BB8A207544}"> + <Result Status="-1" Code="4" Description="Denied" Source="NBPostilionBICISONBSouthAfrica" AppServer="105IVERIAPPPR01" DBServer="105IVERIDBPR01" Gateway="Nedbank" AcquirerCode="05" AcquirerDescription="Do not Honour" /> + <Amount>100</Amount> + <Currency>ZAR</Currency> + <ExpiryDate>092018</ExpiryDate> + <MerchantReference>3d12442ea042e78fd33057b7b50c76f7</MerchantReference> + <Terminal>Default</Terminal> + <TransactionIndex>{8AC33FB1-0D2E-42C7-A0DB-CF8B20279825}</TransactionIndex> + <MerchantName>iVeri Payment Technology</MerchantName> + <MerchantUSN>7771777</MerchantUSN> + <Acquirer>NBPostilionBICISONBSouthAfrica</Acquirer> + <AcquirerReference>70417:04078062</AcquirerReference> + <AcquirerDate>20170417</AcquirerDate> + <AcquirerTime>202648</AcquirerTime> + <DisplayAmount>R 1.00</DisplayAmount> + <BIN>2</BIN> + <Association>Unknown Association</Association> + <CardType>Unknown CardType</CardType> + <Issuer>Unknown</Issuer> + <Jurisdiction>Local</Jurisdiction> + <PANMode>Keyed,CVV</PANMode> + <ReconReference>04078062</ReconReference> + <CardHolderPresence>CardNotPresent</CardHolderPresence> + <MerchantAddress>MERCHANT ADDRESS</MerchantAddress> + <MerchantCity>Sandton</MerchantCity> + <MerchantCountryCode>ZA</MerchantCountryCode> + <MerchantCountry>South Africa</MerchantCountry> + <DistributorName>Nedbank</DistributorName> + <CCNumber>2121........2121</CCNumber> + <PAN>2121........2121</PAN> + </Transaction> + </V_XML> XML end def successful_capture_response - <<-XML -<V_XML Version="2.0" Direction="Response"> - <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Debit" Mode="Test" RequestID="{7C91245F-607D-44AE-8958-C26E447BAEB7}"> - <Result Status="0" AppServer="105IVERIAPPPR02" DBServer="105iveridbpr01" Gateway="Nedbank" AcquirerCode="00" /> - <Amount>100</Amount> - <AuthorisationCode>541268</AuthorisationCode> - <Currency>ZAR</Currency> - <ExpiryDate>092018</ExpiryDate> - <MerchantReference>23b4125c3b8e2777bffee52e196a863b</MerchantReference> - <Terminal>Default</Terminal> - <TransactionIndex>{EF0DC64E-2D00-4B6C-BDA0-2AD265391317}</TransactionIndex> - <MerchantName>iVeri Payment Technology</MerchantName> - <MerchantUSN>7771777</MerchantUSN> - <Acquirer>NBPostilionBICISONBSouthAfrica</Acquirer> - <AcquirerReference>70417:04078057</AcquirerReference> - <AcquirerDate>20170417</AcquirerDate> - <AcquirerTime>200748</AcquirerTime> - <DisplayAmount>R 1.00</DisplayAmount> - <BIN>4</BIN> - <Association>VISA</Association> - <CardType>Unknown CardType</CardType> - <Issuer>Unknown</Issuer> - <Jurisdiction>International</Jurisdiction> - <PANMode>Keyed,CVV</PANMode> - <ReconReference>04078057</ReconReference> - <CardHolderPresence>CardNotPresent</CardHolderPresence> - <MerchantAddress>MERCHANT ADDRESS</MerchantAddress> - <MerchantCity>Sandton</MerchantCity> - <MerchantCountryCode>ZA</MerchantCountryCode> - <MerchantCountry>South Africa</MerchantCountry> - <DistributorName>Nedbank</DistributorName> - <CCNumber>4242........4242</CCNumber> - <PAN>4242........4242</PAN> - </Transaction> -</V_XML> + <<~XML + <V_XML Version="2.0" Direction="Response"> + <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Debit" Mode="Test" RequestID="{7C91245F-607D-44AE-8958-C26E447BAEB7}"> + <Result Status="0" AppServer="105IVERIAPPPR02" DBServer="105iveridbpr01" Gateway="Nedbank" AcquirerCode="00" /> + <Amount>100</Amount> + <AuthorisationCode>541268</AuthorisationCode> + <Currency>ZAR</Currency> + <ExpiryDate>092018</ExpiryDate> + <MerchantReference>23b4125c3b8e2777bffee52e196a863b</MerchantReference> + <Terminal>Default</Terminal> + <TransactionIndex>{EF0DC64E-2D00-4B6C-BDA0-2AD265391317}</TransactionIndex> + <MerchantName>iVeri Payment Technology</MerchantName> + <MerchantUSN>7771777</MerchantUSN> + <Acquirer>NBPostilionBICISONBSouthAfrica</Acquirer> + <AcquirerReference>70417:04078057</AcquirerReference> + <AcquirerDate>20170417</AcquirerDate> + <AcquirerTime>200748</AcquirerTime> + <DisplayAmount>R 1.00</DisplayAmount> + <BIN>4</BIN> + <Association>VISA</Association> + <CardType>Unknown CardType</CardType> + <Issuer>Unknown</Issuer> + <Jurisdiction>International</Jurisdiction> + <PANMode>Keyed,CVV</PANMode> + <ReconReference>04078057</ReconReference> + <CardHolderPresence>CardNotPresent</CardHolderPresence> + <MerchantAddress>MERCHANT ADDRESS</MerchantAddress> + <MerchantCity>Sandton</MerchantCity> + <MerchantCountryCode>ZA</MerchantCountryCode> + <MerchantCountry>South Africa</MerchantCountry> + <DistributorName>Nedbank</DistributorName> + <CCNumber>4242........4242</CCNumber> + <PAN>4242........4242</PAN> + </Transaction> + </V_XML> XML end def failed_capture_response - <<-XML -<V_XML Version="2.0" Direction="Response"> - <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Debit" Mode="Test" RequestID="{9DAAA002-0EF9-46DC-A440-8DCD9E78B36F}"> - <Result Status="-1" Code="14" Description="Missing PAN" Source="NBPostilionBICISONBSouthAfricaTestProvider" AppServer="105IVERIAPPPR02" DBServer="105iveridbpr01" Gateway="Nedbank" AcquirerCode="" AcquirerDescription="" /> - </Transaction> -</V_XML> + <<~XML + <V_XML Version="2.0" Direction="Response"> + <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Debit" Mode="Test" RequestID="{9DAAA002-0EF9-46DC-A440-8DCD9E78B36F}"> + <Result Status="-1" Code="14" Description="Missing PAN" Source="NBPostilionBICISONBSouthAfricaTestProvider" AppServer="105IVERIAPPPR02" DBServer="105iveridbpr01" Gateway="Nedbank" AcquirerCode="" AcquirerDescription="" /> + </Transaction> + </V_XML> XML end def successful_refund_response - <<-XML -<V_XML Version="2.0" Direction="Response"> - <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Credit" Mode="Test" RequestID="{097C55B5-D020-40AD-8949-F9F5E4102F1D}"> - <Result Status="0" AppServer="105IVERIAPPPR02" DBServer="105iveridbpr01" Gateway="Nedbank" AcquirerCode="00" /> - <Amount>100</Amount> - <AuthorisationCode>541996</AuthorisationCode> - <Currency>ZAR</Currency> - <ExpiryDate>092018</ExpiryDate> - <MerchantReference>5be2c040bd46b7eebc70274659779acf</MerchantReference> - <Terminal>Default</Terminal> - <TransactionIndex>{D50DB1B4-B6EC-4AF1-AFF7-71C2AA4A957B}</TransactionIndex> - <MerchantName>iVeri Payment Technology</MerchantName> - <MerchantUSN>7771777</MerchantUSN> - <Acquirer>NBPostilionBICISONBSouthAfrica</Acquirer> - <AcquirerReference>70417:04078059</AcquirerReference> - <AcquirerDate>20170417</AcquirerDate> - <AcquirerTime>201956</AcquirerTime> - <DisplayAmount>R 1.00</DisplayAmount> - <BIN>4</BIN> - <Association>VISA</Association> - <CardType>Unknown CardType</CardType> - <Issuer>Unknown</Issuer> - <Jurisdiction>International</Jurisdiction> - <PANMode /> - <ReconReference>04078059</ReconReference> - <CardHolderPresence>CardNotPresent</CardHolderPresence> - <MerchantAddress>MERCHANT ADDRESS</MerchantAddress> - <MerchantCity>Sandton</MerchantCity> - <MerchantCountryCode>ZA</MerchantCountryCode> - <MerchantCountry>South Africa</MerchantCountry> - <DistributorName>Nedbank</DistributorName> - <CCNumber>4242........4242</CCNumber> - <PAN>4242........4242</PAN> - </Transaction> -</V_XML> + <<~XML + <V_XML Version="2.0" Direction="Response"> + <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Credit" Mode="Test" RequestID="{097C55B5-D020-40AD-8949-F9F5E4102F1D}"> + <Result Status="0" AppServer="105IVERIAPPPR02" DBServer="105iveridbpr01" Gateway="Nedbank" AcquirerCode="00" /> + <Amount>100</Amount> + <AuthorisationCode>541996</AuthorisationCode> + <Currency>ZAR</Currency> + <ExpiryDate>092018</ExpiryDate> + <MerchantReference>5be2c040bd46b7eebc70274659779acf</MerchantReference> + <Terminal>Default</Terminal> + <TransactionIndex>{D50DB1B4-B6EC-4AF1-AFF7-71C2AA4A957B}</TransactionIndex> + <MerchantName>iVeri Payment Technology</MerchantName> + <MerchantUSN>7771777</MerchantUSN> + <Acquirer>NBPostilionBICISONBSouthAfrica</Acquirer> + <AcquirerReference>70417:04078059</AcquirerReference> + <AcquirerDate>20170417</AcquirerDate> + <AcquirerTime>201956</AcquirerTime> + <DisplayAmount>R 1.00</DisplayAmount> + <BIN>4</BIN> + <Association>VISA</Association> + <CardType>Unknown CardType</CardType> + <Issuer>Unknown</Issuer> + <Jurisdiction>International</Jurisdiction> + <PANMode /> + <ReconReference>04078059</ReconReference> + <CardHolderPresence>CardNotPresent</CardHolderPresence> + <MerchantAddress>MERCHANT ADDRESS</MerchantAddress> + <MerchantCity>Sandton</MerchantCity> + <MerchantCountryCode>ZA</MerchantCountryCode> + <MerchantCountry>South Africa</MerchantCountry> + <DistributorName>Nedbank</DistributorName> + <CCNumber>4242........4242</CCNumber> + <PAN>4242........4242</PAN> + </Transaction> + </V_XML> XML end def failed_refund_response - <<-XML -<V_XML Version="2.0" Direction="Response"> - <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Credit" Mode="Test" RequestID="{5097A60A-A112-42F1-9490-FA17A859E7A3}"> - <Result Status="-1" Code="255" Description="Credit is not supported for ApplicationID (D10A603D-4ADE-405B-93F1-826DFC0181E8)" Source="PortalService" AppServer="105IVERIAPPPR02" DBServer="105iveridbpr01" Gateway="Nedbank" AcquirerCode="" AcquirerDescription="" /> - </Transaction> -</V_XML> + <<~XML + <V_XML Version="2.0" Direction="Response"> + <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Credit" Mode="Test" RequestID="{5097A60A-A112-42F1-9490-FA17A859E7A3}"> + <Result Status="-1" Code="255" Description="Credit is not supported for ApplicationID (D10A603D-4ADE-405B-93F1-826DFC0181E8)" Source="PortalService" AppServer="105IVERIAPPPR02" DBServer="105iveridbpr01" Gateway="Nedbank" AcquirerCode="" AcquirerDescription="" /> + </Transaction> + </V_XML> XML end def successful_void_response - <<-XML -<V_XML Version="2.0" Direction="Response"> - <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Void" Mode="Test" RequestID="{0A1A3FFF-C2A3-4B91-85FD-10D1C25B765B}"> - <Result Status="0" AppServer="105IVERIAPPPR02" DBServer="105iveridbpr01" Gateway="Nedbank" /> - <OriginalRequestID>{230390C8-4A9E-4426-BDD3-15D072F135FE}</OriginalRequestID> - </Transaction> -</V_XML> + <<~XML + <V_XML Version="2.0" Direction="Response"> + <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Void" Mode="Test" RequestID="{0A1A3FFF-C2A3-4B91-85FD-10D1C25B765B}"> + <Result Status="0" AppServer="105IVERIAPPPR02" DBServer="105iveridbpr01" Gateway="Nedbank" /> + <OriginalRequestID>{230390C8-4A9E-4426-BDD3-15D072F135FE}</OriginalRequestID> + </Transaction> + </V_XML> XML end def failed_void_response - <<-XML -<V_XML Version="2.0" Direction="Response"> - <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Void" Mode="Test" RequestID="{AE97CCE4-0631-4F08-AB47-9C2698ABEC75}"> - <Result Status="-1" Code="255" Description="Missing OriginalMerchantTrace" Source="NBPostilionBICISONBSouthAfricaTestProvider" AppServer="105IVERIAPPPR01" DBServer="105IVERIDBPR01" Gateway="Nedbank" AcquirerCode="" AcquirerDescription="" /> - </Transaction> -</V_XML> + <<~XML + <V_XML Version="2.0" Direction="Response"> + <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Void" Mode="Test" RequestID="{AE97CCE4-0631-4F08-AB47-9C2698ABEC75}"> + <Result Status="-1" Code="255" Description="Missing OriginalMerchantTrace" Source="NBPostilionBICISONBSouthAfricaTestProvider" AppServer="105IVERIAPPPR01" DBServer="105IVERIDBPR01" Gateway="Nedbank" AcquirerCode="" AcquirerDescription="" /> + </Transaction> + </V_XML> XML end def successful_verify_response - <<-XML -<V_XML Version="2.0" Direction="Response"> - <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Authorisation" Mode="Test" RequestID="{F4337D04-B526-4A7E-A400-2A6DEADDCF57}"> - <Result Status="0" AppServer="105IVERIAPPPR01" DBServer="105IVERIDBPR01" Gateway="Nedbank" AcquirerCode="00" /> - <Amount>0</Amount> - <AuthorisationCode>613755</AuthorisationCode> - <Currency>ZAR</Currency> - <ExpiryDate>092018</ExpiryDate> - <MerchantReference>c0006d1d739905afc9e70beaf4194ea3</MerchantReference> - <Terminal>Default</Terminal> - <TransactionIndex>{5D5F8BF7-2D9D-42C3-AF32-08C5E62CD45E}</TransactionIndex> - <MerchantName>iVeri Payment Technology</MerchantName> - <MerchantUSN>7771777</MerchantUSN> - <Acquirer>NBPostilionBICISONBSouthAfrica</Acquirer> - <AcquirerReference>70418:04078335</AcquirerReference> - <AcquirerDate>20170418</AcquirerDate> - <AcquirerTime>161555</AcquirerTime> - <DisplayAmount>R 0.00</DisplayAmount> - <BIN>4</BIN> - <Association>VISA</Association> - <CardType>Unknown CardType</CardType> - <Issuer>Unknown</Issuer> - <Jurisdiction>International</Jurisdiction> - <PANMode>Keyed,CVV</PANMode> - <ReconReference>04078335</ReconReference> - <CardHolderPresence>CardNotPresent</CardHolderPresence> - <MerchantAddress>MERCHANT ADDRESS</MerchantAddress> - <MerchantCity>Sandton</MerchantCity> - <MerchantCountryCode>ZA</MerchantCountryCode> - <MerchantCountry>South Africa</MerchantCountry> - <DistributorName>Nedbank</DistributorName> - <CCNumber>4242........4242</CCNumber> - <PAN>4242........4242</PAN> - </Transaction> -</V_XML> - XML - end - - def failed_verify_response - <<-XML -<V_XML Version="2.0" Direction="Response"> - <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Authorisation" Mode="Test" RequestID="{A700FAE2-2A76-407D-A540-B41668E2B703}"> - <Result Status="-1" Code="4" Description="Denied" Source="NBPostilionBICISONBSouthAfrica" AppServer="105IVERIAPPPR02" DBServer="105iveridbpr01" Gateway="Nedbank" AcquirerCode="05" AcquirerDescription="Do not Honour" /> - <Amount>0</Amount> - <Currency>ZAR</Currency> - <ExpiryDate>092018</ExpiryDate> - <MerchantReference>e955afb03f224284b09ad6ae7e9b4683</MerchantReference> - <Terminal>Default</Terminal> - <TransactionIndex>{2A378547-AEA4-48E1-8A3E-29F9BBEA954D}</TransactionIndex> - <MerchantName>iVeri Payment Technology</MerchantName> - <MerchantUSN>7771777</MerchantUSN> - <Acquirer>NBPostilionBICISONBSouthAfrica</Acquirer> - <AcquirerReference>70418:04078337</AcquirerReference> - <AcquirerDate>20170418</AcquirerDate> - <AcquirerTime>161716</AcquirerTime> - <DisplayAmount>R 0.00</DisplayAmount> - <BIN>2</BIN> - <Association>Unknown Association</Association> - <CardType>Unknown CardType</CardType> - <Issuer>Unknown</Issuer> - <Jurisdiction>Local</Jurisdiction> - <PANMode>Keyed,CVV</PANMode> - <ReconReference>04078337</ReconReference> - <CardHolderPresence>CardNotPresent</CardHolderPresence> - <MerchantAddress>MERCHANT ADDRESS</MerchantAddress> - <MerchantCity>Sandton</MerchantCity> - <MerchantCountryCode>ZA</MerchantCountryCode> - <MerchantCountry>South Africa</MerchantCountry> - <DistributorName>Nedbank</DistributorName> - <CCNumber>2121........2121</CCNumber> - <PAN>2121........2121</PAN> - </Transaction> -</V_XML> + <<~XML + <V_XML Version="2.0" Direction="Response"> + <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Authorisation" Mode="Test" RequestID="{F4337D04-B526-4A7E-A400-2A6DEADDCF57}"> + <Result Status="0" AppServer="105IVERIAPPPR01" DBServer="105IVERIDBPR01" Gateway="Nedbank" AcquirerCode="00" /> + <Amount>0</Amount> + <AuthorisationCode>613755</AuthorisationCode> + <Currency>ZAR</Currency> + <ExpiryDate>092018</ExpiryDate> + <MerchantReference>c0006d1d739905afc9e70beaf4194ea3</MerchantReference> + <Terminal>Default</Terminal> + <TransactionIndex>{5D5F8BF7-2D9D-42C3-AF32-08C5E62CD45E}</TransactionIndex> + <MerchantName>iVeri Payment Technology</MerchantName> + <MerchantUSN>7771777</MerchantUSN> + <Acquirer>NBPostilionBICISONBSouthAfrica</Acquirer> + <AcquirerReference>70418:04078335</AcquirerReference> + <AcquirerDate>20170418</AcquirerDate> + <AcquirerTime>161555</AcquirerTime> + <DisplayAmount>R 0.00</DisplayAmount> + <BIN>4</BIN> + <Association>VISA</Association> + <CardType>Unknown CardType</CardType> + <Issuer>Unknown</Issuer> + <Jurisdiction>International</Jurisdiction> + <PANMode>Keyed,CVV</PANMode> + <ReconReference>04078335</ReconReference> + <CardHolderPresence>CardNotPresent</CardHolderPresence> + <MerchantAddress>MERCHANT ADDRESS</MerchantAddress> + <MerchantCity>Sandton</MerchantCity> + <MerchantCountryCode>ZA</MerchantCountryCode> + <MerchantCountry>South Africa</MerchantCountry> + <DistributorName>Nedbank</DistributorName> + <CCNumber>4242........4242</CCNumber> + <PAN>4242........4242</PAN> + </Transaction> + </V_XML> XML end def successful_verify_credentials_response - <<-XML -<V_XML Version="2.0" Direction="Response"> - <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Void" Mode="Test" RequestID="{5ED922D0-92AD-40DF-9019-320591A4BA59}"> - <Result Status="-1" Code="255" Description="Missing OriginalMerchantTrace" Source="NBPostilionBICISONBSouthAfricaTestProvider" AppServer="105IVERIAPPPR01" DBServer="105IVERIDBPR01" Gateway="Nedbank" AcquirerCode="" AcquirerDescription="" /> - </Transaction> -</V_XML> + <<~XML + <V_XML Version="2.0" Direction="Response"> + <Transaction ApplicationID="{D10A603D-4ADE-405B-93F1-826DFC0181E8}" Command="Void" Mode="Test" RequestID="{5ED922D0-92AD-40DF-9019-320591A4BA59}"> + <Result Status="-1" Code="255" Description="Missing OriginalMerchantTrace" Source="NBPostilionBICISONBSouthAfricaTestProvider" AppServer="105IVERIAPPPR01" DBServer="105IVERIDBPR01" Gateway="Nedbank" AcquirerCode="" AcquirerDescription="" /> + </Transaction> + </V_XML> XML end def failed_verify_credentials_response - <<-XML -<V_XML Version="2.0" Direction="Response"> - <Result Status="-1" Code="255" Description="The ApplicationID {11111111-1111-1111-1111-111111111111} is not valid for the current CertificateID {11111111-1111-1111-1111-111111111111}" Source="RequestHandler" RequestID="{EE6E5B39-63AD-402C-8331-F25082AD8564}" AppServer="105IVERIAPPPR01" DBServer="105IVERIDBPR01" Gateway="Nedbank" AcquirerCode="" AcquirerDescription="" /> -</V_XML> + <<~XML + <V_XML Version="2.0" Direction="Response"> + <Result Status="-1" Code="255" Description="The ApplicationID {11111111-1111-1111-1111-111111111111} is not valid for the current CertificateID {11111111-1111-1111-1111-111111111111}" Source="RequestHandler" RequestID="{EE6E5B39-63AD-402C-8331-F25082AD8564}" AppServer="105IVERIAPPPR01" DBServer="105IVERIDBPR01" Gateway="Nedbank" AcquirerCode="" AcquirerDescription="" /> + </V_XML> XML end end diff --git a/test/unit/gateways/ixopay_test.rb b/test/unit/gateways/ixopay_test.rb new file mode 100644 index 00000000000..a7f251c0d36 --- /dev/null +++ b/test/unit/gateways/ixopay_test.rb @@ -0,0 +1,673 @@ +require 'test_helper' + +class IxopayTest < Test::Unit::TestCase + include CommStub + + def setup + @gateway = IxopayGateway.new( + username: 'username', + password: 'password', + secret: 'secret', + api_key: 'api_key' + ) + + @declined_card = credit_card('4000300011112220') + @credit_card = credit_card + @amount = 100 + + @options = { + order_id: '1', + billing_address: address, + description: 'Store Purchase', + ip: '192.168.1.1' + } + + @extra_data = { extra_data: { customData1: 'some data', customData2: 'Can be anything really' } } + end + + def test_successful_purchase + response = stub_comms do + @gateway.purchase(@amount, @credit_card, @options) + end.check_request do |_endpoint, data, _headers| + assert_match(/.+<\/description>/, data) + end.respond_with(successful_purchase_response) + + assert_success response + assert_equal 'FINISHED', response.message + assert_equal 'b2bef23a30b537b90fbe|20191016-b2bef23a30b537b90fbe', response.authorization + assert response.test? + end + + def test_successful_purchase_with_extra_data + response = stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(@extra_data)) + end.check_request do |_endpoint, data, _headers| + assert_match(/some data<\/extraData>/, data) + assert_match(/Can be anything really<\/extraData>/, data) + end.respond_with(successful_purchase_response) + + assert_success response + assert_equal 'FINISHED', response.message + assert_equal 'b2bef23a30b537b90fbe|20191016-b2bef23a30b537b90fbe', response.authorization + assert response.test? + end + + def test_failed_purchase + @gateway.expects(:ssl_post).returns(failed_purchase_response) + + response = @gateway.purchase(@amount, @declined_card, @options) + + assert_failure response + assert_equal 'The transaction was declined', response.message + assert_equal '2003', response.error_code + end + + def test_failed_authentication + @gateway.expects(:ssl_post).raises(mock_response_error) + + response = @gateway.purchase(@amount, @credit_card, @options) + + assert_failure response + assert 'Invalid Signature', response.message + end + + def test_successful_authorize + @gateway.expects(:ssl_post).returns(successful_authorize_response) + + response = stub_comms do + @gateway.authorize(@amount, @credit_card, @options) + end.check_request do |_endpoint, data, _headers| + assert match(/.+<\/description>/, data) + end.respond_with(successful_authorize_response) + + assert_success response + assert_equal 'FINISHED', response.message + assert_equal '00eb44f8f0382443cce5|20191028-00eb44f8f0382443cce5', response.authorization + assert response.test? + end + + def test_successful_authorize_with_extra_data + @gateway.expects(:ssl_post).returns(successful_authorize_response) + + response = stub_comms do + @gateway.authorize(@amount, @credit_card, @options.merge(@extra_data)) + end.check_request do |_endpoint, data, _headers| + assert_match(/some data<\/extraData>/, data) + assert_match(/Can be anything really<\/extraData>/, data) + end.respond_with(successful_authorize_response) + + assert_success response + assert_equal 'FINISHED', response.message + assert_equal '00eb44f8f0382443cce5|20191028-00eb44f8f0382443cce5', response.authorization + assert response.test? + end + + def test_failed_authorize + @gateway.expects(:ssl_post).returns(failed_purchase_response) + + response = @gateway.authorize(@amount, @declined_card, @options) + + assert_failure response + assert_equal 'The transaction was declined', response.message + assert_equal '2003', response.error_code + end + + def test_successful_capture + @gateway.expects(:ssl_post).returns(successful_capture_response) + + response = @gateway.capture(@amount, '00eb44f8f0382443cce5|20191028-00eb44f8f0382443cce5') + + assert_success response + assert_equal 'FINISHED', response.message + assert_equal '17dd1e0b09221e9db038|20191031-17dd1e0b09221e9db038', response.authorization + assert response.test? + end + + def test_successful_capture_with_extra_data + @gateway.expects(:ssl_post).returns(successful_capture_response) + + response = stub_comms do + @gateway.capture(@amount, '00eb44f8f0382443cce5|20191028-00eb44f8f0382443cce5', @options.merge(@extra_data)) + end.check_request do |_endpoint, data, _header| + assert_match(/some data<\/extraData>/, data) + assert_match(/Can be anything really<\/extraData>/, data) + end.respond_with(successful_capture_response) + + assert_success response + assert_equal 'FINISHED', response.message + assert_equal '17dd1e0b09221e9db038|20191031-17dd1e0b09221e9db038', response.authorization + assert response.test? + end + + def test_failed_capture + @gateway.expects(:ssl_post).returns(failed_capture_response) + + response = @gateway.capture(@amount, nil) + + assert_failure response + assert_equal 'Transaction of type "capture" requires a referenceTransactionId', response.message + assert_equal '9999', response.error_code + end + + def test_successful_refund + @gateway.expects(:ssl_post).returns(successful_refund_response) + response = @gateway.refund(@amount, 'eb2bef23a30b537b90fb|20191016-b2bef23a30b537b90fbe') + + assert_success response + assert_equal 'FINISHED', response.message + end + + def test_successful_refund_with_extra_data + @gateway.expects(:ssl_post).returns(successful_refund_response) + + response = stub_comms do + @gateway.refund(@amount, 'eb2bef23a30b537b90fb|20191016-b2bef23a30b537b90fbe', @options.merge(@extra_data)) + end.check_request do |_endpoint, data, _header| + assert_match(/some data<\/extraData>/, data) + assert_match(/Can be anything really<\/extraData>/, data) + end.respond_with(successful_refund_response) + + assert_success response + assert_equal 'FINISHED', response.message + end + + def test_refund_includes_currency_option + options = { currency: 'USD' } + + stub_comms do + @gateway.refund(@amount, 'eb2bef23a30b537b90fb|20191016-b2bef23a30b537b90fbe', options) + end.check_request do |_endpoint, data, _headers| + assert_match(/USD<\/currency>/, data) + end.respond_with(successful_refund_response) + end + + def test_failed_refund + @gateway.expects(:ssl_post).returns(failed_refund_response) + response = @gateway.refund(@amount, nil) + + assert_failure response + assert_equal 'Transaction of type "refund" requires a referenceTransactionId', response.message + end + + def test_successful_void + @gateway.expects(:ssl_post).returns(successful_void_response) + response = @gateway.void('eb2bef23a30b537b90fb|20191016-b2bef23a30b537b90fbe') + + assert_success response + assert_equal 'FINISHED', response.message + end + + def test_successful_void_with_extra_data + @gateway.expects(:ssl_post).returns(successful_void_response) + response = stub_comms do + @gateway.void('eb2bef23a30b537b90fb|20191016-b2bef23a30b537b90fbe', @options.merge(@extra_data)) + end.check_request do |_endpoint, data, _header| + assert_match(/some data<\/extraData>/, data) + assert_match(/Can be anything really<\/extraData>/, data) + end.respond_with(successful_void_response) + + assert_success response + assert_equal 'FINISHED', response.message + end + + def test_failed_void + @gateway.expects(:ssl_post).returns(failed_void_response) + response = @gateway.void(nil) + + assert_failure response + assert_equal 'Transaction of type "void" requires a referenceTransactionId', response.message + end + + def test_successful_verify + @gateway.expects(:ssl_post).times(2).returns(successful_authorize_response, successful_void_response) + response = @gateway.verify(credit_card('4111111111111111'), @options) + + assert_success response + assert_equal 'FINISHED', response.message + end + + def test_successful_verify_with_extra_data + @gateway.expects(:ssl_post).times(2).returns(successful_authorize_response, successful_void_response) + response = stub_comms do + @gateway.verify(credit_card('4111111111111111'), @options.merge(@extra_data)) + end.check_request do |_endpoint, data, _header| + assert_match(/some data<\/extraData>/, data) + assert_match(/Can be anything really<\/extraData>/, data) + end.respond_with(successful_authorize_response, successful_void_response) + + assert_success response + assert_equal 'FINISHED', response.message + end + + def test_successful_verify_with_failed_void + @gateway.expects(:ssl_post).times(2).returns(successful_authorize_response, failed_void_response) + + response = @gateway.verify(credit_card('4111111111111111'), @options) + assert_success response + end + + def test_failed_verify + @gateway.expects(:ssl_post).returns(failed_authorize_response) + + response = @gateway.verify(@credit_card, @options) + assert_failure response + end + + def test_scrub + assert @gateway.supports_scrubbing? + assert_equal @gateway.scrub(pre_scrubbed), post_scrubbed + end + + # Stored Credential Tests + # Ixopay does not pass any parameters for cardholder/merchant initiated. + # Ixopay also doesn't support installment transactions, only recurring + # ("RECURRING") and unscheduled ("CARDONFILE"). + # + # Furthermore, Ixopay is slightly unusual in its application of stored + # credentials in that the gateway does not return a true + # network_transaction_id that can be sent on subsequent transactions. + def test_purchase_stored_credentials_initial + options = @options.merge( + stored_credential: stored_credential(:initial, :recurring) + ) + response = stub_comms do + @gateway.purchase(@amount, @credit_card, options) + end.check_request do |_endpoint, data, _headers| + assert_match(/INITIAL<\/transactionIndicator>/, data) + end.respond_with(successful_purchase_response) + + assert_success response + assert_equal 'FINISHED', response.message + end + + def test_authorize_stored_credentials_initial + options = @options.merge( + stored_credential: stored_credential(:initial, :unscheduled) + ) + response = stub_comms do + @gateway.authorize(@amount, @credit_card, options) + end.check_request do |_endpoint, data, _headers| + assert_match(/INITIAL<\/transactionIndicator>/, data) + end.respond_with(successful_authorize_response) + + assert_success response + assert_equal 'FINISHED', response.message + end + + def test_purchase_stored_credentials_recurring + options = @options.merge( + stored_credential: stored_credential(:recurring) + ) + response = stub_comms do + @gateway.purchase(@amount, @credit_card, options) + end.check_request do |_endpoint, data, _headers| + assert_match(/RECURRING<\/transactionIndicator>/, data) + end.respond_with(successful_purchase_response) + + assert_success response + assert_equal 'FINISHED', response.message + end + + def test_authorize_stored_credentials_recurring + options = @options.merge( + stored_credential: stored_credential(:recurring) + ) + response = stub_comms do + @gateway.authorize(@amount, @credit_card, options) + end.check_request do |_endpoint, data, _headers| + assert_match(/RECURRING<\/transactionIndicator>/, data) + end.respond_with(successful_authorize_response) + + assert_success response + assert_equal 'FINISHED', response.message + end + + def test_purchase_stored_credentials_unscheduled + options = @options.merge( + stored_credential: stored_credential(:unscheduled) + ) + response = stub_comms do + @gateway.purchase(@amount, @credit_card, options) + end.check_request do |_endpoint, data, _headers| + assert_match(/CARDONFILE<\/transactionIndicator>/, data) + end.respond_with(successful_purchase_response) + + assert_success response + assert_equal 'FINISHED', response.message + end + + def test_authorize_stored_credentials_unscheduled + options = @options.merge( + stored_credential: stored_credential(:unscheduled) + ) + response = stub_comms do + @gateway.authorize(@amount, @credit_card, options) + end.check_request do |_endpoint, data, _headers| + assert_match(/CARDONFILE<\/transactionIndicator>/, data) + end.respond_with(successful_authorize_response) + + assert_success response + assert_equal 'FINISHED', response.message + end + + def test_three_decimal_currency_handling + response = stub_comms do + @gateway.authorize(14200, @credit_card, @options.merge(currency: 'KWD')) + end.check_request do |_endpoint, data, _headers| + assert_match(/14.200<\/amount>/, data) + assert_match(/KWD<\/currency>/, data) + end.respond_with(successful_authorize_response) + + assert_success response + assert_equal 'FINISHED', response.message + end + + private + + def mock_response_error + mock_response = Net::HTTPUnprocessableEntity.new('1.1', '401', 'Unauthorized') + mock_response.stubs(:body).returns(failed_authentication_response) + + ActiveMerchant::ResponseError.new(mock_response) + end + + def pre_scrubbed + <<-TRANSCRIPT + opening connection to secure.ixopay.com:443... + opened + starting SSL for secure.ixopay.com:443... + SSL established + <- "POST /transaction HTTP/1.1\r\nContent-Type: text/xml; charset=utf-8\r\nAuthorization: Gateway spreedly-integration-1:i8CtuPyY820sX8hvJuRbygSnotj+VibBxqFl9MoFLYdrwC91zxymCv3h72DZBkOYT05P/L1Ig5aQrPf8SdOWtw==\r\nDate: Fri, 18 Oct 2019 19:24:53 GMT\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\nHost: secure.ixopay.com\r\nContent-Length: 1717\r\n\r\n" + <- "\n\n spreedly-dev-api\n 834ab26f399def0fea3e444d6cecbf6c61230e09\n \n Longbob Longsen\n 4111111111111111\n 123\n 09\n 2020\n \n \n 13454623-e012-4f77-b9e7-c9536964f186\n \n Jim\n Smith\n 456 My Street\n Apt 1\n Ottawa\n K1C2N6\n ON\n CA\n (555)555-5555\n Jim\n Smith\n Widgets Inc\n 456 My Street\n Apt 1\n Ottawa\n K1C2N6\n ON\n CA\n (555)555-5555\n Widgets Inc\n test@example.com\n 192.168.1.1\n \n 100\n EUR\n Store Purchase\n http://example.com\n \n\n" + -> "HTTP/1.1 200 OK\r\n" + -> "Date: Fri, 18 Oct 2019 19:24:55 GMT\r\n" + -> "Content-Type: text/html; charset=UTF-8\r\n" + -> "Transfer-Encoding: chunked\r\n" + -> "Connection: close\r\n" + -> "Set-Cookie: __cfduid=db8efa44225d95d93942c576b8f53feb31571426693; expires=Sat, 17-Oct-20 19:24:53 GMT; path=/; domain=.ixopay.com; HttpOnly\r\n" + -> "5: Content-Type: text/xml; charset=UTF-8\r\n" + -> "Cache-Control: no-cache\r\n" + -> "Strict-Transport-Security: max-age=15552000; includeSubDomains; preload\r\n" + -> "X-Content-Type-Options: nosniff\r\n" + -> "X-Server: vau-prod-webfe-esh-02\r\n" + -> "CF-Cache-Status: DYNAMIC\r\n" + -> "Expect-CT: max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\"\r\n" + -> "Server: cloudflare\r\n" + -> "CF-RAY: 527ce522ab3b9f7c-IAD\r\n" + -> "Content-Encoding: gzip\r\n" + -> "\r\n" + -> "18c\r\n" + reading 396 bytes... + -> "\x1F\x8B\b\x00\x00\x00\x00\x00\x00\x03l\x92Mo\xDB0\f\x86\xEF\xF9\x15\x82\xEF\x8D\xFC\x91\xA6\xC9 \xAB\x87eE\x03\xAC=4\xC3\x80\x1De\x89\x89\x85\xD9\x92AI\x85\xFD\xEF\v\xD9q\x96\xB4\xD3E\xE0\xCB\x87/EB\xEC\xB1o\e\xF2\x0E\xE8\xB45e\x92-\xD3\x84\x80\x91Vis*\x93\xE0\x8Fw\x9B\xE4\x91/\x18\x82\v\x8D'}\xDB\x18W&\xB5\xF7\xDD7J\x1D\xC8\x80\xB0\xD4\xBD\xED\xC4\xB0\x94\xB6\xA5\aYC+\xE8\xEF\x9C\xBE\x8D\x05\t_\x10\xC2\\\x90\x12\x9C\xE3\x1E\x030:G1\x83p\x04\x04#a\xAF\xF8\xAA(\xF2j\x9D\x17b\xBD\x11\x0F\xD5}Q\xACW\x0F\x8C^\x13\xB1\xA2\v(k\xE1b\x98\xA7\xD96K\xB3\xCD\xDD\xFF+\xAF\xC8\xA9\x95\x0Fh~\r\x1D\xF0\xA7\xFD\xEB\xFE\xF0\xFCc\x17\xDD/\xE2h.\x86\x16\x8C\x7F\x01_[\xC5\xBF#(\xED\xA5@\xC5\xE8m\xE6\x9F\xDFNxA\xFC\xD0A\x99\xC8\v\x1E\xC5qrB\xD8\xAD:\x89\x84\xB0X\xC2\xDF\xB5\x13\x8C\xFAs\xF7\t\x17\xA8\x9Em\xA3\x00\xF9OkN\x95\xADH\xBC\x1D\x18F\xAFr3\x0E}\xA7qx\xB1\xC6\xD7<\xDD2z\x1D\xDF2\x7F@ \xCF\xD3<\x9D\xA1Q\x98\x99\xA3F\xE7\x0F\xBA\xDF\xE9\x93\xF6\x8E\xAF\xB2x\x18\xFD$\xCFt#\x9C\x7F\xB2\x01\xCF\xF2\xC4~\x12\xA7\xE9\xE9\xD7\xF1\xE7\xA5_b\xE8=\x8Aq\x8F\x7Fa(\x13):\x1F\x10\xF6*\xE1\xF7J\x88,\xDB\xAC\xB7\xC5\x16\xAA\xF8\xEE3\xC8\x17\xD1$\xFE/\xBE\xF8\x00\x00\x00\xFF\xFF\x03\x00\x0F\x10\x82\b\xC1\x02\x00\x00" + read 396 bytes + reading 2 bytes... + -> "\r\n" + read 2 bytes + -> "0\r\n" + -> "\r\n" + Conn close + TRANSCRIPT + end + + def post_scrubbed + transcript = <<-TRANSCRIPT + opening connection to secure.ixopay.com:443... + opened + starting SSL for secure.ixopay.com:443... + SSL established + <- "POST /transaction HTTP/1.1\r\nContent-Type: text/xml; charset=utf-8\r\nAuthorization: Gateway [FILTERED]:i8CtuPyY820sX8hvJuRbygSnotj+VibBxqFl9MoFLYdrwC91zxymCv3h72DZBkOYT05P/L1Ig5aQrPf8SdOWtw==\r\nDate: Fri, 18 Oct 2019 19:24:53 GMT\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\nHost: secure.ixopay.com\r\nContent-Length: 1717\r\n\r\n" + <- "\n\n spreedly-dev-api\n [FILTERED]\n \n Longbob Longsen\n [FILTERED]\n [FILTERED]\n 09\n 2020\n \n \n 13454623-e012-4f77-b9e7-c9536964f186\n \n Jim\n Smith\n 456 My Street\n Apt 1\n Ottawa\n K1C2N6\n ON\n CA\n (555)555-5555\n Jim\n Smith\n Widgets Inc\n 456 My Street\n Apt 1\n Ottawa\n K1C2N6\n ON\n CA\n (555)555-5555\n Widgets Inc\n test@example.com\n 192.168.1.1\n \n 100\n EUR\n Store Purchase\n http://example.com\n \n\n" + -> "HTTP/1.1 200 OK\r\n" + -> "Date: Fri, 18 Oct 2019 19:24:55 GMT\r\n" + -> "Content-Type: text/html; charset=UTF-8\r\n" + -> "Transfer-Encoding: chunked\r\n" + -> "Connection: close\r\n" + -> "Set-Cookie: __cfduid=db8efa44225d95d93942c576b8f53feb31571426693; expires=Sat, 17-Oct-20 19:24:53 GMT; path=/; domain=.ixopay.com; HttpOnly\r\n" + -> "5: Content-Type: text/xml; charset=UTF-8\r\n" + -> "Cache-Control: no-cache\r\n" + -> "Strict-Transport-Security: max-age=15552000; includeSubDomains; preload\r\n" + -> "X-Content-Type-Options: nosniff\r\n" + -> "X-Server: vau-prod-webfe-esh-02\r\n" + -> "CF-Cache-Status: DYNAMIC\r\n" + -> "Expect-CT: max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\"\r\n" + -> "Server: cloudflare\r\n" + -> "CF-RAY: 527ce522ab3b9f7c-IAD\r\n" + -> "Content-Encoding: gzip\r\n" + -> "\r\n" + -> "18c\r\n" + reading 396 bytes... + -> "\x1F\x8B\b\x00\x00\x00\x00\x00\x00\x03l\x92Mo\xDB0\f\x86\xEF\xF9\x15\x82\xEF\x8D\xFC\x91\xA6\xC9 \xAB\x87eE\x03\xAC=4\xC3\x80\x1De\x89\x89\x85\xD9\x92AI\x85\xFD\xEF\v\xD9q\x96\xB4\xD3E\xE0\xCB\x87/EB\xEC\xB1o\e\xF2\x0E\xE8\xB45e\x92-\xD3\x84\x80\x91Vis*\x93\xE0\x8Fw\x9B\xE4\x91/\x18\x82\v\x8D'}\xDB\x18W&\xB5\xF7\xDD7J\x1D\xC8\x80\xB0\xD4\xBD\xED\xC4\xB0\x94\xB6\xA5\aYC+\xE8\xEF\x9C\xBE\x8D\x05\t_\x10\xC2\\\x90\x12\x9C\xE3\x1E\x030:G1\x83p\x04\x04#a\xAF\xF8\xAA(\xF2j\x9D\x17b\xBD\x11\x0F\xD5}Q\xACW\x0F\x8C^\x13\xB1\xA2\v(k\xE1b\x98\xA7\xD96K\xB3\xCD\xDD\xFF+\xAF\xC8\xA9\x95\x0Fh~\r\x1D\xF0\xA7\xFD\xEB\xFE\xF0\xFCc\x17\xDD/\xE2h.\x86\x16\x8C\x7F\x01_[\xC5\xBF#(\xED\xA5@\xC5\xE8m\xE6\x9F\xDFNxA\xFC\xD0A\x99\xC8\v\x1E\xC5qrB\xD8\xAD:\x89\x84\xB0X\xC2\xDF\xB5\x13\x8C\xFAs\xF7\t\x17\xA8\x9Em\xA3\x00\xF9OkN\x95\xADH\xBC\x1D\x18F\xAFr3\x0E}\xA7qx\xB1\xC6\xD7<\xDD2z\x1D\xDF2\x7F@ \xCF\xD3<\x9D\xA1Q\x98\x99\xA3F\xE7\x0F\xBA\xDF\xE9\x93\xF6\x8E\xAF\xB2x\x18\xFD$\xCFt#\x9C\x7F\xB2\x01\xCF\xF2\xC4~\x12\xA7\xE9\xE9\xD7\xF1\xE7\xA5_b\xE8=\x8Aq\x8F\x7Fa(\x13):\x1F\x10\xF6*\xE1\xF7J\x88,\xDB\xAC\xB7\xC5\x16\xAA\xF8\xEE3\xC8\x17\xD1$\xFE/\xBE\xF8\x00\x00\x00\xFF\xFF\x03\x00\x0F\x10\x82\b\xC1\x02\x00\x00" + read 396 bytes + reading 2 bytes... + -> "\r\n" + read 2 bytes + -> "0\r\n" + -> "\r\n" + Conn close + TRANSCRIPT + + remove_invalid_utf_8_byte_sequences(transcript) + end + + def remove_invalid_utf_8_byte_sequences(text) + text.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '') + end + + def successful_purchase_response + <<-XML + + + true + b2bef23a30b537b90fbe + 20191016-b2bef23a30b537b90fbe + FINISHED + Creditcard + + + visa + Longbob Longsen + 09 + 2020 + 411111 + 1111 + + + 5da76cc5ce84b + + XML + end + + def failed_purchase_response + <<-XML + + + false + d74211aa7d0ba8294b4d + 20191016-d74211aa7d0ba8294b4d + ERROR + Creditcard + + + visa + Longbob Longsen + 09 + 2020 + 400030 + 2220 + + + + + The transaction was declined + 2003 + Test decline + transaction_declined + + + + XML + end + + def failed_authentication_response + <<-XML + + + false + ERROR + + + Invalid Signature: Invalid authorization header + 1004 + + + + XML + end + + def successful_authorize_response + <<-XML + + + true + 00eb44f8f0382443cce5 + 20191028-00eb44f8f0382443cce5 + FINISHED + Creditcard + + + visa + Longbob Longsen + 09 + 2020 + 411111 + 1111 + + + + XML + end + + def failed_authorize_response + <<-XML + + + false + 91278c76405116378b85 + 20191028-91278c76405116378b85 + ERROR + Creditcard + + + visa + Longbob Longsen + 09 + 2020 + 400030 + 2220 + + + + + The transaction was declined + 2003 + Test decline + transaction_declined + + + + XML + end + + def successful_capture_response + <<-XML + + + true + 17dd1e0b09221e9db038 + 20191031-17dd1e0b09221e9db038 + FINISHED + Creditcard + + + visa + Longbob Longsen + 09 + 2020 + 411111 + 1111 + + + + XML + end + + def failed_capture_response + <<-XML + + + false + ERROR + + + Transaction of type "capture" requires a referenceTransactionId + 9999 + + + + XML + end + + def successful_refund_response + <<-XML + + true + 21c47c977476d5a3b682 + 20191028-c9e173c255d14f90816b + FINISHED + Creditcard + + XML + end + + def failed_refund_response + <<-XML + + false + ERROR + + + Transaction of type "refund" requires a referenceTransactionId + 9999 + + + + XML + end + + def successful_void_response + <<-XML + + true + cb656bd5286e77501b2e + 20191031-b1f9f7991766cf933659 + FINISHED + Creditcard + + XML + end + + def failed_void_response + <<-XML + + false + ERROR + + + Transaction of type "void" requires a referenceTransactionId + 9999 + + + + XML + end +end diff --git a/test/unit/gateways/jetpay_test.rb b/test/unit/gateways/jetpay_test.rb index 91069432c3e..88a58cea6c5 100644 --- a/test/unit/gateways/jetpay_test.rb +++ b/test/unit/gateways/jetpay_test.rb @@ -6,18 +6,18 @@ class JetpayTest < Test::Unit::TestCase def setup Base.mode = :test - @gateway = JetpayGateway.new(:login => 'login') + @gateway = JetpayGateway.new(login: 'login') @credit_card = credit_card @amount = 100 @options = { - :billing_address => address(:country => 'US'), - :shipping_address => address(:country => 'US'), - :email => 'test@test.com', - :ip => '127.0.0.1', - :order_id => '12345', - :tax => 7 + billing_address: address(country: 'US'), + shipping_address: address(country: 'US'), + email: 'test@test.com', + ip: '127.0.0.1', + order_id: '12345', + tax: 7 } end @@ -76,7 +76,7 @@ def test_successful_void def test_successful_credit # no need for csv - card = credit_card('4242424242424242', :verification_value => nil) + card = credit_card('4242424242424242', verification_value: nil) @gateway.expects(:ssl_post).returns(successful_credit_response) @@ -137,13 +137,13 @@ def test_transcript_scrubbing def test_purchase_sends_order_origin @gateway.expects(:ssl_post).with(anything, regexp_matches(/RECURRING<\/Origin>/)).returns(successful_purchase_response) - @gateway.purchase(@amount, @credit_card, {:origin => 'RECURRING'}) + @gateway.purchase(@amount, @credit_card, { origin: 'RECURRING' }) end private def successful_purchase_response - <<-EOF + <<-XML 8afa688fd002821362 000 @@ -155,21 +155,21 @@ def successful_purchase_response Y Y - EOF + XML end def failed_purchase_response - <<-EOF + <<-XML 7605f7c5d6e8f74deb 005 DECLINED - EOF + XML end def successful_authorize_response - <<-EOF + <<-XML cbf902091334a0b1aa 000 @@ -181,44 +181,44 @@ def successful_authorize_response Y Y - EOF + XML end def successful_capture_response - <<-EOF + <<-XML 010327153017T10018 000 502F6B APPROVED - EOF + XML end def successful_void_response - <<-EOF + <<-XML 010327153x17T10418 000 502F7B VOID PROCESSED - EOF + XML end def successful_credit_response - <<-EOF + <<-XML 010327153017T10017 000 002F6B APPROVED - EOF + XML end def transcript - <<-EOF + <<-XML TESTTERMINAL SALE e23c963a1247fd7aad @@ -227,11 +227,11 @@ def transcript 16 Longbob Longsen 123 - EOF + XML end def scrubbed_transcript - <<-EOF + <<-XML TESTTERMINAL SALE e23c963a1247fd7aad @@ -240,6 +240,6 @@ def scrubbed_transcript 16 Longbob Longsen [FILTERED] - EOF + XML end end diff --git a/test/unit/gateways/jetpay_v2_test.rb b/test/unit/gateways/jetpay_v2_test.rb index 8129bf5eb11..c7533d18e98 100644 --- a/test/unit/gateways/jetpay_v2_test.rb +++ b/test/unit/gateways/jetpay_v2_test.rb @@ -1,22 +1,21 @@ require 'test_helper' class JetpayV2Test < Test::Unit::TestCase - def setup - @gateway = JetpayV2Gateway.new(:login => 'login') + @gateway = JetpayV2Gateway.new(login: 'login') @credit_card = credit_card @amount = 100 @options = { - :device => 'spreedly', - :application => 'spreedly', - :developer_id => 'GenkID', - :billing_address => address(:country => 'US'), - :shipping_address => address(:country => 'US'), - :email => 'test@test.com', - :ip => '127.0.0.1', - :order_id => '12345' + device: 'spreedly', + application: 'spreedly', + developer_id: 'GenkID', + billing_address: address(country: 'US'), + shipping_address: address(country: 'US'), + email: 'test@test.com', + ip: '127.0.0.1', + order_id: '12345' } end @@ -89,7 +88,7 @@ def test_failed_void end def test_successful_credit - card = credit_card('4242424242424242', :verification_value => nil) + card = credit_card('4242424242424242', verification_value: nil) @gateway.expects(:ssl_post).returns(successful_credit_response) @@ -98,7 +97,7 @@ def test_successful_credit end def test_failed_credit - card = credit_card('2424242424242424', :verification_value => nil) + card = credit_card('2424242424242424', verification_value: nil) @gateway.expects(:ssl_post).returns(failed_credit_response) @@ -133,7 +132,7 @@ def test_successful_verify end def test_failed_verify - card = credit_card('2424242424242424', :verification_value => nil) + card = credit_card('2424242424242424', verification_value: nil) @gateway.expects(:ssl_post).returns(failed_credit_response) @@ -169,13 +168,13 @@ def test_purchase_sends_additional_options with(anything, regexp_matches(/Value3<\/UDField3>/)). returns(successful_purchase_response) - @gateway.purchase(@amount, @credit_card, {:tax => '777', :ud_field_1 => 'Value1', :ud_field_2 => 'Value2', :ud_field_3 => 'Value3'}) + @gateway.purchase(@amount, @credit_card, { tax: '777', ud_field_1: 'Value1', ud_field_2: 'Value2', ud_field_3: 'Value3' }) end private def successful_purchase_response - <<-EOF + <<-XML 8afa688fd002821362 000 @@ -187,21 +186,21 @@ def successful_purchase_response Y D - EOF + XML end def failed_purchase_response - <<-EOF + <<-XML 7605f7c5d6e8f74deb 005 DECLINED - EOF + XML end def successful_authorize_response - <<-EOF + <<-XML cbf902091334a0b1aa 000 @@ -213,75 +212,75 @@ def successful_authorize_response Y D - EOF + XML end def successful_capture_response - <<-EOF + <<-XML 010327153017T10018 000 502F6B APPROVED - EOF + XML end def failed_capture_response - <<-EOF + <<-XML 010327153017T10018 025 REJECT ED - EOF + XML end def successful_void_response - <<-EOF + <<-XML 010327153x17T10418 000 502F7B VOID PROCESSED - EOF + XML end def failed_void_response - <<-EOF + <<-XML 010327153x17T10418 900 INVALID MESSAGE TYPE - EOF + XML end def successful_credit_response - <<-EOF + <<-XML 010327153017T10017 000 002F6B APPROVED - EOF + XML end def failed_credit_response - <<-EOF + <<-XML 010327153017T10017 912 INVALID CARD NUMBER - EOF + XML end def transcript - <<-EOF + <<-XML TESTMCC3136X SALE e23c963a1247fd7aad @@ -290,11 +289,11 @@ def transcript 16 Longbob Longsen 123 - EOF + XML end def scrubbed_transcript - <<-EOF + <<-XML TESTMCC3136X SALE e23c963a1247fd7aad @@ -303,6 +302,6 @@ def scrubbed_transcript 16 Longbob Longsen [FILTERED] - EOF + XML end end diff --git a/test/unit/gateways/komoju_test.rb b/test/unit/gateways/komoju_test.rb index dc67d18686c..deaf75df6f4 100644 --- a/test/unit/gateways/komoju_test.rb +++ b/test/unit/gateways/komoju_test.rb @@ -2,19 +2,19 @@ class KomojuTest < Test::Unit::TestCase def setup - @gateway = KomojuGateway.new(:login => 'login') + @gateway = KomojuGateway.new(login: 'login') @credit_card = credit_card @amount = 100 @options = { - :order_id => '1', - :description => 'Store Purchase', - :tax => '10', - :ip => '192.168.0.1', - :email => 'valid@email.com', - :browser_language => 'en', - :browser_user_agent => 'user_agent' + order_id: '1', + description: 'Store Purchase', + tax: '10', + ip: '192.168.0.1', + email: 'valid@email.com', + browser_language: 'en', + browser_user_agent: 'user_agent' } end @@ -59,7 +59,7 @@ def test_successful_credit_card_refund successful_response = successful_credit_card_refund_response @gateway.expects(:ssl_post).returns(JSON.generate(successful_response)) - response = @gateway.refund(@amount, '7e8c55a54256ce23e387f2838c', @options) + response = @gateway.refund(@amount, '7e8c55a54256ce23e387f2838c', @options) assert_success response assert_equal successful_response['id'], response.authorization diff --git a/test/unit/gateways/kushki_test.rb b/test/unit/gateways/kushki_test.rb index 861d82f8354..a44ceb16ad2 100644 --- a/test/unit/gateways/kushki_test.rb +++ b/test/unit/gateways/kushki_test.rb @@ -68,10 +68,8 @@ def test_taxes_are_excluded_when_not_provided response = stub_comms do @gateway.purchase(amount, @credit_card, options) - end.check_request do |endpoint, data, headers| - if /charges/ =~ endpoint - assert_no_match %r{extraTaxes}, data - end + end.check_request do |endpoint, data, _headers| + assert_no_match %r{extraTaxes}, data if /charges/.match?(endpoint) end.respond_with(successful_charge_response, successful_token_response) assert_success response @@ -101,8 +99,8 @@ def test_partial_taxes_do_not_error response = stub_comms do @gateway.purchase(amount, @credit_card, options) - end.check_request do |endpoint, data, headers| - if /charges/ =~ endpoint + end.check_request do |endpoint, data, _headers| + if /charges/.match?(endpoint) assert_match %r{extraTaxes}, data assert_no_match %r{propina}, data assert_match %r{iac}, data @@ -138,8 +136,8 @@ def test_taxes_are_included_when_provided response = stub_comms do @gateway.purchase(amount, @credit_card, options) - end.check_request do |endpoint, data, headers| - if /charges/ =~ endpoint + end.check_request do |endpoint, data, _headers| + if /charges/.match?(endpoint) assert_match %r{extraTaxes}, data assert_match %r{propina}, data end @@ -164,6 +162,33 @@ def test_failed_purchase assert_equal '220', response.error_code end + def test_successful_authorize + @gateway.expects(:ssl_post).returns(successful_authorize_response) + @gateway.expects(:ssl_post).returns(successful_token_response) + + response = @gateway.authorize(@amount, @credit_card) + assert_success response + assert_equal 'Succeeded', response.message + assert_match %r(^\d+$), response.authorization + assert response.test? + end + + def test_failed_authorize + options = { + amount: { + subtotal_iva: '200' + } + } + + @gateway.expects(:ssl_post).returns(failed_authorize_response) + @gateway.expects(:ssl_post).returns(successful_token_response) + + response = @gateway.purchase(@amount, @credit_card, options) + assert_failure response + assert_equal 'Monto de la transacción es diferente al monto de la venta inicial', response.message + assert_equal '220', response.error_code + end + def test_successful_refund @gateway.expects(:ssl_post).returns(successful_charge_response) @gateway.expects(:ssl_post).returns(successful_token_response) @@ -193,6 +218,35 @@ def test_failed_refund assert_equal 'K010', refund.error_code end + def test_successful_capture + @gateway.expects(:ssl_post).returns(successful_authorize_response) + @gateway.expects(:ssl_post).returns(successful_token_response) + + auth = @gateway.authorize(@amount, @credit_card) + assert_success auth + + @gateway.expects(:ssl_post).returns(successful_capture_response) + + assert capture = @gateway.capture(@amount, auth.authorization) + assert_success capture + assert_equal 'Succeeded', capture.message + end + + def test_failed_capture + @gateway.expects(:ssl_post).returns(successful_authorize_response) + @gateway.expects(:ssl_post).returns(successful_token_response) + + auth = @gateway.authorize(@amount, @credit_card) + assert_success auth + + @gateway.expects(:ssl_post).returns(failed_capture_response) + + assert capture = @gateway.capture(@amount, auth.authorization) + assert_failure capture + assert_equal 'Monto de captura inválido.', capture.message + assert_equal 'K012', capture.error_code + end + def test_successful_void @gateway.expects(:ssl_post).returns(successful_charge_response) @gateway.expects(:ssl_post).returns(successful_token_response) @@ -346,6 +400,39 @@ def failed_charge_response ) end + def successful_authorize_response + %( + { + "ticketNumber":"676185788080292214" + } + ) + end + + def failed_authorize_response + %( + { + "code":"220", + "message":"Monto de la transacción es diferente al monto de la venta inicial" + } + ) + end + + def successful_capture_response + %( + { + "ticketNumber":"911597984059374763" + } + ) + end + + def failed_capture_response + %( + { + "code":"K012","message":"Monto de captura inválido." + } + ) + end + def successful_refund_response %( { diff --git a/test/unit/gateways/latitude19_test.rb b/test/unit/gateways/latitude19_test.rb index 75f7b75cba8..afb7de4214f 100644 --- a/test/unit/gateways/latitude19_test.rb +++ b/test/unit/gateways/latitude19_test.rb @@ -1,6 +1,8 @@ require 'test_helper' class Latitude19Test < Test::Unit::TestCase + include CommStub + def setup @gateway = Latitude19Gateway.new(fixtures(:latitude19)) @@ -29,18 +31,18 @@ def test_successful_purchase # end def test_successful_authorize_and_capture - @gateway.expects(:ssl_post).returns(successful_authorize_response) - @gateway.expects(:ssl_post).returns(successful_token_response) - @gateway.expects(:ssl_post).returns(successful_session_response) - - response = @gateway.authorize(@amount, @credit_card, @options) + response = stub_comms do + @gateway.authorize(@amount, @credit_card, @options) + end.respond_with(successful_session_response, successful_token_response, successful_authorize_response) assert_success response assert_equal 'Approved', response.message assert_match %r(^auth\|\w+$), response.authorization - @gateway.expects(:ssl_post).returns(successful_capture_response) - - capture = @gateway.capture(@amount, response.authorization, @options) + capture = stub_comms do + @gateway.capture(@amount, response.authorization, @options) + end.check_request do |_endpoint, data, _headers| + assert_match(/"amount\":\"1.00\"/, data) + end.respond_with(successful_capture_response) assert_success capture assert_equal 'Approved', capture.message end diff --git a/test/unit/gateways/linkpoint_test.rb b/test/unit/gateways/linkpoint_test.rb index 50639eb460a..9d14398a1bb 100644 --- a/test/unit/gateways/linkpoint_test.rb +++ b/test/unit/gateways/linkpoint_test.rb @@ -5,13 +5,13 @@ def setup Base.mode = :test @gateway = LinkpointGateway.new( - :login => 123123, - :pem => 'PEM' + login: 123123, + pem: 'PEM' ) @amount = 100 @credit_card = credit_card('4111111111111111') - @options = { :order_id => 1000, :billing_address => address } + @options = { order_id: 1000, billing_address: address } end def test_instantiating_without_credential_raises @@ -65,7 +65,7 @@ def test_recurring @gateway.expects(:ssl_post).returns(successful_recurring_response) response = assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.recurring(2400, @credit_card, :order_id => 1003, :installments => 12, :startdate => 'immediate', :periodicity => :monthly) + @gateway.recurring(2400, @credit_card, order_id: 1003, installments: 12, startdate: 'immediate', periodicity: :monthly) end assert_success response end @@ -81,13 +81,13 @@ def test_amount_style def test_purchase_is_valid_xml @gateway.send( :parameters, 1000, @credit_card, - :ordertype => 'SALE', - :order_id => 1004, - :billing_address => { - :address1 => '1313 lucky lane', - :city => 'Lost Angeles', - :state => 'CA', - :zip => '90210' + ordertype: 'SALE', + order_id: 1004, + billing_address: { + address1: '1313 lucky lane', + city: 'Lost Angeles', + state: 'CA', + zip: '90210' } ) @@ -98,17 +98,17 @@ def test_purchase_is_valid_xml def test_recurring_is_valid_xml @gateway.send( :parameters, 1000, @credit_card, - :ordertype => 'SALE', - :action => 'SUBMIT', - :installments => 12, - :startdate => 'immediate', - :periodicity => 'monthly', - :order_id => 1006, - :billing_address => { - :address1 => '1313 lucky lane', - :city => 'Lost Angeles', - :state => 'CA', - :zip => '90210' + ordertype: 'SALE', + action: 'SUBMIT', + installments: 12, + startdate: 'immediate', + periodicity: 'monthly', + order_id: 1006, + billing_address: { + address1: '1313 lucky lane', + city: 'Lost Angeles', + state: 'CA', + zip: '90210' } ) assert data = @gateway.send(:post_data, @amount, @credit_card, @options) @@ -117,38 +117,40 @@ def test_recurring_is_valid_xml def test_line_items_are_valid_xml options = { - :ordertype => 'SALE', - :action => 'SUBMIT', - :installments => 12, - :startdate => 'immediate', - :periodicity => 'monthly', - :order_id => 1006, - :billing_address => { - :address1 => '1313 lucky lane', - :city => 'Lost Angeles', - :state => 'CA', - :zip => '90210' - }, - :line_items => [ + ordertype: 'SALE', + action: 'SUBMIT', + installments: 12, + startdate: 'immediate', + periodicity: 'monthly', + order_id: 1006, + billing_address: { + address1: '1313 lucky lane', + city: 'Lost Angeles', + state: 'CA', + zip: '90210' + }, + line_items: [ { - :id => '123456', - :description => 'Logo T-Shirt', - :price => '12.00', - :quantity => '1', - :options => [ + id: '123456', + description: 'Logo T-Shirt', + price: '12.00', + quantity: '1', + options: [ { - :name => 'Color', - :value => 'Red'}, + name: 'Color', + value: 'Red' + }, { - :name => 'Size', - :value => 'XL'} + name: 'Size', + value: 'XL' + } ] }, { - :id => '111', - :description => 'keychain', - :price => '3.00', - :quantity => '1' + id: '111', + description: 'keychain', + price: '3.00', + quantity: '1' } ] } @@ -158,17 +160,17 @@ def test_line_items_are_valid_xml end def test_declined_purchase_is_valid_xml - @gateway = LinkpointGateway.new(:login => 123123, :pem => 'PEM') + @gateway = LinkpointGateway.new(login: 123123, pem: 'PEM') @gateway.send( :parameters, 1000, @credit_card, - :ordertype => 'SALE', - :order_id => 1005, - :billing_address => { - :address1 => '1313 lucky lane', - :city => 'Lost Angeles', - :state => 'CA', - :zip => '90210' + ordertype: 'SALE', + order_id: 1005, + billing_address: { + address1: '1313 lucky lane', + city: 'Lost Angeles', + state: 'CA', + zip: '90210' } ) @@ -180,9 +182,9 @@ def test_overriding_test_mode Base.mode = :production gateway = LinkpointGateway.new( - :login => 'LOGIN', - :pem => 'PEM', - :test => true + login: 'LOGIN', + pem: 'PEM', + test: true ) assert gateway.test? @@ -192,8 +194,8 @@ def test_using_production_mode Base.mode = :production gateway = LinkpointGateway.new( - :login => 'LOGIN', - :pem => 'PEM' + login: 'LOGIN', + pem: 'PEM' ) assert !gateway.test? @@ -204,7 +206,7 @@ def test_supported_countries end def test_supported_card_types - assert_equal [:visa, :master, :american_express, :discover, :jcb, :diners_club], LinkpointGateway.supported_cardtypes + assert_equal %i[visa master american_express discover jcb diners_club], LinkpointGateway.supported_cardtypes end def test_avs_result @@ -254,5 +256,4 @@ def transcript def scrubbed_transcript '[FILTERED]916[FILTERED]providedJim Smith' end - end diff --git a/test/unit/gateways/litle_test.rb b/test/unit/gateways/litle_test.rb index 2eafd178f35..cdee0760780 100644 --- a/test/unit/gateways/litle_test.rb +++ b/test/unit/gateways/litle_test.rb @@ -20,7 +20,8 @@ def setup brand: 'visa', number: '44444444400009', payment_cryptogram: 'BwABBJQ1AgAAAAAgJDUCAAAAAAA=' - }) + } + ) @decrypted_android_pay = ActiveMerchant::Billing::NetworkTokenizationCreditCard.new( { source: :android_pay, @@ -29,7 +30,8 @@ def setup brand: 'visa', number: '4457000300000007', payment_cryptogram: 'BwABBJQ1AgAAAAAgJDUCAAAAAAA=' - }) + } + ) @amount = 100 @options = {} @check = check( @@ -44,11 +46,43 @@ def setup account_number: '1099999999', account_type: 'checking' ) + + @long_address = { + address1: '1234 Supercalifragilisticexpialidocious', + address2: 'Unit 6', + city: '‎Lake Chargoggagoggmanchauggagoggchaubunagungamaugg', + state: 'ME', + zip: '09901', + country: 'US' + } end def test_successful_purchase response = stub_comms do @gateway.purchase(@amount, @credit_card) + end.check_request do |endpoint, _data, _headers| + # Counterpoint to test_successful_postlive_url: + assert_match(/www\.testvantivcnp\.com/, endpoint) + end.respond_with(successful_purchase_response) + + assert_success response + + assert_equal '100000000000000006;sale;100', response.authorization + assert response.test? + end + + def test_successful_postlive_url + @gateway = LitleGateway.new( + login: 'login', + password: 'password', + merchant_id: 'merchant_id', + url_override: 'postlive' + ) + + response = stub_comms do + @gateway.purchase(@amount, @credit_card) + end.check_request do |endpoint, _data, _headers| + assert_match(/payments\.vantivpostlive\.com/, endpoint) end.respond_with(successful_purchase_response) assert_success response @@ -87,7 +121,7 @@ def test_passing_merchant_data ) 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(some-affiliate), data) assert_match(%r(super-awesome-campaign), data) assert_match(%r(brilliant-group), data) @@ -97,7 +131,7 @@ def test_passing_merchant_data def test_passing_name_on_card stub_comms do @gateway.purchase(@amount, @credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r(\s*Longbob Longsen<), data) end.respond_with(successful_purchase_response) end @@ -105,15 +139,39 @@ def test_passing_name_on_card def test_passing_order_id stub_comms do @gateway.purchase(@amount, @credit_card, order_id: '774488') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/774488/, data) end.respond_with(successful_purchase_response) end + def test_passing_customer_id_on_purchase + stub_comms do + @gateway.purchase(@amount, @credit_card, customer_id: '8675309') + end.check_request do |_endpoint, data, _headers| + assert_match(%r(customerId=\"8675309\">\n), data) + end.respond_with(successful_purchase_response) + end + + def test_passing_customer_id_on_capture + stub_comms do + @gateway.capture(@amount, @credit_card, customer_id: '8675309') + end.check_request do |_endpoint, data, _headers| + assert_match(%r(customerId=\"8675309\">\n), data) + end.respond_with(successful_capture_response) + end + + def test_passing_customer_id_on_refund + stub_comms do + @gateway.credit(@amount, @credit_card, customer_id: '8675309') + end.check_request do |_endpoint, data, _headers| + assert_match(%r(customerId=\"8675309\">\n), data) + end.respond_with(successful_credit_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| + end.check_request do |_endpoint, data, _headers| assert_match(/.*Widgets.*456.*Apt 1.*Otta.*ON.*K1C.*CA.*555-5/m, data) end.respond_with(successful_purchase_response) end @@ -121,17 +179,25 @@ def test_passing_billing_address def test_passing_shipping_address stub_comms do @gateway.purchase(@amount, @credit_card, shipping_address: address) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/.*Widgets.*456.*Apt 1.*Otta.*ON.*K1C.*CA.*555-5/m, data) end.respond_with(successful_purchase_response) end + def test_truncating_billing_address + stub_comms do + @gateway.purchase(@amount, @credit_card, billing_address: @long_address) + end.check_request do |_endpoint, data, _headers| + refute_match(/Supercalifragilisticexpialidocious/m, data) + end.respond_with(successful_purchase_response) + end + def test_passing_descriptor stub_comms do @gateway.authorize(@amount, @credit_card, { descriptor_name: 'Name', descriptor_phone: 'Phone' }) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r(.*Name<)m, data) assert_match(%r(.*Phone<)m, data) end.respond_with(successful_authorize_response) @@ -140,7 +206,7 @@ def test_passing_descriptor def test_passing_debt_repayment stub_comms do @gateway.authorize(@amount, @credit_card, { debt_repayment: true }) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r(true), data) end.respond_with(successful_authorize_response) end @@ -148,15 +214,38 @@ def test_passing_debt_repayment def test_passing_payment_cryptogram stub_comms do @gateway.purchase(@amount, @decrypted_apple_pay) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/BwABBJQ1AgAAAAAgJDUCAAAAAAA=/, data) end.respond_with(successful_purchase_response) end + def test_passing_basis_date + stub_comms do + @gateway.purchase(@amount, 'token', { basis_expiration_month: '04', basis_expiration_year: '2027' }) + end.check_request do |_endpoint, data, _headers| + assert_match(/0427<\/expDate>/, data) + end.respond_with(successful_purchase_response) + end + + def test_does_not_pass_empty_checknum + check = check( + name: 'Tom Black', + routing_number: '011075150', + account_number: '4099999992', + number: nil, + account_type: 'checking' + ) + stub_comms do + @gateway.purchase(@amount, check) + end.check_request do |_endpoint, data, _headers| + assert_not_match(//m, data) + end.respond_with(successful_purchase_response) + end + def test_add_applepay_order_source stub_comms do @gateway.purchase(@amount, @decrypted_apple_pay) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match 'applepay', data end.respond_with(successful_purchase_response) end @@ -164,7 +253,7 @@ def test_add_applepay_order_source def test_add_android_pay_order_source stub_comms do @gateway.purchase(@amount, @decrypted_android_pay) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match 'androidpay', data end.respond_with(successful_purchase_response) end @@ -181,7 +270,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(/100000000000000001/, data) end.respond_with(successful_capture_response) @@ -217,7 +306,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(/100000000000000006/, data) end.respond_with(successful_refund_response) @@ -234,6 +323,23 @@ def test_failed_refund assert_equal '360', response.params['response'] end + def test_successful_credit + credit = stub_comms do + @gateway.credit(@amount, @credit_card) + end.respond_with(successful_credit_response) + + assert_success credit + assert_equal 'Approved', credit.message + end + + def test_failed_credit + credit = stub_comms do + @gateway.credit(@amount, @credit_card) + end.respond_with(failed_credit_response) + + assert_failure credit + end + def test_successful_void_of_authorization response = stub_comms do @gateway.authorize(@amount, @credit_card) @@ -244,7 +350,7 @@ def test_successful_void_of_authorization void = stub_comms do @gateway.void(response.authorization) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/1000000000000000011000000000000000034242424242424242Track Data', data assert_match 'retail', data assert_match %r{.+<\/pos>}m, data @@ -364,7 +470,7 @@ def test_add_swipe_data_with_creditcard def test_order_source_with_creditcard_no_track_data stub_comms do @gateway.purchase(@amount, @credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match 'ecommerce', data assert %r{.+<\/pos>}m !~ data end.respond_with(successful_purchase_response) @@ -373,7 +479,7 @@ def test_order_source_with_creditcard_no_track_data def test_order_source_override stub_comms do @gateway.purchase(@amount, @credit_card, order_source: 'recurring') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match 'recurring', data end.respond_with(successful_purchase_response) end @@ -400,7 +506,7 @@ def test_stored_credential_cit_card_on_file_initial 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(%r(initialCOF), data) end.respond_with(successful_authorize_stored_credentials) @@ -419,7 +525,7 @@ def test_stored_credential_cit_card_on_file_used 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(%r(cardholderInitiatedCOF), data) assert_match(%r(#{network_transaction_id}), data) assert_match(%r(ecommerce), data) @@ -443,7 +549,7 @@ def test_stored_credential_cit_cof_doesnt_override_order_source 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(%r(cardholderInitiatedCOF), data) assert_match(%r(#{network_transaction_id}), data) assert_match(%r(3dsAuthenticated), data) @@ -464,7 +570,7 @@ def test_stored_credential_mit_card_on_file_initial 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(%r(initialCOF), data) end.respond_with(successful_authorize_stored_credentials) @@ -483,7 +589,7 @@ def test_stored_credential_mit_card_on_file_used 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(%r(merchantInitiatedCOF), data) assert_match(%r(#{network_transaction_id}), data) assert_match(%r(ecommerce), data) @@ -504,7 +610,7 @@ def test_stored_credential_installment_initial 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(%r(initialInstallment), data) end.respond_with(successful_authorize_stored_credentials) @@ -523,7 +629,7 @@ def test_stored_credential_installment_used 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(%r(#{network_transaction_id}), data) assert_match(%r(installment), data) end.respond_with(successful_authorize_stored_credentials) @@ -543,7 +649,7 @@ def test_stored_credential_recurring_initial 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(%r(initialRecurring), data) end.respond_with(successful_authorize_stored_credentials) @@ -562,7 +668,7 @@ def test_stored_credential_recurring_used 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(%r(#{network_transaction_id}), data) assert_match(%r(recurring), data) end.respond_with(successful_authorize_stored_credentials) @@ -740,6 +846,28 @@ def failed_refund_response ) end + def successful_credit_response + %( + + + + 908410935514139173 + 1 + 000 + 2020-10-30T19:19:38.935 + Approved + + + ) + end + + def failed_credit_response + %( + + + ) + end + def successful_void_of_auth_response %( @@ -864,7 +992,7 @@ def unsuccessful_xml_schema_validation_response end def pre_scrub - <<-pre_scrub + <<-REQUEST opening connection to www.testlitle.com:443... opened starting SSL for www.testlitle.com:443... @@ -890,11 +1018,11 @@ def pre_scrub -> "0\r\n" -> "\r\n" Conn close - pre_scrub + REQUEST end def post_scrub - <<-post_scrub + <<-REQUEST opening connection to www.testlitle.com:443... opened starting SSL for www.testlitle.com:443... @@ -920,7 +1048,6 @@ def post_scrub -> "0\r\n" -> "\r\n" Conn close - post_scrub + REQUEST end - end diff --git a/test/unit/gateways/maxipago_test.rb b/test/unit/gateways/maxipago_test.rb index b437bcda00a..afac8fc8912 100644 --- a/test/unit/gateways/maxipago_test.rb +++ b/test/unit/gateways/maxipago_test.rb @@ -3,18 +3,18 @@ class MaxipagoTest < Test::Unit::TestCase def setup @gateway = MaxipagoGateway.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', - :installments => 3 + order_id: '1', + billing_address: address, + description: 'Store Purchase', + installments: 3 } end diff --git a/test/unit/gateways/mercado_pago_test.rb b/test/unit/gateways/mercado_pago_test.rb index 02dbc7f7324..2c4d446575a 100644 --- a/test/unit/gateways/mercado_pago_test.rb +++ b/test/unit/gateways/mercado_pago_test.rb @@ -7,26 +7,23 @@ def setup @gateway = MercadoPagoGateway.new(access_token: 'access_token') @credit_card = credit_card @elo_credit_card = credit_card('5067268650517446', - :month => 10, - :year => 2020, - :first_name => 'John', - :last_name => 'Smith', - :verification_value => '737' - ) + month: 10, + year: 2020, + first_name: 'John', + last_name: 'Smith', + verification_value: '737') @cabal_credit_card = credit_card('6035227716427021', - :month => 10, - :year => 2020, - :first_name => 'John', - :last_name => 'Smith', - :verification_value => '737' - ) + month: 10, + year: 2020, + first_name: 'John', + last_name: 'Smith', + verification_value: '737') @naranja_credit_card = credit_card('5895627823453005', - :month => 10, - :year => 2020, - :first_name => 'John', - :last_name => 'Smith', - :verification_value => '123' - ) + month: 10, + year: 2020, + first_name: 'John', + last_name: 'Smith', + verification_value: '123') @amount = 100 @options = { @@ -100,6 +97,17 @@ def test_successful_authorize assert response.test? end + def test_successful_authorize_with_capture_option + @gateway.expects(:ssl_post).at_most(2).returns(successful_authorize_with_capture_option_response) + + response = @gateway.authorize(@amount, @credit_card, @options.merge(capture: true)) + assert_success response + + assert_equal '4261941|1.0', response.authorization + assert_equal 'accredited', response.message + assert response.test? + end + def test_successful_authorize_with_elo @gateway.expects(:ssl_post).at_most(2).returns(successful_authorize_with_elo_response) @@ -274,10 +282,8 @@ def test_does_not_send_brand response = stub_comms do @gateway.purchase(@amount, credit_card, @options) - end.check_request do |endpoint, data, headers| - if endpoint =~ /payments/ - assert_not_match(%r("payment_method_id":"amex"), data) - end + end.check_request do |endpoint, data, _headers| + assert_not_match(%r("payment_method_id":"amex"), data) if endpoint =~ /payments/ end.respond_with(successful_purchase_response) assert_success response @@ -289,31 +295,39 @@ def test_sends_payment_method_id response = stub_comms do @gateway.purchase(@amount, credit_card, @options.merge(payment_method_id: 'diners')) - end.check_request do |endpoint, data, headers| - if endpoint =~ /payments/ - assert_match(%r("payment_method_id":"diners"), data) - end + end.check_request do |endpoint, data, _headers| + assert_match(%r("payment_method_id":"diners"), data) if endpoint =~ /payments/ end.respond_with(successful_purchase_response) assert_success response assert_equal '4141491|1.0', response.authorization end + def test_successful_purchase_with_notification_url + response = stub_comms do + @gateway.purchase(@amount, credit_card, @options.merge(notification_url: 'www.mercado-pago.com')) + end.check_request do |endpoint, data, _headers| + assert_match(%r("notification_url":"www.mercado-pago.com"), data) if endpoint =~ /payments/ + end.respond_with(successful_purchase_response) + + assert_success response + end + def test_includes_deviceid_header @options[:device_id] = '1a2b3c' - @gateway.expects(:ssl_post).with(anything, anything, {'Content-Type' => 'application/json'}).returns(successful_purchase_response) - @gateway.expects(:ssl_post).with(anything, anything, {'Content-Type' => 'application/json', 'X-Device-Session-ID' => '1a2b3c'}).returns(successful_purchase_response) + @gateway.expects(:ssl_post).with(anything, anything, { 'Content-Type' => 'application/json' }).returns(successful_purchase_response) + @gateway.expects(:ssl_post).with(anything, anything, { 'Content-Type' => 'application/json', 'X-meli-session-id' => '1a2b3c' }).returns(successful_purchase_response) response = @gateway.purchase(@amount, @credit_card, @options) assert_success response end def test_includes_additional_data - @options[:additional_info] = {'foo' => 'bar', 'baz' => 'quux'} + @options[:additional_info] = { 'foo' => 'bar', 'baz' => 'quux' } response = stub_comms do @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| - if data =~ /payment_method_id/ + end.check_request do |_endpoint, data, _headers| + if /payment_method_id/.match?(data) assert_match(/"foo":"bar"/, data) assert_match(/"baz":"quux"/, data) end @@ -325,16 +339,114 @@ def test_includes_additional_data def test_includes_issuer_id response = stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(issuer_id: '1a2b3c4d')) - end.check_request do |endpoint, data, headers| - if endpoint =~ /payments/ - assert_match(%r("issuer_id":"1a2b3c4d"), data) - end + end.check_request do |endpoint, data, _headers| + assert_match(%r("issuer_id":"1a2b3c4d"), data) if endpoint =~ /payments/ end.respond_with(successful_purchase_response) assert_success response assert_equal '4141491|1.0', response.authorization end + def test_purchase_includes_taxes_array + taxes_type = 'IVA' + taxes_value = 500.0 + taxes_object = { value: taxes_value, type: taxes_type } + taxes_array = [taxes_object, taxes_object] + + stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(taxes: taxes_array)) + end.check_request do |endpoint, data, _headers| + single_pattern = "{\"value\":#{taxes_value},\"type\":\"#{taxes_type}\"}" + pattern = "\"taxes\":[#{single_pattern},#{single_pattern}]" + assert_match(pattern, data) if endpoint =~ /payments/ + end.respond_with(successful_purchase_response) + end + + def test_purchase_includes_taxes_hash + taxes_type = 'IVA' + taxes_value = 500.0 + taxes_object = { value: taxes_value, type: taxes_type } + + stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(taxes: taxes_object)) + end.check_request do |endpoint, data, _headers| + pattern = "\"taxes\":[{\"value\":#{taxes_value},\"type\":\"#{taxes_type}\"}]" + assert_match(pattern, data) if endpoint =~ /payments/ + end.respond_with(successful_purchase_response) + end + + def test_purchase_includes_net_amount + net_amount = 9500 + + stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(net_amount: net_amount)) + end.check_request do |endpoint, data, _headers| + assert_match("\"net_amount\":#{net_amount}", data) if endpoint =~ /payments/ + end.respond_with(successful_purchase_response) + end + + def test_authorize_includes_taxes_array + taxes_type = 'IVA' + taxes_value = 500.0 + taxes_object = { value: taxes_value, type: taxes_type } + taxes_array = [taxes_object, taxes_object] + + stub_comms do + @gateway.authorize(@amount, @credit_card, @options.merge(taxes: taxes_array)) + end.check_request do |endpoint, data, _headers| + single_pattern = "{\"value\":#{taxes_value},\"type\":\"#{taxes_type}\"}" + pattern = "\"taxes\":[#{single_pattern},#{single_pattern}]" + assert_match(pattern, data) if endpoint =~ /payments/ + end.respond_with(successful_authorize_response) + end + + def test_authorize_includes_taxes_hash + taxes_type = 'IVA' + taxes_value = 500.0 + taxes_object = { value: taxes_value, type: taxes_type } + + stub_comms do + @gateway.authorize(@amount, @credit_card, @options.merge(taxes: taxes_object)) + end.check_request do |endpoint, data, _headers| + pattern = "\"taxes\":[{\"value\":#{taxes_value},\"type\":\"#{taxes_type}\"}]" + assert_match(pattern, data) if endpoint =~ /payments/ + end.respond_with(successful_authorize_response) + end + + def test_authorize_includes_net_amount + net_amount = 9500 + + stub_comms do + @gateway.authorize(@amount, @credit_card, @options.merge(net_amount: net_amount)) + end.check_request do |endpoint, data, _headers| + assert_match("\"net_amount\":#{net_amount}", data) if endpoint =~ /payments/ + end.respond_with(successful_authorize_response) + end + + def test_invalid_taxes_type + assert_raises(ArgumentError) do + stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(taxes: 10)) + end.respond_with(successful_purchase_response) + end + end + + def test_invalid_taxes_embedded_type + assert_raises(ArgumentError) do + stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(taxes: [{ value: 500, type: 'IVA' }, 10])) + end.respond_with(successful_purchase_response) + end + end + + def test_invalid_taxes_shape + assert_raises(ArgumentError) do + stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(taxes: [{ amount: 500, type: 'IVA' }])) + end.respond_with(successful_purchase_response) + end + end + private def pre_scrubbed @@ -483,6 +595,12 @@ def successful_authorize_response ) end + def successful_authorize_with_capture_option_response + %( + {"id":4261941,"date_created":"2017-07-13T14:24:46.000-04:00","date_approved":null,"date_last_updated":"2017-07-13T14:24:46.000-04:00","date_of_expiration":null,"money_release_date":null,"operation_type":"regular_payment","issuer_id":"25","payment_method_id":"visa","payment_type_id":"credit_card","status":"authorized","status_detail":"accredited","currency_id":"BRL","description":"Store Purchase","live_mode":false,"sponsor_id":null,"authorization_code":null,"related_exchange_rate":null,"collector_id":263489584,"payer":{"type":"guest","id":null,"email":"user+br@example.com","identification":{"type":null,"number":null},"phone":{"area_code":null,"number":null,"extension":null},"first_name":null,"last_name":null,"entity_type":null},"metadata":{},"additional_info":{"payer":{"address":{"zip_code":"K1C2N6","street_name":"My Street","street_number":"456"}}},"order":{"type":"mercadopago","id":"2294029672081601730"},"external_reference":null,"transaction_amount":5,"transaction_amount_refunded":0,"coupon_amount":0,"differential_pricing_id":null,"deduction_schema":null,"transaction_details":{"net_received_amount":0,"total_paid_amount":5,"overpaid_amount":0,"external_resource_url":null,"installment_amount":5,"financial_institution":null,"payment_method_reference_id":null,"payable_deferral_period":null,"acquirer_reference":null},"fee_details":[],"captured":false,"binary_mode":false,"call_for_authorize_id":null,"statement_descriptor":"WWW.MERCADOPAGO.COM","installments":1,"card":{"id":null,"first_six_digits":"450995","last_four_digits":"3704","expiration_month":9,"expiration_year":2018,"date_created":"2017-07-13T14:24:46.000-04:00","date_last_updated":"2017-07-13T14:24:46.000-04:00","cardholder":{"name":"Longbob Longsen","identification":{"number":null,"type":null}}},"notification_url":null,"refunds":[],"processing_mode":"aggregator","merchant_account_id":null,"acquirer":null,"merchant_number":null} + ) + end + def successful_authorize_with_elo_response %( {"id":18044850,"date_created":"2019-03-04T09:44:37.000-04:00","date_approved":null,"date_last_updated":"2019-03-04T09:44:40.000-04:00","date_of_expiration":null,"money_release_date":null,"operation_type":"regular_payment","issuer_id":"687","payment_method_id":"elo","payment_type_id":"credit_card","status":"authorized","status_detail":"pending_capture","currency_id":"BRL","description":"Store Purchase","live_mode":false,"sponsor_id":null,"authorization_code":null,"money_release_schema":null,"taxes_amount":0,"counter_currency":null,"shipping_amount":0,"pos_id":null,"store_id":null,"collector_id":263489584,"payer":{"first_name":"Test","last_name":"Test","email":"test_user_80507629@testuser.com","identification":{"number":"32659430","type":"DNI"},"phone":{"area_code":"01","number":"1111-1111","extension":""},"type":"registered","entity_type":null,"id":"413001901"},"metadata":{},"additional_info":{"payer":{"address":{"zip_code":"K1C2N6","street_name":"456 My Street Apt 1"}},"shipments":{"receiver_address":{"zip_code":"K1C2N6","street_name":"456 My Street Apt 1"}}},"order":{},"external_reference":"24cd4658b9ea6dbf164f9fb9f67e5e78","transaction_amount":5,"transaction_amount_refunded":0,"coupon_amount":0,"differential_pricing_id":null,"deduction_schema":null,"transaction_details":{"net_received_amount":0,"total_paid_amount":5,"overpaid_amount":0,"external_resource_url":null,"installment_amount":5,"financial_institution":null,"payment_method_reference_id":null,"payable_deferral_period":null,"acquirer_reference":null},"fee_details":[],"captured":false,"binary_mode":true,"call_for_authorize_id":null,"statement_descriptor":"MERCADOPAGO","installments":1,"card":{"id":null,"first_six_digits":"506726","last_four_digits":"7446","expiration_month":10,"expiration_year":2020,"date_created":"2019-03-04T09:44:37.000-04:00","date_last_updated":"2019-03-04T09:44:37.000-04:00","cardholder":{"name":"John Smith","identification":{"number":null,"type":null}}},"notification_url":null,"refunds":[],"processing_mode":"aggregator","merchant_account_id":null,"acquirer":null,"merchant_number":null,"acquirer_reconciliation":[]} diff --git a/test/unit/gateways/merchant_e_solutions_test.rb b/test/unit/gateways/merchant_e_solutions_test.rb index ca891477a85..7cced6c3594 100644 --- a/test/unit/gateways/merchant_e_solutions_test.rb +++ b/test/unit/gateways/merchant_e_solutions_test.rb @@ -7,17 +7,17 @@ def setup Base.mode = :test @gateway = MerchantESolutionsGateway.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 @@ -38,7 +38,7 @@ def test_unsuccessful_purchase end def test_purchase_with_long_order_id_truncates_id - options = {order_id: 'thisislongerthan17characters'} + options = { order_id: 'thisislongerthan17characters' } @gateway.expects(:ssl_post).with( anything, all_of( @@ -143,8 +143,8 @@ def test_unsuccessful_cvv_check def test_visa_3dsecure_params_submitted stub_comms(@gateway, :ssl_request) do - @gateway.purchase(@amount, @credit_card, @options.merge({:xid => '1', :cavv => '2'})) - end.check_request do |method, endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, @options.merge({ xid: '1', cavv: '2' })) + end.check_request do |_method, _endpoint, data, _headers| assert_match(/xid=1/, data) assert_match(/cavv=2/, data) end.respond_with(successful_purchase_response) @@ -152,8 +152,8 @@ def test_visa_3dsecure_params_submitted def test_mastercard_3dsecure_params_submitted stub_comms(@gateway, :ssl_request) do - @gateway.purchase(@amount, @credit_card, @options.merge({:ucaf_collection_ind => '1', :ucaf_auth_data => '2'})) - end.check_request do |method, endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, @options.merge({ ucaf_collection_ind: '1', ucaf_auth_data: '2' })) + end.check_request do |_method, _endpoint, data, _headers| assert_match(/ucaf_collection_ind=1/, data) assert_match(/ucaf_auth_data=2/, data) end.respond_with(successful_purchase_response) @@ -164,7 +164,7 @@ def test_supported_countries end def test_supported_card_types - assert_equal [:visa, :master, :american_express, :discover, :jcb], MerchantESolutionsGateway.supported_cardtypes + assert_equal %i[visa master american_express discover jcb], MerchantESolutionsGateway.supported_cardtypes end def test_scrub diff --git a/test/unit/gateways/merchant_one_test.rb b/test/unit/gateways/merchant_one_test.rb index 16e3b879473..78189ec91cb 100644 --- a/test/unit/gateways/merchant_one_test.rb +++ b/test/unit/gateways/merchant_one_test.rb @@ -1,23 +1,22 @@ require 'test_helper' class MerchantOneTest < Test::Unit::TestCase - def setup @gateway = MerchantOneGateway.new(fixtures(:merchant_one)) @credit_card = credit_card @amount = 1000 @options = { - :order_id => '1', - :description => 'Store Purchase', - :billing_address => { - :name =>'Jim Smith', - :address1 =>'1234 My Street', - :address2 =>'Apt 1', - :city =>'Tampa', - :state =>'FL', - :zip =>'33603', - :country =>'US', - :phone =>'(813)421-4331' + order_id: '1', + description: 'Store Purchase', + billing_address: { + name: 'Jim Smith', + address1: '1234 My Street', + address2: 'Apt 1', + city: 'Tampa', + state: 'FL', + zip: '33603', + country: 'US', + phone: '(813)421-4331' } } end diff --git a/test/unit/gateways/merchant_partners_test.rb b/test/unit/gateways/merchant_partners_test.rb index 3307fa37d61..d86a9697e0e 100644 --- a/test/unit/gateways/merchant_partners_test.rb +++ b/test/unit/gateways/merchant_partners_test.rb @@ -19,7 +19,7 @@ def setup 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| parse(data) do |doc| assert_not_nil root = doc.at_xpath(@request_root) assert_equal @gateway.options[:account_id], root.at_xpath('//acctid').content @@ -51,7 +51,7 @@ def test_failed_purchase def test_successful_authorize_and_capture response = stub_comms do @gateway.authorize(@amount, @credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_not_nil root = doc.at_xpath(@request_root) assert_equal @gateway.options[:account_id], root.at_xpath('//acctid').content @@ -70,7 +70,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| parse(data) do |doc| assert_not_nil root = doc.at_xpath(@request_root) assert_equal @gateway.options[:account_id], root.at_xpath('//acctid').content @@ -115,7 +115,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| parse(data) do |doc| assert_not_nil root = doc.at_xpath(@request_root) assert_equal @gateway.options[:account_id], root.at_xpath('//acctid').content @@ -145,7 +145,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| parse(data) do |doc| assert_not_nil root = doc.at_xpath(@request_root) assert_equal @gateway.options[:account_id], root.at_xpath('//acctid').content @@ -170,7 +170,7 @@ def test_failed_refund def test_successful_credit response = stub_comms do @gateway.credit(@amount, @credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_not_nil root = doc.at_xpath(@request_root) assert_equal @gateway.options[:account_id], root.at_xpath('//acctid').content @@ -217,7 +217,7 @@ def test_failed_verify def test_successful_store response = stub_comms do @gateway.store(@credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_not_nil root = doc.at_xpath(@request_root) assert_equal @gateway.options[:account_id], root.at_xpath('//acctid').content @@ -247,7 +247,7 @@ def test_successful_stored_purchase purchase = stub_comms do @gateway.purchase(@amount, response.authorization) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_not_nil root = doc.at_xpath(@request_root) assert_equal @gateway.options[:account_id], root.at_xpath('//acctid').content @@ -275,7 +275,7 @@ def test_successful_stored_credit credit = stub_comms do @gateway.credit(@amount, response.authorization) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| parse(data) do |doc| assert_not_nil root = doc.at_xpath(@request_root) assert_equal @gateway.options[:account_id], root.at_xpath('//acctid').content diff --git a/test/unit/gateways/merchant_ware_test.rb b/test/unit/gateways/merchant_ware_test.rb index bfaf52f2462..a63e8259543 100644 --- a/test/unit/gateways/merchant_ware_test.rb +++ b/test/unit/gateways/merchant_ware_test.rb @@ -5,17 +5,17 @@ class MerchantWareTest < Test::Unit::TestCase def setup @gateway = MerchantWareGateway.new( - :login => 'login', - :password => 'password', - :name => 'name' - ) + login: 'login', + password: 'password', + name: 'name' + ) @credit_card = credit_card @amount = 100 @options = { - :order_id => '1', - :billing_address => address + order_id: '1', + billing_address: address } end @@ -32,8 +32,8 @@ def test_successful_authorization end def test_soap_fault_during_authorization - response_500 = stub(:code => '500', :message => 'Internal Server Error', :body => fault_authorization_response) - @gateway.expects(:ssl_post).raises(ActiveMerchant::ResponseError.new(response_500)) + response500 = stub(code: '500', message: 'Internal Server Error', body: fault_authorization_response) + @gateway.expects(:ssl_post).raises(ActiveMerchant::ResponseError.new(response500)) assert response = @gateway.authorize(@amount, @credit_card, @options) assert_instance_of Response, response @@ -42,8 +42,8 @@ def test_soap_fault_during_authorization assert_nil response.authorization assert_equal 'Server was unable to process request. ---> strPAN should be at least 13 to at most 19 characters in size. Parameter name: strPAN', response.message - assert_equal response_500.code, response.params['http_code'] - assert_equal response_500.message, response.params['http_message'] + assert_equal response500.code, response.params['http_code'] + assert_equal response500.message, response.params['http_message'] end def test_failed_authorization @@ -110,10 +110,10 @@ def test_cvv_result def test_add_swipe_data_with_creditcard @credit_card.track_data = 'Track Data' - options = {:order_id => '1'} + options = { order_id: '1' } 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 'Track Data', data end.respond_with(successful_authorization_response) end @@ -121,100 +121,99 @@ def test_add_swipe_data_with_creditcard private def successful_authorization_response - <<-XML - - - - - - 4706382 - 1 - 7/3/2009 2:05:04 AM - APPROVED - VI0100 - Longbob Longsen - 1.00 - 5 - ************4242 - 0 - N - M - 1 - - - - + <<~XML + + + + + + 4706382 + 1 + 7/3/2009 2:05:04 AM + APPROVED + VI0100 + Longbob Longsen + 1.00 + 5 + ************4242 + 0 + N + M + 1 + + + + XML end def fault_authorization_response - <<-XML - - - - - soap:Server - Server was unable to process request. ---> strPAN should be at least 13 to at most 19 characters in size. -Parameter name: strPAN - - - - + <<~XML + + + + + soap:Server + Server was unable to process request. ---> strPAN should be at least 13 to at most 19 characters in size. + Parameter name: strPAN + + + + XML end def failed_authorization_response - <<-XML - - - - - - - 1 - 7/3/2009 3:04:33 AM - FAILED;1014;transaction type not supported by version - - Longbob Longsen - 1.00 - 5 - *********0123 - 0 - - - 1 - - - - + <<~XML + + + + + + + 1 + 7/3/2009 3:04:33 AM + FAILED;1014;transaction type not supported by version + + Longbob Longsen + 1.00 + 5 + *********0123 + 0 + + + 1 + + + + XML end def failed_void_response - <<-XML - - - - - - 4707277 - - 7/3/2009 3:28:38 AM - DECLINED;1012;decline - - - - 3 - - 0 - - - 0 - - - - + <<~XML + + + + + + 4707277 + + 7/3/2009 3:28:38 AM + DECLINED;1012;decline + + + + 3 + + 0 + + + 0 + + + + XML end - end diff --git a/test/unit/gateways/merchant_ware_version_four_test.rb b/test/unit/gateways/merchant_ware_version_four_test.rb index 4119f8f63d9..b51f07a34f7 100644 --- a/test/unit/gateways/merchant_ware_version_four_test.rb +++ b/test/unit/gateways/merchant_ware_version_four_test.rb @@ -3,18 +3,18 @@ class MerchantWareVersionFourTest < Test::Unit::TestCase def setup @gateway = MerchantWareVersionFourGateway.new( - :login => 'login', - :password => 'password', - :name => 'name' - ) + login: 'login', + password: 'password', + name: 'name' + ) @credit_card = credit_card @authorization = '1236564' @amount = 100 @options = { - :order_id => '1', - :billing_address => address + order_id: '1', + billing_address: address } end @@ -31,8 +31,8 @@ def test_successful_authorization end def test_soap_fault_during_authorization - response_400 = stub(:code => '400', :message => 'Bad Request', :body => failed_authorize_response) - @gateway.expects(:ssl_post).raises(ActiveMerchant::ResponseError.new(response_400)) + response400 = stub(code: '400', message: 'Bad Request', body: failed_authorize_response) + @gateway.expects(:ssl_post).raises(ActiveMerchant::ResponseError.new(response400)) assert response = @gateway.authorize(@amount, @credit_card, @options) assert_instance_of Response, response @@ -41,8 +41,8 @@ def test_soap_fault_during_authorization assert_nil response.authorization assert_equal 'amount cannot be null. Parameter name: amount', response.message - assert_equal response_400.code, response.params['http_code'] - assert_equal response_400.message, response.params['http_message'] + assert_equal response400.code, response.params['http_code'] + assert_equal response400.message, response.params['http_message'] end def test_failed_authorization @@ -161,212 +161,212 @@ def post_scrubbed end def successful_authorize_response - <<-XML - - - - - - 1.00 - APPROVED - MC0110 - N - - - 0 - M - 0 - - - - 1236564 - 10/10/2008 1:13:55 PM - 7 - - - - + <<~XML + + + + + + 1.00 + APPROVED + MC0110 + N + + + 0 + M + 0 + + + + 1236564 + 10/10/2008 1:13:55 PM + 7 + + + + XML end def failed_authorize_response - <<-XML - - - - - - - - - - - - 0 - - 0 - amount cannot be null. Parameter name: amount - - - - - 0 - - - - + <<~XML + + + + + + + + + + + + 0 + + 0 + amount cannot be null. Parameter name: amount + + + + + 0 + + + + XML end def failed_authorization_response - <<-XML - - - - - - 1.00 - DECLINED;1024;invalid exp date - - - Visa Test Card - ************0019 - 4 - - 1 - - - TT0017 - - 5/15/2013 8:47:14 AM - 5 - - - - + <<~XML + + + + + + 1.00 + DECLINED;1024;invalid exp date + + + Visa Test Card + ************0019 + 4 + + 1 + + + TT0017 + + 5/15/2013 8:47:14 AM + 5 + + + + XML end def successful_void_response - <<-XML - - - - - - - APPROVED - VOID - - - - 0 - - 0 - - - - 266783537 - 7/9/2015 3:13:51 PM - 3 - - - - + <<~XML + + + + + + + APPROVED + VOID + + + + 0 + + 0 + + + + 266783537 + 7/9/2015 3:13:51 PM + 3 + + + + XML end def failed_void_response - <<-XML - - - - - - DECLINED;1019;original transaction id not found - - - - - 0 - - 0 - - - - - 5/15/2013 9:37:04 AM - 3 - - - - + <<~XML + + + + + + DECLINED;1019;original transaction id not found + + + + + 0 + + 0 + + + + + 5/15/2013 9:37:04 AM + 3 + + + + XML end def successful_purchase_using_prior_transaction_response - <<-XML - - - - - - 5.00 - APPROVED - MC0110 - - - - 0 - - 0 - - - - 1236564 - 10/10/2008 1:13:55 PM - 7 - - - - + <<~XML + + + + + + 5.00 + APPROVED + MC0110 + + + + 0 + + 0 + + + + 1236564 + 10/10/2008 1:13:55 PM + 7 + + + + XML end def invalid_credit_card_number_response - <<-XML - - - - - - - - - - - - 0 - - 0 - Invalid card number. - - - - - 0 - - - - + <<~XML + + + + + + + + + + + + 0 + + 0 + Invalid card number. + + + + + 0 + + + + XML end end diff --git a/test/unit/gateways/merchant_warrior_test.rb b/test/unit/gateways/merchant_warrior_test.rb index 2d718e7da74..5d026d70996 100644 --- a/test/unit/gateways/merchant_warrior_test.rb +++ b/test/unit/gateways/merchant_warrior_test.rb @@ -5,10 +5,10 @@ class MerchantWarriorTest < Test::Unit::TestCase def setup @gateway = MerchantWarriorGateway.new( - :merchant_uuid => '4e922de8c2a4c', - :api_key => 'g6jrxa9o', - :api_passphrase => 'vp4ujoem' - ) + merchant_uuid: '4e922de8c2a4c', + api_key: 'g6jrxa9o', + api_passphrase: 'vp4ujoem' + ) @credit_card = credit_card @success_amount = 10000 @@ -16,11 +16,21 @@ def setup @failure_amount = 10033 @options = { - :address => address, - :transaction_product => 'TestProduct' + address: address, + transaction_product: 'TestProduct' } end + def test_successful_authorize + @gateway.expects(:ssl_post).returns(successful_authorize_response) + + assert response = @gateway.authorize(@success_amount, @credit_card, @options) + assert_success response + assert_equal 'Transaction approved', response.message + assert response.test? + assert_equal '1336-20be3569-b600-11e6-b9c3-005056b209e0', response.authorization + end + def test_successful_purchase @gateway.expects(:ssl_post).returns(successful_purchase_response) @@ -61,13 +71,33 @@ def test_failed_refund assert_nil response.authorization end + def test_successful_void + @gateway.expects(:ssl_post).returns(successful_refund_response) + + assert response = @gateway.void(@transaction_id, amount: @success_amount) + assert_success response + assert_equal 'Transaction approved', response.message + assert response.test? + assert_equal '30-d4d19f4-db17-11df-9322-0022198101cd', response.authorization + end + + def test_failed_void + @gateway.expects(:ssl_post).returns(failed_refund_response) + + assert response = @gateway.void(@transaction_id, amount: @success_amount) + assert_failure response + assert_equal 'MW -016:transactionID has already been reversed', response.message + assert response.test? + assert_nil response.authorization + end + def test_successful_store @credit_card.month = '2' @credit_card.year = '2005' store = stub_comms do @gateway.store(@credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/cardExpiryMonth=02\b/, data) assert_match(/cardExpiryYear=05\b/, data) end.respond_with(successful_store_response) @@ -84,7 +114,7 @@ def test_scrub_name stub_comms do @gateway.purchase(@success_amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/customerName=Ren\+\+Stimpy/, data) assert_match(/paymentCardName=Chars\+Merchant-Warrior\+Dont\+Like\+\+More\.\+\+Here/, data) end.respond_with(successful_purchase_response) @@ -105,7 +135,7 @@ def test_address stub_comms do @gateway.purchase(@success_amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/customerName=Bat\+Man/, data) assert_match(/customerCountry=US/, data) assert_match(/customerState=NY/, data) @@ -126,7 +156,7 @@ def test_address_without_state stub_comms do @gateway.purchase(@success_amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/customerState=N%2FA/, data) end.respond_with(successful_purchase_response) end @@ -134,11 +164,127 @@ def test_address_without_state def test_orderid_truncated stub_comms do @gateway.purchase(@success_amount, @credit_card, order_id: 'ThisIsQuiteALongDescriptionWithLotsOfChars') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/transactionProduct=ThisIsQuiteALongDescriptionWithLot&/, data) end.respond_with(successful_purchase_response) end + def test_authorize_recurring_flag_absent + stub_comms do + @gateway.authorize(@success_amount, @credit_card) + end.check_request do |_endpoint, data, _headers| + assert_not_match(/recurringFlag&/, data) + end.respond_with(successful_authorize_response) + end + + def test_authorize_recurring_flag_present + recurring_flag = 1 + + stub_comms do + @gateway.authorize(@success_amount, @credit_card, recurring_flag: recurring_flag) + end.check_request do |_endpoint, data, _headers| + assert_match(/recurringFlag=#{recurring_flag}&/, data) + end.respond_with(successful_authorize_response) + end + + def test_purchase_recurring_flag_absent + stub_comms do + @gateway.purchase(@success_amount, @credit_card) + end.check_request do |_endpoint, data, _headers| + assert_not_match(/recurringFlag&/, data) + end.respond_with(successful_purchase_response) + end + + def test_purchase_recurring_flag_present + recurring_flag = 1 + + stub_comms do + @gateway.purchase(@success_amount, @credit_card, recurring_flag: recurring_flag) + end.check_request do |_endpoint, data, _headers| + assert_match(/recurringFlag=#{recurring_flag}&/, data) + end.respond_with(successful_purchase_response) + end + + def test_authorize_with_soft_descriptor_absent + stub_comms do + @gateway.authorize(@success_amount, @credit_card) + end.check_request do |_endpoint, data, _headers| + assert_not_match(/descriptorName&/, data) + assert_not_match(/descriptorCity&/, data) + assert_not_match(/descriptorState&/, data) + end.respond_with(successful_authorize_response) + end + + def test_authorize_with_soft_descriptor_present + stub_comms do + @gateway.authorize(@success_amount, @credit_card, soft_descriptor_options) + end.check_request do |_endpoint, data, _headers| + assert_match(/descriptorName=FOO%2ATest&/, data) + assert_match(/descriptorCity=Melbourne&/, data) + assert_match(/descriptorState=VIC&/, data) + end.respond_with(successful_authorize_response) + end + + def test_purchase_with_soft_descriptor_absent + stub_comms do + @gateway.purchase(@success_amount, @credit_card) + end.check_request do |_endpoint, data, _headers| + assert_not_match(/descriptorName&/, data) + assert_not_match(/descriptorCity&/, data) + assert_not_match(/descriptorState&/, data) + end.respond_with(successful_purchase_response) + end + + def test_purchase_with_soft_descriptor_present + stub_comms do + @gateway.purchase(@success_amount, @credit_card, soft_descriptor_options) + end.check_request do |_endpoint, data, _headers| + assert_match(/descriptorName=FOO%2ATest&/, data) + assert_match(/descriptorCity=Melbourne&/, data) + assert_match(/descriptorState=VIC&/, data) + end.respond_with(successful_purchase_response) + end + + def test_capture_with_soft_descriptor_absent + stub_comms do + @gateway.capture(@success_amount, @credit_card) + end.check_request do |_endpoint, data, _headers| + assert_not_match(/descriptorName&/, data) + assert_not_match(/descriptorCity&/, data) + assert_not_match(/descriptorState&/, data) + end.respond_with(successful_capture_response) + end + + def test_capture_with_soft_descriptor_present + stub_comms do + @gateway.capture(@success_amount, @credit_card, soft_descriptor_options) + end.check_request do |_endpoint, data, _headers| + assert_match(/descriptorName=FOO%2ATest&/, data) + assert_match(/descriptorCity=Melbourne&/, data) + assert_match(/descriptorState=VIC&/, data) + end.respond_with(successful_capture_response) + end + + def test_refund_with_soft_descriptor_absent + stub_comms do + @gateway.refund(@success_amount, @credit_card) + end.check_request do |_endpoint, data, _headers| + assert_not_match(/descriptorName&/, data) + assert_not_match(/descriptorCity&/, data) + assert_not_match(/descriptorState&/, data) + end.respond_with(successful_refund_response) + end + + def test_refund_with_soft_descriptor_present + stub_comms do + @gateway.refund(@success_amount, @credit_card, soft_descriptor_options) + end.check_request do |_endpoint, data, _headers| + assert_match(/descriptorName=FOO%2ATest&/, data) + assert_match(/descriptorCity=Melbourne&/, data) + assert_match(/descriptorState=VIC&/, data) + end.respond_with(successful_refund_response) + end + def test_scrub assert @gateway.supports_scrubbing? assert_equal @gateway.scrub(pre_scrubbed), post_scrubbed @@ -147,78 +293,120 @@ def test_scrub private def successful_purchase_response - <<-XML - - - 0 - Transaction approved - 30-98a79008-dae8-11df-9322-0022198101cd - 44639 - Approved - 0 - 2010-10-19 - - - - c0aca5a0d9573322c79cc323d6cc8050 - + <<~XML + + + 0 + Transaction approved + 30-98a79008-dae8-11df-9322-0022198101cd + 44639 + Approved + 0 + 2010-10-19 + + + + c0aca5a0d9573322c79cc323d6cc8050 + XML end def failed_purchase_response - <<-XML - - - 4 - Card has expired - 30-69433444-af1-11df-9322-0022198101cd - 44657 - Expired+Card - 4 - 2010-10-19 - - - - c0aca5a0d9573322c79cc323d6cc8050 - + <<~XML + + + 4 + Card has expired + 30-69433444-af1-11df-9322-0022198101cd + 44657 + Expired+Card + 4 + 2010-10-19 + + + + c0aca5a0d9573322c79cc323d6cc8050 + XML end def successful_refund_response - <<-XML - - - 0 - Transaction approved - 30-d4d19f4-db17-11df-9322-0022198101cd - 44751 - Approved - 0 - 2010-10-19 - + <<~XML + + + 0 + Transaction approved + 30-d4d19f4-db17-11df-9322-0022198101cd + 44751 + Approved + 0 + 2010-10-19 + XML end def failed_refund_response - <<-XML - - - -2 - MW -016:transactionID has already been reversed - + <<~XML + + + -2 + MW -016:transactionID has already been reversed + XML end def successful_store_response - <<-XML - - - 0 - Operation successful - KOCI10023982 - s5KQIxsZuiyvs3Sc - 10023982 - + <<~XML + + + 0 + Operation successful + KOCI10023982 + s5KQIxsZuiyvs3Sc + 10023982 + + XML + end + + def successful_authorize_response + <<~XML + + + 0 + Transaction approved + 1336-20be3569-b600-11e6-b9c3-005056b209e0 + 12345 + 731357421 + 731357421 + Honour with identification + 08 + 2016-11-29 + 512345XXXXXX2346 + 1.00 + mc + 05 + 21 + + + + 65b172551b7d3a0706c0ce5330c98470 + + XML + end + + def successful_capture_response + <<~XML + + + 0 + Transaction approved + 1336-fe4d3be6-b604-11e6-b9c3-005056b209e0 + 731357526 + 731357526 + Approved or completed successfully + 00 + 2016-11-30 + XML end @@ -229,4 +417,12 @@ def pre_scrubbed def post_scrubbed 'transactionAmount=1.00&transactionCurrency=AUD&hash=adb50f6ff360f861e6f525e8daae76b5&transactionProduct=98fc25d40a47f3d24da460c0ca307c&customerName=Longbob+Longsen&customerCountry=AU&customerState=Queensland&customerCity=Brisbane&customerAddress=123+test+st&customerPostCode=4000&customerIP=&customerPhone=&customerEmail=&paymentCardNumber=[FILTERED]&paymentCardName=Longbob+Longsen&paymentCardExpiry=0520&paymentCardCSC=[FILTERED]&merchantUUID=51f7da294af8f&apiKey=[FILTERED]&method=processCard' end + + def soft_descriptor_options + { + descriptor_name: 'FOO*Test', + descriptor_city: 'Melbourne', + descriptor_state: 'VIC' + } + end end diff --git a/test/unit/gateways/mercury_test.rb b/test/unit/gateways/mercury_test.rb index e7d298f52b4..d9b2e8d9cd0 100644 --- a/test/unit/gateways/mercury_test.rb +++ b/test/unit/gateways/mercury_test.rb @@ -9,18 +9,18 @@ def setup @gateway = MercuryGateway.new(fixtures(:mercury)) @amount = 100 - @credit_card = credit_card('5499990123456781', :brand => 'master') + @credit_card = credit_card('5499990123456781', brand: 'master') @declined_card = credit_card('4000300011112220') @options = { - :order_id => 'c111111111.1' + order_id: 'c111111111.1' } end 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(/InvoiceNo>c111111111.1OneTime/, data) assert_match(/RecordNo>RecordNumberRequested/, data) @@ -36,7 +36,7 @@ def test_successful_purchase def test_successful_purchase_with_allow_partial_auth response = stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(allow_partial_auth: true)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/PartialAuth>Allow#{Regexp.escape(track_data)}<\/Track1>/, data) end.respond_with(successful_purchase_response) @@ -82,7 +82,7 @@ def test_card_present_with_track_2_data @credit_card.track_data = track_data 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(/#{Regexp.escape(stripped_track_data)}<\/Track2>/, data) end.respond_with(successful_purchase_response) @@ -92,11 +92,11 @@ def test_card_present_with_track_2_data def test_card_present_with_max_length_track_1_data track_data = '%B373953192351004^CARDUSER/JOHN^200910100000019301000000877000000930001234567?' - stripped_data = 'B373953192351004^CARDUSER/JOHN^200910100000019301000000877000000930001234567' + stripped_data = 'B373953192351004^CARDUSER/JOHN^200910100000019301000000877000000930001234567' @credit_card.track_data = track_data 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(/#{Regexp.escape(stripped_data)}<\/Track1>/, data) end.respond_with(successful_purchase_response) @@ -109,7 +109,7 @@ def test_card_present_with_invalid_data @credit_card.track_data = track_data 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(/#{Regexp.escape(track_data)}<\/Track1>/, data) end.respond_with(successful_purchase_response) @@ -125,88 +125,88 @@ def test_transcript_scrubbing private def successful_purchase_response - <<-RESPONSE - - - - Processor - 000000 - Approved - AP* - - - - 595901 - 5499990123456781 - 0813 - M/C - Sale - 000011 - Captured - 0194 - 1 - Y - M - 999 - LM Integration (Ruby) - - 1.00 - 1.00 - - KbMCC0742510421 - |17|410100700000 - - - + <<~RESPONSE + + + + Processor + 000000 + Approved + AP* + + + + 595901 + 5499990123456781 + 0813 + M/C + Sale + 000011 + Captured + 0194 + 1 + Y + M + 999 + LM Integration (Ruby) + + 1.00 + 1.00 + + KbMCC0742510421 + |17|410100700000 + + + RESPONSE end def failed_purchase_response - <<-RESPONSE - - - - Server - 000000 - Error - No Live Cards on Test Merchant ID Allowed. - - - - + <<~RESPONSE + + + + Server + 000000 + Error + No Live Cards on Test Merchant ID Allowed. + + + + RESPONSE end def successful_refund_response - <<-RESPONSE - - - - Processor - 000000 - Approved - AP - - - - 595901 - 5499990123456781 - 0813 - M/C - VoidSale - VOIDED - Captured - 0568 - 123 - 999 - - 1.00 - 1.00 - - K - - - + <<~RESPONSE + + + + Processor + 000000 + Approved + AP + + + + 595901 + 5499990123456781 + 0813 + M/C + VoidSale + VOIDED + Captured + 0568 + 123 + 999 + + 1.00 + 1.00 + + K + + + RESPONSE end diff --git a/test/unit/gateways/metrics_global_test.rb b/test/unit/gateways/metrics_global_test.rb index e8e3e7da467..b8c2d7072bc 100644 --- a/test/unit/gateways/metrics_global_test.rb +++ b/test/unit/gateways/metrics_global_test.rb @@ -1,15 +1,16 @@ require 'test_helper' +require 'active_support/core_ext/kernel/singleton_class' class MetricsGlobalTest < Test::Unit::TestCase include CommStub def setup @gateway = ActiveMerchant::Billing::MetricsGlobalGateway.new( - :login => 'X', - :password => 'Y' + login: 'X', + password: 'Y' ) @amount = 100 - @credit_card = credit_card('4111111111111111', :verification_value => '999') + @credit_card = credit_card('4111111111111111', verification_value: '999') @subscription_id = '100748' @subscription_status = 'active' end @@ -44,9 +45,9 @@ def test_failed_authorization def test_add_address_outsite_north_america result = {} - @gateway.send(:add_address, result, :billing_address => {:address1 => '164 Waverley Street', :country => 'DE', :state => ''}) + @gateway.send(:add_address, result, billing_address: { address1: '164 Waverley Street', country: 'DE', state: '' }) - assert_equal ['address', 'city', 'company', 'country', 'phone', 'state', 'zip'], result.stringify_keys.keys.sort + assert_equal %w[address city company country phone state zip], result.stringify_keys.keys.sort assert_equal 'n/a', result[:state] assert_equal '164 Waverley Street', result[:address] assert_equal 'DE', result[:country] @@ -55,9 +56,9 @@ def test_add_address_outsite_north_america def test_add_address result = {} - @gateway.send(:add_address, result, :billing_address => {:address1 => '164 Waverley Street', :country => 'US', :state => 'CO'}) + @gateway.send(:add_address, result, billing_address: { address1: '164 Waverley Street', country: 'US', state: 'CO' }) - assert_equal ['address', 'city', 'company', 'country', 'phone', 'state', 'zip'], result.stringify_keys.keys.sort + assert_equal %w[address city company country phone state zip], result.stringify_keys.keys.sort assert_equal 'CO', result[:state] assert_equal '164 Waverley Street', result[:address] assert_equal 'US', result[:country] @@ -65,13 +66,13 @@ def test_add_address 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 @@ -90,7 +91,7 @@ def test_add_duplicate_window_with_duplicate_window end def test_purchase_is_valid_csv - params = { :amount => '1.01' } + params = { amount: '1.01' } @gateway.send(:add_creditcard, params, @credit_card) @@ -100,7 +101,7 @@ def test_purchase_is_valid_csv def test_purchase_meets_minimum_requirements params = { - :amount => '1.01', + amount: '1.01' } @gateway.send(:add_creditcard, params, @credit_card) @@ -113,15 +114,15 @@ def test_purchase_meets_minimum_requirements def test_successful_refund @gateway.expects(:ssl_post).returns(successful_purchase_response) - assert response = @gateway.refund(@amount, '123456789', :card_number => @credit_card.number) + assert response = @gateway.refund(@amount, '123456789', card_number: @credit_card.number) assert_success response assert_equal 'This transaction has been approved', response.message end def test_refund_passing_extra_info response = stub_comms do - @gateway.refund(50, '123456789', :card_number => @credit_card.number, :first_name => 'Bob', :last_name => 'Smith', :zip => '12345') - end.check_request do |endpoint, data, headers| + @gateway.refund(50, '123456789', card_number: @credit_card.number, first_name: 'Bob', last_name: 'Smith', zip: '12345') + end.check_request do |_endpoint, data, _headers| assert_match(/x_first_name=Bob/, data) assert_match(/x_last_name=Smith/, data) assert_match(/x_zip=12345/, data) @@ -132,7 +133,7 @@ def test_refund_passing_extra_info def test_failed_refund @gateway.expects(:ssl_post).returns(failed_refund_response) - assert response = @gateway.refund(@amount, '123456789', :card_number => @credit_card.number) + assert response = @gateway.refund(@amount, '123456789', card_number: @credit_card.number) assert_failure response assert_equal 'The referenced transaction does not meet the criteria for issuing a credit', response.message end @@ -140,7 +141,7 @@ def test_failed_refund def test_deprecated_credit @gateway.expects(:ssl_post).returns(successful_purchase_response) assert_deprecation_warning(Gateway::CREDIT_DEPRECATION_MESSAGE) do - assert response = @gateway.credit(@amount, '123456789', :card_number => @credit_card.number) + assert response = @gateway.credit(@amount, '123456789', card_number: @credit_card.number) assert_success response assert_equal 'This transaction has been approved', response.message end @@ -151,7 +152,7 @@ def test_supported_countries end def test_supported_card_types - assert_equal [:visa, :master, :american_express, :discover, :diners_club, :jcb], MetricsGlobalGateway.supported_cardtypes + assert_equal %i[visa master american_express discover diners_club jcb], MetricsGlobalGateway.supported_cardtypes end def test_failure_without_response_reason_text @@ -188,11 +189,11 @@ def test_message_from public :message_from } result = { - :response_code => 2, - :card_code => 'N', - :avs_result_code => 'A', - :response_reason_code => '27', - :response_reason_text => 'Failure.', + response_code: 2, + card_code: 'N', + avs_result_code: 'A', + response_reason_code: '27', + response_reason_text: 'Failure.' } assert_equal 'CVV does not match', @gateway.message_from(result) diff --git a/test/unit/gateways/micropayment_test.rb b/test/unit/gateways/micropayment_test.rb index 5e63d8f0fa3..ca773b448ec 100644 --- a/test/unit/gateways/micropayment_test.rb +++ b/test/unit/gateways/micropayment_test.rb @@ -15,7 +15,7 @@ def setup 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_match(/accessKey=key/, data) assert_match(/number=#{@credit_card.number}/, data) assert_match(/cvc2=#{@credit_card.verification_value}/, data) @@ -40,7 +40,7 @@ def test_failed_purchase def test_successful_authorize_and_capture response = stub_comms do @gateway.authorize(@amount, @credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/accessKey=key/, data) assert_match(/number=#{@credit_card.number}/, data) assert_match(/cvc2=#{@credit_card.verification_value}/, data) @@ -52,7 +52,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(/accessKey=key/, data) assert_match(/transactionId=www.spreedly.com-IDhngtaj81a1/, data) assert_match(/sessionId=CC747358d9598614c3ba1e9a7b82a28318cd81bc/, data) @@ -89,7 +89,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(/accessKey=key/, data) assert_match(/transactionId=www.spreedly.com-IDhngtaj81a1/, data) assert_match(/sessionId=CC747358d9598614c3ba1e9a7b82a28318cd81bc/, data) @@ -115,7 +115,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(/accessKey=key/, data) assert_match(/transactionId=www.spreedly.com-IDhm7nyju168/, data) assert_match(/sessionId=CCadc2b593ca98bfd730c383582de00faed995b0/, data) diff --git a/test/unit/gateways/migs_test.rb b/test/unit/gateways/migs_test.rb index 73ef494ff7b..8f5eb3dbe6e 100644 --- a/test/unit/gateways/migs_test.rb +++ b/test/unit/gateways/migs_test.rb @@ -3,12 +3,12 @@ class MigsTest < Test::Unit::TestCase def setup @gateway = MigsGateway.new( - login: 'login', - password: 'password', - secure_hash: '76AF3392002D202A60D0AB5F9D81653C', - advanced_login: 'advlogin', - advanced_password: 'advpass' - ) + login: 'login', + password: 'password', + secure_hash: '76AF3392002D202A60D0AB5F9D81653C', + advanced_login: 'advlogin', + advanced_password: 'advpass' + ) @credit_card = credit_card @amount = 100 @authorization = '2070000742' @@ -124,54 +124,54 @@ def expect_commit_with_tx_source end def pre_scrubbed - <<-EOS -opening connection to migs.mastercard.com.au:443... -opened -starting SSL for migs.mastercard.com.au:443... -SSL established -<- "POST /vpcdps 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: migs.mastercard.com.au\r\nContent-Length: 354\r\n\r\n" -<- "vpc_Amount=100&vpc_Currency=SAR&vpc_OrderInfo=1&vpc_CardNum=4987654321098769&vpc_CardSecurityCode=123&vpc_CardExp=2105&vpc_Version=1&vpc_Merchant=TESTH-STATION&vpc_AccessCode=F1CE6F32&vpc_Command=pay&vpc_MerchTxnRef=84c1f31ded35dea26ac297fd7ba092da&vpc_SecureHash=CD1B2B8BC325C6C8FC1A041AD6AC90821984277113DF708B16B37809E7B0EC33&vpc_SecureHashType=SHA256&vpc_VerType=3DS&vpc_3DSXID=YzRjZWRjODY4MmY2NGQ3ZTgzNDQ&vpc_VerToken=AAACAgeVABgnAggAQ5UAAAAAAAA&vpc_3DSenrolled=Y&vpc_3DSECI=05&3DSstatus=Y" --> "HTTP/1.1 200 OK\r\n" --> "Date: Tue, 13 Feb 2018 19:02:18 GMT\r\n" --> "Expires: Sun, 15 Jul 1990 00:00:00 GMT\r\n" --> "Pragma: no-cache\r\n" --> "Cache-Control: no-cache\r\n" --> "Content-Length: 595\r\n" --> "P3P: CP=\"NOI DSP COR CURa ADMa TA1a OUR BUS IND UNI COM NAV INT\"\r\n" --> "Content-Type: text/plain;charset=iso-8859-1\r\n" --> "Connection: close\r\n" --> "Set-Cookie: TS01c4b9ca=01fb8d8de2ba6ffaf7439497dd78d9b3348c82bcf24d4619e65a406161e57276b6b293e77732a293be63bf750213e588797bc86f05; Path=/; Secure; HTTPOnly\r\n" --> "\r\n" -reading 595 bytes... --> "vpc_AVSResultCode=Unsupported&vpc_AcqAVSRespCode=Unsupported&vpc_AcqCSCRespCode=Unsupported&vpc_AcqResponseCode=00&vpc_Amount=100&vpc_AuthorizeId=239491&vpc_BatchNo=20180214&vpc_CSCResultCode=Unsupported&vpc_Card=VC&vpc_Command=pay&vpc_Currency=SAR&vpc_Locale=en_SA&vpc_MerchTxnRef=84c1f31ded35dea26ac297fd7ba092da&vpc_Merchant=TESTH-STATION&vpc_Message=Approved&vpc_OrderInfo=1&vpc_ReceiptNo=804506239491&vpc_RiskOverallResult=ACC&vpc_SecureHash=99993E000461810D9F71B1A4FC5EA2D68DF6BA1F7EBA6A9FC544DA035627C03C&vpc_SecureHashType=SHA256&vpc_TransactionNo=372&vpc_TxnResponseCode=0&vpc_Version=1&vpc_VerType=3DS&vpc_3DSXID=YzRjZWRjODY4MmY2NGQ3ZTgzNDQ&vpc_VerToken=AAACAgeVABgnAggAQ5UAAAAAAAA&vpc_3DSenrolled=Y&vpc_3DSECI=05&3DSstatus=Y" -read 595 bytes -Conn close - EOS + <<~REQUEST + opening connection to migs.mastercard.com.au:443... + opened + starting SSL for migs.mastercard.com.au:443... + SSL established + <- "POST /vpcdps 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: migs.mastercard.com.au\r\nContent-Length: 354\r\n\r\n" + <- "vpc_Amount=100&vpc_Currency=SAR&vpc_OrderInfo=1&vpc_CardNum=4987654321098769&vpc_CardSecurityCode=123&vpc_CardExp=2105&vpc_Version=1&vpc_Merchant=TESTH-STATION&vpc_AccessCode=F1CE6F32&vpc_Command=pay&vpc_MerchTxnRef=84c1f31ded35dea26ac297fd7ba092da&vpc_SecureHash=CD1B2B8BC325C6C8FC1A041AD6AC90821984277113DF708B16B37809E7B0EC33&vpc_SecureHashType=SHA256&vpc_VerType=3DS&vpc_3DSXID=YzRjZWRjODY4MmY2NGQ3ZTgzNDQ&vpc_VerToken=AAACAgeVABgnAggAQ5UAAAAAAAA&vpc_3DSenrolled=Y&vpc_3DSECI=05&3DSstatus=Y" + -> "HTTP/1.1 200 OK\r\n" + -> "Date: Tue, 13 Feb 2018 19:02:18 GMT\r\n" + -> "Expires: Sun, 15 Jul 1990 00:00:00 GMT\r\n" + -> "Pragma: no-cache\r\n" + -> "Cache-Control: no-cache\r\n" + -> "Content-Length: 595\r\n" + -> "P3P: CP=\"NOI DSP COR CURa ADMa TA1a OUR BUS IND UNI COM NAV INT\"\r\n" + -> "Content-Type: text/plain;charset=iso-8859-1\r\n" + -> "Connection: close\r\n" + -> "Set-Cookie: TS01c4b9ca=01fb8d8de2ba6ffaf7439497dd78d9b3348c82bcf24d4619e65a406161e57276b6b293e77732a293be63bf750213e588797bc86f05; Path=/; Secure; HTTPOnly\r\n" + -> "\r\n" + reading 595 bytes... + -> "vpc_AVSResultCode=Unsupported&vpc_AcqAVSRespCode=Unsupported&vpc_AcqCSCRespCode=Unsupported&vpc_AcqResponseCode=00&vpc_Amount=100&vpc_AuthorizeId=239491&vpc_BatchNo=20180214&vpc_CSCResultCode=Unsupported&vpc_Card=VC&vpc_Command=pay&vpc_Currency=SAR&vpc_Locale=en_SA&vpc_MerchTxnRef=84c1f31ded35dea26ac297fd7ba092da&vpc_Merchant=TESTH-STATION&vpc_Message=Approved&vpc_OrderInfo=1&vpc_ReceiptNo=804506239491&vpc_RiskOverallResult=ACC&vpc_SecureHash=99993E000461810D9F71B1A4FC5EA2D68DF6BA1F7EBA6A9FC544DA035627C03C&vpc_SecureHashType=SHA256&vpc_TransactionNo=372&vpc_TxnResponseCode=0&vpc_Version=1&vpc_VerType=3DS&vpc_3DSXID=YzRjZWRjODY4MmY2NGQ3ZTgzNDQ&vpc_VerToken=AAACAgeVABgnAggAQ5UAAAAAAAA&vpc_3DSenrolled=Y&vpc_3DSECI=05&3DSstatus=Y" + read 595 bytes + Conn close + REQUEST end def post_scrubbed - <<-EOS -opening connection to migs.mastercard.com.au:443... -opened -starting SSL for migs.mastercard.com.au:443... -SSL established -<- "POST /vpcdps 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: migs.mastercard.com.au\r\nContent-Length: 354\r\n\r\n" -<- "vpc_Amount=100&vpc_Currency=SAR&vpc_OrderInfo=1&vpc_CardNum=[FILTERED]&vpc_CardSecurityCode=[FILTERED]&vpc_CardExp=2105&vpc_Version=1&vpc_Merchant=TESTH-STATION&vpc_AccessCode=[FILTERED]&vpc_Command=pay&vpc_MerchTxnRef=84c1f31ded35dea26ac297fd7ba092da&vpc_SecureHash=CD1B2B8BC325C6C8FC1A041AD6AC90821984277113DF708B16B37809E7B0EC33&vpc_SecureHashType=SHA256&vpc_VerType=3DS&vpc_3DSXID=[FILTERED]&vpc_VerToken=[FILTERED]&vpc_3DSenrolled=Y&vpc_3DSECI=05&3DSstatus=Y" --> "HTTP/1.1 200 OK\r\n" --> "Date: Tue, 13 Feb 2018 19:02:18 GMT\r\n" --> "Expires: Sun, 15 Jul 1990 00:00:00 GMT\r\n" --> "Pragma: no-cache\r\n" --> "Cache-Control: no-cache\r\n" --> "Content-Length: 595\r\n" --> "P3P: CP=\"NOI DSP COR CURa ADMa TA1a OUR BUS IND UNI COM NAV INT\"\r\n" --> "Content-Type: text/plain;charset=iso-8859-1\r\n" --> "Connection: close\r\n" --> "Set-Cookie: TS01c4b9ca=01fb8d8de2ba6ffaf7439497dd78d9b3348c82bcf24d4619e65a406161e57276b6b293e77732a293be63bf750213e588797bc86f05; Path=/; Secure; HTTPOnly\r\n" --> "\r\n" -reading 595 bytes... --> "vpc_AVSResultCode=Unsupported&vpc_AcqAVSRespCode=Unsupported&vpc_AcqCSCRespCode=Unsupported&vpc_AcqResponseCode=00&vpc_Amount=100&vpc_AuthorizeId=239491&vpc_BatchNo=20180214&vpc_CSCResultCode=Unsupported&vpc_Card=VC&vpc_Command=pay&vpc_Currency=SAR&vpc_Locale=en_SA&vpc_MerchTxnRef=84c1f31ded35dea26ac297fd7ba092da&vpc_Merchant=TESTH-STATION&vpc_Message=Approved&vpc_OrderInfo=1&vpc_ReceiptNo=804506239491&vpc_RiskOverallResult=ACC&vpc_SecureHash=99993E000461810D9F71B1A4FC5EA2D68DF6BA1F7EBA6A9FC544DA035627C03C&vpc_SecureHashType=SHA256&vpc_TransactionNo=372&vpc_TxnResponseCode=0&vpc_Version=1&vpc_VerType=3DS&vpc_3DSXID=[FILTERED]&vpc_VerToken=[FILTERED]&vpc_3DSenrolled=Y&vpc_3DSECI=05&3DSstatus=Y" -read 595 bytes -Conn close - EOS + <<~REQUEST + opening connection to migs.mastercard.com.au:443... + opened + starting SSL for migs.mastercard.com.au:443... + SSL established + <- "POST /vpcdps 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: migs.mastercard.com.au\r\nContent-Length: 354\r\n\r\n" + <- "vpc_Amount=100&vpc_Currency=SAR&vpc_OrderInfo=1&vpc_CardNum=[FILTERED]&vpc_CardSecurityCode=[FILTERED]&vpc_CardExp=2105&vpc_Version=1&vpc_Merchant=TESTH-STATION&vpc_AccessCode=[FILTERED]&vpc_Command=pay&vpc_MerchTxnRef=84c1f31ded35dea26ac297fd7ba092da&vpc_SecureHash=CD1B2B8BC325C6C8FC1A041AD6AC90821984277113DF708B16B37809E7B0EC33&vpc_SecureHashType=SHA256&vpc_VerType=3DS&vpc_3DSXID=[FILTERED]&vpc_VerToken=[FILTERED]&vpc_3DSenrolled=Y&vpc_3DSECI=05&3DSstatus=Y" + -> "HTTP/1.1 200 OK\r\n" + -> "Date: Tue, 13 Feb 2018 19:02:18 GMT\r\n" + -> "Expires: Sun, 15 Jul 1990 00:00:00 GMT\r\n" + -> "Pragma: no-cache\r\n" + -> "Cache-Control: no-cache\r\n" + -> "Content-Length: 595\r\n" + -> "P3P: CP=\"NOI DSP COR CURa ADMa TA1a OUR BUS IND UNI COM NAV INT\"\r\n" + -> "Content-Type: text/plain;charset=iso-8859-1\r\n" + -> "Connection: close\r\n" + -> "Set-Cookie: TS01c4b9ca=01fb8d8de2ba6ffaf7439497dd78d9b3348c82bcf24d4619e65a406161e57276b6b293e77732a293be63bf750213e588797bc86f05; Path=/; Secure; HTTPOnly\r\n" + -> "\r\n" + reading 595 bytes... + -> "vpc_AVSResultCode=Unsupported&vpc_AcqAVSRespCode=Unsupported&vpc_AcqCSCRespCode=Unsupported&vpc_AcqResponseCode=00&vpc_Amount=100&vpc_AuthorizeId=239491&vpc_BatchNo=20180214&vpc_CSCResultCode=Unsupported&vpc_Card=VC&vpc_Command=pay&vpc_Currency=SAR&vpc_Locale=en_SA&vpc_MerchTxnRef=84c1f31ded35dea26ac297fd7ba092da&vpc_Merchant=TESTH-STATION&vpc_Message=Approved&vpc_OrderInfo=1&vpc_ReceiptNo=804506239491&vpc_RiskOverallResult=ACC&vpc_SecureHash=99993E000461810D9F71B1A4FC5EA2D68DF6BA1F7EBA6A9FC544DA035627C03C&vpc_SecureHashType=SHA256&vpc_TransactionNo=372&vpc_TxnResponseCode=0&vpc_Version=1&vpc_VerType=3DS&vpc_3DSXID=[FILTERED]&vpc_VerToken=[FILTERED]&vpc_3DSenrolled=Y&vpc_3DSECI=05&3DSstatus=Y" + read 595 bytes + Conn close + REQUEST end end diff --git a/test/unit/gateways/modern_payments_cim_test.rb b/test/unit/gateways/modern_payments_cim_test.rb index 0e6aa87a998..e126c3a4a54 100644 --- a/test/unit/gateways/modern_payments_cim_test.rb +++ b/test/unit/gateways/modern_payments_cim_test.rb @@ -5,17 +5,17 @@ def setup Base.mode = :test @gateway = ModernPaymentsCimGateway.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 @@ -83,80 +83,80 @@ def test_soap_fault_response private def successful_create_customer_response - <<-XML - - - - - 6677348 - - - + <<~XML + + + + + 6677348 + + + XML end def successful_modify_customer_credit_card_response - <<-XML - - - - - 6677757 - - - + <<~XML + + + + + 6677757 + + + XML end def unsuccessful_credit_card_authorization_response - <<-XML - - - - - - 999 - - - - RESPONSECODE=D,AUTHCODE=,DECLINEREASON.1.TAG=,DECLINEREASON.1.ERRORCLASS=card declined,DECLINEREASON.1.PARAM1=05:DECLINE,DECLINEREASON.1.PARAM2=The authorization is declined,DECLINEREASON.1.MESSAGE=Card was declined: The authorization is declined,AVSDATA - RESPONSECODE=D,AUTHCODE=,DECLINEREASON.1.TAG=,DECLINEREASON.1.ERRORCLASS=card declined,DECLINEREASON.1.PARAM1=05:DECLINE,DECLINEREASON.1.PARAM2=The authorization is declined,DECLINEREASON.1.MESSAGE=Card was declined: The authorization is declined,AVSDATA - false - - - - + <<~XML + + + + + + 999 + + + + RESPONSECODE=D,AUTHCODE=,DECLINEREASON.1.TAG=,DECLINEREASON.1.ERRORCLASS=card declined,DECLINEREASON.1.PARAM1=05:DECLINE,DECLINEREASON.1.PARAM2=The authorization is declined,DECLINEREASON.1.MESSAGE=Card was declined: The authorization is declined,AVSDATA + RESPONSECODE=D,AUTHCODE=,DECLINEREASON.1.TAG=,DECLINEREASON.1.ERRORCLASS=card declined,DECLINEREASON.1.PARAM1=05:DECLINE,DECLINEREASON.1.PARAM2=The authorization is declined,DECLINEREASON.1.MESSAGE=Card was declined: The authorization is declined,AVSDATA + false + + + + XML end def soap_fault_response - <<-XML - - - - - soap:Client - System.Web.Services.Protocols.SoapException: Server did not recognize the value of HTTP Header SOAPAction: h heheheh http://secure.modpay.com:81/ws/CreateCustomer. - at System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest() - at System.Web.Services.Protocols.SoapServerProtocol.RouteRequest(SoapServerMessage message) - at System.Web.Services.Protocols.SoapServerProtocol.Initialize() - at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing) - - - - + <<~XML + + + + + soap:Client + System.Web.Services.Protocols.SoapException: Server did not recognize the value of HTTP Header SOAPAction: h heheheh http://secure.modpay.com:81/ws/CreateCustomer. + at System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest() + at System.Web.Services.Protocols.SoapServerProtocol.RouteRequest(SoapServerMessage message) + at System.Web.Services.Protocols.SoapServerProtocol.Initialize() + at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing) + + + + XML end def successful_authorization_response - <<-XML -18713505020411ZC00 17093294 -RESPONSECODE=A -AUTHCODE=020411 -DECLINEREASON= -AVSDATA=Z -TRANSID=C00 17093294 -Approvedtrue + <<~XML + 18713505020411ZC00 17093294 + RESPONSECODE=A + AUTHCODE=020411 + DECLINEREASON= + AVSDATA=Z + TRANSID=C00 17093294 + Approvedtrue XML end end diff --git a/test/unit/gateways/monei_test.rb b/test/unit/gateways/monei_test.rb index 79d9a2c2365..884d2500efd 100755 --- a/test/unit/gateways/monei_test.rb +++ b/test/unit/gateways/monei_test.rb @@ -138,7 +138,7 @@ def test_3ds_request }) stub_comms do @gateway.purchase(@amount, @credit_card, options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| body = CGI.unescape data assert_match %r{}, body assert_match %r{05}, body @@ -150,287 +150,287 @@ def test_3ds_request private def successful_purchase_response - return <<-XML - - - - - 7621.0198.1858 - 8a829449488d79090148996c441551fb - 1 - - - - 1.00 - EUR - 7621.0198.1858 DEFAULT Store Purchase - 1.0 - INTERN - 2014-09-21 18:14:42 - - - - 2014-09-21 18:14:42 - ACK - NEW - Successful Processing - Request successfully processed in 'Merchant in Connector Test Mode' - - - - + return <<~XML + + + + + 7621.0198.1858 + 8a829449488d79090148996c441551fb + 1 + + + + 1.00 + EUR + 7621.0198.1858 DEFAULT Store Purchase + 1.0 + INTERN + 2014-09-21 18:14:42 + + + + 2014-09-21 18:14:42 + ACK + NEW + Successful Processing + Request successfully processed in 'Merchant in Connector Test Mode' + + + + XML end def failed_purchase_response - <<-XML - - - - - 9086.6774.0834 - 8a82944a488d36c101489972b0ee6ace - 1 - - - - 2014-09-21 18:21:43 - NOK - REJECTED_VALIDATION - Account Validation - invalid cc number/brand combination - - - + <<~XML + + + + + 9086.6774.0834 + 8a82944a488d36c101489972b0ee6ace + 1 + + + + 2014-09-21 18:21:43 + NOK + REJECTED_VALIDATION + Account Validation + invalid cc number/brand combination + + + XML end def successful_authorize_response - <<-XML - - - - - 6853.2944.1442 - 8a82944a488d36c101489976f0cc6b1c - 1 - - - - 1.00 - EUR - 6853.2944.1442 DEFAULT Store Purchase - 1.0 - INTERN - 2014-09-21 18:26:22 - - - - 2014-09-21 18:26:22 - ACK - NEW - Successful Processing - Request successfully processed in 'Merchant in Connector Test Mode' - - - - + <<~XML + + + + + 6853.2944.1442 + 8a82944a488d36c101489976f0cc6b1c + 1 + + + + 1.00 + EUR + 6853.2944.1442 DEFAULT Store Purchase + 1.0 + INTERN + 2014-09-21 18:26:22 + + + + 2014-09-21 18:26:22 + ACK + NEW + Successful Processing + Request successfully processed in 'Merchant in Connector Test Mode' + + + + XML end def failed_authorize_response - <<-XML - - - - - 4727.2856.0290 - 8a829449488d79090148998943a853f6 - 1 - - - - 2014-09-21 18:46:22 - NOK - REJECTED_VALIDATION - Account Validation - invalid cc number/brand combination - - - + <<~XML + + + + + 4727.2856.0290 + 8a829449488d79090148998943a853f6 + 1 + + + + 2014-09-21 18:46:22 + NOK + REJECTED_VALIDATION + Account Validation + invalid cc number/brand combination + + + XML end def successful_capture_response - <<-XML - - - - - 1269.8369.2962 - 8a82944a488d36c10148998d9b316cc6 - - 8a829449488d79090148998d97f05439 - - - - 1.00 - EUR - 1269.8369.2962 DEFAULT Store Purchase - 1.0 - INTERN - 2014-09-21 18:51:07 - - - - 2014-09-21 18:51:07 - ACK - NEW - Successful Processing - Request successfully processed in 'Merchant in Connector Test Mode' - - - - + <<~XML + + + + + 1269.8369.2962 + 8a82944a488d36c10148998d9b316cc6 + + 8a829449488d79090148998d97f05439 + + + + 1.00 + EUR + 1269.8369.2962 DEFAULT Store Purchase + 1.0 + INTERN + 2014-09-21 18:51:07 + + + + 2014-09-21 18:51:07 + ACK + NEW + Successful Processing + Request successfully processed in 'Merchant in Connector Test Mode' + + + + XML end def failed_capture_response - <<-XML - - - - - 0239.0447.7858 - 8a82944a488d36c10148998fc4b66cfc - - - - - - 2014-09-21 18:53:29 - NOK - REJECTED_VALIDATION - Format Error - invalid Request/Transaction/Payment/Presentation tag (not present or [partially] empty) - - - + <<~XML + + + + + 0239.0447.7858 + 8a82944a488d36c10148998fc4b66cfc + + + + + + 2014-09-21 18:53:29 + NOK + REJECTED_VALIDATION + Format Error + invalid Request/Transaction/Payment/Presentation tag (not present or [partially] empty) + + + XML end def successful_refund_response - <<-XML - - - - - 3009.2986.8450 - 8a829449488d790901489992a493546f - - 8a82944a488d36c101489992a10f6d21 - - - - 1.00 - EUR - 3009.2986.8450 DEFAULT Store Purchase - 1.0 - INTERN - 2014-09-21 18:56:37 - - - - 2014-09-21 18:56:37 - ACK - NEW - Successful Processing - Request successfully processed in 'Merchant in Connector Test Mode' - - - + <<~XML + + + + + 3009.2986.8450 + 8a829449488d790901489992a493546f + + 8a82944a488d36c101489992a10f6d21 + + + + 1.00 + EUR + 3009.2986.8450 DEFAULT Store Purchase + 1.0 + INTERN + 2014-09-21 18:56:37 + + + + 2014-09-21 18:56:37 + ACK + NEW + Successful Processing + Request successfully processed in 'Merchant in Connector Test Mode' + + + XML end def failed_refund_response - <<-XML - - - - - 5070.8829.8658 - 8a829449488d790901489994b2c65481 - - - - - - 2014-09-21 18:58:52 - NOK - REJECTED_VALIDATION - Format Error - invalid Request/Transaction/Payment/Presentation tag (not present or [partially] empty) - - - + <<~XML + + + + + 5070.8829.8658 + 8a829449488d790901489994b2c65481 + + + + + + 2014-09-21 18:58:52 + NOK + REJECTED_VALIDATION + Format Error + invalid Request/Transaction/Payment/Presentation tag (not present or [partially] empty) + + + XML end def successful_void_response - <<-XML - - - - - 4587.6991.6578 - 8a82944a488d36c1014899957fff6d49 - - 8a829449488d7909014899957cb45486 - - - - 1.00 - EUR - 4587.6991.6578 DEFAULT Store Purchase - 1.0 - INTERN - 2014-09-21 18:59:44 - - - - 2014-09-21 18:59:44 - ACK - NEW - Successful Processing - Request successfully processed in 'Merchant in Connector Test Mode' - - - - + <<~XML + + + + + 4587.6991.6578 + 8a82944a488d36c1014899957fff6d49 + + 8a829449488d7909014899957cb45486 + + + + 1.00 + EUR + 4587.6991.6578 DEFAULT Store Purchase + 1.0 + INTERN + 2014-09-21 18:59:44 + + + + 2014-09-21 18:59:44 + ACK + NEW + Successful Processing + Request successfully processed in 'Merchant in Connector Test Mode' + + + + XML end def failed_void_response - <<-XML - - - - 5843.9770.9986 - 8a829449488d7909014899965cd354b6 - - - - - - 2014-09-21 19:00:41 - NOK - REJECTED_VALIDATION - Reference Error - reversal needs at least one successful transaction of type (CP or DB or RB or PA) - - - - + <<~XML + + + + 5843.9770.9986 + 8a829449488d7909014899965cd354b6 + + + + + + 2014-09-21 19:00:41 + NOK + REJECTED_VALIDATION + Reference Error + reversal needs at least one successful transaction of type (CP or DB or RB or PA) + + + + XML end end diff --git a/test/unit/gateways/moneris_test.rb b/test/unit/gateways/moneris_test.rb index 75959d1e808..7351da3af84 100644 --- a/test/unit/gateways/moneris_test.rb +++ b/test/unit/gateways/moneris_test.rb @@ -7,13 +7,13 @@ def setup Base.mode = :test @gateway = MonerisGateway.new( - :login => 'store3', - :password => 'yesguy' + login: 'store3', + password: 'yesguy' ) @amount = 100 @credit_card = credit_card('4242424242424242') - @options = { :order_id => '1', :customer => '1', :billing_address => address} + @options = { order_id: '1', customer: '1', billing_address: address } end def test_default_options @@ -32,8 +32,8 @@ def test_successful_purchase def test_successful_first_purchase_with_credential_on_file gateway = MonerisGateway.new( - :login => 'store3', - :password => 'yesguy' + login: 'store3', + password: 'yesguy' ) gateway.expects(:ssl_post).returns(successful_first_cof_purchase_response) assert response = gateway.purchase( @@ -53,8 +53,8 @@ def test_successful_first_purchase_with_credential_on_file def test_successful_subsequent_purchase_with_credential_on_file gateway = MonerisGateway.new( - :login => 'store3', - :password => 'yesguy' + login: 'store3', + password: 'yesguy' ) gateway.expects(:ssl_post).returns(successful_first_cof_authorize_response) assert response = gateway.authorize( @@ -91,8 +91,7 @@ def test_successful_purchase_with_network_tokenization @gateway.expects(:ssl_post).returns(successful_purchase_network_tokenization) @credit_card = network_tokenization_credit_card('4242424242424242', payment_cryptogram: 'BwABB4JRdgAAAAAAiFF2AAAAAAA=', - verification_value: nil - ) + verification_value: nil) assert response = @gateway.purchase(100, @credit_card, @options) assert_success response assert_equal '101965-0_10;0bbb277b543a17b6781243889a689573', response.authorization @@ -129,11 +128,11 @@ def test_amount_style def test_preauth_is_valid_xml params = { - :order_id => 'order1', - :amount => '1.01', - :pan => '4242424242424242', - :expdate => '0303', - :crypt_type => 7, + order_id: 'order1', + amount: '1.01', + pan: '4242424242424242', + expdate: '0303', + crypt_type: 7 } assert data = @gateway.send(:post_data, 'preauth', params) @@ -143,11 +142,11 @@ def test_preauth_is_valid_xml def test_purchase_is_valid_xml params = { - :order_id => 'order1', - :amount => '1.01', - :pan => '4242424242424242', - :expdate => '0303', - :crypt_type => 7, + order_id: 'order1', + amount: '1.01', + pan: '4242424242424242', + expdate: '0303', + crypt_type: 7 } assert data = @gateway.send(:post_data, 'purchase', params) @@ -157,11 +156,11 @@ def test_purchase_is_valid_xml def test_capture_is_valid_xml params = { - :order_id => 'order1', - :amount => '1.01', - :pan => '4242424242424242', - :expdate => '0303', - :crypt_type => 7, + order_id: 'order1', + amount: '1.01', + pan: '4242424242424242', + expdate: '0303', + crypt_type: 7 } assert data = @gateway.send(:post_data, 'preauth', params) @@ -170,10 +169,11 @@ def test_capture_is_valid_xml end def test_successful_verify - response = stub_comms do - @gateway.verify(@credit_card, @options) - end.respond_with(successful_authorize_response, failed_void_response) + @gateway.expects(:ssl_post).returns(successful_verify_response) + + assert response = @gateway.verify(@credit_card, @options) assert_success response + assert_equal '125-0_14;93565164-01571', response.authorization assert_equal 'Approved', response.message end @@ -182,7 +182,7 @@ def test_supported_countries end def test_supported_card_types - assert_equal [:visa, :master, :american_express, :diners_club, :discover], MonerisGateway.supported_cardtypes + assert_equal %i[visa master american_express diners_club discover], MonerisGateway.supported_cardtypes end def test_should_raise_error_if_transaction_param_empty_on_credit_request @@ -200,6 +200,15 @@ def test_successful_store @data_key = response.params['data_key'] end + def test_successful_store_with_duration + @gateway.expects(:ssl_post).returns(successful_store_with_duration_response) + assert response = @gateway.store(@credit_card, duration: 600) + assert_success response + assert_equal 'Successfully registered cc details', response.message + assert response.params['data_key'].present? + @data_key = response.params['data_key'] + end + def test_successful_unstore @gateway.expects(:ssl_post).returns(successful_unstore_response) test_successful_store @@ -221,7 +230,7 @@ def test_update def test_successful_purchase_with_vault @gateway.expects(:ssl_post).returns(successful_purchase_response) test_successful_store - assert response = @gateway.purchase(100, @data_key, {:order_id => generate_unique_id, :customer => generate_unique_id}) + assert response = @gateway.purchase(100, @data_key, { order_id: generate_unique_id, customer: generate_unique_id }) assert_success response assert_equal 'Approved', response.message assert response.authorization.present? @@ -231,8 +240,7 @@ def test_successful_authorize_with_network_tokenization @gateway.expects(:ssl_post).returns(successful_authorization_network_tokenization) @credit_card = network_tokenization_credit_card('4242424242424242', payment_cryptogram: 'BwABB4JRdgAAAAAAiFF2AAAAAAA=', - verification_value: nil - ) + verification_value: nil) assert response = @gateway.authorize(100, @credit_card, @options) assert_success response assert_equal '109232-0_10;d88d9f5f3472898832c54d6b5572757e', response.authorization @@ -241,7 +249,7 @@ def test_successful_authorize_with_network_tokenization def test_successful_authorization_with_vault @gateway.expects(:ssl_post).returns(successful_purchase_response) test_successful_store - assert response = @gateway.authorize(100, @data_key, {:order_id => generate_unique_id, :customer => generate_unique_id}) + assert response = @gateway.authorize(100, @data_key, { order_id: generate_unique_id, customer: generate_unique_id }) assert_success response assert_equal 'Approved', response.message assert response.authorization.present? @@ -260,7 +268,7 @@ def test_cvv_enabled_and_provided @credit_card.verification_value = '452' stub_comms(gateway) do gateway.purchase(@amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{cvd_indicator>1<}, data) assert_match(%r{cvd_value>452<}, data) end.respond_with(successful_purchase_response) @@ -272,7 +280,7 @@ def test_cvv_enabled_but_not_provided @credit_card.verification_value = '' stub_comms(gateway) do gateway.purchase(@amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{cvd_indicator>0<}, data) assert_no_match(%r{cvd_value>}, data) end.respond_with(successful_purchase_response) @@ -282,7 +290,7 @@ def test_cvv_disabled_and_provided @credit_card.verification_value = '452' stub_comms do @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_no_match(%r{cvd_value>}, data) assert_no_match(%r{cvd_indicator>}, data) end.respond_with(successful_purchase_response) @@ -292,7 +300,7 @@ def test_cvv_disabled_but_not_provided @credit_card.verification_value = '' stub_comms do @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_no_match(%r{cvd_value>}, data) assert_no_match(%r{cvd_indicator>}, data) end.respond_with(successful_purchase_response) @@ -304,7 +312,7 @@ def test_avs_enabled_and_provided billing_address = address(address1: '1234 Anystreet', address2: '') stub_comms(gateway) do gateway.purchase(@amount, @credit_card, billing_address: billing_address, order_id: '1') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{avs_street_number>1234<}, data) assert_match(%r{avs_street_name>Anystreet<}, data) assert_match(%r{avs_zipcode>#{billing_address[:zip]}<}, data) @@ -316,7 +324,7 @@ def test_avs_enabled_but_not_provided stub_comms(gateway) do gateway.purchase(@amount, @credit_card, @options.tap { |x| x.delete(:billing_address) }) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_no_match(%r{avs_street_number>}, data) assert_no_match(%r{avs_street_name>}, data) assert_no_match(%r{avs_zipcode>}, data) @@ -327,7 +335,7 @@ def test_avs_disabled_and_provided billing_address = address(address1: '1234 Anystreet', address2: '') stub_comms do @gateway.purchase(@amount, @credit_card, billing_address: billing_address, order_id: '1') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_no_match(%r{avs_street_number>}, data) assert_no_match(%r{avs_street_name>}, data) assert_no_match(%r{avs_zipcode>}, data) @@ -337,7 +345,7 @@ def test_avs_disabled_and_provided def test_avs_disabled_and_not_provided stub_comms do @gateway.purchase(@amount, @credit_card, @options.tap { |x| x.delete(:billing_address) }) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_no_match(%r{avs_street_number>}, data) assert_no_match(%r{avs_street_name>}, data) assert_no_match(%r{avs_zipcode>}, data) @@ -358,7 +366,7 @@ def test_avs_result_valid_with_address def test_customer_can_be_specified stub_comms do @gateway.purchase(@amount, @credit_card, order_id: '3', customer: 'Joe Jones') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{cust_id>Joe Jones}, data) end.respond_with(successful_purchase_response) end @@ -366,7 +374,7 @@ def test_customer_can_be_specified def test_customer_not_specified_card_name_used stub_comms do @gateway.purchase(@amount, @credit_card, order_id: '3') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{cust_id>Longbob Longsen}, data) end.respond_with(successful_purchase_response) end @@ -376,7 +384,7 @@ def test_add_swipe_data_with_creditcard 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 '00', data assert_match 'Track Data', data end.respond_with(successful_purchase_response) @@ -394,7 +402,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/<\/issuer_id>/, data) assert_match(/C<\/payment_indicator>/, data) assert_match(/0<\/payment_information>/, data) @@ -407,7 +415,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/abc123<\/issuer_id>/, data) assert_match(/Z<\/payment_indicator>/, data) assert_match(/2<\/payment_information>/, data) @@ -420,7 +428,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/<\/issuer_id>/, data) assert_match(/R<\/payment_indicator>/, data) assert_match(/0<\/payment_information>/, data) @@ -433,7 +441,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/abc123<\/issuer_id>/, data) assert_match(/R<\/payment_indicator>/, data) assert_match(/2<\/payment_information>/, data) @@ -446,7 +454,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/<\/issuer_id>/, data) assert_match(/C<\/payment_indicator>/, data) assert_match(/0<\/payment_information>/, data) @@ -459,7 +467,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/abc123<\/issuer_id>/, data) assert_match(/Z<\/payment_indicator>/, data) assert_match(/2<\/payment_information>/, data) @@ -472,7 +480,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/<\/issuer_id>/, data) assert_match(/R<\/payment_indicator>/, data) assert_match(/0<\/payment_information>/, data) @@ -485,7 +493,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/abc123<\/issuer_id>/, data) assert_match(/R<\/payment_indicator>/, data) assert_match(/2<\/payment_information>/, data) @@ -498,7 +506,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/<\/issuer_id>/, data) assert_match(/C<\/payment_indicator>/, data) assert_match(/0<\/payment_information>/, data) @@ -511,7 +519,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/abc123<\/issuer_id>/, data) assert_match(/Z<\/payment_indicator>/, data) assert_match(/2<\/payment_information>/, data) @@ -524,7 +532,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/<\/issuer_id>/, data) assert_match(/C<\/payment_indicator>/, data) assert_match(/0<\/payment_information>/, data) @@ -537,7 +545,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/abc123<\/issuer_id>/, data) assert_match(/U<\/payment_indicator>/, data) assert_match(/2<\/payment_information>/, data) @@ -550,7 +558,7 @@ def test_add_cof_overrides_stored_credential_option options = stored_credential_options(:merchant, :unscheduled, id: 'abc123').merge(issuer_id: 'xyz987', payment_indicator: 'R', payment_information: '0') 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(/xyz987<\/issuer_id>/, data) assert_match(/R<\/payment_indicator>/, data) assert_match(/0<\/payment_information>/, data) @@ -573,141 +581,141 @@ def stored_credential_options(*args, id: nil) end def successful_purchase_response - <<-RESPONSE - - - - 1026.1 - 661221050010170010 - 027 - 01 - 013511 - 18:41:13 - 2008-01-05 - 00 - true - APPROVED * = - 1.00 - V - 58-0_3 - false - - + <<~RESPONSE + + + + 1026.1 + 661221050010170010 + 027 + 01 + 013511 + 18:41:13 + 2008-01-05 + 00 + true + APPROVED * = + 1.00 + V + 58-0_3 + false + + RESPONSE end def successful_first_cof_purchase_response - <<-RESPONSE - - - - - a33ba7edd448b91ef8d2f85fea614b8d - 660114080015099160 - 027 - 01 - 822665 - 07:43:28 - 2018-11-11 - 00 - true - APPROVED * = - 1.00 - V - 799655-0_11 - false - null - null - 355689484440192 - false - - + <<~RESPONSE + + + + + a33ba7edd448b91ef8d2f85fea614b8d + 660114080015099160 + 027 + 01 + 822665 + 07:43:28 + 2018-11-11 + 00 + true + APPROVED * = + 1.00 + V + 799655-0_11 + false + null + null + 355689484440192 + false + + RESPONSE end def successful_first_cof_authorize_response - <<-RESPONSE - - - - 8dbc28468af2007779bbede7ec1bab6c - 660109300018229130 - 027 - 01 - 718280 - 07:50:53 - 2018-11-11 - 01 - true - APPROVED * = - 1.00 - V - 830724-0_11 - false - null - null - 1A8315282537312 - 550923784451193 - false - - + <<~RESPONSE + + + + 8dbc28468af2007779bbede7ec1bab6c + 660109300018229130 + 027 + 01 + 718280 + 07:50:53 + 2018-11-11 + 01 + true + APPROVED * = + 1.00 + V + 830724-0_11 + false + null + null + 1A8315282537312 + 550923784451193 + false + + RESPONSE end def successful_subsequent_cof_purchase_response - <<-RESPONSE - - - - 830724-0_11;8dbc28468af2007779bbede7ec1bab6c - 660109490014038930 - 027 - 01 - 111234 - 07:50:54 - 2018-11-11 - 00 - true - APPROVED * = - 1.00 - V - 455422-0_11 - false - null - null - 762097792112819 - false - - + <<~RESPONSE + + + + 830724-0_11;8dbc28468af2007779bbede7ec1bab6c + 660109490014038930 + 027 + 01 + 111234 + 07:50:54 + 2018-11-11 + 00 + true + APPROVED * = + 1.00 + V + 455422-0_11 + false + null + null + 762097792112819 + false + + RESPONSE end def successful_purchase_network_tokenization - <<-RESPONSE - - - - 0bbb277b543a17b6781243889a689573 - 660110910011133780 - 027 - 01 - 368269 - 22:54:10 - 2015-07-05 - 00 - true - APPROVED * = - 1.00 - V - 101965-0_10 - false - null - null - false - false - - + <<~RESPONSE + + + + 0bbb277b543a17b6781243889a689573 + 660110910011133780 + 027 + 01 + 368269 + 22:54:10 + 2015-07-05 + 00 + true + APPROVED * = + 1.00 + V + 101965-0_10 + false + null + null + false + false + + RESPONSE end @@ -742,128 +750,163 @@ def successful_authorize_response end def successful_authorization_network_tokenization - <<-RESPONSE - - - - d88d9f5f3472898832c54d6b5572757e - 660110910011139740 - 027 - 01 - 873534 - 09:31:41 - 2015-07-09 - 01 - true - APPROVED * = - 1.00 - V - 109232-0_10 - false - null - null - false - false - - + <<~RESPONSE + + + + d88d9f5f3472898832c54d6b5572757e + 660110910011139740 + 027 + 01 + 873534 + 09:31:41 + 2015-07-09 + 01 + true + APPROVED * = + 1.00 + V + 109232-0_10 + false + null + null + false + false + + RESPONSE end def successful_purchase_response_with_avs_result - <<-RESPONSE - - - - 9c7189ec64b58f541335be1ca6294d09 - 660110910011136190 - 027 - 01 - 115497 - 15:20:51 - 2014-06-18 - 00 - trueAPPROVED * = - 10.10 - V - 491573-0_9 - false - null - null - false - A - null - false - - + <<~RESPONSE + + + + 9c7189ec64b58f541335be1ca6294d09 + 660110910011136190 + 027 + 01 + 115497 + 15:20:51 + 2014-06-18 + 00 + trueAPPROVED * = + 10.10 + V + 491573-0_9 + false + null + null + false + A + null + false + + RESPONSE end def failed_purchase_response - <<-RESPONSE - - - - 1026.1 - 661221050010170010 - 481 - 01 - 013511 - 18:41:13 - 2008-01-05 - 00 - true - DECLINED * = - 1.00 - V - 97-2-0 - false - - + <<~RESPONSE + + + + 1026.1 + 661221050010170010 + 481 + 01 + 013511 + 18:41:13 + 2008-01-05 + 00 + true + DECLINED * = + 1.00 + V + 97-2-0 + false + + RESPONSE end def successful_store_response - <<-RESPONSE - - - - 1234567890 - 027 - true - Successfully registered cc details * = - - + <<~RESPONSE + + + + 1234567890 + 027 + true + Successfully registered cc details * = + + + RESPONSE + end + + def successful_store_with_duration_response + <<~RESPONSE + + + + 1234567890 + null + null + 001 + null + null + Successfully registered CC details. + null + true + null + null + null + false + null + null + null + null + true + cc + null + + + 4242***4242 + 2010 + + + RESPONSE end def successful_unstore_response - <<-RESPONSE - - - - 1234567890 - 027 - true - Successfully deleted cc details * = - - + <<~RESPONSE + + + + 1234567890 + 027 + true + Successfully deleted cc details * = + + RESPONSE end def successful_update_response - <<-RESPONSE - - - - 1234567890 - 027 - true - Successfully updated cc details * = - - + <<~RESPONSE + + + + 1234567890 + 027 + true + Successfully updated cc details * = + + RESPONSE end @@ -894,6 +937,37 @@ def failed_void_response RESPONSE end + def successful_verify_response + <<-RESPONSE + + + + 93565164-01571 + 660158360010251110 + 027 + 01 + 000000 + 16:06:11 + 2019-11-04 + 06 + true + APPROVED * = + 0.00 + V + 125-0_14 + false + null + null + null + null + 1M + 2 + false + + + RESPONSE + end + def xml_purchase_fixture 'store1yesguy1.01424242424242424203037order1' end @@ -903,7 +977,7 @@ def xml_capture_fixture end def pre_scrub - <<-pre_scrub + <<-REQUEST opening connection to esqa.moneris.com:443... opened starting SSL for esqa.moneris.com:443... @@ -927,11 +1001,11 @@ def pre_scrub -> "0\r\n" -> "\r\n" Conn close - pre_scrub + REQUEST end def post_scrub - <<-post_scrub + <<-REQUEST opening connection to esqa.moneris.com:443... opened starting SSL for esqa.moneris.com:443... @@ -955,6 +1029,6 @@ def post_scrub -> "0\r\n" -> "\r\n" Conn close - post_scrub + REQUEST end end diff --git a/test/unit/gateways/moneris_us_test.rb b/test/unit/gateways/moneris_us_test.rb deleted file mode 100644 index 3263bebbc43..00000000000 --- a/test/unit/gateways/moneris_us_test.rb +++ /dev/null @@ -1,649 +0,0 @@ -require 'test_helper' - -class MonerisUsTest < Test::Unit::TestCase - include CommStub - - def setup - Base.mode = :test - - @gateway = MonerisUsGateway.new( - :login => 'monusqa002', - :password => 'qatoken' - ) - - @amount = 100 - @credit_card = credit_card('4242424242424242') - @check = check({ - routing_number: '011000015', - account_number: '1234455', - number: 123 - }) - @options = { :order_id => '1', :billing_address => address } - end - - def test_default_options - assert_equal 7, @gateway.options[:crypt_type] - assert_equal 'monusqa002', @gateway.options[:login] - assert_equal 'qatoken', @gateway.options[:password] - end - - def test_successful_purchase - @gateway.expects(:ssl_post).returns(successful_purchase_response) - - assert response = @gateway.authorize(100, @credit_card, @options) - assert_success response - assert_equal '58-0_3;1026.1', response.authorization - end - - def test_failed_purchase - @gateway.expects(:ssl_post).returns(failed_purchase_response) - - assert response = @gateway.authorize(100, @credit_card, @options) - assert_failure response - end - - def test_successful_echeck_purchase - @gateway.expects(:ssl_post).returns(successful_echeck_purchase_response) - - assert response = @gateway.authorize(100, @check, @options) - assert_success response - assert_equal '1522-0_25;cb80f38f44af2168fd9033cdf2d0d4c0', response.authorization - end - - def test_deprecated_credit - @gateway.expects(:ssl_post).with(anything, regexp_matches(/txn_number>123<\//), anything).returns('') - @gateway.expects(:parse).returns({}) - assert_deprecation_warning(Gateway::CREDIT_DEPRECATION_MESSAGE) do - @gateway.credit(@amount, '123;456', @options) - end - end - - def test_refund - @gateway.expects(:ssl_post).with(anything, regexp_matches(/txn_number>123<\//), anything).returns('') - @gateway.expects(:parse).returns({}) - @gateway.refund(@amount, '123;456', @options) - end - - def test_successful_verify - response = stub_comms do - @gateway.verify(@credit_card, @options) - end.respond_with(successful_authorize_response, successful_capture_response) - assert_success response - assert_equal '830337-0_25;d315c7a28623dec77dc136450692d2dd', response.authorization - end - - def test_successful_verify_and_failed_void - response = stub_comms do - @gateway.verify(@credit_card, @options) - end.respond_with(successful_authorize_response, failed_capture_response) - assert_success response - assert_equal '830337-0_25;d315c7a28623dec77dc136450692d2dd', response.authorization - assert_equal 'Approved', response.message - end - - def test_failed_verify - response = stub_comms do - @gateway.verify(@credit_card, @options) - end.respond_with(failed_authorize_response, successful_capture_response) - assert_failure response - assert_equal 'Declined', response.message - end - - def test_amount_style - assert_equal '10.34', @gateway.send(:amount, 1034) - - assert_raise(ArgumentError) do - @gateway.send(:amount, '10.34') - end - end - - def test_preauth_is_valid_xml - params = { - :order_id => 'order1', - :amount => '1.01', - :pan => '4242424242424242', - :expdate => '0303', - :crypt_type => 7, - } - - assert data = @gateway.send(:post_data, 'us_preauth', params) - assert REXML::Document.new(data) - assert_equal xml_capture_fixture.size, data.size - end - - def test_purchase_is_valid_xml - params = { - :order_id => 'order1', - :amount => '1.01', - :pan => '4242424242424242', - :expdate => '0303', - :crypt_type => 7, - } - - assert data = @gateway.send(:post_data, 'us_purchase', params) - assert REXML::Document.new(data) - assert_equal xml_purchase_fixture.size, data.size - end - - def test_capture_is_valid_xml - params = { - :order_id => 'order1', - :amount => '1.01', - :pan => '4242424242424242', - :expdate => '0303', - :crypt_type => 7, - } - - assert data = @gateway.send(:post_data, 'us_preauth', params) - assert REXML::Document.new(data) - assert_equal xml_capture_fixture.size, data.size - end - - def test_supported_countries - assert_equal ['US'], MonerisUsGateway.supported_countries - end - - def test_supported_card_types - assert_equal [:visa, :master, :american_express, :diners_club, :discover], MonerisUsGateway.supported_cardtypes - end - - def test_should_raise_error_if_transaction_param_empty_on_credit_request - [nil, '', '1234'].each do |invalid_transaction_param| - assert_raise(ArgumentError) { @gateway.void(invalid_transaction_param) } - end - end - - def test_successful_store - @gateway.expects(:ssl_post).returns(successful_store_response) - assert response = @gateway.store(@credit_card) - assert_success response - assert_equal 'Successfully registered cc details', response.message - assert response.params['data_key'].present? - @data_key = response.params['data_key'] - end - - def test_successful_unstore - @gateway.expects(:ssl_post).returns(successful_unstore_response) - test_successful_store - assert response = @gateway.unstore(@data_key) - assert_success response - assert_equal 'Successfully deleted cc details', response.message - assert response.params['data_key'].present? - end - - def test_update - @gateway.expects(:ssl_post).returns(successful_update_response) - test_successful_store - assert response = @gateway.update(@data_key, @credit_card) - assert_success response - assert_equal 'Successfully updated cc details', response.message - assert response.params['data_key'].present? - end - - def test_successful_purchase_with_vault - @gateway.expects(:ssl_post).returns(successful_purchase_response) - test_successful_store - assert response = @gateway.purchase(100, @data_key, {:order_id => generate_unique_id, :customer => generate_unique_id}) - assert_success response - assert_equal 'Approved', response.message - assert response.authorization.present? - end - - def test_successful_authorization_with_vault - @gateway.expects(:ssl_post).returns(successful_purchase_response) - test_successful_store - assert response = @gateway.authorize(100, @data_key, {:order_id => generate_unique_id, :customer => generate_unique_id}) - assert_success response - assert_equal 'Approved', response.message - assert response.authorization.present? - end - - def test_failed_authorization_with_vault - @gateway.expects(:ssl_post).returns(failed_purchase_response) - test_successful_store - assert response = @gateway.authorize(100, @data_key, @options) - assert_failure response - end - - def test_cvv_enabled_and_provided - gateway = MonerisGateway.new(login: 'store1', password: 'yesguy', cvv_enabled: true) - - @credit_card.verification_value = '452' - stub_comms(gateway) do - gateway.purchase(@amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| - assert_match(%r{cvd_indicator>1<}, data) - assert_match(%r{cvd_value>452<}, data) - end.respond_with(successful_purchase_response) - end - - def test_cvv_enabled_but_not_provided - gateway = MonerisGateway.new(login: 'store1', password: 'yesguy', cvv_enabled: true) - - @credit_card.verification_value = '' - stub_comms(gateway) do - gateway.purchase(@amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| - assert_match(%r{cvd_indicator>0<}, data) - assert_no_match(%r{cvd_value>}, data) - end.respond_with(successful_purchase_response) - end - - def test_cvv_disabled_and_provided - @credit_card.verification_value = '452' - stub_comms do - @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| - assert_no_match(%r{cvd_value>}, data) - assert_no_match(%r{cvd_indicator>}, data) - end.respond_with(successful_purchase_response) - end - - def test_cvv_disabled_but_not_provided - @credit_card.verification_value = '' - stub_comms do - @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| - assert_no_match(%r{cvd_value>}, data) - assert_no_match(%r{cvd_indicator>}, data) - end.respond_with(successful_purchase_response) - end - - def test_avs_enabled_and_provided - gateway = MonerisGateway.new(login: 'store1', password: 'yesguy', avs_enabled: true) - - billing_address = address(address1: '1234 Anystreet', address2: '') - stub_comms(gateway) do - gateway.purchase(@amount, @credit_card, billing_address: billing_address, order_id: '1') - end.check_request do |endpoint, data, headers| - assert_match(%r{avs_street_number>1234<}, data) - assert_match(%r{avs_street_name>Anystreet<}, data) - assert_match(%r{avs_zipcode>#{billing_address[:zip]}<}, data) - end.respond_with(successful_purchase_response_with_avs_result) - end - - def test_avs_enabled_but_not_provided - gateway = MonerisGateway.new(login: 'store1', password: 'yesguy', avs_enabled: true) - - stub_comms(gateway) do - gateway.purchase(@amount, @credit_card, @options.tap { |x| x.delete(:billing_address) }) - end.check_request do |endpoint, data, headers| - assert_no_match(%r{avs_street_number>}, data) - assert_no_match(%r{avs_street_name>}, data) - assert_no_match(%r{avs_zipcode>}, data) - end.respond_with(successful_purchase_response) - end - - def test_avs_disabled_and_provided - billing_address = address(address1: '1234 Anystreet', address2: '') - stub_comms do - @gateway.purchase(@amount, @credit_card, billing_address: billing_address, order_id: '1') - end.check_request do |endpoint, data, headers| - assert_no_match(%r{avs_street_number>}, data) - assert_no_match(%r{avs_street_name>}, data) - assert_no_match(%r{avs_zipcode>}, data) - end.respond_with(successful_purchase_response_with_avs_result) - end - - def test_avs_disabled_and_not_provided - stub_comms do - @gateway.purchase(@amount, @credit_card, @options.tap { |x| x.delete(:billing_address) }) - end.check_request do |endpoint, data, headers| - assert_no_match(%r{avs_street_number>}, data) - assert_no_match(%r{avs_street_name>}, data) - assert_no_match(%r{avs_zipcode>}, data) - end.respond_with(successful_purchase_response) - end - - def test_avs_result_valid_with_address - @gateway.expects(:ssl_post).returns(successful_purchase_response_with_avs_result) - assert response = @gateway.purchase(100, @credit_card, @options) - assert_equal(response.avs_result, { - 'code' => 'A', - 'message' => 'Street address matches, but postal code does not match.', - 'street_match' => 'Y', - 'postal_match' => 'N' - }) - end - - def test_customer_can_be_specified - stub_comms do - @gateway.purchase(@amount, @credit_card, order_id: '3', customer: 'Joe Jones') - end.check_request do |endpoint, data, headers| - assert_match(%r{cust_id>Joe Jones}, data) - end.respond_with(successful_purchase_response) - end - - def test_customer_not_specified_card_name_used - stub_comms do - @gateway.purchase(@amount, @credit_card, order_id: '3') - end.check_request do |endpoint, data, headers| - assert_match(%r{cust_id>Longbob Longsen}, data) - end.respond_with(successful_purchase_response) - end - - def test_transcript_scrubbing - assert @gateway.supports_scrubbing? - assert_equal @gateway.scrub(pre_scrub), post_scrub - end - - private - - def successful_purchase_response - <<-RESPONSE - - - - 1026.1 - 661221050010170010 - 027 - 01 - 013511 - 18:41:13 - 2008-01-05 - 00 - true - APPROVED * = - 1.00 - V - 58-0_3 - false - - - RESPONSE - end - - def successful_purchase_response_with_avs_result - <<-RESPONSE - - - - 9c7189ec64b58f541335be1ca6294d09 - 660110910011136190 - 027 - 01 - 115497 - 15:20:51 - 2014-06-18 - 00 - trueAPPROVED * = - 10.10 - V - 491573-0_9 - false - null - null - false - A - null - false - - - RESPONSE - end - - def failed_purchase_response - <<-RESPONSE - - - - 1026.1 - 661221050010170010 - 481 - 01 - 013511 - 18:41:13 - 2008-01-05 - 00 - true - DECLINED * = - 1.00 - V - 97-2-0 - false - - - RESPONSE - end - - def successful_authorize_response - <<-RESPONSE - - - - d315c7a28623dec77dc136450692d2dd - 640000030011763320 - 001 - 00 - 372611 - 09:08:58 - 2015-04-21 - 01 - true - APPROVED* - 1.00 - V - 830337-0_25 - false - null - null - false - A - - - - RESPONSE - end - - def failed_authorize_response - <<-RESPONSE - - - - 1fa06a83bbd1285ccfa1312835d5aa8d - 640020510015803330 - 481 - 05 - 242724 - 09:12:31 - 2015-04-21 - 01 - true - DECLINED* - 1.05 - V - 118187-0_25 - false - null - null - false - A - - - - RESPONSE - end - - def successful_capture_response - <<-RESPONSE - - - - 3a7150ceb7026fccc380743ea3f47fdf - 640000030011763340 - 001 - 00 - 224958 - 09:13:45 - 2015-04-21 - 02 - true - APPROVED* - 0.00 - V - 830339-1_25 - false - null - null - false - A - - - RESPONSE - end - - def failed_capture_response - <<-RESPONSE - - - - 3a7150ceb7026fccc380743ea3f47fdf - 640000030011763350 - 476 - 12 - 224958 - 09:13:46 - 2015-04-21 - 02 - true - DECLINED* - 0.00 - V - 830340-2_25 - false - null - null - false - - - RESPONSE - end - - def successful_store_response - <<-RESPONSE - - - - 1234567890 - 027 - true - Successfully registered cc details * = - - - RESPONSE - end - - def successful_unstore_response - <<-RESPONSE - - - - 1234567890 - 027 - true - Successfully deleted cc details * = - - - RESPONSE - end - - def successful_update_response - <<-RESPONSE - - - - 1234567890 - 027 - true - Successfully updated cc details * = - - - RESPONSE - end - - def successful_echeck_purchase_response - <<-RESPONSE - - - - cb80f38f44af2168fd9033cdf2d0d4c0 - 001000040010015220 - 005 - 01 - - 08:23:37 - 2018-06-18 - 00 - true - REGISTERED * = - 1.0 - CQ - 1522-0_25 - false - null - null - false - null - true - - - RESPONSE - end - - def xml_purchase_fixture - 'monusqa002qatoken1.01424242424242424203037order1' - end - - def xml_capture_fixture - 'monusqa002qatoken1.01424242424242424203037order1' - end - - def pre_scrub - %q{ -opening connection to esplusqa.moneris.com:443... -opened -starting SSL for esplusqa.moneris.com:443... -SSL established -<- "POST /gateway_us/servlet/MpgRequest 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: esplusqa.moneris.com\r\nContent-Length: 291\r\n\r\n" -<- "monusqa002qatokencec9ca34132f0945446589e36fff9cceLongbob Longsen1.00424242424242424219097" --> "HTTP/1.1 200 OK\r\n" --> "Date: Mon, 08 Jan 2018 19:20:26 GMT\r\n" --> "Content-Length: 659\r\n" --> "X-UA-Compatible: IE=Edge\r\n" --> "Connection: close\r\n" --> "Content-Type: text/html; charset=UTF-8\r\n" --> "Set-Cookie: TS01d02998=01649737b16d4ca54c296a0a369f4e549e4191e85d8d022d01468e559975e945b419002a42; Path=/\r\n" --> "Set-Cookie: TS01d02998_28=01e24a44e55591744bc115f421ddccd549b1655d75bda586c8ea625670efaa4432f67c8b7e06e7af82c70ef3ac4f46d7435664f2ac; Path=/\r\n" --> "\r\n" -reading 659 bytes... --> "cec9ca34132f0945446589e36fff9cce6400000300136301900010082712513:20:242018-01-0800trueAPPROVED*1.00V113295-0_25falsenullnullfalseA " -read 659 bytes -Conn close - } - end - - def post_scrub - %q{ -opening connection to esplusqa.moneris.com:443... -opened -starting SSL for esplusqa.moneris.com:443... -SSL established -<- "POST /gateway_us/servlet/MpgRequest 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: esplusqa.moneris.com\r\nContent-Length: 291\r\n\r\n" -<- "monusqa002[FILTERED]cec9ca34132f0945446589e36fff9cceLongbob Longsen1.00[FILTERED]19097" --> "HTTP/1.1 200 OK\r\n" --> "Date: Mon, 08 Jan 2018 19:20:26 GMT\r\n" --> "Content-Length: 659\r\n" --> "X-UA-Compatible: IE=Edge\r\n" --> "Connection: close\r\n" --> "Content-Type: text/html; charset=UTF-8\r\n" --> "Set-Cookie: TS01d02998=01649737b16d4ca54c296a0a369f4e549e4191e85d8d022d01468e559975e945b419002a42; Path=/\r\n" --> "Set-Cookie: TS01d02998_28=01e24a44e55591744bc115f421ddccd549b1655d75bda586c8ea625670efaa4432f67c8b7e06e7af82c70ef3ac4f46d7435664f2ac; Path=/\r\n" --> "\r\n" -reading 659 bytes... --> "cec9ca34132f0945446589e36fff9cce6400000300136301900010082712513:20:242018-01-0800trueAPPROVED*1.00V113295-0_25falsenullnullfalseA " -read 659 bytes -Conn close - } - end - -end diff --git a/test/unit/gateways/money_movers_test.rb b/test/unit/gateways/money_movers_test.rb index c5c3b275baf..6bd903e88c9 100644 --- a/test/unit/gateways/money_movers_test.rb +++ b/test/unit/gateways/money_movers_test.rb @@ -3,8 +3,8 @@ class MoneyMoversTest < Test::Unit::TestCase def setup @gateway = MoneyMoversGateway.new( - :login => 'demo', - :password => 'password' + login: 'demo', + password: 'password' ) @credit_card = credit_card('4111111111111111') @@ -12,9 +12,9 @@ def setup @amount = 100 @options = { - :order_id => '1', - :billing_address => address, - :description => 'Store Purchase' + order_id: '1', + billing_address: address, + description: 'Store Purchase' } end @@ -44,8 +44,8 @@ def test_unsuccessful_request def test_add_address result = {} - @gateway.send(:add_address, result, :billing_address => {:address1 => '1 Main St.', :address2 => 'apt 13', :country => 'US', :state => 'MI', :phone => '1234567890'}) - assert_equal ['address1', 'address2', 'city', 'company', 'country', 'phone', 'state', 'zip'], result.stringify_keys.keys.sort + @gateway.send(:add_address, result, billing_address: { address1: '1 Main St.', address2: 'apt 13', country: 'US', state: 'MI', phone: '1234567890' }) + assert_equal %w[address1 address2 city company country phone state zip], result.stringify_keys.keys.sort assert_equal 'MI', result[:state] assert_equal '1 Main St.', result[:address1] assert_equal 'apt 13', result[:address2] @@ -54,13 +54,13 @@ def test_add_address def test_add_invoice result = {} - @gateway.send(:add_invoice, result, :order_id => '#1001', :description => 'This is a great order') + @gateway.send(:add_invoice, result, order_id: '#1001', description: 'This is a great order') assert_equal '#1001', result[:orderid] assert_equal 'This is a great order', result[:orderdescription] end def test_purchase_is_valid_csv - params = {:amount => @amount} + params = { amount: @amount } @gateway.send(:add_creditcard, params, @credit_card) assert data = @gateway.send(:post_data, 'auth', params) @@ -68,7 +68,7 @@ def test_purchase_is_valid_csv end def test_purchase_meets_minimum_requirements - params = {:amount => @amount} + params = { amount: @amount } @gateway.send(:add_creditcard, params, @credit_card) assert data = @gateway.send(:post_data, 'auth', params) minimum_requirements.each do |key| @@ -77,8 +77,8 @@ def test_purchase_meets_minimum_requirements end def test_expdate_formatting - assert_equal '0909', @gateway.send(:expdate, credit_card('4111111111111111', :month => '9', :year => '2009')) - assert_equal '0711', @gateway.send(:expdate, credit_card('4111111111111111', :month => '7', :year => '2011')) + assert_equal '0909', @gateway.send(:expdate, credit_card('4111111111111111', month: '9', year: '2009')) + assert_equal '0711', @gateway.send(:expdate, credit_card('4111111111111111', month: '7', year: '2011')) end def test_supported_countries @@ -86,7 +86,7 @@ def test_supported_countries end def test_supported_card_types - assert_equal @gateway.supported_cardtypes, [:visa, :master, :american_express, :discover] + assert_equal @gateway.supported_cardtypes, %i[visa master american_express discover] end def test_avs_result diff --git a/test/unit/gateways/mundipagg_test.rb b/test/unit/gateways/mundipagg_test.rb index fd0af377ec6..daaa38ddf17 100644 --- a/test/unit/gateways/mundipagg_test.rb +++ b/test/unit/gateways/mundipagg_test.rb @@ -39,7 +39,34 @@ def setup description: 'Store Purchase' } + @submerchant_options = { + submerchant: { + "merchant_category_code": '44444', + "payment_facilitator_code": '5555555', + "code": 'code2', + "name": 'Sub Tony Stark', + "document": '123456789', + "type": 'individual', + "phone": { + "country_code": '55', + "number": '000000000', + "area_code": '21' + }, + "address": { + "street": 'Malibu Point', + "number": '10880', + "complement": 'A', + "neighborhood": 'Central Malibu', + "city": 'Malibu', + "state": 'CA', + "country": 'US', + "zip_code": '24210-460' + } + } + } + @gateway_response_error = 'Esta loja n??o possui um meio de pagamento configurado para a bandeira VR' + @acquirer_message = 'Simulator|Transação de simulada negada por falta de crédito, utilizado para realizar simulação de autorização parcial.' end def test_successful_purchase @@ -58,7 +85,7 @@ def test_successful_purchase_with_holder_document @options[:holder_document] = 'a1b2c3d4' 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(/a1b2c3d4/, data) end.respond_with(successful_purchase_response) @@ -66,11 +93,40 @@ def test_successful_purchase_with_holder_document assert response.test? end + def test_successful_purchase_with_submerchant + options = @options.update(@submerchant_options) + response = stub_comms do + @gateway.purchase(@amount, @credit_card, options) + end.check_request do |_endpoint, data, _headers| + assert_match(/44444/, data) + assert_match(/5555555/, data) + assert_match(/code2/, data) + assert_match(/Sub Tony Stark/, data) + assert_match(/123456789/, data) + assert_match(/individual/, data) + assert_match(/55/, data) + assert_match(/000000000/, data) + assert_match(/21/, data) + assert_match(/Malibu Point/, data) + assert_match(/10880/, data) + assert_match(/A/, data) + assert_match(/Central Malibu/, data) + assert_match(/Malibu/, data) + assert_match(/CA/, data) + assert_match(/US/, data) + assert_match(/24210-460/, data) + end.respond_with(successful_purchase_response) + + assert_success response + assert_equal 'Simulator|Transação de simulação autorizada com sucesso', response.message + assert response.test? + end + def test_billing_not_sent @options.delete(:billing_address) stub_comms do @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| refute data['billing_address'] end.respond_with(successful_purchase_response) end @@ -80,7 +136,8 @@ def test_failed_purchase response = @gateway.purchase(@amount, @credit_card, @options) assert_failure response - assert_equal Gateway::STANDARD_ERROR_CODE[:processing_error], response.error_code + assert_equal @acquirer_message, response.message + assert_equal '92', response.error_code end def test_failed_purchase_with_top_level_errors @@ -100,6 +157,16 @@ def test_failed_purchase_with_gateway_response_errors assert_equal @gateway_response_error, response.message end + def test_failed_purchase_with_acquirer_return_code + @gateway.expects(:ssl_post).returns(failed_response_with_acquirer_return_code) + + response = @gateway.purchase(@amount, @credit_card, @options) + + assert_failure response + assert_equal 'VR|', response.message + assert_equal '14', response.error_code + end + def test_successful_authorize @gateway.expects(:ssl_post).returns(successful_authorize_response) @@ -124,12 +191,24 @@ def test_successful_authorize_with_partially_missing_address assert response.test? end + def test_successful_authorize_with_submerchant + options = @options.update(@submerchant_options) + + @gateway.expects(:ssl_post).returns(successful_authorize_response) + response = @gateway.authorize(@amount, @credit_card, options) + assert_success response + + assert_equal 'ch_gm5wrlGMI2Fb0x6K', response.authorization + assert response.test? + end + def test_failed_authorize @gateway.expects(:ssl_post).returns(failed_authorize_response) response = @gateway.authorize(@amount, @credit_card, @options) assert_failure response - assert_equal Gateway::STANDARD_ERROR_CODE[:processing_error], response.error_code + assert_equal @acquirer_message, response.message + assert_equal '92', response.error_code end def test_failed_authorize_with_top_level_errors @@ -258,7 +337,7 @@ def test_gateway_id_fallback } 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(/"gateway_affiliation_id":"abc123"/, data) end.respond_with(successful_purchase_response) end @@ -611,6 +690,79 @@ def failed_response_with_gateway_response_errors ) end + def failed_response_with_acquirer_return_code + %( + { + "id": "ch_9qY3lpeCJyTe2Gxz", + "code": "3Y4ZFENCK4", + "gateway_id": "db9a46cb-2c59-4663-a658-e7817302d97c", + "amount": 2946, + "status": "failed", + "currency": "BRL", + "payment_method": "credit_card", + "created_at": "2019-11-15T16:21:58Z", + "updated_at": "2019-11-15T16:21:59Z", + "customer": { + "id": "cus_KD14bY1F51UR1GrX", + "name": "JOSE NETO", + "email": "jose_bar@uol.com.br", + "delinquent": false, + "created_at": "2019-11-15T16:21:58Z", + "updated_at": "2019-11-15T16:21:58Z", + "phones": {} + }, + "last_transaction": { + "id": "tran_P2zwvPztdVCg6pvA", + "transaction_type": "credit_card", + "gateway_id": "174a1d12-cbea-4c09-a27a-23bbad992cc9", + "amount": 2946, + "status": "not_authorized", + "success": false, + "installments": 1, + "acquirer_name": "vr", + "acquirer_affiliation_code": "", + "acquirer_tid": "28128131916", + "acquirer_nsu": "281281", + "acquirer_message": "VR|", + "acquirer_return_code": "14", + "operation_type": "auth_and_capture", + "card": { + "id": "card_V2pQo2IbjtPqaXRZ", + "first_six_digits": "627416", + "last_four_digits": "7116", + "brand": "VR", + "holder_name": "JOSE NETO", + "holder_document": "27207590822", + "exp_month": 8, + "exp_year": 2029, + "status": "active", + "type": "voucher", + "created_at": "2019-11-15T16:21:58Z", + "updated_at": "2019-11-15T16:21:58Z", + "billing_address": { + "street": "R.Dr.Eduardo de Souza Aranha,", + "number": "67", + "zip_code": "04530030", + "neighborhood": "Av Das Nacoes Unidas 6873", + "city": "Sao Paulo", + "state": "SP", + "country": "BR", + "line_1": "67, R.Dr.Eduardo de Souza Aranha,, Av Das Nacoes Unidas 6873" + } + }, + "created_at": "2019-11-15T16:21:58Z", + "updated_at": "2019-11-15T16:21:58Z", + "gateway_response": { + "code": "201", + "errors": [] + }, + "antifraud_response": {}, + "metadata": {} + } + } + ) + end + def successful_authorize_response %( { diff --git a/test/unit/gateways/nab_transact_test.rb b/test/unit/gateways/nab_transact_test.rb index d02ebadce3a..b4afc7c7313 100644 --- a/test/unit/gateways/nab_transact_test.rb +++ b/test/unit/gateways/nab_transact_test.rb @@ -5,16 +5,16 @@ class NabTransactTest < Test::Unit::TestCase def setup @gateway = NabTransactGateway.new( - :login => 'login', - :password => 'password' - ) + login: 'login', + password: 'password' + ) @credit_card = credit_card @amount = 200 @options = { - :order_id => '1', - :billing_address => address, - :description => 'Test NAB Purchase' + order_id: '1', + billing_address: address, + description: 'Test NAB Purchase' } end @@ -33,7 +33,7 @@ def test_successful_purchase_with_merchant_descriptor name, location = 'Active Merchant', 'USA' response = assert_metadata(name, location) do - response = @gateway.purchase(@amount, @credit_card, @options.merge(:merchant_name => name, :merchant_location => location)) + response = @gateway.purchase(@amount, @credit_card, @options.merge(merchant_name: name, merchant_location: location)) end assert response @@ -52,7 +52,7 @@ def test_successful_authorize_with_merchant_descriptor name, location = 'Active Merchant', 'USA' response = assert_metadata(name, location) do - response = @gateway.authorize(@amount, @credit_card, @options.merge(:merchant_name => name, :merchant_location => location)) + response = @gateway.authorize(@amount, @credit_card, @options.merge(merchant_name: name, merchant_location: location)) end assert response @@ -71,7 +71,7 @@ def test_successful_capture_with_merchant_descriptor name, location = 'Active Merchant', 'USA' response = assert_metadata(name, location) do - response = @gateway.capture(@amount, '009887*test*009887*200', @options.merge(:merchant_name => name, :merchant_location => location)) + response = @gateway.capture(@amount, '009887*test*009887*200', @options.merge(merchant_name: name, merchant_location: location)) end assert response @@ -103,19 +103,19 @@ def test_supported_countries end def test_supported_card_types - assert_equal [:visa, :master, :american_express, :diners_club, :jcb], NabTransactGateway.supported_cardtypes + assert_equal %i[visa master american_express diners_club jcb], NabTransactGateway.supported_cardtypes end def test_successful_refund @gateway.expects(:ssl_post).with(&check_transaction_type(:refund)).returns(successful_refund_response) - assert_success @gateway.refund(@amount, '009887', {:order_id => '1'}) + assert_success @gateway.refund(@amount, '009887', { order_id: '1' }) end def test_successful_refund_with_merchant_descriptor name, location = 'Active Merchant', 'USA' response = assert_metadata(name, location) do - response = @gateway.refund(@amount, '009887', {:order_id => '1', :merchant_name => name, :merchant_location => location}) + response = @gateway.refund(@amount, '009887', { order_id: '1', merchant_name: name, merchant_location: location }) end assert response @@ -125,13 +125,13 @@ def test_successful_refund_with_merchant_descriptor def test_successful_credit @gateway.expects(:ssl_post).with(&check_transaction_type(:unmatched_refund)).returns(successful_refund_response) - assert_success @gateway.credit(@amount, @credit_card, {:order_id => '1'}) + assert_success @gateway.credit(@amount, @credit_card, { order_id: '1' }) end def test_failed_refund @gateway.expects(:ssl_post).with(&check_transaction_type(:refund)).returns(failed_refund_response) - response = @gateway.refund(@amount, '009887', {:order_id => '1'}) + response = @gateway.refund(@amount, '009887', { order_id: '1' }) assert_failure response assert_equal 'Only $1.00 available for refund', response.message end @@ -139,7 +139,7 @@ def test_failed_refund def test_request_timeout_default stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/60/, data) end.respond_with(successful_purchase_response) end @@ -148,7 +148,7 @@ def test_override_request_timeout gateway = NabTransactGateway.new(login: 'login', password: 'password', request_timeout: 44) stub_comms(gateway, :ssl_request) do gateway.purchase(@amount, @credit_card, @options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/44/, data) end.respond_with(successful_purchase_response) end @@ -156,7 +156,7 @@ def test_override_request_timeout def test_nonfractional_currencies stub_comms(@gateway, :ssl_request) do @gateway.authorize(10000, @credit_card, @options.merge(currency: 'JPY')) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/100<\/amount>/, data) end.respond_with(successful_authorize_response) end @@ -169,60 +169,60 @@ def test_scrub private def pre_scrubbed - <<-'PRE_SCRUBBED' -opening connection to transact.nab.com.au:443... -opened -starting SSL for transact.nab.com.au:443... -SSL established -<- "POST /test/xmlapi/payment 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: transact.nab.com.au\r\nContent-Length: 715\r\n\r\n" -<- "6673348a21d79657983ab247b2483e20151212075932886818+00060xml-4.2XYZ0010abcd1234Payment023200AUD444433332222111105/17111" --> "HTTP/1.1 200 OK\r\n" --> "Date: Sat, 12 Dec 2015 07:59:34 GMT\r\n" --> "Server: Apache-Coyote/1.1\r\n" --> "Content-Type: text/xml;charset=ISO-8859-1\r\n" --> "Content-Length: 920\r\n" --> "Connection: close\r\n" --> "\r\n" -reading 920 bytes... --> "" --> "6673348a21d79657983ab247b2483e20151212185934964000+660xml-4.2PaymentXYZ0010000Normal023200AUDNo103Invalid Purchase Order Number444433...11105/176Visa" -read 920 bytes -Conn close + <<~'PRE_SCRUBBED' + opening connection to transact.nab.com.au:443... + opened + starting SSL for transact.nab.com.au:443... + SSL established + <- "POST /test/xmlapi/payment 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: transact.nab.com.au\r\nContent-Length: 715\r\n\r\n" + <- "6673348a21d79657983ab247b2483e20151212075932886818+00060xml-4.2XYZ0010abcd1234Payment023200AUD444433332222111105/17111" + -> "HTTP/1.1 200 OK\r\n" + -> "Date: Sat, 12 Dec 2015 07:59:34 GMT\r\n" + -> "Server: Apache-Coyote/1.1\r\n" + -> "Content-Type: text/xml;charset=ISO-8859-1\r\n" + -> "Content-Length: 920\r\n" + -> "Connection: close\r\n" + -> "\r\n" + reading 920 bytes... + -> "" + -> "6673348a21d79657983ab247b2483e20151212185934964000+660xml-4.2PaymentXYZ0010000Normal023200AUDNo103Invalid Purchase Order Number444433...11105/176Visa" + read 920 bytes + Conn close PRE_SCRUBBED end def post_scrubbed - <<-'POST_SCRUBBED' -opening connection to transact.nab.com.au:443... -opened -starting SSL for transact.nab.com.au:443... -SSL established -<- "POST /test/xmlapi/payment 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: transact.nab.com.au\r\nContent-Length: 715\r\n\r\n" -<- "6673348a21d79657983ab247b2483e20151212075932886818+00060xml-4.2XYZ0010[FILTERED]Payment023200AUD[FILTERED]05/17[FILTERED]" --> "HTTP/1.1 200 OK\r\n" --> "Date: Sat, 12 Dec 2015 07:59:34 GMT\r\n" --> "Server: Apache-Coyote/1.1\r\n" --> "Content-Type: text/xml;charset=ISO-8859-1\r\n" --> "Content-Length: 920\r\n" --> "Connection: close\r\n" --> "\r\n" -reading 920 bytes... --> "" --> "6673348a21d79657983ab247b2483e20151212185934964000+660xml-4.2PaymentXYZ0010000Normal023200AUDNo103Invalid Purchase Order Number444433...11105/176Visa" -read 920 bytes -Conn close + <<~'POST_SCRUBBED' + opening connection to transact.nab.com.au:443... + opened + starting SSL for transact.nab.com.au:443... + SSL established + <- "POST /test/xmlapi/payment 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: transact.nab.com.au\r\nContent-Length: 715\r\n\r\n" + <- "6673348a21d79657983ab247b2483e20151212075932886818+00060xml-4.2XYZ0010[FILTERED]Payment023200AUD[FILTERED]05/17[FILTERED]" + -> "HTTP/1.1 200 OK\r\n" + -> "Date: Sat, 12 Dec 2015 07:59:34 GMT\r\n" + -> "Server: Apache-Coyote/1.1\r\n" + -> "Content-Type: text/xml;charset=ISO-8859-1\r\n" + -> "Content-Length: 920\r\n" + -> "Connection: close\r\n" + -> "\r\n" + reading 920 bytes... + -> "" + -> "6673348a21d79657983ab247b2483e20151212185934964000+660xml-4.2PaymentXYZ0010000Normal023200AUDNo103Invalid Purchase Order Number444433...11105/176Visa" + read 920 bytes + Conn close POST_SCRUBBED end def check_transaction_type(type) - Proc.new do |endpoint, data, headers| + Proc.new do |_endpoint, data, _headers| request_hash = Hash.from_xml(data) request_hash['NABTransactMessage']['Payment']['TxnList']['Txn']['txnType'] == NabTransactGateway::TRANSACTIONS[type].to_s end end def valid_metadata(name, location) - return <<-XML.gsub(/^\s{4}/, '').gsub(/\n/, '') + return <<-XML.gsub(/^\s{4}/, '').delete("\n") XML end @@ -230,7 +230,7 @@ def valid_metadata(name, location) def assert_metadata(name, location, &block) stub_comms(@gateway, :ssl_request) do yield - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| metadata_matcher = Regexp.escape(valid_metadata(name, location)) assert_match %r{#{metadata_matcher}}, data end.respond_with(successful_purchase_response) @@ -456,5 +456,4 @@ def failed_refund_response XML end - end diff --git a/test/unit/gateways/ncr_secure_pay_test.rb b/test/unit/gateways/ncr_secure_pay_test.rb index 4fabb3b8779..6dee2375635 100644 --- a/test/unit/gateways/ncr_secure_pay_test.rb +++ b/test/unit/gateways/ncr_secure_pay_test.rb @@ -18,7 +18,7 @@ def setup 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(/\login\<\/username\>/, data) assert_match(/\password\<\/password\>/, data) assert_match(/\sale\<\/action\>/, data) @@ -43,7 +43,7 @@ def test_failed_purchase def test_successful_authorize 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(/\login\<\/username\>/, data) assert_match(/\password\<\/password\>/, data) assert_match(/\preauth\<\/action\>/, data) @@ -67,7 +67,7 @@ def test_failed_authorize def test_successful_capture response = stub_comms do @gateway.capture(@amount, '12345', @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/\login\<\/username\>/, data) assert_match(/\password\<\/password\>/, data) assert_match(/\preauthcomplete\<\/action\>/, data) @@ -90,7 +90,7 @@ def test_failed_capture def test_successful_refund response = stub_comms do @gateway.refund(@amount, '12345', @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/\login\<\/username\>/, data) assert_match(/\password\<\/password\>/, data) assert_match(/\credit\<\/action\>/, data) @@ -113,7 +113,7 @@ def test_failed_refund def test_successful_void response = stub_comms do @gateway.void('12345', @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/\login\<\/username\>/, data) assert_match(/\password\<\/password\>/, data) assert_match(/\void\<\/action\>/, data) diff --git a/test/unit/gateways/net_registry_test.rb b/test/unit/gateways/net_registry_test.rb index f04017728d2..40d0daba5fa 100644 --- a/test/unit/gateways/net_registry_test.rb +++ b/test/unit/gateways/net_registry_test.rb @@ -3,15 +3,15 @@ class NetRegistryTest < Test::Unit::TestCase def setup @gateway = NetRegistryGateway.new( - :login => 'X', - :password => 'Y' + login: 'X', + password: 'Y' ) @amount = 100 @credit_card = credit_card @options = { - :order_id => '1', - :billing_address => address + order_id: '1', + billing_address: address } end @@ -67,7 +67,7 @@ def test_successful_authorization_and_capture assert_success response assert_match %r{\A\d{6}\z}, response.authorization - response = @gateway.capture(@amount, response.authorization, :credit_card => @credit_card) + response = @gateway.capture(@amount, response.authorization, credit_card: @credit_card) assert_success response end @@ -96,7 +96,7 @@ def test_purchase_with_invalid_month end def test_bad_login - gateway = NetRegistryGateway.new(:login => 'bad-login', :password => 'bad-login') + gateway = NetRegistryGateway.new(login: 'bad-login', password: 'bad-login') gateway.stubs(:ssl_post).returns(bad_login_response) response = gateway.purchase(@amount, @credit_card, @options) @@ -107,319 +107,319 @@ def test_bad_login private def successful_purchase_response - <<-RESPONSE -approved -00015X000000 -Transaction No: 00000000 ------------------------- -MERCHANTNAME -LOCATION AU - -MERCH ID 10000000 -TERM ID Y0TR00 -COUNTRY CODE AU -16/07/07 18:59 -RRN 00015X000000 -VISA -411111-111 -CREDIT A/C 12/10 - -AUTHORISATION NO: 000000 -APPROVED 08 - -PURCHASE $1.00 -TOTAL AUD $1.00 - -PLEASE RETAIN AS RECORD - OF PURCHASE - -(SUBJECT TO CARDHOLDER'S - ACCEPTANCE) ------------------------- -. -settlement_date=16/07/07 -card_desc=VISA -status=approved -txn_ref=0707161858000000 -refund_mode=0 -transaction_no=000000 -rrn=00015X000000 -response_text=SIGNATURE REQUIRED -pld=0 -total_amount=100 -card_no=4111111111111111 -version=V1.0 -merchant_index=123 -card_expiry=12/10 -training_mode=0 -operator_no=10000 -response_code=08 -card_type=6 -approved=1 -cashout_amount=0 -receipt_array=ARRAY(0x83725cc) -account_type=CREDIT A/C -result=1 + <<~RESPONSE + approved + 00015X000000 + Transaction No: 00000000 + ------------------------ + MERCHANTNAME + LOCATION AU + + MERCH ID 10000000 + TERM ID Y0TR00 + COUNTRY CODE AU + 16/07/07 18:59 + RRN 00015X000000 + VISA + 411111-111 + CREDIT A/C 12/10 + + AUTHORISATION NO: 000000 + APPROVED 08 + + PURCHASE $1.00 + TOTAL AUD $1.00 + + PLEASE RETAIN AS RECORD + OF PURCHASE + + (SUBJECT TO CARDHOLDER'S + ACCEPTANCE) + ------------------------ + . + settlement_date=16/07/07 + card_desc=VISA + status=approved + txn_ref=0707161858000000 + refund_mode=0 + transaction_no=000000 + rrn=00015X000000 + response_text=SIGNATURE REQUIRED + pld=0 + total_amount=100 + card_no=4111111111111111 + version=V1.0 + merchant_index=123 + card_expiry=12/10 + training_mode=0 + operator_no=10000 + response_code=08 + card_type=6 + approved=1 + cashout_amount=0 + receipt_array=ARRAY(0x83725cc) + account_type=CREDIT A/C + result=1 RESPONSE end def successful_credit_response - <<-RESPONSE -approved -00015X000000 -Transaction No: 00000000 ------------------------- -MERCHANTNAME -LOCATION AU - -MERCH ID 10000000 -TERM ID Y0TR00 -COUNTRY CODE AU -16/07/07 19:03 -RRN 00015X000000 -VISA -411111-111 -CREDIT A/C 12/10 - -AUTHORISATION NO: -APPROVED 08 - -** REFUND ** $1.00 -TOTAL AUD $1.00 - -PLEASE RETAIN AS RECORD - OF REFUND - -(SUBJECT TO CARDHOLDER'S - ACCEPTANCE) ------------------------- -. -settlement_date=16/07/07 -card_desc=VISA -status=approved -txn_ref=0707161902000000 -refund_mode=1 -transaction_no=000000 -rrn=00015X000000 -response_text=SIGNATURE REQUIRED -pld=0 -total_amount=100 -card_no=4111111111111111 -version=V1.0 -merchant_index=123 -card_expiry=12/10 -training_mode=0 -operator_no=10000 -response_code=08 -card_type=6 -approved=1 -cashout_amount=0 -receipt_array=ARRAY(0x837241c) -account_type=CREDIT A/C -result=1 + <<~RESPONSE + approved + 00015X000000 + Transaction No: 00000000 + ------------------------ + MERCHANTNAME + LOCATION AU + + MERCH ID 10000000 + TERM ID Y0TR00 + COUNTRY CODE AU + 16/07/07 19:03 + RRN 00015X000000 + VISA + 411111-111 + CREDIT A/C 12/10 + + AUTHORISATION NO: + APPROVED 08 + + ** REFUND ** $1.00 + TOTAL AUD $1.00 + + PLEASE RETAIN AS RECORD + OF REFUND + + (SUBJECT TO CARDHOLDER'S + ACCEPTANCE) + ------------------------ + . + settlement_date=16/07/07 + card_desc=VISA + status=approved + txn_ref=0707161902000000 + refund_mode=1 + transaction_no=000000 + rrn=00015X000000 + response_text=SIGNATURE REQUIRED + pld=0 + total_amount=100 + card_no=4111111111111111 + version=V1.0 + merchant_index=123 + card_expiry=12/10 + training_mode=0 + operator_no=10000 + response_code=08 + card_type=6 + approved=1 + cashout_amount=0 + receipt_array=ARRAY(0x837241c) + account_type=CREDIT A/C + result=1 RESPONSE end def successful_authorization_response - <<-RESPONSE -approved -00015X000000 -Transaction No: 00000000 ------------------------- -MERCHANTNAME -LOCATION AU - -MERCH ID 10000000 -TERM ID Y0TR00 -COUNTRY CODE AU -17/07/07 15:22 -RRN 00015X000000 -VISA -411111-111 -CREDIT A/C 12/10 - -AUTHORISATION NO: 000000 -APPROVED 08 - -PURCHASE $1.00 -TOTAL AUD $1.00 - -PLEASE RETAIN AS RECORD - OF PURCHASE - -(SUBJECT TO CARDHOLDER'S - ACCEPTANCE) ------------------------- -. -settlement_date=17/07/07 -card_desc=VISA -status=approved -txn_ref=0707171521000000 -refund_mode=0 -transaction_no=000000 -rrn=00015X000000 -response_text=SIGNATURE REQUIRED -pld=0 -total_amount=100 -card_no=4111111111111111 -version=V1.0 -merchant_index=123 -card_expiry=12/10 -training_mode=0 -operator_no=10000 -response_code=08 -card_type=6 -approved=1 -cashout_amount=0 -receipt_array=ARRAY(0x836a25c) -account_type=CREDIT A/C -result=1 + <<~RESPONSE + approved + 00015X000000 + Transaction No: 00000000 + ------------------------ + MERCHANTNAME + LOCATION AU + + MERCH ID 10000000 + TERM ID Y0TR00 + COUNTRY CODE AU + 17/07/07 15:22 + RRN 00015X000000 + VISA + 411111-111 + CREDIT A/C 12/10 + + AUTHORISATION NO: 000000 + APPROVED 08 + + PURCHASE $1.00 + TOTAL AUD $1.00 + + PLEASE RETAIN AS RECORD + OF PURCHASE + + (SUBJECT TO CARDHOLDER'S + ACCEPTANCE) + ------------------------ + . + settlement_date=17/07/07 + card_desc=VISA + status=approved + txn_ref=0707171521000000 + refund_mode=0 + transaction_no=000000 + rrn=00015X000000 + response_text=SIGNATURE REQUIRED + pld=0 + total_amount=100 + card_no=4111111111111111 + version=V1.0 + merchant_index=123 + card_expiry=12/10 + training_mode=0 + operator_no=10000 + response_code=08 + card_type=6 + approved=1 + cashout_amount=0 + receipt_array=ARRAY(0x836a25c) + account_type=CREDIT A/C + result=1 RESPONSE end def successful_capture_response - <<-RESPONSE -approved -00015X000000 -Transaction No: 00000000 ------------------------- -MERCHANTNAME -LOCATION AU - -MERCH ID 10000000 -TERM ID Y0TR00 -COUNTRY CODE AU -17/07/07 15:23 -RRN 00015X000000 -VISA -411111-111 -CREDIT A/C 12/10 - -AUTHORISATION NO: 000000 -APPROVED 08 - -PURCHASE $1.00 -TOTAL AUD $1.00 - -PLEASE RETAIN AS RECORD - OF PURCHASE - -(SUBJECT TO CARDHOLDER'S - ACCEPTANCE) ------------------------- -. -settlement_date=17/07/07 -card_desc=VISA -status=approved -txn_ref=0707171522000000 -refund_mode=0 -transaction_no=000000 -rrn=00015X000000 -response_text=SIGNATURE REQUIRED -pld=0 -total_amount=100 -card_no=4111111111111111 -version=V1.0 -merchant_index=123 -card_expiry=12/10 -training_mode=0 -operator_no=10000 -response_code=08 -card_type=6 -approved=1 -cashout_amount=0 -receipt_array=ARRAY(0x8378200) -account_type=CREDIT A/C -result=1 + <<~RESPONSE + approved + 00015X000000 + Transaction No: 00000000 + ------------------------ + MERCHANTNAME + LOCATION AU + + MERCH ID 10000000 + TERM ID Y0TR00 + COUNTRY CODE AU + 17/07/07 15:23 + RRN 00015X000000 + VISA + 411111-111 + CREDIT A/C 12/10 + + AUTHORISATION NO: 000000 + APPROVED 08 + + PURCHASE $1.00 + TOTAL AUD $1.00 + + PLEASE RETAIN AS RECORD + OF PURCHASE + + (SUBJECT TO CARDHOLDER'S + ACCEPTANCE) + ------------------------ + . + settlement_date=17/07/07 + card_desc=VISA + status=approved + txn_ref=0707171522000000 + refund_mode=0 + transaction_no=000000 + rrn=00015X000000 + response_text=SIGNATURE REQUIRED + pld=0 + total_amount=100 + card_no=4111111111111111 + version=V1.0 + merchant_index=123 + card_expiry=12/10 + training_mode=0 + operator_no=10000 + response_code=08 + card_type=6 + approved=1 + cashout_amount=0 + receipt_array=ARRAY(0x8378200) + account_type=CREDIT A/C + result=1 RESPONSE end def purchase_with_invalid_credit_card_response - <<-RESPONSE -declined -00015X000000 -Transaction No: 00000000 ------------------------- -MERCHANTNAME -LOCATION AU - -MERCH ID 10000000 -TERM ID Y0TR40 -COUNTRY CODE AU -16/07/07 19:20 -RRN 00015X000000 -VISA -411111-111 -CREDIT A/C 12/10 - -AUTHORISATION NO: -DECLINED 31 - -PURCHASE $1.00 -TOTAL AUD $1.00 - -(SUBJECT TO CARDHOLDER'S - ACCEPTANCE) ------------------------- -. -settlement_date=16/07/07 -card_desc=VISA -status=declined -txn_ref=0707161919000000 -refund_mode=0 -transaction_no=000000 -rrn=00015X000000 -response_text=INVALID CARD -pld=0 -total_amount=100 -card_no=4111111111111111 -version=V1.0 -merchant_index=123 -card_expiry=12/10 -training_mode=0 -operator_no=10000 -response_code=31 -card_type=6 -approved=0 -cashout_amount=0 -receipt_array=ARRAY(0x83752d0) -account_type=CREDIT A/C -result=0 + <<~RESPONSE + declined + 00015X000000 + Transaction No: 00000000 + ------------------------ + MERCHANTNAME + LOCATION AU + + MERCH ID 10000000 + TERM ID Y0TR40 + COUNTRY CODE AU + 16/07/07 19:20 + RRN 00015X000000 + VISA + 411111-111 + CREDIT A/C 12/10 + + AUTHORISATION NO: + DECLINED 31 + + PURCHASE $1.00 + TOTAL AUD $1.00 + + (SUBJECT TO CARDHOLDER'S + ACCEPTANCE) + ------------------------ + . + settlement_date=16/07/07 + card_desc=VISA + status=declined + txn_ref=0707161919000000 + refund_mode=0 + transaction_no=000000 + rrn=00015X000000 + response_text=INVALID CARD + pld=0 + total_amount=100 + card_no=4111111111111111 + version=V1.0 + merchant_index=123 + card_expiry=12/10 + training_mode=0 + operator_no=10000 + response_code=31 + card_type=6 + approved=0 + cashout_amount=0 + receipt_array=ARRAY(0x83752d0) + account_type=CREDIT A/C + result=0 RESPONSE end def purchase_with_expired_credit_card_response - <<-RESPONSE -failed - - -. -response_text=CARD EXPIRED -approved=0 -status=failed -txn_ref=0707161910000000 -version=V1.0 -pld=0 -response_code=Q816 -result=-1 + <<~RESPONSE + failed + + + . + response_text=CARD EXPIRED + approved=0 + status=failed + txn_ref=0707161910000000 + version=V1.0 + pld=0 + response_code=Q816 + result=-1 RESPONSE end def purchase_with_invalid_month_response - <<-RESPONSE -failed -Invalid month + <<~RESPONSE + failed + Invalid month RESPONSE end def bad_login_response - <<-RESPONSE -failed + <<~RESPONSE + failed -. -status=failed -result=-1 + . + status=failed + result=-1 RESPONSE end end diff --git a/test/unit/gateways/netaxept_test.rb b/test/unit/gateways/netaxept_test.rb index 5dddbde3427..92d60776572 100644 --- a/test/unit/gateways/netaxept_test.rb +++ b/test/unit/gateways/netaxept_test.rb @@ -5,15 +5,15 @@ class NetaxeptTest < Test::Unit::TestCase def setup @gateway = NetaxeptGateway.new( - :login => 'login', - :password => 'password' - ) + login: 'login', + password: 'password' + ) @credit_card = credit_card @amount = 100 @options = { - :order_id => '1' + order_id: '1' } end @@ -57,7 +57,7 @@ def test_handles_currency_with_money @gateway.expects(:ssl_get).returns(successful_purchase_response[2]).in_sequence(s) @gateway.expects(:ssl_get).returns(successful_purchase_response[3]).in_sequence(s) - assert_success @gateway.purchase(100, @credit_card, @options.merge(:currency => 'USD')) + assert_success @gateway.purchase(100, @credit_card, @options.merge(currency: 'USD')) end def test_handles_currency_with_option @@ -67,7 +67,7 @@ def test_handles_currency_with_option @gateway.expects(:ssl_get).returns(successful_purchase_response[2]).in_sequence(s) @gateway.expects(:ssl_get).returns(successful_purchase_response[3]).in_sequence(s) - assert_success @gateway.purchase(@amount, @credit_card, @options.merge(:currency => 'USD')) + assert_success @gateway.purchase(@amount, @credit_card, @options.merge(currency: 'USD')) end def test_handles_setup_transaction_error @@ -91,7 +91,7 @@ def test_handles_query_error end def test_url_escape_password - @gateway = NetaxeptGateway.new(:login => 'login', :password => '1a=W+Yr2') + @gateway = NetaxeptGateway.new(login: 'login', password: '1a=W+Yr2') s = sequence('request') @gateway.expects(:ssl_get).with(regexp_matches(/token=1a%3DW%2BYr2/)).returns(successful_purchase_response[0]).in_sequence(s) diff --git a/test/unit/gateways/netbanx_test.rb b/test/unit/gateways/netbanx_test.rb index a4a424d27f3..359521c8c35 100644 --- a/test/unit/gateways/netbanx_test.rb +++ b/test/unit/gateways/netbanx_test.rb @@ -15,7 +15,7 @@ def setup end def test_successful_purchase - @gateway.expects(:ssl_request).returns(successful_purchase_response) + @gateway.expects(:ssl_request).twice.returns(success_verification_response, successful_purchase_response) response = @gateway.purchase(@amount, @credit_card, @options) assert_success response @@ -34,7 +34,7 @@ def test_failed_purchase end def test_successful_authorize - @gateway.expects(:ssl_request).returns(successful_authorize_response) + @gateway.expects(:ssl_request).twice.returns(auth_verification_response, successful_authorize_response) response = @gateway.authorize(@amount, @credit_card, @options) assert_success response @@ -56,7 +56,7 @@ def test_failed_authorize def test_successful_capture @gateway.expects(:ssl_request).returns(successful_capture_response) - response = @gateway.authorize(@amount, '056ff3a9-5274-4452-92ab-0e3b3e591c3b') + response = @gateway.capture(@amount, '056ff3a9-5274-4452-92ab-0e3b3e591c3b') assert_success response assert_equal '11e0906b-6596-4490-b0e3-825f71a82799', response.authorization @@ -75,7 +75,7 @@ def test_failed_capture end def test_successful_refund - @gateway.expects(:ssl_request).returns(successful_capture_response) + @gateway.expects(:ssl_request).twice.returns(success_verification_response, successful_capture_response) response = @gateway.refund(@amount, '056ff3a9-5274-4452-92ab-0e3b3e591c3b') assert_success response @@ -128,8 +128,8 @@ def test_successful_store assert response.test? end - def test_successful_purchase_with_token - @gateway.expects(:ssl_request).returns(successful_purchase_with_token_response) + def test_successful_purchase_token + @gateway.expects(:ssl_request).twice.returns(success_verification_response, purchase_with_token_response) response = @gateway.purchase(@amount, 'CL0RCSnrkREnfwA', @options) assert_success response @@ -311,7 +311,7 @@ def failed_purchase_response RESPONSE end - def successful_purchase_with_token_response + def purchase_with_token_response <<-RESPONSE { "links": [ @@ -416,6 +416,26 @@ def successful_authorize_response RESPONSE end + def auth_verification_response + <<-RESPONSE + { + "id": "b8c53059-9da3-4054-8caf-3769161a3cdc", + "status": "COMPLETED", + "message": "OK" + } + RESPONSE + end + + def success_verification_response + <<-RESPONSE + { + "id": "11e0906b-6596-4490-b0e3-825f71a82799", + "status": "COMPLETED", + "message": "OK" + } + RESPONSE + end + def failed_authorize_response <<-RESPONSE { diff --git a/test/unit/gateways/netbilling_test.rb b/test/unit/gateways/netbilling_test.rb index 724e3037542..5b0b7609013 100644 --- a/test/unit/gateways/netbilling_test.rb +++ b/test/unit/gateways/netbilling_test.rb @@ -4,11 +4,11 @@ class NetbillingTest < Test::Unit::TestCase include CommStub def setup - @gateway = NetbillingGateway.new(:login => 'login') + @gateway = NetbillingGateway.new(login: 'login') @credit_card = credit_card('4242424242424242') @amount = 100 - @options = { :billing_address => address } + @options = { billing_address: address } end def test_successful_request @@ -43,11 +43,11 @@ def test_cvv_result end def test_site_tag_sent_if_provided - @gateway = NetbillingGateway.new(:login => 'login', :site_tag => 'dummy-site-tag') + @gateway = NetbillingGateway.new(login: 'login', site_tag: 'dummy-site-tag') 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(/site_tag=dummy-site-tag/, data) end.respond_with(successful_purchase_response) @@ -57,7 +57,7 @@ def test_site_tag_sent_if_provided def test_site_tag_not_sent_if_not_provided 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_no_match(/site_tag/, data) end.respond_with(successful_purchase_response) diff --git a/test/unit/gateways/netpay_test.rb b/test/unit/gateways/netpay_test.rb index 6b107d2e9f5..92cd1ff0452 100644 --- a/test/unit/gateways/netpay_test.rb +++ b/test/unit/gateways/netpay_test.rb @@ -3,10 +3,10 @@ class NetpayTest < Test::Unit::TestCase def setup @gateway = NetpayGateway.new( - :store_id => '12345', - :login => 'login', - :password => 'password' - ) + store_id: '12345', + login: 'login', + password: 'password' + ) @credit_card = credit_card @amount = 1000 @@ -14,7 +14,7 @@ def setup @order_id = 'C3836048-631F-112B-001E-7C08C0406975' @options = { - :description => 'Store Purchase' + description: 'Store Purchase' } end @@ -64,7 +64,7 @@ def test_successful_purchase_with_ip ) ).returns(successful_response) - assert response = @gateway.purchase(@amount, @credit_card, :ip => '127.0.0.1') + assert response = @gateway.purchase(@amount, @credit_card, ip: '127.0.0.1') assert_success response end @@ -150,7 +150,7 @@ def test_supported_countries end def test_supported_cardtypes - assert_equal [:visa, :master, :american_express, :diners_club], NetpayGateway.supported_cardtypes + assert_equal %i[visa master american_express diners_club], NetpayGateway.supported_cardtypes end private diff --git a/test/unit/gateways/network_merchants_test.rb b/test/unit/gateways/network_merchants_test.rb index 57fbb837167..5ea99c7da9e 100644 --- a/test/unit/gateways/network_merchants_test.rb +++ b/test/unit/gateways/network_merchants_test.rb @@ -3,18 +3,18 @@ class NetworkMerchantsTest < Test::Unit::TestCase def setup @gateway = NetworkMerchantsGateway.new( - :login => 'login', - :password => 'password' - ) + login: 'login', + password: 'password' + ) @credit_card = credit_card @check = check @amount = 100 @options = { - :order_id => '1', - :billing_address => address, - :description => 'Store Purchase' + order_id: '1', + billing_address: address, + description: 'Store Purchase' } end @@ -60,7 +60,7 @@ def test_successful_check_purchase def test_purchase_and_store @gateway.expects(:ssl_post).returns(successful_purchase_and_store) - assert response = @gateway.purchase(@amount, @credit_card, @options.merge(:store => true)) + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(store: true)) assert_success response assert_equal 'SUCCESS', response.message assert_equal '1378262091', response.params['customer_vault_id'] @@ -156,7 +156,7 @@ def test_purchase_on_stored_card end def test_invalid_login - gateway = NetworkMerchantsGateway.new(:login => '', :password => '') + gateway = NetworkMerchantsGateway.new(login: '', password: '') gateway.expects(:ssl_post).returns(failed_login) assert response = gateway.purchase(@amount, @credit_card, @options) assert_failure response diff --git a/test/unit/gateways/nmi_test.rb b/test/unit/gateways/nmi_test.rb index 72b90edaa32..4ef8387f6dc 100644 --- a/test/unit/gateways/nmi_test.rb +++ b/test/unit/gateways/nmi_test.rb @@ -21,7 +21,7 @@ def setup 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_match(/username=#{@gateway.options[:login]}/, data) assert_match(/password=#{@gateway.options[:password]}/, data) assert_match(/type=sale/, data) @@ -43,7 +43,7 @@ def test_purchase_with_options response = stub_comms do @gateway.purchase(@amount, @credit_card, options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| test_transaction_options(data) assert_match(/merchant_defined_field_8=value8/, data) @@ -65,7 +65,7 @@ def test_failed_purchase def test_successful_purchase_with_echeck response = stub_comms do @gateway.purchase(@amount, @check) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/username=#{@gateway.options[:login]}/, data) assert_match(/password=#{@gateway.options[:password]}/, data) assert_match(/type=sale/, data) @@ -96,12 +96,43 @@ def test_failed_purchase_with_echeck assert_equal 'FAILED', response.message end + def test_successful_purchase_with_3ds + version = '2.1.0' + eci = '02' + cavv = 'jJ81HADVRtXfCBATEp01CJUAAAA' + ds_transaction_id = '97267598-FAE6-48F2-8083-C23433990FBC' + xid = '00000000000000000501' + options_with_3ds = @transaction_options.merge( + three_d_secure: { + version: version, + eci: eci, + cavv: cavv, + ds_transaction_id: ds_transaction_id, + xid: xid + } + ) + + response = stub_comms do + @gateway.purchase(@amount, @credit_card, options_with_3ds) + end.check_request do |_endpoint, data, _headers| + assert_match(/three_ds_version=2.1.0/, data) + assert_match(/eci=02/, data) + assert_match(/cavv=jJ81HADVRtXfCBATEp01CJUAAAA/, data) + assert_match(/directory_server_id=97267598-FAE6-48F2-8083-C23433990FBC/, data) + assert_match(/xid=00000000000000000501/, data) + end.respond_with(successful_3ds_purchase_response) + + assert_success response + assert response.test? + assert_equal 'Succeeded', response.message + end + def test_authorize_with_options options = @transaction_options.merge(@merchant_defined_fields) response = stub_comms do @gateway.authorize(@amount, @credit_card, options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| test_transaction_options(data) assert_match(/merchant_defined_field_8=value8/, data) @@ -113,7 +144,7 @@ def test_authorize_with_options def test_successful_authorize_and_capture response = stub_comms do @gateway.authorize(@amount, @credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/username=#{@gateway.options[:login]}/, data) assert_match(/password=#{@gateway.options[:password]}/, data) assert_match(/type=auth/, data) @@ -128,7 +159,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(/username=#{@gateway.options[:login]}/, data) assert_match(/password=#{@gateway.options[:password]}/, data) assert_match(/type=capture/, data) @@ -167,7 +198,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(/username=#{@gateway.options[:login]}/, data) assert_match(/password=#{@gateway.options[:password]}/, data) assert_match(/type=void/, data) @@ -195,7 +226,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(/username=#{@gateway.options[:login]}/, data) assert_match(/password=#{@gateway.options[:password]}/, data) assert_match(/type=refund/, data) @@ -217,7 +248,7 @@ def test_failed_refund def test_successful_credit response = stub_comms do @gateway.credit(@amount, @credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/username=#{@gateway.options[:login]}/, data) assert_match(/password=#{@gateway.options[:password]}/, data) assert_match(/type=credit/, data) @@ -237,7 +268,7 @@ def test_successful_credit def test_credit_with_options response = stub_comms do @gateway.credit(@amount, @credit_card, @transaction_options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| test_transaction_options(data) end.respond_with(successful_credit_response) @@ -274,7 +305,7 @@ def test_failed_verify def test_successful_store response = stub_comms do @gateway.store(@credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/username=#{@gateway.options[:login]}/, data) assert_match(/password=#{@gateway.options[:password]}/, data) assert_match(/customer_vault=add_customer/, data) @@ -304,7 +335,7 @@ def test_failed_store def test_successful_store_with_echeck response = stub_comms do @gateway.store(@check) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/username=#{@gateway.options[:login]}/, data) assert_match(/password=#{@gateway.options[:password]}/, data) assert_match(/customer_vault=add_customer/, data) @@ -346,7 +377,7 @@ def test_transcript_scrubbing def test_includes_cvv_tag stub_comms do @gateway.purchase(@amount, @credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{cvv}, data) end.respond_with(successful_purchase_response) end @@ -355,14 +386,14 @@ def test_blank_cvv_not_sent @credit_card.verification_value = nil 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(%r{cvv}, data) end.respond_with(successful_purchase_response) @credit_card.verification_value = ' ' 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(%r{cvv}, data) end.respond_with(successful_purchase_response) end @@ -373,7 +404,7 @@ def test_supported_countries end def test_supported_card_types - assert_equal [:visa, :master, :american_express, :discover], NmiGateway.supported_cardtypes + assert_equal %i[visa master american_express discover], NmiGateway.supported_cardtypes end def test_duplicate_window_deprecation @@ -386,7 +417,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/initiated_by=customer/, data) assert_match(/stored_credential_indicator=stored/, data) assert_match(/billing_method=recurring/, data) @@ -400,7 +431,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/initiated_by=customer/, data) assert_match(/stored_credential_indicator=used/, data) assert_match(/billing_method=recurring/, data) @@ -414,7 +445,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/initiated_by=merchant/, data) assert_match(/stored_credential_indicator=stored/, data) assert_match(/billing_method=recurring/, data) @@ -428,7 +459,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/initiated_by=merchant/, data) assert_match(/stored_credential_indicator=used/, data) assert_match(/billing_method=recurring/, data) @@ -442,7 +473,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/initiated_by=customer/, data) assert_match(/stored_credential_indicator=stored/, data) assert_match(/billing_method=installment/, data) @@ -456,7 +487,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/initiated_by=customer/, data) assert_match(/stored_credential_indicator=used/, data) assert_match(/billing_method=installment/, data) @@ -470,7 +501,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/initiated_by=merchant/, data) assert_match(/stored_credential_indicator=stored/, data) assert_match(/billing_method=installment/, data) @@ -484,7 +515,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/initiated_by=merchant/, data) assert_match(/stored_credential_indicator=used/, data) assert_match(/billing_method=installment/, data) @@ -498,7 +529,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/initiated_by=customer/, data) assert_match(/stored_credential_indicator=stored/, data) refute_match(/billing_method/, data) @@ -512,7 +543,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/initiated_by=customer/, data) assert_match(/stored_credential_indicator=used/, data) refute_match(/billing_method/, data) @@ -526,7 +557,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/initiated_by=merchant/, data) assert_match(/stored_credential_indicator=stored/, data) refute_match(/billing_method/, data) @@ -540,7 +571,7 @@ 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| + end.check_request do |_endpoint, data, _headers| assert_match(/initiated_by=merchant/, data) assert_match(/stored_credential_indicator=used/, data) refute_match(/billing_method/, data) @@ -554,7 +585,7 @@ def test_purchase_with_stored_credential options = stored_credential_options(:merchant, :installment, id: 'abc123') 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(/initiated_by=merchant/, data) assert_match(/stored_credential_indicator=used/, data) assert_match(/billing_method=installment/, data) @@ -568,7 +599,7 @@ def test_stored_credential_installment_takes_precedence_over_recurring_option options = stored_credential_options(:merchant, :installment, id: 'abc123').merge(recurring: true) 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(/initiated_by=merchant/, data) assert_match(/stored_credential_indicator=used/, data) assert_match(/billing_method=installment/, data) @@ -582,7 +613,7 @@ def test_stored_credential_unscheduled_takes_precedence_over_recurring_option options = stored_credential_options(:merchant, :unscheduled, id: 'abc123').merge(recurring: true) 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(/initiated_by=merchant/, data) assert_match(/stored_credential_indicator=used/, data) refute_match(/billing_method/, data) @@ -597,7 +628,7 @@ def test_stored_credential_unscheduled_takes_precedence_over_recurring_option def test_verify(options = {}) response = stub_comms do @gateway.verify(@credit_card, options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/username=#{@gateway.options[:login]}/, data) assert_match(/password=#{@gateway.options[:password]}/, data) assert_match(/type=validate/, data) @@ -661,6 +692,10 @@ def failed_echeck_purchase_response 'response=2&responsetext=FAILED&authcode=123456&transactionid=2762783009&avsresponse=&cvvresponse=&orderid=8070b75a09d75c3e84e1c17d44bbbf34&type=&response_code=200' end + def successful_3ds_purchase_response + 'response=1&responsetext=SUCCESS&authcode=123456&transactionid=97267598-FAE6-48F2-8083-C23433990FBC&avsresponse=&cvvresponse=&orderid=b6c1c57f709cfaa65a5cf5b8532ad181&type=&response_code=100' + end + def successful_authorization_response 'response=1&responsetext=SUCCESS&authcode=123456&transactionid=2762787830&avsresponse=N&cvvresponse=N&orderid=7655856b032e28d2106d724fc26cd04d&type=&response_code=100' end diff --git a/test/unit/gateways/ogone_test.rb b/test/unit/gateways/ogone_test.rb index 8454a030cfd..d6f42c1eccc 100644 --- a/test/unit/gateways/ogone_test.rb +++ b/test/unit/gateways/ogone_test.rb @@ -1,25 +1,24 @@ require 'test_helper' class OgoneTest < Test::Unit::TestCase - def setup - @credentials = { :login => 'pspid', - :user => 'username', - :password => 'password', - :signature => 'mynicesig', - :signature_encryptor => 'sha512', - :timeout => '30' } + @credentials = { login: 'pspid', + user: 'username', + password: 'password', + signature: 'mynicesig', + signature_encryptor: 'sha512', + timeout: '30' } @gateway = OgoneGateway.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', @@ -57,7 +56,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? @@ -77,7 +76,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? @@ -85,7 +84,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'] @@ -127,7 +126,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? @@ -135,7 +134,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'] @@ -153,7 +152,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? @@ -208,19 +207,19 @@ def test_failed_verify end def test_successful_store - @gateway.expects(:authorize).with(1, @credit_card, :billing_id => @billing_id).returns(OgoneResponse.new(true, '', @gateway.send(:parse, successful_purchase_response), :authorization => '3014726;RES')) + @gateway.expects(:authorize).with(1, @credit_card, billing_id: @billing_id).returns(OgoneResponse.new(true, '', @gateway.send(:parse, successful_purchase_response), authorization: '3014726;RES')) @gateway.expects(:void).with('3014726;RES') - 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 @billing_id, response.billing_id end def test_store_amount_at_gateway_level - gateway = OgoneGateway.new(@credentials.merge(:store_amount => 100)) - gateway.expects(:authorize).with(100, @credit_card, :billing_id => @billing_id).returns(OgoneResponse.new(true, '', gateway.send(:parse, successful_purchase_response_100), :authorization => '3014726;RES')) + gateway = OgoneGateway.new(@credentials.merge(store_amount: 100)) + gateway.expects(:authorize).with(100, @credit_card, billing_id: @billing_id).returns(OgoneResponse.new(true, '', gateway.send(:parse, successful_purchase_response_100), authorization: '3014726;RES')) gateway.expects(:void).with('3014726;RES') - 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 @billing_id, response.billing_id @@ -231,7 +230,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(OgoneGateway::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? @@ -255,11 +254,11 @@ def test_create_readable_error_message_upon_failure end def test_supported_countries - assert_equal ['BE', 'DE', 'FR', 'NL', 'AT', 'CH'], OgoneGateway.supported_countries + assert_equal %w[BE DE FR NL AT CH], OgoneGateway.supported_countries end def test_supported_card_types - assert_equal [:visa, :master, :american_express, :diners_club, :discover, :jcb, :maestro], OgoneGateway.supported_cardtypes + assert_equal %i[visa master american_express diners_club discover jcb maestro], OgoneGateway.supported_cardtypes end def test_default_currency @@ -273,7 +272,7 @@ def test_default_currency end def test_custom_currency_at_gateway_level - gateway = OgoneGateway.new(@credentials.merge(:currency => 'USD')) + gateway = OgoneGateway.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) @@ -281,11 +280,11 @@ def test_custom_currency_at_gateway_level end def test_local_custom_currency_overwrite_gateway_level - gateway = OgoneGateway.new(@credentials.merge(:currency => 'USD')) + gateway = OgoneGateway.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 @@ -344,13 +343,13 @@ def test_format_error_message_with_no_separator end def test_without_signature - gateway = OgoneGateway.new(@credentials.merge(:signature => nil, :signature_encryptor => nil)) + gateway = OgoneGateway.new(@credentials.merge(signature: nil, signature_encryptor: nil)) gateway.expects(:ssl_post).returns(successful_purchase_response) assert_deprecation_warning(OgoneGateway::OGONE_NO_SIGNATURE_DEPRECATION_MESSAGE) do gateway.purchase(@amount, @credit_card, @options) end - gateway = OgoneGateway.new(@credentials.merge(:signature => nil, :signature_encryptor => 'none')) + gateway = OgoneGateway.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) @@ -358,27 +357,27 @@ def test_without_signature end def test_signature_for_accounts_created_before_10_may_20101 - gateway = OgoneGateway.new(@credentials.merge(:signature_encryptor => nil)) + gateway = OgoneGateway.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 = OgoneGateway.new(@credentials.merge(:signature_encryptor => 'sha1')) + gateway = OgoneGateway.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 = OgoneGateway.new(@credentials.merge(:signature_encryptor => 'sha256')) + gateway = OgoneGateway.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 = OgoneGateway.new(@credentials.merge(:signature_encryptor => 'sha512')) + gateway = OgoneGateway.new(@credentials.merge(signature_encryptor: 'sha512')) assert signature = gateway.send(:add_signature, @parameters) assert_equal Digest::SHA512.hexdigest(string_to_digest).upcase, signature end @@ -393,13 +392,13 @@ def test_3dsecure_win_3ds_option post = {} gateway = OgoneGateway.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 @@ -408,16 +407,16 @@ def test_3dsecure_additional_options gateway = OgoneGateway.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', - :cancel_url => 'https://cancel_url', - :paramvar => 'param_var', - :paramplus => 'param_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', + cancel_url: 'https://cancel_url', + paramvar: 'param_var', + paramplus: 'param_plus', + complus: 'com_plus', + language: 'fr_FR' }) assert_equal post['HTTP_ACCEPT'], 'text/html' assert_equal post['HTTP_USER_AGENT'], 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)' @@ -466,7 +465,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_purchase_response_100 - <<-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 failed_authorization_response - <<-END + <<-XML - END + XML end def pre_scrub @@ -806,5 +805,4 @@ def post_scrub Conn close } end - end diff --git a/test/unit/gateways/omise_test.rb b/test/unit/gateways/omise_test.rb index 5c31855fd64..2e0baf68e30 100644 --- a/test/unit/gateways/omise_test.rb +++ b/test/unit/gateways/omise_test.rb @@ -23,11 +23,11 @@ def setup end def test_supported_countries - assert_equal @gateway.supported_countries, %w( TH JP ) + assert_equal @gateway.supported_countries, %w(TH JP) end def test_supported_cardtypes - assert_equal @gateway.supported_cardtypes, [:visa, :master, :jcb] + assert_equal @gateway.supported_cardtypes, %i[visa master jcb] end def test_supports_scrubbing @@ -50,7 +50,7 @@ def test_request_headers end def test_post_data - post_data = @gateway.send(:post_data, { card: {number: '4242424242424242'} }) + post_data = @gateway.send(:post_data, { card: { number: '4242424242424242' } }) assert_equal '{"card":{"number":"4242424242424242"}}', post_data end @@ -73,7 +73,7 @@ def test_error_response def test_error_code_from response = @gateway.send(:parse, invalid_security_code_response) - error_code = @gateway.send(:error_code_from, response) + error_code = @gateway.send(:error_code_from, response) assert_equal 'invalid_security_code', error_code end @@ -90,7 +90,7 @@ def test_invalid_cvc end def test_card_declined - card_declined = @gateway.send(:parse, failed_capture_response) + card_declined = @gateway.send(:parse, failed_capture_response) card_declined_code = @gateway.send(:standard_error_code_mapping, card_declined) assert_equal 'card_declined', card_declined_code end @@ -138,7 +138,7 @@ def test_add_creditcard def test_add_customer_without_card result = {} customer_id = 'cust_test_4zjzcgm8kpdt4xdhdw2' - @gateway.send(:add_customer, result, {customer_id: customer_id}) + @gateway.send(:add_customer, result, { customer_id: customer_id }) assert_equal 'cust_test_4zjzcgm8kpdt4xdhdw2', result[:customer] end @@ -146,21 +146,21 @@ def test_add_customer_with_card_id result = {} customer_id = 'cust_test_4zjzcgm8kpdt4xdhdw2' result[:card] = 'card_test_4zguktjcxanu3dw171a' - @gateway.send(:add_customer, result, {customer_id: customer_id}) + @gateway.send(:add_customer, result, { customer_id: customer_id }) assert_equal customer_id, result[:customer] end def test_add_amount result = {} desc = 'Charge for order 3947' - @gateway.send(:add_amount, result, @amount, {description: desc}) + @gateway.send(:add_amount, result, @amount, { description: desc }) assert_equal desc, result[:description] end def test_add_amount_with_correct_currency result = {} jpy_currency = 'JPY' - @gateway.send(:add_amount, result, @amount, {currency: jpy_currency}) + @gateway.send(:add_amount, result, @amount, { currency: jpy_currency }) assert_equal jpy_currency, result[:currency] end @@ -812,5 +812,4 @@ def failed_capture_response } RESPONSE end - end diff --git a/test/unit/gateways/openpay_test.rb b/test/unit/gateways/openpay_test.rb index e1df79e5c2c..9407048819b 100644 --- a/test/unit/gateways/openpay_test.rb +++ b/test/unit/gateways/openpay_test.rb @@ -113,7 +113,7 @@ def test_unsuccessful_verify def test_successful_purchase_with_card_id @gateway.expects(:ssl_request).returns(successful_purchase_response) - assert response = @gateway.purchase(@amount, {credit_card: 'a2b79p8xmzeyvmolqfja'}, @options) + assert response = @gateway.purchase(@amount, { credit_card: 'a2b79p8xmzeyvmolqfja' }, @options) assert_instance_of Response, response assert_success response @@ -171,7 +171,7 @@ def test_successful_unstore def test_passing_device_session_id response = stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, @credit_card, device_session_id: 'TheDeviceSessionID') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(%r{"device_session_id":"TheDeviceSessionID"}, data) end.respond_with(successful_purchase_response) @@ -181,7 +181,7 @@ def test_passing_device_session_id def test_passing_payment_installments response = stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, @credit_card, payments: '6') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(%r{"payments":"6"}, data) assert_match(%r{"payment_plan":}, data) end.respond_with(successful_purchase_response) @@ -208,225 +208,225 @@ def test_whitespace_string_cvv_transcript_scrubbing private def successful_new_card - <<-RESPONSE -{ - "type":"debit", - "brand":"mastercard", - "address":{ - "line1":"Av 5 de Febrero", - "line2":"Roble 207", - "line3":"col carrillo", - "state":"Queretaro", - "city":"Queretaro", - "postal_code":"76900", - "country_code":"MX" - }, - "id":"kgipbqixvjg3gbzowl7l", - "card_number":"1111", - "holder_name":"Juan Perez Ramirez", - "expiration_year":"20", - "expiration_month":"12", - "allows_charges":true, - "allows_payouts":false, - "creation_date":"2013-12-12T17:50:00-06:00", - "bank_name":"DESCONOCIDO", - "bank_code":"000", - "customer_id":"a2b79p8xmzeyvmolqfja" -} + <<~RESPONSE + { + "type":"debit", + "brand":"mastercard", + "address":{ + "line1":"Av 5 de Febrero", + "line2":"Roble 207", + "line3":"col carrillo", + "state":"Queretaro", + "city":"Queretaro", + "postal_code":"76900", + "country_code":"MX" + }, + "id":"kgipbqixvjg3gbzowl7l", + "card_number":"1111", + "holder_name":"Juan Perez Ramirez", + "expiration_year":"20", + "expiration_month":"12", + "allows_charges":true, + "allows_payouts":false, + "creation_date":"2013-12-12T17:50:00-06:00", + "bank_name":"DESCONOCIDO", + "bank_code":"000", + "customer_id":"a2b79p8xmzeyvmolqfja" + } RESPONSE end def successful_new_customer - <<-RESPONSE -{ - "id":"a2b79p8xmzeyvmolqfja", - "name":"Anacleto", - "last_name":"Morones", - "email":"morones.an@elllano.com", - "phone_number":"44209087654", - "status":"active", - "balance":0, - "clabe":"646180109400003235", - "address":{ - "line1":"Camino Real", - "line2":"Col. San Pablo", - "state":"Queretaro", - "city":"Queretaro", - "postal_code":"76000", - "country_code":"MX" - }, - "creation_date":"2013-12-12T16:29:11-06:00" -} + <<~RESPONSE + { + "id":"a2b79p8xmzeyvmolqfja", + "name":"Anacleto", + "last_name":"Morones", + "email":"morones.an@elllano.com", + "phone_number":"44209087654", + "status":"active", + "balance":0, + "clabe":"646180109400003235", + "address":{ + "line1":"Camino Real", + "line2":"Col. San Pablo", + "state":"Queretaro", + "city":"Queretaro", + "postal_code":"76000", + "country_code":"MX" + }, + "creation_date":"2013-12-12T16:29:11-06:00" + } RESPONSE end def successful_refunded_response - <<-RESPONSE -{ - "amount": 1.00, - "authorization": "801585", - "method": "card", - "operation_type": "in", - "transaction_type": "charge", - "card": { - "type": "debit", - "brand": "mastercard", - "address": { - "line1": "1234 My Street", - "line2": "Apt 1", - "line3": null, - "state": "ON", - "city": "Ottawa", - "postal_code": "K1C2N6", - "country_code": "CA" - }, - "card_number": "1111", - "holder_name": "Longbob Longsen", - "expiration_year": "15", - "expiration_month": "09", - "allows_charges": true, - "allows_payouts": false, - "creation_date": "2014-01-20T17:08:43-06:00", - "bank_name": "DESCONOCIDO", - "bank_code": "000", - "customer_id": null - }, - "status": "completed", - "refund": { - "amount": 1.00, - "authorization": "030706", - "method": "card", - "operation_type": "out", - "transaction_type": "refund", - "status": "completed", - "currency": "MXN", - "id": "tspoc4u9msdbnkkhpcmi", - "creation_date": "2014-01-20T17:08:44-06:00", - "description": "Store Purchase", - "error_message": null, - "order_id": null - }, - "currency": "MXN", - "id": "tei4hnvyp4agt5ecnbow", - "creation_date": "2014-01-20T17:08:43-06:00", - "description": "Store Purchase", - "error_message": null, - "order_id": null, - "error_code": null -} + <<~RESPONSE + { + "amount": 1.00, + "authorization": "801585", + "method": "card", + "operation_type": "in", + "transaction_type": "charge", + "card": { + "type": "debit", + "brand": "mastercard", + "address": { + "line1": "1234 My Street", + "line2": "Apt 1", + "line3": null, + "state": "ON", + "city": "Ottawa", + "postal_code": "K1C2N6", + "country_code": "CA" + }, + "card_number": "1111", + "holder_name": "Longbob Longsen", + "expiration_year": "15", + "expiration_month": "09", + "allows_charges": true, + "allows_payouts": false, + "creation_date": "2014-01-20T17:08:43-06:00", + "bank_name": "DESCONOCIDO", + "bank_code": "000", + "customer_id": null + }, + "status": "completed", + "refund": { + "amount": 1.00, + "authorization": "030706", + "method": "card", + "operation_type": "out", + "transaction_type": "refund", + "status": "completed", + "currency": "MXN", + "id": "tspoc4u9msdbnkkhpcmi", + "creation_date": "2014-01-20T17:08:44-06:00", + "description": "Store Purchase", + "error_message": null, + "order_id": null + }, + "currency": "MXN", + "id": "tei4hnvyp4agt5ecnbow", + "creation_date": "2014-01-20T17:08:43-06:00", + "description": "Store Purchase", + "error_message": null, + "order_id": null, + "error_code": null + } RESPONSE end def successful_capture_response - <<-RESPONSE -{ - "amount": 1.00, - "authorization": "801585", - "method": "card", - "operation_type": "in", - "transaction_type": "charge", - "card": { - "type": "debit", - "brand": "mastercard", - "address": null, - "card_number": "1111", - "holder_name": "Longbob Longsen", - "expiration_year": "15", - "expiration_month": "09", - "allows_charges": true, - "allows_payouts": false, - "creation_date": "2014-01-18T21:01:10-06:00", - "bank_name": "DESCONOCIDO", - "bank_code": "000", - "customer_id": null - }, - "status": "completed", - "currency": "MXN", - "id": "tubpycc6gtsk71fu3tsd", - "creation_date": "2014-01-18T21:01:10-06:00", - "description": "Store Purchase", - "error_message": null, - "order_id": null, - "error_code": null -} + <<~RESPONSE + { + "amount": 1.00, + "authorization": "801585", + "method": "card", + "operation_type": "in", + "transaction_type": "charge", + "card": { + "type": "debit", + "brand": "mastercard", + "address": null, + "card_number": "1111", + "holder_name": "Longbob Longsen", + "expiration_year": "15", + "expiration_month": "09", + "allows_charges": true, + "allows_payouts": false, + "creation_date": "2014-01-18T21:01:10-06:00", + "bank_name": "DESCONOCIDO", + "bank_code": "000", + "customer_id": null + }, + "status": "completed", + "currency": "MXN", + "id": "tubpycc6gtsk71fu3tsd", + "creation_date": "2014-01-18T21:01:10-06:00", + "description": "Store Purchase", + "error_message": null, + "order_id": null, + "error_code": null + } RESPONSE end def successful_authorization_response - <<-RESPONSE -{ - "amount": 1.00, - "authorization": "801585", - "method": "card", - "operation_type": "in", - "transaction_type": "charge", - "card": { - "type": "debit", - "brand": "mastercard", - "address": null, - "card_number": "1111", - "holder_name": "Longbob Longsen", - "expiration_year": "15", - "expiration_month": "09", - "allows_charges": true, - "allows_payouts": false, - "creation_date": "2014-01-18T21:01:10-06:00", - "bank_name": "DESCONOCIDO", - "bank_code": "000", - "customer_id": null - }, - "status": "in_progress", - "currency": "MXN", - "id": "tubpycc6gtsk71fu3tsd", - "creation_date": "2014-01-18T21:01:10-06:00", - "description": "Store Purchase", - "error_message": null, - "order_id": null, - "error_code": null -} + <<~RESPONSE + { + "amount": 1.00, + "authorization": "801585", + "method": "card", + "operation_type": "in", + "transaction_type": "charge", + "card": { + "type": "debit", + "brand": "mastercard", + "address": null, + "card_number": "1111", + "holder_name": "Longbob Longsen", + "expiration_year": "15", + "expiration_month": "09", + "allows_charges": true, + "allows_payouts": false, + "creation_date": "2014-01-18T21:01:10-06:00", + "bank_name": "DESCONOCIDO", + "bank_code": "000", + "customer_id": null + }, + "status": "in_progress", + "currency": "MXN", + "id": "tubpycc6gtsk71fu3tsd", + "creation_date": "2014-01-18T21:01:10-06:00", + "description": "Store Purchase", + "error_message": null, + "order_id": null, + "error_code": null + } RESPONSE end def successful_purchase_response(status = 'completed') - <<-RESPONSE -{ - "amount": 1.00, - "authorization": "801585", - "method": "card", - "operation_type": "in", - "transaction_type": "charge", - "card": { - "type": "debit", - "brand": "mastercard", - "address": { - "line1": "1234 My Street", - "line2": "Apt 1", - "line3": null, - "state": "ON", - "city": "Ottawa", - "postal_code": "K1C2N6", - "country_code": "CA" - }, - "card_number": "1111", - "holder_name": "Longbob Longsen", - "expiration_year": "15", - "expiration_month": "09", - "allows_charges": true, - "allows_payouts": false, - "creation_date": "2014-01-18T21:49:38-06:00", - "bank_name": "BANCOMER", - "bank_code": "012", - "customer_id": null - }, - "status": "#{status}", - "currency": "MXN", - "id": "tay1mauq3re4iuuk8bm4", - "creation_date": "2014-01-18T21:49:38-06:00", - "description": "Store Purchase", - "error_message": null, - "order_id": null, - "error_code": null -} + <<~RESPONSE + { + "amount": 1.00, + "authorization": "801585", + "method": "card", + "operation_type": "in", + "transaction_type": "charge", + "card": { + "type": "debit", + "brand": "mastercard", + "address": { + "line1": "1234 My Street", + "line2": "Apt 1", + "line3": null, + "state": "ON", + "city": "Ottawa", + "postal_code": "K1C2N6", + "country_code": "CA" + }, + "card_number": "1111", + "holder_name": "Longbob Longsen", + "expiration_year": "15", + "expiration_month": "09", + "allows_charges": true, + "allows_payouts": false, + "creation_date": "2014-01-18T21:49:38-06:00", + "bank_name": "BANCOMER", + "bank_code": "012", + "customer_id": null + }, + "status": "#{status}", + "currency": "MXN", + "id": "tay1mauq3re4iuuk8bm4", + "creation_date": "2014-01-18T21:49:38-06:00", + "description": "Store Purchase", + "error_message": null, + "order_id": null, + "error_code": null + } RESPONSE end @@ -435,26 +435,26 @@ def successful_void_response end def failed_purchase_response - <<-RESPONSE -{ - "category": "gateway", - "description": "The card was declined", - "http_code": 402, - "error_code": 3001, - "request_id": "337cf033-9cd6-4314-a880-c71700e1625f" -} + <<~RESPONSE + { + "category": "gateway", + "description": "The card was declined", + "http_code": 402, + "error_code": 3001, + "request_id": "337cf033-9cd6-4314-a880-c71700e1625f" + } RESPONSE end def failed_authorize_response - <<-RESPONSE -{ - "category":"gateway", - "description":"The card is not supported on online transactions", - "http_code":412, - "error_code":3008, - "request_id":"a4001ef2-7613-4ec8-a23b-4de45154dbe4" -} + <<~RESPONSE + { + "category":"gateway", + "description":"The card is not supported on online transactions", + "http_code":412, + "error_code":3008, + "request_id":"a4001ef2-7613-4ec8-a23b-4de45154dbe4" + } RESPONSE end diff --git a/test/unit/gateways/opp_test.rb b/test/unit/gateways/opp_test.rb index 28efb3e2d72..6dfcf179097 100644 --- a/test/unit/gateways/opp_test.rb +++ b/test/unit/gateways/opp_test.rb @@ -7,8 +7,8 @@ def setup @gateway = OppGateway.new(fixtures(:opp)) @amount = 100 - @valid_card = credit_card('4200000000000000', month: 05, year: 2018, verification_value: '123') - @invalid_card = credit_card('4444444444444444', month: 05, year: 2018, verification_value: '123') + @valid_card = credit_card('4200000000000000', month: 05, year: Date.today.year + 2, verification_value: '123') + @invalid_card = credit_card('4444444444444444', month: 05, year: Date.today.year + 2, verification_value: '123') request_type = 'complete' # 'minimal' || 'complete' time = Time.now.to_i @@ -27,7 +27,7 @@ def setup city: 'Istambul', state: 'IS', zip: 'H12JK2354', - country: 'TR', + country: 'TR' }, shipping_address: { name: '', @@ -35,7 +35,7 @@ def setup city: 'Moskau', state: 'MO', zip: 'MO2342432', - country: 'RU', + country: 'RU' }, customer: { merchant_customer_id: "merchantCustomerId #{ip}", @@ -48,13 +48,13 @@ def setup company_name: 'No such deal Ltd.', identification_doctype: 'PASSPORT', identification_docid: 'FakeID2342431234123', - ip: ip, - }, + ip: ip + } } @minimal_request_options = { order_id: "Order #{time}", - description: 'Store Purchase - Books', + description: 'Store Purchase - Books' } @complete_request_options['customParameters[SHOPPER_test124TestName009]'] = 'customParameters_test' @@ -173,11 +173,11 @@ def test_failed_store end def test_passes_3d_secure_fields - options = @complete_request_options.merge({eci: 'eci', cavv: 'cavv', xid: 'xid'}) + options = @complete_request_options.merge({ eci: 'eci', cavv: 'cavv', xid: 'xid' }) response = stub_comms(@gateway, :raw_ssl_request) do @gateway.purchase(@amount, @valid_card, options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/threeDSecure.eci=eci/, data) assert_match(/threeDSecure.verificationId=cavv/, data) assert_match(/threeDSecure.xid=xid/, data) @@ -194,11 +194,11 @@ def test_scrub private def pre_scrubbed - 'paymentType=DB&amount=1.00¤cy=EUR&paymentBrand=VISA&card.holder=Longbob+Longsen&card.number=4200000000000000&card.expiryMonth=05&card.expiryYear=2018& card.cvv=123&billing.street1=456+My+Street&billing.street2=Apt+1&billing.city=Ottawa&billing.state=ON&billing.postcode=K1C2N6&billing.country=CA&authentication.entityId=8a8294174b7ecb28014b9699220015ca&authentication.password=sy6KJsT8&authentication.userId=8a8294174b7ecb28014b9699220015cc' + 'paymentType=DB&amount=1.00¤cy=EUR&descriptor=&merchantInvoiceId=&merchantTransactionId=50b5c1763c20c456a6208f7831dd0a04&paymentBrand=VISA&card.holder=Longbob+Longsen&card.number=4200000000000000&card.expiryMonth=05&card.expiryYear=2022&card.cvv=123&customParameters[SHOPPER_pluginId]=activemerchant&authentication.entityId=5c6602174b7ecb28014b96992' end def post_scrubbed - 'paymentType=DB&amount=1.00¤cy=EUR&paymentBrand=VISA&card.holder=Longbob+Longsen&card.number=[FILTERED]&card.expiryMonth=05&card.expiryYear=2018& card.cvv=[FILTERED]&billing.street1=456+My+Street&billing.street2=Apt+1&billing.city=Ottawa&billing.state=ON&billing.postcode=K1C2N6&billing.country=CA&authentication.entityId=8a8294174b7ecb28014b9699220015ca&authentication.password=[FILTERED]&authentication.userId=8a8294174b7ecb28014b9699220015cc' + 'paymentType=DB&amount=1.00¤cy=EUR&descriptor=&merchantInvoiceId=&merchantTransactionId=50b5c1763c20c456a6208f7831dd0a04&paymentBrand=VISA&card.holder=Longbob+Longsen&card.number=[FILTERED]&card.expiryMonth=05&card.expiryYear=2022&card.cvv=[FILTERED]&customParameters[SHOPPER_pluginId]=activemerchant&authentication.entityId=5c6602174b7ecb28014b96992' end def successful_response(type, id) @@ -224,8 +224,7 @@ def successful_response(type, id) 'buildNumber' => '20150618-111601.r185004.opp-tags-20150618_stage', 'timestamp' => '2015-06-20 19:31:01+0000', 'ndc' => '8a8294174b7ecb28014b9699220015ca_4453edbc001f405da557c05cb3c3add9' - }) - ) + })) end def successful_store_response(id) @@ -246,11 +245,10 @@ def successful_store_response(id) 'buildNumber' => '20150618-111601.r185004.opp-tags-20150618_stage', 'timestamp' => '2015-06-20 19:31:01+0000', 'ndc' => '8a8294174b7ecb28014b9699220015ca_4453edbc001f405da557c05cb3c3add9' - }) - ) + })) end - def failed_response(type, id, code='100.100.101') + def failed_response(type, id, code = '100.100.101') OppMockResponse.new(400, JSON.generate({ 'id' => id, @@ -270,11 +268,10 @@ def failed_response(type, id, code='100.100.101') 'buildNumber' => '20150618-111601.r185004.opp-tags-20150618_stage', 'timestamp' => '2015-06-20 20:40:26+0000', 'ndc' => '8a8294174b7ecb28014b9699220015ca_5200332e7d664412a84ed5f4777b3c7d' - }) - ) + })) end - def failed_store_response(id, code='100.100.101') + def failed_store_response(id, code = '100.100.101') OppMockResponse.new(400, JSON.generate({ 'id' => id, @@ -292,8 +289,7 @@ def failed_store_response(id, code='100.100.101') 'buildNumber' => '20150618-111601.r185004.opp-tags-20150618_stage', 'timestamp' => '2015-06-20 20:40:26+0000', 'ndc' => '8a8294174b7ecb28014b9699220015ca_5200332e7d664412a84ed5f4777b3c7d' - }) - ) + })) end class OppMockResponse @@ -304,5 +300,4 @@ def initialize(code, body) @body = body end end - end diff --git a/test/unit/gateways/optimal_payment_test.rb b/test/unit/gateways/optimal_payment_test.rb index f8d194e94ad..f5622504397 100644 --- a/test/unit/gateways/optimal_payment_test.rb +++ b/test/unit/gateways/optimal_payment_test.rb @@ -10,19 +10,19 @@ class OptimalPaymentTest < Test::Unit::TestCase def setup @gateway = OptimalPaymentGateway.new( - :account_number => '12345678', - :store_id => 'login', - :password => 'password' + account_number: '12345678', + store_id: 'login', + password: 'password' ) @credit_card = credit_card @amount = 100 @options = { - :order_id => '1', - :billing_address => address, - :description => 'Store Purchase', - :email => 'email@example.com' + order_id: '1', + billing_address: address, + description: 'Store Purchase', + email: 'email@example.com' } end @@ -34,26 +34,26 @@ def test_full_request def test_ip_address_is_passed stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(ip: '1.2.3.4')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match %r{customerIP%3E1.2.3.4%3C}, data end.respond_with(successful_purchase_response) end def test_minimal_request options = { - :order_id => '1', - :description => 'Store Purchase', - :billing_address => { - :zip => 'K1C2N6', + order_id: '1', + description: 'Store Purchase', + billing_address: { + zip: 'K1C2N6' } } credit_card = CreditCard.new( - :number => '4242424242424242', - :month => 9, - :year => Time.now.year + 1, - :first_name => 'Longbob', - :last_name => 'Longsen', - :brand => 'visa' + number: '4242424242424242', + month: 9, + year: Time.now.year + 1, + first_name: 'Longbob', + last_name: 'Longsen', + brand: 'visa' ) @gateway.instance_variable_set('@credit_card', credit_card) assert_match minimal_request, @gateway.cc_auth_request(@amount, options) @@ -73,7 +73,7 @@ def test_successful_purchase def test_purchase_from_canada_includes_state_field @options[:billing_address][:country] = 'CA' - @gateway.expects(:ssl_post).with do |url, data| + @gateway.expects(:ssl_post).with do |_url, data| data =~ /state/ && data !~ /region/ end.returns(successful_purchase_response) @@ -82,7 +82,7 @@ def test_purchase_from_canada_includes_state_field def test_purchase_from_us_includes_state_field @options[:billing_address][:country] = 'US' - @gateway.expects(:ssl_post).with do |url, data| + @gateway.expects(:ssl_post).with do |_url, data| data =~ /state/ && data !~ /region/ end.returns(successful_purchase_response) @@ -91,7 +91,7 @@ def test_purchase_from_us_includes_state_field def test_purchase_from_any_other_country_includes_region_field @options[:billing_address][:country] = 'GB' - @gateway.expects(:ssl_post).with do |url, data| + @gateway.expects(:ssl_post).with do |_url, data| data =~ /region/ && data !~ /state/ end.returns(successful_purchase_response) @@ -99,8 +99,8 @@ def test_purchase_from_any_other_country_includes_region_field end def test_purchase_with_shipping_address - @options[:shipping_address] = {:country => 'CA'} - @gateway.expects(:ssl_post).with do |url, data| + @options[:shipping_address] = { country: 'CA' } + @gateway.expects(:ssl_post).with do |_url, data| xml = data.split('&').detect { |string| string =~ /txnRequest=/ }.gsub('txnRequest=', '') doc = Nokogiri::XML.parse(CGI.unescape(xml)) doc.xpath('//xmlns:shippingDetails/xmlns:country').first.text == 'CA' && doc.to_s.include?('') @@ -111,7 +111,7 @@ def test_purchase_with_shipping_address def test_purchase_without_shipping_address @options[:shipping_address] = nil - @gateway.expects(:ssl_post).with do |url, data| + @gateway.expects(:ssl_post).with do |_url, data| xml = data.split('&').detect { |string| string =~ /txnRequest=/ }.gsub('txnRequest=', '') doc = Nokogiri::XML.parse(CGI.unescape(xml)) doc.to_s.include?('') == false @@ -131,22 +131,22 @@ def test_purchase_without_billing_address def test_cvd_fields_pass_correctly 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(/cvdIndicator%3E1%3C\/cvdIndicator%3E%0A%20%20%20%20%3Ccvd%3E123%3C\/cvd/, data) end.respond_with(successful_purchase_response) credit_card = CreditCard.new( - :number => '4242424242424242', - :month => 9, - :year => Time.now.year + 1, - :first_name => 'Longbob', - :last_name => 'Longsen', - :brand => 'visa' + number: '4242424242424242', + month: 9, + year: Time.now.year + 1, + first_name: 'Longbob', + last_name: 'Longsen', + brand: 'visa' ) 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(/cvdIndicator%3E0%3C\/cvdIndicator%3E%0A%20%20%3C\/card/, data) end.respond_with(failed_purchase_response) end @@ -174,10 +174,10 @@ def test_unsuccessful_request def test_in_production_with_test_param_sends_request_to_test_server ActiveMerchant::Billing::Base.mode = :production @gateway = OptimalPaymentGateway.new( - :account_number => '12345678', - :store_id => 'login', - :password => 'password', - :test => true + account_number: '12345678', + store_id: 'login', + password: 'password', + test: true ) @gateway.expects(:ssl_post).with('https://webservices.test.optimalpayments.com/creditcardWS/CreditCardServlet/v1', anything).returns(successful_purchase_response) @@ -214,17 +214,17 @@ def test_avs_results_not_in_response def test_deprecated_options assert_deprecation_warning("The 'account' option is deprecated in favor of 'account_number' and will be removed in a future version.") do @gateway = OptimalPaymentGateway.new( - :account => '12345678', - :store_id => 'login', - :password => 'password' + account: '12345678', + store_id: 'login', + password: 'password' ) end assert_deprecation_warning("The 'login' option is deprecated in favor of 'store_id' and will be removed in a future version.") do @gateway = OptimalPaymentGateway.new( - :account_number => '12345678', - :login => 'login', - :password => 'password' + account_number: '12345678', + login: 'login', + password: 'password' ) end end @@ -237,202 +237,202 @@ def test_scrub private def full_request - str = <<-XML - - - 12345678 - login - password - - 1 - 1.0 - - 4242424242424242 - - 9 - #{Time.now.year + 1} - - VI - 1 - 123 - - - WEB - Jim - Smith - 456 My Street - Apt 1 - Ottawa - ON - CA - K1C2N6 - (555)555-5555 - email@example.com - - + str = <<~XML + + + 12345678 + login + password + + 1 + 1.0 + + 4242424242424242 + + 9 + #{Time.now.year + 1} + + VI + 1 + 123 + + + WEB + Jim + Smith + 456 My Street + Apt 1 + Ottawa + ON + CA + K1C2N6 + (555)555-5555 + email@example.com + + XML Regexp.new(Regexp.escape(str).sub('xmlns', '[^>]+').sub('/>', '(/>|>]+>)')) end def minimal_request - str = <<-XML - - - 12345678 - login - password - - 1 - 1.0 - - 4242424242424242 - - 9 - #{Time.now.year + 1} - - VI - 0 - - - WEB - K1C2N6 - - + str = <<~XML + + + 12345678 + login + password + + 1 + 1.0 + + 4242424242424242 + + 9 + #{Time.now.year + 1} + + VI + 0 + + + WEB + K1C2N6 + + XML Regexp.new(Regexp.escape(str).sub('xmlns', '[^>]+').sub('/>', '(/>|>]+>)')) end # Place raw successful response from gateway here def successful_purchase_response - <<-XML - - 126740505 - ACCEPTED - 0 - No Error - 112232 - B - M - - InternalResponseCode - 0 - - - SubErrorCode - 0 - - - InternalResponseDescription - no_error - - 2009-01-08T17:00:45.210-05:00 - false - + <<~XML + + 126740505 + ACCEPTED + 0 + No Error + 112232 + B + M + + InternalResponseCode + 0 + + + SubErrorCode + 0 + + + InternalResponseDescription + no_error + + 2009-01-08T17:00:45.210-05:00 + false + XML end # Place raw successful response from gateway here def successful_purchase_response_without_avs_results - <<-XML - - 126740505 - ACCEPTED - 0 - No Error - 112232 - - InternalResponseCode - 0 - - - SubErrorCode - 0 - - - InternalResponseDescription - no_error - - 2009-01-08T17:00:45.210-05:00 - false - + <<~XML + + 126740505 + ACCEPTED + 0 + No Error + 112232 + + InternalResponseCode + 0 + + + SubErrorCode + 0 + + + InternalResponseDescription + no_error + + 2009-01-08T17:00:45.210-05:00 + false + XML end # Place raw failed response from gateway here def failed_purchase_response - <<-XML - - 126740506 - DECLINED - 3009 - D - Your request has been declined by the issuing bank. - B - M - - InternalResponseCode - 160 - - - SubErrorCode - 1005 - - - InternalResponseDescription - auth declined - - 2009-01-08T17:00:46.529-05:00 - false - + <<~XML + + 126740506 + DECLINED + 3009 + D + Your request has been declined by the issuing bank. + B + M + + InternalResponseCode + 160 + + + SubErrorCode + 1005 + + + InternalResponseDescription + auth declined + + 2009-01-08T17:00:46.529-05:00 + false + XML end def pre_scrubbed - <<-EOS -opening connection to webservices.test.optimalpayments.com:443... -opened -starting SSL for webservices.test.optimalpayments.com:443... -SSL established -<- "POST /creditcardWS/CreditCardServlet/v1 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: webservices.test.optimalpayments.com\r\nContent-Length: 1616\r\n\r\n" -<- "txnMode=ccPurchase&txnRequest=%3CccAuthRequestV1%20xmlns=%22http://www.optimalpayments.com/creditcard/xmlschema/v1%22%20xmlns:xsi=%22http://www.w3.org/2001/XMLSchema-instance%22%20xsi:schemaLocation=%22http://www.optimalpayments.com/creditcard/xmlschema/v1%22%3E%0A%20%20%3CmerchantAccount%3E%0A%20%20%20%20%3CaccountNum%3E1001134550%3C/accountNum%3E%0A%20%20%20%20%3CstoreID%3Etest%3C/storeID%3E%0A%20%20%20%20%3CstorePwd%3Etest%3C/storePwd%3E%0A%20%20%3C/merchantAccount%3E%0A%20%20%3CmerchantRefNum%3E1%3C/merchantRefNum%3E%0A%20%20%3Camount%3E1.0%3C/amount%3E%0A%20%20%3Ccard%3E%0A%20%20%20%20%3CcardNum%3E4387751111011%3C/cardNum%3E%0A%20%20%20%20%3CcardExpiry%3E%0A%20%20%20%20%20%20%3Cmonth%3E9%3C/month%3E%0A%20%20%20%20%20%20%3Cyear%3E2019%3C/year%3E%0A%20%20%20%20%3C/cardExpiry%3E%0A%20%20%20%20%3CcardType%3EVI%3C/cardType%3E%0A%20%20%20%20%3CcvdIndicator%3E1%3C/cvdIndicator%3E%0A%20%20%20%20%3Ccvd%3E123%3C/cvd%3E%0A%20%20%3C/card%3E%0A%20%20%3CbillingDetails%3E%0A%20%20%20%20%3CcardPayMethod%3EWEB%3C/cardPayMethod%3E%0A%20%20%20%20%3CfirstName%3EJim%3C/firstName%3E%0A%20%20%20%20%3ClastName%3ESmith%3C/lastName%3E%0A%20%20%20%20%3Cstreet%3E456%20My%20Street%3C/street%3E%0A%20%20%20%20%3Cstreet2%3EApt%201%3C/street2%3E%0A%20%20%20%20%3Ccity%3EOttawa%3C/city%3E%0A%20%20%20%20%3Cstate%3EON%3C/state%3E%0A%20%20%20%20%3Ccountry%3ECA%3C/country%3E%0A%20%20%20%20%3Czip%3EK1C2N6%3C/zip%3E%0A%20%20%20%20%3Cphone%3E(555)555-5555%3C/phone%3E%0A%20%20%20%20%3Cemail%3Eemail@example.com%3C/email%3E%0A%20%20%3C/billingDetails%3E%0A%20%20%3CcustomerIP%3E1.2.3.4%3C/customerIP%3E%0A%3C/ccAuthRequestV1%3E%0A" --> "HTTP/1.1 200 OK\r\n" --> "Server: WebServer32xS10i3\r\n" --> "Content-Length: 632\r\n" --> "X-ApplicationUid: GUID=610a301289c34e8254330b7edc724f5b\r\n" --> "Content-Type: application/xml\r\n" --> "Date: Mon, 12 Feb 2018 21:57:42 GMT\r\n" --> "Connection: close\r\n" --> "\r\n" -reading 632 bytes... --> "<" --> "?xml version=\"1.0\" encoding=\"UTF-8\"?>\n498871860ACCEPTED0No Error369231XMInternalResponseCode0SubErrorCode0InternalResponseDescriptionno_error2018-02-12T16:57:42.289-05:00false" -read 632 bytes -Conn close - EOS + <<~REQUEST + opening connection to webservices.test.optimalpayments.com:443... + opened + starting SSL for webservices.test.optimalpayments.com:443... + SSL established + <- "POST /creditcardWS/CreditCardServlet/v1 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: webservices.test.optimalpayments.com\r\nContent-Length: 1616\r\n\r\n" + <- "txnMode=ccPurchase&txnRequest=%3CccAuthRequestV1%20xmlns=%22http://www.optimalpayments.com/creditcard/xmlschema/v1%22%20xmlns:xsi=%22http://www.w3.org/2001/XMLSchema-instance%22%20xsi:schemaLocation=%22http://www.optimalpayments.com/creditcard/xmlschema/v1%22%3E%0A%20%20%3CmerchantAccount%3E%0A%20%20%20%20%3CaccountNum%3E1001134550%3C/accountNum%3E%0A%20%20%20%20%3CstoreID%3Etest%3C/storeID%3E%0A%20%20%20%20%3CstorePwd%3Etest%3C/storePwd%3E%0A%20%20%3C/merchantAccount%3E%0A%20%20%3CmerchantRefNum%3E1%3C/merchantRefNum%3E%0A%20%20%3Camount%3E1.0%3C/amount%3E%0A%20%20%3Ccard%3E%0A%20%20%20%20%3CcardNum%3E4387751111011%3C/cardNum%3E%0A%20%20%20%20%3CcardExpiry%3E%0A%20%20%20%20%20%20%3Cmonth%3E9%3C/month%3E%0A%20%20%20%20%20%20%3Cyear%3E2019%3C/year%3E%0A%20%20%20%20%3C/cardExpiry%3E%0A%20%20%20%20%3CcardType%3EVI%3C/cardType%3E%0A%20%20%20%20%3CcvdIndicator%3E1%3C/cvdIndicator%3E%0A%20%20%20%20%3Ccvd%3E123%3C/cvd%3E%0A%20%20%3C/card%3E%0A%20%20%3CbillingDetails%3E%0A%20%20%20%20%3CcardPayMethod%3EWEB%3C/cardPayMethod%3E%0A%20%20%20%20%3CfirstName%3EJim%3C/firstName%3E%0A%20%20%20%20%3ClastName%3ESmith%3C/lastName%3E%0A%20%20%20%20%3Cstreet%3E456%20My%20Street%3C/street%3E%0A%20%20%20%20%3Cstreet2%3EApt%201%3C/street2%3E%0A%20%20%20%20%3Ccity%3EOttawa%3C/city%3E%0A%20%20%20%20%3Cstate%3EON%3C/state%3E%0A%20%20%20%20%3Ccountry%3ECA%3C/country%3E%0A%20%20%20%20%3Czip%3EK1C2N6%3C/zip%3E%0A%20%20%20%20%3Cphone%3E(555)555-5555%3C/phone%3E%0A%20%20%20%20%3Cemail%3Eemail@example.com%3C/email%3E%0A%20%20%3C/billingDetails%3E%0A%20%20%3CcustomerIP%3E1.2.3.4%3C/customerIP%3E%0A%3C/ccAuthRequestV1%3E%0A" + -> "HTTP/1.1 200 OK\r\n" + -> "Server: WebServer32xS10i3\r\n" + -> "Content-Length: 632\r\n" + -> "X-ApplicationUid: GUID=610a301289c34e8254330b7edc724f5b\r\n" + -> "Content-Type: application/xml\r\n" + -> "Date: Mon, 12 Feb 2018 21:57:42 GMT\r\n" + -> "Connection: close\r\n" + -> "\r\n" + reading 632 bytes... + -> "<" + -> "?xml version=\"1.0\" encoding=\"UTF-8\"?>\n498871860ACCEPTED0No Error369231XMInternalResponseCode0SubErrorCode0InternalResponseDescriptionno_error2018-02-12T16:57:42.289-05:00false" + read 632 bytes + Conn close + REQUEST end def post_scrubbed - <<-EOS -opening connection to webservices.test.optimalpayments.com:443... -opened -starting SSL for webservices.test.optimalpayments.com:443... -SSL established -<- "POST /creditcardWS/CreditCardServlet/v1 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: webservices.test.optimalpayments.com\r\nContent-Length: 1616\r\n\r\n" -<- "txnMode=ccPurchase&txnRequest=%3CccAuthRequestV1%20xmlns=%22http://www.optimalpayments.com/creditcard/xmlschema/v1%22%20xmlns:xsi=%22http://www.w3.org/2001/XMLSchema-instance%22%20xsi:schemaLocation=%22http://www.optimalpayments.com/creditcard/xmlschema/v1%22%3E%0A%20%20%3CmerchantAccount%3E%0A%20%20%20%20%3CaccountNum%3E1001134550%3C/accountNum%3E%0A%20%20%20%20%3CstoreID%3Etest%3C/storeID%3E%0A%20%20%20%20%3CstorePwd%3E[FILTERED]%3C/storePwd%3E%0A%20%20%3C/merchantAccount%3E%0A%20%20%3CmerchantRefNum%3E1%3C/merchantRefNum%3E%0A%20%20%3Camount%3E1.0%3C/amount%3E%0A%20%20%3Ccard%3E%0A%20%20%20%20%3CcardNum%3E[FILTERED]%3C/cardNum%3E%0A%20%20%20%20%3CcardExpiry%3E%0A%20%20%20%20%20%20%3Cmonth%3E9%3C/month%3E%0A%20%20%20%20%20%20%3Cyear%3E2019%3C/year%3E%0A%20%20%20%20%3C/cardExpiry%3E%0A%20%20%20%20%3CcardType%3EVI%3C/cardType%3E%0A%20%20%20%20%3CcvdIndicator%3E1%3C/cvdIndicator%3E%0A%20%20%20%20%3Ccvd%3E[FILTERED]%3C/cvd%3E%0A%20%20%3C/card%3E%0A%20%20%3CbillingDetails%3E%0A%20%20%20%20%3CcardPayMethod%3EWEB%3C/cardPayMethod%3E%0A%20%20%20%20%3CfirstName%3EJim%3C/firstName%3E%0A%20%20%20%20%3ClastName%3ESmith%3C/lastName%3E%0A%20%20%20%20%3Cstreet%3E456%20My%20Street%3C/street%3E%0A%20%20%20%20%3Cstreet2%3EApt%201%3C/street2%3E%0A%20%20%20%20%3Ccity%3EOttawa%3C/city%3E%0A%20%20%20%20%3Cstate%3EON%3C/state%3E%0A%20%20%20%20%3Ccountry%3ECA%3C/country%3E%0A%20%20%20%20%3Czip%3EK1C2N6%3C/zip%3E%0A%20%20%20%20%3Cphone%3E(555)555-5555%3C/phone%3E%0A%20%20%20%20%3Cemail%3Eemail@example.com%3C/email%3E%0A%20%20%3C/billingDetails%3E%0A%20%20%3CcustomerIP%3E1.2.3.4%3C/customerIP%3E%0A%3C/ccAuthRequestV1%3E%0A" --> "HTTP/1.1 200 OK\r\n" --> "Server: WebServer32xS10i3\r\n" --> "Content-Length: 632\r\n" --> "X-ApplicationUid: GUID=610a301289c34e8254330b7edc724f5b\r\n" --> "Content-Type: application/xml\r\n" --> "Date: Mon, 12 Feb 2018 21:57:42 GMT\r\n" --> "Connection: close\r\n" --> "\r\n" -reading 632 bytes... --> "<" --> "?xml version=\"1.0\" encoding=\"UTF-8\"?>\n498871860ACCEPTED0No Error369231XMInternalResponseCode0SubErrorCode0InternalResponseDescriptionno_error2018-02-12T16:57:42.289-05:00false" -read 632 bytes -Conn close - EOS + <<~REQUEST + opening connection to webservices.test.optimalpayments.com:443... + opened + starting SSL for webservices.test.optimalpayments.com:443... + SSL established + <- "POST /creditcardWS/CreditCardServlet/v1 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: webservices.test.optimalpayments.com\r\nContent-Length: 1616\r\n\r\n" + <- "txnMode=ccPurchase&txnRequest=%3CccAuthRequestV1%20xmlns=%22http://www.optimalpayments.com/creditcard/xmlschema/v1%22%20xmlns:xsi=%22http://www.w3.org/2001/XMLSchema-instance%22%20xsi:schemaLocation=%22http://www.optimalpayments.com/creditcard/xmlschema/v1%22%3E%0A%20%20%3CmerchantAccount%3E%0A%20%20%20%20%3CaccountNum%3E1001134550%3C/accountNum%3E%0A%20%20%20%20%3CstoreID%3Etest%3C/storeID%3E%0A%20%20%20%20%3CstorePwd%3E[FILTERED]%3C/storePwd%3E%0A%20%20%3C/merchantAccount%3E%0A%20%20%3CmerchantRefNum%3E1%3C/merchantRefNum%3E%0A%20%20%3Camount%3E1.0%3C/amount%3E%0A%20%20%3Ccard%3E%0A%20%20%20%20%3CcardNum%3E[FILTERED]%3C/cardNum%3E%0A%20%20%20%20%3CcardExpiry%3E%0A%20%20%20%20%20%20%3Cmonth%3E9%3C/month%3E%0A%20%20%20%20%20%20%3Cyear%3E2019%3C/year%3E%0A%20%20%20%20%3C/cardExpiry%3E%0A%20%20%20%20%3CcardType%3EVI%3C/cardType%3E%0A%20%20%20%20%3CcvdIndicator%3E1%3C/cvdIndicator%3E%0A%20%20%20%20%3Ccvd%3E[FILTERED]%3C/cvd%3E%0A%20%20%3C/card%3E%0A%20%20%3CbillingDetails%3E%0A%20%20%20%20%3CcardPayMethod%3EWEB%3C/cardPayMethod%3E%0A%20%20%20%20%3CfirstName%3EJim%3C/firstName%3E%0A%20%20%20%20%3ClastName%3ESmith%3C/lastName%3E%0A%20%20%20%20%3Cstreet%3E456%20My%20Street%3C/street%3E%0A%20%20%20%20%3Cstreet2%3EApt%201%3C/street2%3E%0A%20%20%20%20%3Ccity%3EOttawa%3C/city%3E%0A%20%20%20%20%3Cstate%3EON%3C/state%3E%0A%20%20%20%20%3Ccountry%3ECA%3C/country%3E%0A%20%20%20%20%3Czip%3EK1C2N6%3C/zip%3E%0A%20%20%20%20%3Cphone%3E(555)555-5555%3C/phone%3E%0A%20%20%20%20%3Cemail%3Eemail@example.com%3C/email%3E%0A%20%20%3C/billingDetails%3E%0A%20%20%3CcustomerIP%3E1.2.3.4%3C/customerIP%3E%0A%3C/ccAuthRequestV1%3E%0A" + -> "HTTP/1.1 200 OK\r\n" + -> "Server: WebServer32xS10i3\r\n" + -> "Content-Length: 632\r\n" + -> "X-ApplicationUid: GUID=610a301289c34e8254330b7edc724f5b\r\n" + -> "Content-Type: application/xml\r\n" + -> "Date: Mon, 12 Feb 2018 21:57:42 GMT\r\n" + -> "Connection: close\r\n" + -> "\r\n" + reading 632 bytes... + -> "<" + -> "?xml version=\"1.0\" encoding=\"UTF-8\"?>\n498871860ACCEPTED0No Error369231XMInternalResponseCode0SubErrorCode0InternalResponseDescriptionno_error2018-02-12T16:57:42.289-05:00false" + read 632 bytes + Conn close + REQUEST end def pre_scrubbed_double_escaped diff --git a/test/unit/gateways/orbital_avs_result_test.rb b/test/unit/gateways/orbital_avs_result_test.rb index 9596e3c7e4c..32abbbded5f 100644 --- a/test/unit/gateways/orbital_avs_result_test.rb +++ b/test/unit/gateways/orbital_avs_result_test.rb @@ -26,13 +26,13 @@ def test_empty_data end def test_response_with_orbital_avs - response = Response.new(true, 'message', {}, :avs_result => OrbitalGateway::AVSResult.new('A')) + response = Response.new(true, 'message', {}, avs_result: OrbitalGateway::AVSResult.new('A')) assert_equal 'A', response.avs_result['code'] end def test_response_with_orbital_avs_nil - response = Response.new(true, 'message', {}, :avs_result => OrbitalGateway::AVSResult.new(nil)) + response = Response.new(true, 'message', {}, avs_result: OrbitalGateway::AVSResult.new(nil)) assert response.avs_result.has_key?('code') end diff --git a/test/unit/gateways/orbital_test.rb b/test/unit/gateways/orbital_test.rb index 6f594600095..6939a5689d5 100644 --- a/test/unit/gateways/orbital_test.rb +++ b/test/unit/gateways/orbital_test.rb @@ -8,13 +8,15 @@ class OrbitalGatewayTest < Test::Unit::TestCase def setup @gateway = ActiveMerchant::Billing::OrbitalGateway.new( - :login => 'login', - :password => 'password', - :merchant_id => 'merchant_id' + login: 'login', + password: 'password', + merchant_id: 'merchant_id' ) @customer_ref_num = 'ABC' + # Electronic Check object with test credentials of saving account + @echeck = check(account_number: '072403004', account_type: 'savings', routing_number: '072403004') - @level_2 = { + @level2 = { tax_indicator: '1', tax: '10', advice_addendum_1: 'taa1 - test', @@ -27,10 +29,56 @@ def setup address2: address[:address2], city: address[:city], state: address[:state], - zip: address[:zip], + zip: address[:zip] + } + + @level3 = { + freight_amount: '15', + duty_amount: '10', + dest_country: 'US', + ship_from_zip: '12345', + discount_amount: '20', + vat_tax: '25', + alt_tax: '30', + vat_rate: '7', + alt_ind: 'Y' + } + + @line_items = + [ + { + desc: 'credit card payment', + prod_cd: 'service', + qty: '30', + u_o_m: 'EAC', + tax_amt: '10', + tax_rate: '8.25', + line_tot: '20', + disc: '6', + unit_cost: '5', + gross_net: 'Y', + disc_ind: 'Y' + }, + { + desc: 'credit card payment', + prod_cd: 'service', + qty: '30', + u_o_m: 'EAC', + tax_amt: '10', + tax_rate: '8.25', + line_tot: '20', + disc: '6', + unit_cost: '5', + gross_net: 'Y', + disc_ind: 'Y' + } + ] + + @options = { + order_id: '1', + card_indicators: 'y' } - @options = { :order_id => '1'} @options_stored_credentials = { mit_msg_type: 'MRSB', mit_stored_credential_ind: 'Y', @@ -44,17 +92,13 @@ def setup network_transaction_id: 'abcdefg12345678' } } - @normalized_initial_stored_credential = { - stored_credential: { - initial_transaction: true, - initiator: 'customer' - } - } @three_d_secure_options = { three_d_secure: { eci: '5', xid: 'TESTXID', cavv: 'TESTCAVV', + version: '2', + ds_transaction_id: '97267598FAE648F28083C23433990FBC' } } end @@ -62,47 +106,128 @@ def setup def test_successful_purchase @gateway.expects(:ssl_post).returns(successful_purchase_response) - assert response = @gateway.purchase(50, credit_card, :order_id => '1') + assert response = @gateway.purchase(50, credit_card, order_id: '1') assert_instance_of Response, response assert_success response assert_equal '4A5398CF9B87744GG84A1D30F2F2321C66249416;1', response.authorization end - def test_level_2_data + def test_successful_purchase_with_echeck + @gateway.expects(:ssl_post).returns(successful_purchase_with_echeck_response) + + assert response = @gateway.purchase(50, @echeck, order_id: '9baedc697f2cf06457de78') + assert_instance_of Response, response + assert_equal 'Approved', response.message + assert_success response + assert_equal '5F8E8BEE7299FD339A38F70CFF6E5D010EF55498;9baedc697f2cf06457de78', response.authorization + end + + def test_failed_purchase_with_echeck + @gateway.expects(:ssl_post).returns(failed_echeck_for_invalid_routing_response) + + assert response = @gateway.purchase(50, @echeck, order_id: '9baedc697f2cf06457de78') + assert_instance_of Response, response + assert_failure response + assert_equal 'Invalid ECP Account Route: []. The field is missing, invalid, or it has exceeded the max length of: [9].', response.message + assert_equal '888', response.params['proc_status'] + end + + def test_successful_force_capture_with_echeck + @gateway.expects(:ssl_post).returns(successful_force_capture_with_echeck_response) + + assert response = @gateway.purchase(31, @echeck, order_id: '2', force_capture: true) + assert_instance_of Response, response + assert_match 'APPROVAL', response.message + assert_equal 'Approved and Completed', response.params['status_msg'] + assert_equal '5F8ED3D950A43BD63369845D5385B6354C3654B4;2930847bc732eb4e8102cf', response.authorization + end + + def test_level2_data + stub_comms do + @gateway.purchase(50, credit_card, @options.merge(level_2_data: @level2)) + end.check_request do |_endpoint, data, _headers| + assert_match %{#{@level2[:tax_indicator].to_i}}, data + assert_match %{#{@level2[:tax].to_i}}, data + assert_match %{#{@level2[:advice_addendum_1]}}, data + assert_match %{#{@level2[:advice_addendum_2]}}, data + assert_match %{#{@level2[:advice_addendum_3]}}, data + assert_match %{#{@level2[:advice_addendum_4]}}, data + assert_match %{#{@level2[:purchase_order]}}, data + assert_match %{#{@level2[:zip]}}, data + assert_match %{#{@level2[:name]}}, data + assert_match %{#{@level2[:address1]}}, data + assert_match %{#{@level2[:address2]}}, data + assert_match %{#{@level2[:city]}}, data + assert_match %{#{@level2[:state]}}, data + end.respond_with(successful_purchase_response) + end + + def test_level3_data + stub_comms do + @gateway.purchase(50, credit_card, @options.merge(level_3_data: @level3)) + end.check_request do |_endpoint, data, _headers| + assert_match %{#{@level3[:freight_amount].to_i}}, data + assert_match %{#{@level3[:duty_amount].to_i}}, data + assert_match %{#{@level3[:dest_country]}}, data + assert_match %{#{@level3[:ship_from_zip].to_i}}, data + assert_match %{#{@level3[:discount_amount].to_i}}, data + assert_match %{#{@level3[:vat_tax].to_i}}, data + assert_match %{#{@level3[:vat_rate].to_i}}, data + assert_match %{#{@level3[:alt_tax].to_i}}, data + assert_match %{#{@level3[:alt_ind]}}, data + end.respond_with(successful_purchase_response) + end + + def test_line_items_data stub_comms do - @gateway.purchase(50, credit_card, @options.merge(level_2_data: @level_2)) - end.check_request do |endpoint, data, headers| - assert_match %{#{@level_2[:tax_indicator].to_i}}, data - assert_match %{#{@level_2[:tax].to_i}}, data - assert_match %{#{@level_2[:advice_addendum_1]}}, data - assert_match %{#{@level_2[:advice_addendum_2]}}, data - assert_match %{#{@level_2[:advice_addendum_3]}}, data - assert_match %{#{@level_2[:advice_addendum_4]}}, data - assert_match %{#{@level_2[:purchase_order]}}, data - assert_match %{#{@level_2[:zip]}}, data - assert_match %{#{@level_2[:name]}}, data - assert_match %{#{@level_2[:address1]}}, data - assert_match %{#{@level_2[:address2]}}, data - assert_match %{#{@level_2[:city]}}, data - assert_match %{#{@level_2[:state]}}, data + @gateway.purchase(50, credit_card, @options.merge(line_items: @line_items)) + end.check_request do |_endpoint, data, _headers| + assert_match %{1}, data + assert_match %{#{@line_items[1][:desc]}}, data + assert_match %{#{@line_items[1][:prod_cd]}}, data + assert_match %{#{@line_items[1][:qty].to_i}}, data + assert_match %{#{@line_items[1][:u_o_m]}}, data + assert_match %{#{@line_items[1][:tax_amt].to_i}}, data + assert_match %{#{@line_items[1][:tax_rate]}}, data + assert_match %{#{@line_items[1][:line_tot].to_i}}, data + assert_match %{#{@line_items[1][:disc].to_i}}, data + assert_match %{#{@line_items[1][:unit_cost].to_i}}, data + assert_match %{#{@line_items[1][:gross_net]}}, data + assert_match %{#{@line_items[1][:disc_ind]}}, data + assert_match %{2}, data end.respond_with(successful_purchase_response) end def test_network_tokenization_credit_card_data stub_comms do @gateway.purchase(50, network_tokenization_credit_card(nil, eci: '5', transaction_id: 'BwABB4JRdgAAAAAAiFF2AAAAAAA='), @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match %{5}, data assert_match %{Y}, data assert_match %{DigitalTokenCryptogram}, data - assert_match %{XID}, data + end.respond_with(successful_purchase_response) + end + + def test_schema_for_soft_descriptors_with_network_tokenization_credit_card_data + options = @options.merge( + soft_descriptors: { + merchant_name: 'Merch', + product_description: 'Description', + merchant_email: 'email@example' + } + ) + stub_comms do + @gateway.purchase(50, network_tokenization_credit_card(nil, eci: '5', transaction_id: 'BwABB4JRdgAAAAAAiFF2AAAAAAA='), options) + end.check_request do |_endpoint, data, _headers| + # Soft descriptor fields should come before dpan and cryptogram fields + assert_match %{email@example<\/SDMerchantEmail>Y<\/DPANInd>5}, data assert_match %{TESTCAVV}, data assert_match %{TESTXID}, data @@ -112,7 +237,7 @@ def test_three_d_secure_data_on_visa_purchase def test_three_d_secure_data_on_visa_authorization stub_comms do @gateway.authorize(50, credit_card, @options.merge(@three_d_secure_options)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match %{5}, data assert_match %{TESTCAVV}, data assert_match %{TESTXID}, data @@ -122,25 +247,31 @@ def test_three_d_secure_data_on_visa_authorization def test_three_d_secure_data_on_master_purchase stub_comms do @gateway.purchase(50, credit_card(nil, brand: 'master'), @options.merge(@three_d_secure_options)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match %{5}, data assert_match %{TESTCAVV}, data + assert_match %{2}, data + assert_match %{97267598FAE648F28083C23433990FBC}, data + assert_match %{4}, data end.respond_with(successful_purchase_response) end def test_three_d_secure_data_on_master_authorization stub_comms do @gateway.authorize(50, credit_card(nil, brand: 'master'), @options.merge(@three_d_secure_options)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match %{5}, data assert_match %{TESTCAVV}, data + assert_match %{2}, data + assert_match %{97267598FAE648F28083C23433990FBC}, data + assert_match %{4}, data end.respond_with(successful_purchase_response) end def test_three_d_secure_data_on_american_express_purchase stub_comms do @gateway.purchase(50, credit_card(nil, brand: 'american_express'), @options.merge(@three_d_secure_options)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match %{5}, data assert_match %{TESTCAVV}, data assert_match %{ASK}, data @@ -150,7 +281,7 @@ def test_three_d_secure_data_on_american_express_purchase def test_three_d_secure_data_on_american_express_authorization stub_comms do @gateway.authorize(50, credit_card(nil, brand: 'american_express'), @options.merge(@three_d_secure_options)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match %{5}, data assert_match %{TESTCAVV}, data assert_match %{ASK}, data @@ -159,20 +290,20 @@ def test_three_d_secure_data_on_american_express_authorization def test_currency_exponents stub_comms do - @gateway.purchase(50, credit_card, :order_id => '1') - end.check_request do |endpoint, data, headers| + @gateway.purchase(50, credit_card, order_id: '1') + end.check_request do |_endpoint, data, _headers| assert_match %r{2<\/CurrencyExponent>}, data end.respond_with(successful_purchase_response) stub_comms do - @gateway.purchase(50, credit_card, :order_id => '1', :currency => 'CAD') - end.check_request do |endpoint, data, headers| + @gateway.purchase(50, credit_card, order_id: '1', currency: 'CAD') + end.check_request do |_endpoint, data, _headers| assert_match %r{2<\/CurrencyExponent>}, data end.respond_with(successful_purchase_response) stub_comms do - @gateway.purchase(50, credit_card, :order_id => '1', :currency => 'JPY') - end.check_request do |endpoint, data, headers| + @gateway.purchase(50, credit_card, order_id: '1', currency: 'JPY') + end.check_request do |_endpoint, data, _headers| assert_match %r{0<\/CurrencyExponent>}, data end.respond_with(successful_purchase_response) end @@ -180,7 +311,7 @@ def test_currency_exponents def test_unauthenticated_response @gateway.expects(:ssl_post).returns(failed_purchase_response) - assert response = @gateway.purchase(101, credit_card, :order_id => '1') + assert response = @gateway.purchase(101, credit_card, order_id: '1') assert_instance_of Response, response assert_failure response assert_equal 'AUTH DECLINED 12001', response.message @@ -215,14 +346,14 @@ def test_order_id_required def test_order_id_as_number @gateway.expects(:ssl_post).returns(successful_purchase_response) assert_nothing_raised do - @gateway.purchase(101, credit_card, :order_id => 1) + @gateway.purchase(101, credit_card, order_id: 1) end end def test_order_id_format response = stub_comms do - @gateway.purchase(101, credit_card, :order_id => ' #101.23,56 $Hi &thére@Friends') - end.check_request do |endpoint, data, headers| + @gateway.purchase(101, credit_card, order_id: ' #101.23,56 $Hi &thére@Friends') + end.check_request do |_endpoint, data, _headers| assert_match(/101-23,56 \$Hi &thre@Fr<\/OrderID>/, data) end.respond_with(successful_purchase_response) assert_success response @@ -230,8 +361,8 @@ def test_order_id_format def test_order_id_format_for_capture response = stub_comms do - @gateway.capture(101, '4A5398CF9B87744GG84A1D30F2F2321C66249416;1001.1', :order_id => '#1001.1') - end.check_request do |endpoint, data, headers| + @gateway.capture(101, '4A5398CF9B87744GG84A1D30F2F2321C66249416;1001.1', order_id: '#1001.1') + end.check_request do |_endpoint, data, _headers| assert_match(/1001-1<\/OrderID>/, data) end.respond_with(successful_purchase_response) assert_success response @@ -239,14 +370,14 @@ def test_order_id_format_for_capture def test_numeric_merchant_id_for_caputre gateway = ActiveMerchant::Billing::OrbitalGateway.new( - :login => 'login', - :password => 'password', - :merchant_id => 700000123456 + login: 'login', + password: 'password', + merchant_id: 700000123456 ) response = stub_comms(gateway) do gateway.capture(101, '4A5398CF9B87744GG84A1D30F2F2321C66249416;1', @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/700000123456<\/MerchantID>/, data) end.respond_with(successful_purchase_response) assert_success response @@ -259,8 +390,8 @@ def test_expiry_date def test_phone_number response = stub_comms do - @gateway.purchase(50, credit_card, :order_id => 1, :billing_address => address(:phone => '123-456-7890')) - end.check_request do |endpoint, data, headers| + @gateway.purchase(50, credit_card, order_id: 1, billing_address: address(phone: '123-456-7890')) + end.check_request do |_endpoint, data, _headers| assert_match(/1234567890/, data) end.respond_with(successful_purchase_response) assert_success response @@ -270,8 +401,8 @@ def test_truncates_address long_address = '1850 Treebeard Drive in Fangorn Forest by the Fields of Rohan' response = stub_comms do - @gateway.purchase(50, credit_card, :order_id => 1, :billing_address => address(:address1 => long_address)) - end.check_request do |endpoint, data, headers| + @gateway.purchase(50, credit_card, order_id: 1, billing_address: address(address1: long_address)) + end.check_request do |_endpoint, data, _headers| assert_match(/1850 Treebeard Drive/, data) assert_no_match(/Fields of Rohan/, data) end.respond_with(successful_purchase_response) @@ -280,12 +411,12 @@ def test_truncates_address def test_truncates_name card = credit_card('4242424242424242', - :first_name => 'John', - :last_name => 'Jacob Jingleheimer Smith-Jones') + first_name: 'John', + last_name: 'Jacob Jingleheimer Smith-Jones') response = stub_comms do - @gateway.purchase(50, card, :order_id => 1, :billing_address => address) - end.check_request do |endpoint, data, headers| + @gateway.purchase(50, card, order_id: 1, billing_address: address) + end.check_request do |_endpoint, data, _headers| assert_match(/John Jacob/, data) assert_no_match(/Jones/, data) end.respond_with(successful_purchase_response) @@ -296,8 +427,8 @@ def test_truncates_city long_city = 'Friendly Village of Crooked Creek' response = stub_comms do - @gateway.purchase(50, credit_card, :order_id => 1, :billing_address => address(:city => long_city)) - end.check_request do |endpoint, data, headers| + @gateway.purchase(50, credit_card, order_id: 1, billing_address: address(city: long_city)) + end.check_request do |_endpoint, data, _headers| assert_match(/Friendly Village/, data) assert_no_match(/Creek/, data) end.respond_with(successful_purchase_response) @@ -308,8 +439,8 @@ def test_truncates_phone long_phone = '123456789012345' response = stub_comms do - @gateway.purchase(50, credit_card, :order_id => 1, :billing_address => address(:phone => long_phone)) - end.check_request do |endpoint, data, headers| + @gateway.purchase(50, credit_card, order_id: 1, billing_address: address(phone: long_phone)) + end.check_request do |_endpoint, data, _headers| assert_match(/12345678901234 1, :billing_address => address(:zip => long_zip)) - end.check_request do |endpoint, data, headers| + @gateway.purchase(50, credit_card, order_id: 1, billing_address: address(zip: long_zip)) + end.check_request do |_endpoint, data, _headers| assert_match(/1234567890 '456% M|a^in \\S/treet', - :address2 => '|Apt. ^Num\\ber /One%', - :city => 'R^ise o\\f /th%e P|hoenix', - :state => '%O|H\\I/O', - :dest_address1 => '2/21%B |B^aker\\ St.', - :dest_address2 => 'L%u%xury S|u^i\\t/e', - :dest_city => '/Winn/i%p|e^g\\', - :dest_zip => 'A1A 2B2', - :dest_state => '^MB' + address1: '456% M|a^in \\S/treet', + address2: '|Apt. ^Num\\ber /One%', + city: 'R^ise o\\f /th%e P|hoenix', + state: '%O|H\\I/O', + dest_address1: '2/21%B |B^aker\\ St.', + dest_address2: 'L%u%xury S|u^i\\t/e', + dest_city: '/Winn/i%p|e^g\\', + dest_zip: 'A1A 2B2', + dest_state: '^MB' ) response = stub_comms do - @gateway.purchase(50, credit_card, :order_id => 1, - :billing_address => address_with_invalid_chars) - end.check_request do |endpoint, data, headers| + @gateway.purchase(50, credit_card, order_id: 1, + billing_address: address_with_invalid_chars) + end.check_request do |_endpoint, data, _headers| assert_match(/456 Main Street address_with_invalid_chars) + billing_address: address_with_invalid_chars) end - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/456 Main Street 'John', - :last_name => 'Jacob Jingleheimer Smith-Jones') + first_name: 'John', + last_name: 'Jacob Jingleheimer Smith-Jones') long_address = address( - :address1 => '456 Stréêt Name is Really Long', - :address2 => 'Apårtmeñt 123456789012345678901', - :city => '¡Vancouver-by-the-sea!', - :state => 'ßC', - :zip => 'Postäl Cøde', - :dest_name => 'Pierré von Bürgermeister de Queso', - :dest_address1 => '9876 Stréêt Name is Really Long', - :dest_address2 => 'Apårtmeñt 987654321098765432109', - :dest_city => 'Montréal-of-the-south!', - :dest_state => 'Oñtario', - :dest_zip => 'Postäl Zïps' + address1: '456 Stréêt Name is Really Long', + address2: 'Apårtmeñt 123456789012345678901', + city: '¡Vancouver-by-the-sea!', + state: 'ßC', + zip: 'Postäl Cøde', + dest_name: 'Pierré von Bürgermeister de Queso', + dest_address1: '9876 Stréêt Name is Really Long', + dest_address2: 'Apårtmeñt 987654321098765432109', + dest_city: 'Montréal-of-the-south!', + dest_state: 'Oñtario', + dest_zip: 'Postäl Zïps' ) response = stub_comms do - @gateway.purchase(50, card, :order_id => 1, - :billing_address => long_address) - end.check_request do |endpoint, data, headers| + @gateway.purchase(50, card, order_id: 1, + billing_address: long_address) + end.check_request do |_endpoint, data, _headers| assert_match(/456 Stréêt Name is Really Lo long_address) + billing_address: long_address) end - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/456 Stréêt Name is Really Lo nil, - :address2 => nil, - :city => nil, - :state => nil, - :zip => nil, - :email => nil, - :phone => nil, - :fax => nil + address1: nil, + address2: nil, + city: nil, + state: nil, + zip: nil, + email: nil, + phone: nil, + fax: nil } - response = @gateway.purchase(50, credit_card, :order_id => 1, :billing_address => address(address_options)) + response = @gateway.purchase(50, credit_card, order_id: 1, billing_address: address(address_options)) assert_success response end def test_dest_address billing_address = address( - :dest_zip => '90001', - :dest_address1 => '456 Main St.', - :dest_city => 'Somewhere', - :dest_state => 'CA', - :dest_name => 'Joan Smith', - :dest_phone => '(123) 456-7890', - :dest_country => 'US') - - response = stub_comms do - @gateway.purchase(50, credit_card, :order_id => 1, - :billing_address => billing_address) - end.check_request do |endpoint, data, headers| + dest_zip: '90001', + dest_address1: '456 Main St.', + dest_city: 'Somewhere', + dest_state: 'CA', + dest_name: 'Joan Smith', + dest_phone: '(123) 456-7890', + dest_country: 'US' + ) + + response = stub_comms do + @gateway.purchase(50, credit_card, order_id: 1, + billing_address: billing_address) + end.check_request do |_endpoint, data, _headers| assert_match(/90001/, data) assert_match(/456 Main St./, data) assert_match(/ 1, - :billing_address => billing_address.merge(:dest_country => 'BR')) - end.check_request do |endpoint, data, headers| + @gateway.purchase(50, credit_card, order_id: 1, + billing_address: billing_address.merge(dest_country: 'BR')) + end.check_request do |_endpoint, data, _headers| assert_match(//, data) assert_no_match(//, data) end.respond_with(successful_purchase_response) @@ -484,36 +679,170 @@ def test_successful_purchase_with_negative_stored_credentials_indicator def test_successful_purchase_with_stored_credentials stub_comms do @gateway.purchase(50, credit_card, @options.merge(@options_stored_credentials)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match %{#{@options_stored_credentials[:mit_msg_type]}}, data assert_match %{#{@options_stored_credentials[:mit_stored_credential_ind]}}, data assert_match %{#{@options_stored_credentials[:mit_submitted_transaction_id]}}, data end.respond_with(successful_purchase_response) end - def test_successful_purchase_with_normalized_stored_credentials - stub_comms do - @gateway.purchase(50, credit_card, @options.merge(@normalized_mit_stored_credential)) - end.check_request do |endpoint, data, headers| - assert_match %{MUSE}, data - assert_match %{Y}, data - assert_match %{abcdefg12345678}, data + def test_stored_credential_recurring_cit_initial + options = stored_credential_options(:cardholder, :recurring, :initial) + response = stub_comms do + @gateway.purchase(50, credit_card, options) + end.check_request do |_endpoint, data, _headers| + assert_match(/CSTOYCSTO}, data - assert_match %{Y}, data + def test_stored_credential_recurring_cit_used + credit_card.verification_value = nil + options = stored_credential_options(:cardholder, :recurring, id: 'abc123') + response = stub_comms do + @gateway.purchase(50, credit_card, options) + end.check_request do |_endpoint, data, _headers| + assert_match(/CRECYCSTOYMRECYabc123CSTOYCUSEYCSTOYMUSEYabc123CSTOYCINSYCSTOYMINSYabc123MRSB}, data assert_match %{Y}, data assert_match %{123456abcdef}, data @@ -524,10 +853,10 @@ def test_default_managed_billing response = stub_comms do assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do assert_deprecation_warning do - @gateway.add_customer_profile(credit_card, :managed_billing => {:start_date => '10-10-2014' }) + @gateway.add_customer_profile(credit_card, managed_billing: { start_date: '10-10-2014' }) end end - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/R/, data) assert_match(/IO/, data) assert_match(/10102014/, data) @@ -541,14 +870,15 @@ def test_managed_billing assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do assert_deprecation_warning do @gateway.add_customer_profile(credit_card, - :managed_billing => { - :start_date => '10-10-2014', - :end_date => '10-10-2015', - :max_dollar_value => 1500, - :max_transactions => 12}) + managed_billing: { + start_date: '10-10-2014', + end_date: '10-10-2015', + max_dollar_value: 1500, + max_transactions: 12 + }) end end - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/R/, data) assert_match(/IO/, data) assert_match(/10102014/, data) @@ -561,8 +891,8 @@ def test_managed_billing def test_dont_send_customer_data_by_default response = stub_comms do - @gateway.purchase(50, credit_card, :order_id => 1) - end.check_request do |endpoint, data, headers| + @gateway.purchase(50, credit_card, order_id: 1) + end.check_request do |_endpoint, data, _headers| assert_no_match(/K1C2N6/, data) assert_no_match(/456 My Street/, data) assert_no_match(/Apt 1/, data) @@ -573,8 +903,8 @@ def test_dont_send_customer_data_by_default def test_send_customer_data_when_customer_profiles_is_enabled @gateway.options[:customer_profiles] = true response = stub_comms do - @gateway.purchase(50, credit_card, :order_id => 1) - end.check_request do |endpoint, data, headers| + @gateway.purchase(50, credit_card, order_id: 1) + end.check_request do |_endpoint, data, _headers| assert_match(/A/, data) assert_match(/NO/, data) end.respond_with(successful_purchase_response) @@ -584,8 +914,8 @@ def test_send_customer_data_when_customer_profiles_is_enabled def test_send_customer_data_when_customer_ref_is_provided @gateway.options[:customer_profiles] = true response = stub_comms do - @gateway.purchase(50, credit_card, :order_id => 1, :customer_ref_num => @customer_ref_num) - end.check_request do |endpoint, data, headers| + @gateway.purchase(50, credit_card, order_id: 1, customer_ref_num: @customer_ref_num) + end.check_request do |_endpoint, data, _headers| assert_match(/ABC/, data) assert_match(/S/, data) assert_match(/NO/, data) @@ -593,11 +923,29 @@ def test_send_customer_data_when_customer_ref_is_provided assert_success response end + def test_send_card_indicators_when_provided_purchase + response = stub_comms do + @gateway.purchase(50, credit_card, order_id: 1, card_indicators: @options[:card_indicators]) + end.check_request do |_endpoint, data, _headers| + assert_match(/y/, data) + end.respond_with(successful_purchase_response) + assert_success response + end + + def test_send_card_indicators_when_provided_authorize + response = stub_comms do + @gateway.authorize(50, credit_card, order_id: 1, card_indicators: @options[:card_indicators]) + end.check_request do |_endpoint, data, _headers| + assert_match(/y/, data) + end.respond_with(successful_purchase_response) + assert_success response + end + def test_dont_send_customer_profile_from_order_ind_for_profile_purchase @gateway.options[:customer_profiles] = true response = stub_comms do - @gateway.purchase(50, nil, :order_id => 1, :customer_ref_num => @customer_ref_num) - end.check_request do |endpoint, data, headers| + @gateway.purchase(50, nil, order_id: 1, customer_ref_num: @customer_ref_num) + end.check_request do |_endpoint, data, _headers| assert_no_match(//, data) end.respond_with(successful_purchase_response) assert_success response @@ -606,8 +954,8 @@ def test_dont_send_customer_profile_from_order_ind_for_profile_purchase def test_dont_send_customer_profile_from_order_ind_for_profile_authorize @gateway.options[:customer_profiles] = true response = stub_comms do - @gateway.authorize(50, nil, :order_id => 1, :customer_ref_num => @customer_ref_num) - end.check_request do |endpoint, data, headers| + @gateway.authorize(50, nil, order_id: 1, customer_ref_num: @customer_ref_num) + end.check_request do |_endpoint, data, _headers| assert_no_match(//, data) end.respond_with(successful_purchase_response) assert_success response @@ -616,8 +964,8 @@ def test_dont_send_customer_profile_from_order_ind_for_profile_authorize def test_currency_code_and_exponent_are_set_for_profile_purchase @gateway.options[:customer_profiles] = true response = stub_comms do - @gateway.purchase(50, nil, :order_id => 1, :customer_ref_num => @customer_ref_num) - end.check_request do |endpoint, data, headers| + @gateway.purchase(50, nil, order_id: 1, customer_ref_num: @customer_ref_num) + end.check_request do |_endpoint, data, _headers| assert_match(/ABC/, data) assert_match(/124/, data) assert_match(/2/, data) @@ -628,8 +976,8 @@ def test_currency_code_and_exponent_are_set_for_profile_purchase def test_currency_code_and_exponent_are_set_for_profile_authorizations @gateway.options[:customer_profiles] = true response = stub_comms do - @gateway.authorize(50, nil, :order_id => 1, :customer_ref_num => @customer_ref_num) - end.check_request do |endpoint, data, headers| + @gateway.authorize(50, nil, order_id: 1, customer_ref_num: @customer_ref_num) + end.check_request do |_endpoint, data, _headers| assert_match(/ABC/, data) assert_match(/124/, data) assert_match(/2/, data) @@ -637,18 +985,49 @@ def test_currency_code_and_exponent_are_set_for_profile_authorizations assert_success response end - # K1C2N6 - # 456 My Street - # Apt 1 - # Ottawa - # ON - # 5555555555 - # Longbob Longsen - # CA + def test_successful_authorize_with_echeck + @gateway.expects(:ssl_post).returns(successful_authorize_with_echeck_response) + + assert response = @gateway.authorize(50, @echeck, order_id: '2') + assert_instance_of Response, response + assert_equal 'Approved', response.message + assert_success response + assert_equal '5F8E8D2B077217F3EF1ACD3B61610E4CD12954A3;2', response.authorization + end + + def test_failed_authorize_with_echeck + @gateway.expects(:ssl_post).returns(failed_echeck_for_invalid_amount_response) + + assert response = @gateway.authorize(-1, @echeck, order_id: '9baedc697f2cf06457de78') + assert_instance_of Response, response + assert_failure response + assert_equal 'Error validating amount. Must be numeric, equal to zero or greater [-1]', response.message + assert_equal '885', response.params['proc_status'] + end + + def test_successful_refund_with_echeck + @gateway.expects(:ssl_post).returns(successful_refund_with_echeck_response) + + assert response = @gateway.refund(50, '1;2', @options) + assert_instance_of Response, response + assert_success response + assert_equal '1', response.params['approval_status'] + end + + def test_failed_refund_with_echeck + @gateway.expects(:ssl_post).returns(failed_refund_with_echeck_response) + + assert response = @gateway.refund(50, '1;2', @options) + assert_instance_of Response, response + assert_failure response + assert_equal 'Refund Transactions By TxRefNum Are Only Valid When The Original Transaction Was An AUTH Or AUTH CAPTURE.', response.message + assert_equal '9806', response.params['proc_status'] + end + def test_send_address_details_for_united_states response = stub_comms do - @gateway.purchase(50, credit_card, :order_id => 1, :billing_address => address) - end.check_request do |endpoint, data, headers| + @gateway.purchase(50, credit_card, order_id: 1, billing_address: address) + end.check_request do |_endpoint, data, _headers| assert_match(/K1C2N6/, data) assert_match(/456 My Street/, data) assert_match(/Apt 1/, data) @@ -665,8 +1044,8 @@ def test_send_address_details_for_united_states def test_dont_send_address_details_for_germany response = stub_comms do - @gateway.purchase(50, credit_card, :order_id => 1, :billing_address => address(:country => 'DE')) - end.check_request do |endpoint, data, headers| + @gateway.purchase(50, credit_card, order_id: 1, billing_address: address(country: 'DE')) + end.check_request do |_endpoint, data, _headers| assert_no_match(/K1C2N6/, data) assert_no_match(/456 My Street/, data) assert_no_match(/Apt 1/, data) @@ -681,8 +1060,8 @@ def test_dont_send_address_details_for_germany def test_allow_sending_avs_parts_when_no_country_specified response = stub_comms do - @gateway.purchase(50, credit_card, :order_id => 1, :billing_address => address(:country => nil)) - end.check_request do |endpoint, data, headers| + @gateway.purchase(50, credit_card, order_id: 1, billing_address: address(country: nil)) + end.check_request do |_endpoint, data, _headers| assert_match(/K1C2N6/, data) assert_match(/456 My Street/, data) assert_match(/Apt 1/, data) @@ -697,9 +1076,9 @@ def test_allow_sending_avs_parts_when_no_country_specified def test_american_requests_adhere_to_xml_schema response = stub_comms do - @gateway.purchase(50, credit_card, :order_id => 1, :billing_address => address) - end.check_request do |endpoint, data, headers| - schema_file = File.read("#{File.dirname(__FILE__)}/../../schema/orbital/Request_PTI77.xsd") + @gateway.purchase(50, credit_card, order_id: 1, billing_address: address) + end.check_request do |_endpoint, data, _headers| + schema_file = File.read("#{File.dirname(__FILE__)}/../../schema/orbital/Request_PTI83.xsd") doc = Nokogiri::XML(data) xsd = Nokogiri::XML::Schema(schema_file) assert xsd.valid?(doc), 'Request does not adhere to DTD' @@ -709,9 +1088,9 @@ def test_american_requests_adhere_to_xml_schema def test_german_requests_adhere_to_xml_schema response = stub_comms do - @gateway.purchase(50, credit_card, :order_id => 1, :billing_address => address(:country => 'DE')) - end.check_request do |endpoint, data, headers| - schema_file = File.read("#{File.dirname(__FILE__)}/../../schema/orbital/Request_PTI77.xsd") + @gateway.purchase(50, credit_card, order_id: 1, billing_address: address(country: 'DE')) + end.check_request do |_endpoint, data, _headers| + schema_file = File.read("#{File.dirname(__FILE__)}/../../schema/orbital/Request_PTI83.xsd") doc = Nokogiri::XML(data) xsd = Nokogiri::XML::Schema(schema_file) assert xsd.valid?(doc), 'Request does not adhere to DTD' @@ -724,7 +1103,7 @@ def test_add_customer_profile assert_deprecation_warning do @gateway.add_customer_profile(credit_card) end - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/C/, data) assert_match(/Longbob Longsen/, data) end.respond_with(successful_profile_response) @@ -734,9 +1113,9 @@ def test_add_customer_profile def test_add_customer_profile_with_email response = stub_comms do assert_deprecation_warning do - @gateway.add_customer_profile(credit_card, { :billing_address => { :email => 'xiaobozzz@example.com' } }) + @gateway.add_customer_profile(credit_card, { billing_address: { email: 'xiaobozzz@example.com' } }) end - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/C/, data) assert_match(/xiaobozzz@example.com/, data) end.respond_with(successful_profile_response) @@ -748,7 +1127,7 @@ def test_update_customer_profile assert_deprecation_warning do @gateway.update_customer_profile(credit_card) end - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/U/, data) assert_match(/Longbob Longsen/, data) end.respond_with(successful_profile_response) @@ -760,7 +1139,7 @@ def test_retrieve_customer_profile assert_deprecation_warning do @gateway.retrieve_customer_profile(@customer_ref_num) end - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_no_match(/Longbob Longsen/, data) assert_match(/R/, data) assert_match(/ABC/, data) @@ -773,7 +1152,7 @@ def test_delete_customer_profile assert_deprecation_warning do @gateway.delete_customer_profile(@customer_ref_num) end - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_no_match(/Longbob Longsen/, data) assert_match(/D/, data) assert_match(/ABC/, data) @@ -785,7 +1164,7 @@ def test_attempts_seconday_url @gateway.expects(:ssl_post).with(OrbitalGateway.test_url, anything, anything).raises(ActiveMerchant::ConnectionError.new('message', nil)) @gateway.expects(:ssl_post).with(OrbitalGateway.secondary_test_url, anything, anything).returns(successful_purchase_response) - response = @gateway.purchase(50, credit_card, :order_id => '1') + response = @gateway.purchase(50, credit_card, order_id: '1') assert_success response end @@ -793,8 +1172,8 @@ def test_attempts_seconday_url def test_headers_when_retry_logic_is_enabled @gateway.options[:retry_logic] = true response = stub_comms do - @gateway.purchase(50, credit_card, :order_id => 1, :trace_number => 1) - end.check_request do |endpoint, data, headers| + @gateway.purchase(50, credit_card, order_id: 1, trace_number: 1) + end.check_request do |_endpoint, _data, headers| assert_equal('1', headers['Trace-number']) assert_equal('merchant_id', headers['Merchant-Id']) end.respond_with(successful_purchase_response) @@ -804,19 +1183,67 @@ def test_headers_when_retry_logic_is_enabled def test_retry_logic_not_enabled @gateway.options[:retry_logic] = false response = stub_comms do - @gateway.purchase(50, credit_card, :order_id => 1, :trace_number => 1) - end.check_request do |endpoint, data, headers| + @gateway.purchase(50, credit_card, order_id: 1, trace_number: 1) + end.check_request do |_endpoint, _data, headers| + assert_equal(false, headers.has_key?('Trace-number')) + assert_equal(false, headers.has_key?('Merchant-Id')) + end.respond_with(successful_purchase_response) + assert_success response + end + + def test_headers_when_retry_logic_param_exists + response = stub_comms do + @gateway.purchase(50, credit_card, order_id: 1, retry_logic: 'true', trace_number: 1) + end.check_request do |_endpoint, _data, headers| + assert_equal('1', headers['Trace-number']) + assert_equal('merchant_id', headers['Merchant-Id']) + end.respond_with(successful_purchase_response) + assert_success response + end + + def test_retry_logic_when_param_nonexistant + response = stub_comms do + @gateway.purchase(50, credit_card, order_id: 1, trace_number: 1) + end.check_request do |_endpoint, _data, headers| assert_equal(false, headers.has_key?('Trace-number')) assert_equal(false, headers.has_key?('Merchant-Id')) end.respond_with(successful_purchase_response) assert_success response end + def test_headers_when_trace_number_nonexistant + response = stub_comms do + @gateway.purchase(50, credit_card, order_id: 1, retry_logic: 'true') + end.check_request do |_endpoint, _data, headers| + assert_equal(nil, headers['Trace-number']) + assert_equal(nil, headers['Merchant-Id']) + end.respond_with(successful_purchase_response) + assert_success response + end + + def test_payment_delivery_when_param_correct + response = stub_comms do + @gateway.purchase(50, @echeck, order_id: 1, payment_delivery: 'A') + end.check_request do |_endpoint, data, _headers| + assert_match(/A/, data) + end.respond_with(successful_purchase_response) + assert_success response + end + + def test_payment_delivery_when_no_payment_delivery_param + response = stub_comms do + @gateway.purchase(50, @echeck, order_id: 1) + end.check_request do |_endpoint, data, _headers| + assert_match(/B/, data) + end.respond_with(successful_purchase_response) + assert_success response + end + ActiveMerchant::Billing::OrbitalGateway::APPROVED.each do |resp_code| define_method "test_approval_response_code_#{resp_code}" do @gateway.expects(:ssl_post).returns(successful_purchase_response(resp_code)) - assert response = @gateway.purchase(50, credit_card, :order_id => '1') + assert response = @gateway.purchase(50, credit_card, order_id: '1') assert_instance_of Response, response assert_success response end @@ -825,7 +1252,7 @@ def test_retry_logic_not_enabled def test_account_num_is_removed_from_response @gateway.expects(:ssl_post).returns(successful_purchase_response) - response = @gateway.purchase(50, credit_card, :order_id => '1') + response = @gateway.purchase(50, credit_card, order_id: '1') assert_instance_of Response, response assert_success response assert_nil response.params['account_num'] @@ -838,7 +1265,7 @@ def test_cc_account_num_is_removed_from_response assert_deprecation_warning do response = @gateway.add_customer_profile(credit_card, - :billing_address => address) + billing_address: address) end assert_instance_of Response, response @@ -883,7 +1310,7 @@ def test_cvv_indicator_present_for_visas_with_cvvs def test_cvv_indicator_absent_for_recurring stub_comms do - @gateway.purchase(50, credit_card(nil, {verification_value: nil}), @options) + @gateway.purchase(50, credit_card(nil, { verification_value: nil }), @options) end.check_request do |_endpoint, data, _headers| assert_no_match %r{}, data assert_no_match %r{}, data @@ -897,6 +1324,16 @@ def test_scrub 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(resp_code = '00') %Q{AC700000000000001VI411111111111111114A5398CF9B87744GG84A1D30F2F2321C66249416101#{resp_code}H N091922Approved00YN144951} end @@ -913,63 +1350,91 @@ def successful_void_response '700000208761001250FB1C41FEC9D016FF0BEBAD0884B174AD0853B010001192013172049' end + def successful_purchase_with_echeck_response + 'AC041756001EC9baedc697f2cf06457de785F8E8BEE7299FD339A38F70CFF6E5D010EF55498201003 123456Approved102 030414' + end + + def successful_force_capture_with_echeck_response + 'FC041756001EC2930847bc732eb4e8102cf5F8ED3D950A43BD63369845D5385B6354C3654B420100Approved and CompletedAPPROVAL 081105' + end + + def failed_echeck_for_invalid_routing_response + '888Invalid ECP Account Route: []. The field is missing, invalid, or it has exceeded the max length of: [9].' + end + + def failed_echeck_for_invalid_amount_response + '885Error validating amount. Must be numeric, equal to zero or greater [-1]' + end + + def successful_authorize_with_echeck_response + 'A041756001EC25F8E8D2B077217F3EF1ACD3B61610E4CD12954A3001003 123456Approved102 030931' + end + + def successful_refund_with_echeck_response + 'R041756001ECXXXXX3004b67774a1bbfe1387f5e1855F8E8D8A542ED5CC24449BC4CECD337BE05754C2201031106' + end + + def failed_refund_with_echeck_response + '9806Refund Transactions By TxRefNum Are Only Valid When The Original Transaction Was An AUTH Or AUTH CAPTURE.' + end + def pre_scrubbed - <<-EOS -opening connection to orbitalvar1.paymentech.net:443... -opened -starting SSL for orbitalvar1.paymentech.net:443... -SSL established -<- "POST /authorize HTTP/1.1\r\nContent-Type: application/PTI71\r\nMime-Version: 1.1\r\nContent-Transfer-Encoding: text\r\nRequest-Number: 1\r\nDocument-Type: Request\r\nInterface-Version: Ruby|ActiveMerchant|Proprietary Gateway\r\nContent-Length: 964\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: orbitalvar1.paymentech.net\r\n\r\n" -<- "\n\n \n T16WAYSACT\n zbp8X1ykGZ\n EC\n AC\n 000001\n 041756\n 001\n 4112344112344113\n 0917\n 840\n 2\n 1\n 123\n K1C2N6\n 456 My Street\n Apt 1\n Ottawa\n ON\n 5555555555\n Longbob Longsen\n CA\n b141cf3ce2a442732e1906\n 100\n \n\n" --> "HTTP/1.1 200 OK\r\n" --> "Date: Thu, 02 Jun 2016 07:04:44 GMT\r\n" --> "content-type: text/plain; charset=ISO-8859-1\r\n" --> "content-length: 1200\r\n" --> "content-transfer-encoding: text/xml\r\n" --> "document-type: Response\r\n" --> "mime-version: 1.0\r\n" --> "Connection: close\r\n" --> "\r\n" -reading 1200 bytes... --> "AC041756001VI4112344112344113b141cf3ce2a442732e1906574FDA8CECFBC3DA073FF74A7E6DE4E0BA87545B201007 Mtst595Approved100IUM030444" -read 1200 bytes -Conn close - EOS + <<~REQUEST + opening connection to orbitalvar1.paymentech.net:443... + opened + starting SSL for orbitalvar1.paymentech.net:443... + SSL established + <- "POST /authorize HTTP/1.1\r\nContent-Type: application/PTI71\r\nMime-Version: 1.1\r\nContent-Transfer-Encoding: text\r\nRequest-Number: 1\r\nDocument-Type: Request\r\nInterface-Version: Ruby|ActiveMerchant|Proprietary Gateway\r\nContent-Length: 964\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: orbitalvar1.paymentech.net\r\n\r\n" + <- "\n\n \n T16WAYSACT\n zbp8X1ykGZ\n EC\n AC\n 000001\n 041756\n 001\n 4112344112344113\n 0917\n 840\n 2\n 1\n 123\n K1C2N6\n 456 My Street\n Apt 1\n Ottawa\n ON\n 5555555555\n Longbob Longsen\n CA\n b141cf3ce2a442732e1906\n 100\n \n\n" + -> "HTTP/1.1 200 OK\r\n" + -> "Date: Thu, 02 Jun 2016 07:04:44 GMT\r\n" + -> "content-type: text/plain; charset=ISO-8859-1\r\n" + -> "content-length: 1200\r\n" + -> "content-transfer-encoding: text/xml\r\n" + -> "document-type: Response\r\n" + -> "mime-version: 1.0\r\n" + -> "Connection: close\r\n" + -> "\r\n" + reading 1200 bytes... + -> "AC041756001VI4112344112344113b141cf3ce2a442732e1906574FDA8CECFBC3DA073FF74A7E6DE4E0BA87545B201007 Mtst595Approved100IUM030444" + read 1200 bytes + Conn close + REQUEST end def post_scrubbed - <<-EOS -opening connection to orbitalvar1.paymentech.net:443... -opened -starting SSL for orbitalvar1.paymentech.net:443... -SSL established -<- "POST /authorize HTTP/1.1\r\nContent-Type: application/PTI71\r\nMime-Version: 1.1\r\nContent-Transfer-Encoding: text\r\nRequest-Number: 1\r\nDocument-Type: Request\r\nInterface-Version: Ruby|ActiveMerchant|Proprietary Gateway\r\nContent-Length: 964\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: orbitalvar1.paymentech.net\r\n\r\n" -<- "\n\n \n [FILTERED]\n [FILTERED]\n EC\n AC\n 000001\n [FILTERED]\n 001\n [FILTERED]\n 0917\n 840\n 2\n 1\n [FILTERED]\n K1C2N6\n 456 My Street\n Apt 1\n Ottawa\n ON\n 5555555555\n Longbob Longsen\n CA\n b141cf3ce2a442732e1906\n 100\n \n\n" --> "HTTP/1.1 200 OK\r\n" --> "Date: Thu, 02 Jun 2016 07:04:44 GMT\r\n" --> "content-type: text/plain; charset=ISO-8859-1\r\n" --> "content-length: 1200\r\n" --> "content-transfer-encoding: text/xml\r\n" --> "document-type: Response\r\n" --> "mime-version: 1.0\r\n" --> "Connection: close\r\n" --> "\r\n" -reading 1200 bytes... --> "AC[FILTERED]001VI[FILTERED]b141cf3ce2a442732e1906574FDA8CECFBC3DA073FF74A7E6DE4E0BA87545B201007 Mtst595Approved100IUM030444" -read 1200 bytes -Conn close - EOS + <<~REQUEST + opening connection to orbitalvar1.paymentech.net:443... + opened + starting SSL for orbitalvar1.paymentech.net:443... + SSL established + <- "POST /authorize HTTP/1.1\r\nContent-Type: application/PTI71\r\nMime-Version: 1.1\r\nContent-Transfer-Encoding: text\r\nRequest-Number: 1\r\nDocument-Type: Request\r\nInterface-Version: Ruby|ActiveMerchant|Proprietary Gateway\r\nContent-Length: 964\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: orbitalvar1.paymentech.net\r\n\r\n" + <- "\n\n \n [FILTERED]\n [FILTERED]\n EC\n AC\n 000001\n [FILTERED]\n 001\n [FILTERED]\n 0917\n 840\n 2\n 1\n [FILTERED]\n K1C2N6\n 456 My Street\n Apt 1\n Ottawa\n ON\n 5555555555\n Longbob Longsen\n CA\n b141cf3ce2a442732e1906\n 100\n \n\n" + -> "HTTP/1.1 200 OK\r\n" + -> "Date: Thu, 02 Jun 2016 07:04:44 GMT\r\n" + -> "content-type: text/plain; charset=ISO-8859-1\r\n" + -> "content-length: 1200\r\n" + -> "content-transfer-encoding: text/xml\r\n" + -> "document-type: Response\r\n" + -> "mime-version: 1.0\r\n" + -> "Connection: close\r\n" + -> "\r\n" + reading 1200 bytes... + -> "AC[FILTERED]001VI[FILTERED]b141cf3ce2a442732e1906574FDA8CECFBC3DA073FF74A7E6DE4E0BA87545B201007 Mtst595Approved100IUM030444" + read 1200 bytes + Conn close + REQUEST end def pre_scrubbed_profile - <<-EOS -000001253997LONGBOB LONGSEN109273631CREATE0Profile Request Processed456 MY STREETAPT 1OTTAWAONK1C2N65555555555CANOCCA41123441123441130919 - EOS + <<~REQUEST + 000001253997LONGBOB LONGSEN109273631CREATE0Profile Request Processed456 MY STREETAPT 1OTTAWAONK1C2N65555555555CANOCCA41123441123441130919 + REQUEST end def post_scrubbed_profile - <<-EOS -000001[FILTERED]LONGBOB LONGSEN109273631CREATE0Profile Request Processed456 MY STREETAPT 1OTTAWAONK1C2N65555555555CANOCCA[FILTERED]0919 - EOS + <<~REQUEST + 000001[FILTERED]LONGBOB LONGSEN109273631CREATE0Profile Request Processed456 MY STREETAPT 1OTTAWAONK1C2N65555555555CANOCCA[FILTERED]0919 + REQUEST end end diff --git a/test/unit/gateways/pac_net_raven_test.rb b/test/unit/gateways/pac_net_raven_test.rb index 79530834e28..e98214fe6bd 100644 --- a/test/unit/gateways/pac_net_raven_test.rb +++ b/test/unit/gateways/pac_net_raven_test.rb @@ -158,29 +158,29 @@ def test_failed_void def test_argument_error_prn exception = assert_raises(ArgumentError) { - PacNetRavenGateway.new(:user => 'user', :secret => 'secret') + PacNetRavenGateway.new(user: 'user', secret: 'secret') } assert_equal 'Missing required parameter: prn', exception.message end def test_argument_error_user exception = assert_raises(ArgumentError) { - PacNetRavenGateway.new(:secret => 'secret', :prn => 123456) + PacNetRavenGateway.new(secret: 'secret', prn: 123456) } assert_equal 'Missing required parameter: user', exception.message end def test_argument_error_secret exception = assert_raises(ArgumentError) { - PacNetRavenGateway.new(:user => 'user', :prn => 123456) + PacNetRavenGateway.new(user: 'user', prn: 123456) } assert_equal 'Missing required parameter: secret', exception.message end def test_add_address result = {} - @gateway.send(:add_address, result, :billing_address => {:address1 => 'Address 1', :address2 => 'Address 2', :zip => 'ZIP'}) - assert_equal ['BillingPostalCode', 'BillingStreetAddressLineFour', 'BillingStreetAddressLineOne'], result.stringify_keys.keys.sort + @gateway.send(:add_address, result, billing_address: { address1: 'Address 1', address2: 'Address 2', zip: 'ZIP' }) + assert_equal %w[BillingPostalCode BillingStreetAddressLineFour BillingStreetAddressLineOne], result.stringify_keys.keys.sort assert_equal 'ZIP', result['BillingPostalCode'] assert_equal 'Address 2', result['BillingStreetAddressLineFour'] assert_equal 'Address 1', result['BillingStreetAddressLineOne'] @@ -189,7 +189,7 @@ def test_add_address def test_add_creditcard result = {} @gateway.send(:add_creditcard, result, @credit_card) - assert_equal ['CVV2', 'CardNumber', 'Expiry'], result.stringify_keys.keys.sort + assert_equal %w[CVV2 CardNumber Expiry], result.stringify_keys.keys.sort assert_equal @credit_card.number, result['CardNumber'] assert_equal @gateway.send(:expdate, @credit_card), result['Expiry'] assert_equal @credit_card.verification_value, result['CVV2'] @@ -203,13 +203,13 @@ def test_add_currency_code_default def test_add_currency_code_from_options result = {} - @gateway.send(:add_currency_code, result, 100, {currency: 'CAN'}) + @gateway.send(:add_currency_code, result, 100, { currency: 'CAN' }) assert_equal 'CAN', result['Currency'] end def test_parse result = @gateway.send(:parse, 'key1=value1&key2=value2') - h = {'key1' => 'value1', 'key2' => 'value2'} + h = { 'key1' => 'value1', 'key2' => 'value2' } assert_equal h, result end @@ -308,45 +308,45 @@ def test_success def test_message_from_approved assert_equal 'This transaction has been approved', @gateway.send(:message_from, { 'Status' => 'Approved', - 'Message'=> nil + 'Message' => nil }) end def test_message_from_declined assert_equal 'This transaction has been declined', @gateway.send(:message_from, { 'Status' => 'Declined', - 'Message'=> nil + 'Message' => nil }) end def test_message_from_voided assert_equal 'This transaction has been voided', @gateway.send(:message_from, { 'Status' => 'Voided', - 'Message'=> nil + 'Message' => nil }) end def test_message_from_status assert_equal 'This is the message', @gateway.send(:message_from, { 'Status' => 'SomeStatus', - 'Message'=> 'This is the message' + 'Message' => 'This is the message' }) end def test_post_data - @gateway.stubs(:request_id => 'wouykiikdvqbwwxueppby') - @gateway.stubs(:timestamp => '2013-10-08T14:31:54.Z') + @gateway.stubs(request_id: 'wouykiikdvqbwwxueppby') + @gateway.stubs(timestamp: '2013-10-08T14:31:54.Z') assert_equal "PymtType=cc_preauth&RAPIVersion=2&UserName=user&Timestamp=2013-10-08T14%3A31%3A54.Z&RequestID=wouykiikdvqbwwxueppby&Signature=7794efc8c0d39f0983edc10f778e6143ba13531d&CardNumber=4242424242424242&Expiry=09#{@credit_card.year.to_s[-2..-1]}&CVV2=123&Currency=USD&BillingStreetAddressLineOne=Address+1&BillingStreetAddressLineFour=Address+2&BillingPostalCode=ZIP123", @gateway.send(:post_data, 'cc_preauth', { - 'CardNumber' => @credit_card.number, - 'Expiry' => @gateway.send(:expdate, @credit_card), - 'CVV2' => @credit_card.verification_value, - 'Currency' => 'USD', - 'BillingStreetAddressLineOne' => 'Address 1', - 'BillingStreetAddressLineFour' => 'Address 2', - 'BillingPostalCode' => 'ZIP123' - }) + 'CardNumber' => @credit_card.number, + 'Expiry' => @gateway.send(:expdate, @credit_card), + 'CVV2' => @credit_card.verification_value, + 'Currency' => 'USD', + 'BillingStreetAddressLineOne' => 'Address 1', + 'BillingStreetAddressLineFour' => 'Address 2', + 'BillingPostalCode' => 'ZIP123' + }) end def test_signature_for_cc_preauth_action @@ -356,9 +356,9 @@ def test_signature_for_cc_preauth_action 'RequestID' => 'wouykiikdvqbwwxueppby', 'PymtType' => 'cc_preauth' }, { - 'Amount' => 100, - 'Currency' => 'USD', - 'TrackingNumber' => '123456789' + 'Amount' => 100, + 'Currency' => 'USD', + 'TrackingNumber' => '123456789' }) end @@ -369,9 +369,9 @@ def test_signature_for_cc_settle_action 'RequestID' => 'wouykiikdvqbwwxueppby', 'PymtType' => 'cc_settle' }, { - 'Amount' => 100, - 'Currency' => 'USD', - 'TrackingNumber' => '123456789' + 'Amount' => 100, + 'Currency' => 'USD', + 'TrackingNumber' => '123456789' }) end @@ -382,9 +382,9 @@ def test_signature_for_cc_debit_action 'RequestID' => 'wouykiikdvqbwwxueppby', 'PymtType' => 'cc_debit' }, { - 'Amount' => 100, - 'Currency' => 'USD', - 'TrackingNumber' => '123456789' + 'Amount' => 100, + 'Currency' => 'USD', + 'TrackingNumber' => '123456789' }) end @@ -395,9 +395,9 @@ def test_signature_for_cc_refund_action 'RequestID' => 'wouykiikdvqbwwxueppby', 'PymtType' => 'cc_refund' }, { - 'Amount' => 100, - 'Currency' => 'USD', - 'TrackingNumber' => '123456789' + 'Amount' => 100, + 'Currency' => 'USD', + 'TrackingNumber' => '123456789' }) end @@ -407,9 +407,9 @@ def test_signature_for_void_action 'Timestamp' => '2013-10-08T14:31:54.Z', 'RequestID' => 'wouykiikdvqbwwxueppby' }, { - 'Amount' => 100, - 'Currency' => 'USD', - 'TrackingNumber' => '123456789' + 'Amount' => 100, + 'Currency' => 'USD', + 'TrackingNumber' => '123456789' }) end diff --git a/test/unit/gateways/pagarme_test.rb b/test/unit/gateways/pagarme_test.rb index 9319ad47a8c..b8a0a644db0 100644 --- a/test/unit/gateways/pagarme_test.rb +++ b/test/unit/gateways/pagarme_test.rb @@ -974,5 +974,4 @@ def failed_json_response } SUCCESS_RESPONSE end - end diff --git a/test/unit/gateways/pago_facil_test.rb b/test/unit/gateways/pago_facil_test.rb index cb75a847402..6d6e119997e 100644 --- a/test/unit/gateways/pago_facil_test.rb +++ b/test/unit/gateways/pago_facil_test.rb @@ -70,159 +70,153 @@ def test_invalid_json private def successful_purchase_response - {'WebServices_Transacciones'=> - {'transaccion'=> - {'autorizado'=>'1', - 'autorizacion'=>'305638', - 'transaccion'=>'S-PFE12S12I12568', - 'texto'=>'Transaction has been successful!-Approved', - 'mode'=>'R', - 'empresa'=>'Usuario Invitado', - 'TransIni'=>'15:33:18 pm 25/02/2014', - 'TransFin'=>'15:33:27 pm 25/02/2014', - 'param1'=>'', - 'param2'=>'', - 'param3'=>'', - 'param4'=>'', - 'param5'=>'', - 'TipoTC'=>'Visa', - 'data'=> - {'anyoExpiracion'=>'(2) **', - 'apellidos'=>'Reyes Garza', - 'calleyNumero'=>'Anatole France 311', - 'celular'=>'5550123456', - 'colonia'=>'Polanco', - 'cp'=>'11560', - 'cvt'=>'(3) ***', - 'email'=>'comprador@correo.com', - 'estado'=>'Distrito Federal', - 'idPedido'=>'1', - 'idServicio'=>'3', - 'idSucursal'=>'60f961360ca187d533d5adba7d969d6334771370', - 'idUsuario'=>'62ad6f592ecf2faa87ef2437ed85a4d175e73c58', - 'mesExpiracion'=>'(2) **', - 'monto'=>'1.00', - 'municipio'=>'Miguel Hidalgo', - 'nombre'=>'Juan', - 'numeroTarjeta'=>'(16) **** **** ****1111', - 'pais'=>'Mexico', - 'telefono'=>'5550220910', - 'transFechaHora'=>'1393363998', - 'bin'=>'(6) ***1'}, - 'dataVal'=> - {'idSucursal'=>'12', - 'cp'=>'11560', - 'nombre'=>'Juan', - 'apellidos'=>'Reyes Garza', - 'numeroTarjeta'=>'(16) **** **** ****1111', - 'cvt'=>'(3) ***', - 'monto'=>'1.00', - 'mesExpiracion'=>'(2) **', - 'anyoExpiracion'=>'(2) **', - 'idUsuario'=>'14', - 'source'=>'1', - 'idServicio'=>'3', - 'recurrente'=>'0', - 'plan'=>'NOR', - 'diferenciado'=>'00', - 'mensualidades'=>'00', - 'ip'=>'187.162.238.170', - 'httpUserAgent'=>'Ruby', - 'idPedido'=>'1', - 'tipoTarjeta'=>'Visa', - 'hashKeyCC'=>'e5be0afe08f125ec4f6f1251141c60df88d65eae', - 'idEmpresa'=>'12', - 'nombre_comercial'=>'Usuario Invitado', - 'transFechaHora'=>'1393363998', - 'noProcess'=>'', - 'noMail'=>'', - 'notaMail'=>'', - 'settingsTransaction'=> - {'noMontoMes'=>'0.00', - 'noTransaccionesDia'=>'0', - 'minTransaccionTc'=>'5', - 'tiempoDevolucion'=>'30', - 'sendPdfTransCliente'=>'1', - 'noMontoDia'=>'0.00', - 'noTransaccionesMes'=>'0'}, - 'email'=>'comprador@correo.com', - 'telefono'=>'5550220910', - 'celular'=>'5550123456', - 'calleyNumero'=>'Anatole France 311', - 'colonia'=>'Polanco', - 'municipio'=>'Miguel Hidalgo', - 'estado'=>'Distrito Federal', - 'pais'=>'Mexico', - 'idCaja'=>'', - 'paisDetectedIP'=>'MX', - 'qa'=>'1', - 'https'=>'on'}, - 'status'=>'success' - } - } - }.to_json + { 'WebServices_Transacciones' => + { 'transaccion' => + { 'autorizado' => '1', + 'autorizacion' => '305638', + 'transaccion' => 'S-PFE12S12I12568', + 'texto' => 'Transaction has been successful!-Approved', + 'mode' => 'R', + 'empresa' => 'Usuario Invitado', + 'TransIni' => '15:33:18 pm 25/02/2014', + 'TransFin' => '15:33:27 pm 25/02/2014', + 'param1' => '', + 'param2' => '', + 'param3' => '', + 'param4' => '', + 'param5' => '', + 'TipoTC' => 'Visa', + 'data' => + { 'anyoExpiracion' => '(2) **', + 'apellidos' => 'Reyes Garza', + 'calleyNumero' => 'Anatole France 311', + 'celular' => '5550123456', + 'colonia' => 'Polanco', + 'cp' => '11560', + 'cvt' => '(3) ***', + 'email' => 'comprador@correo.com', + 'estado' => 'Distrito Federal', + 'idPedido' => '1', + 'idServicio' => '3', + 'idSucursal' => '60f961360ca187d533d5adba7d969d6334771370', + 'idUsuario' => '62ad6f592ecf2faa87ef2437ed85a4d175e73c58', + 'mesExpiracion' => '(2) **', + 'monto' => '1.00', + 'municipio' => 'Miguel Hidalgo', + 'nombre' => 'Juan', + 'numeroTarjeta' => '(16) **** **** ****1111', + 'pais' => 'Mexico', + 'telefono' => '5550220910', + 'transFechaHora' => '1393363998', + 'bin' => '(6) ***1' }, + 'dataVal' => + { 'idSucursal' => '12', + 'cp' => '11560', + 'nombre' => 'Juan', + 'apellidos' => 'Reyes Garza', + 'numeroTarjeta' => '(16) **** **** ****1111', + 'cvt' => '(3) ***', + 'monto' => '1.00', + 'mesExpiracion' => '(2) **', + 'anyoExpiracion' => '(2) **', + 'idUsuario' => '14', + 'source' => '1', + 'idServicio' => '3', + 'recurrente' => '0', + 'plan' => 'NOR', + 'diferenciado' => '00', + 'mensualidades' => '00', + 'ip' => '187.162.238.170', + 'httpUserAgent' => 'Ruby', + 'idPedido' => '1', + 'tipoTarjeta' => 'Visa', + 'hashKeyCC' => 'e5be0afe08f125ec4f6f1251141c60df88d65eae', + 'idEmpresa' => '12', + 'nombre_comercial' => 'Usuario Invitado', + 'transFechaHora' => '1393363998', + 'noProcess' => '', + 'noMail' => '', + 'notaMail' => '', + 'settingsTransaction' => + { 'noMontoMes' => '0.00', + 'noTransaccionesDia' => '0', + 'minTransaccionTc' => '5', + 'tiempoDevolucion' => '30', + 'sendPdfTransCliente' => '1', + 'noMontoDia' => '0.00', + 'noTransaccionesMes' => '0' }, + 'email' => 'comprador@correo.com', + 'telefono' => '5550220910', + 'celular' => '5550123456', + 'calleyNumero' => 'Anatole France 311', + 'colonia' => 'Polanco', + 'municipio' => 'Miguel Hidalgo', + 'estado' => 'Distrito Federal', + 'pais' => 'Mexico', + 'idCaja' => '', + 'paisDetectedIP' => 'MX', + 'qa' => '1', + 'https' => 'on' }, + 'status' => 'success' } } }.to_json end def failed_purchase_response - {'WebServices_Transacciones'=> - {'transaccion'=> - {'autorizado'=>'0', - 'transaccion'=>'n/a', - 'autorizacion'=>'n/a', - 'texto'=>'Errores en los datos de entrada Validaciones', - 'error'=> - {'numeroTarjeta'=>"'1111111111111111' no es de una institucion permitida"}, - 'empresa'=>'Sin determinar', - 'TransIni'=>'16:10:20 pm 25/02/2014', - 'TransFin'=>'16:10:20 pm 25/02/2014', - 'param1'=>'', - 'param2'=>'', - 'param3'=>'', - 'param4'=>'', - 'param5'=>'', - 'TipoTC'=>'', - 'data'=> - {'anyoExpiracion'=>'(2) **', - 'apellidos'=>'Reyes Garza', - 'calleyNumero'=>'Anatole France 311', - 'celular'=>'5550123456', - 'colonia'=>'Polanco', - 'cp'=>'11560', - 'cvt'=>'(3) ***', - 'email'=>'comprador@correo.com', - 'estado'=>'Distrito Federal', - 'idPedido'=>'1', - 'idServicio'=>'3', - 'idSucursal'=>'60f961360ca187d533d5adba7d969d6334771370', - 'idUsuario'=>'62ad6f592ecf2faa87ef2437ed85a4d175e73c58', - 'mesExpiracion'=>'(2) **', - 'monto'=>'1.00', - 'municipio'=>'Miguel Hidalgo', - 'nombre'=>'Juan', - 'numeroTarjeta'=>'(16) **** **** ****1111', - 'pais'=>'Mexico', - 'telefono'=>'5550220910', - 'transFechaHora'=>'1393366220', - 'bin'=>'(6) ***1'}, - 'dataVal'=> - {'email'=>'comprador@correo.com', - 'telefono'=>'5550220910', - 'celular'=>'5550123456', - 'calleyNumero'=>'Anatole France 311', - 'colonia'=>'Polanco', - 'municipio'=>'Miguel Hidalgo', - 'estado'=>'Distrito Federal', - 'pais'=>'Mexico', - 'idCaja'=>'', - 'numeroTarjeta'=>'', - 'cvt'=>'', - 'anyoExpiracion'=>'', - 'mesExpiracion'=>'', - 'https'=>'on'}, - 'status'=>'success' - } - } - }.to_json + { 'WebServices_Transacciones' => + { 'transaccion' => + { 'autorizado' => '0', + 'transaccion' => 'n/a', + 'autorizacion' => 'n/a', + 'texto' => 'Errores en los datos de entrada Validaciones', + 'error' => + { 'numeroTarjeta' => "'1111111111111111' no es de una institucion permitida" }, + 'empresa' => 'Sin determinar', + 'TransIni' => '16:10:20 pm 25/02/2014', + 'TransFin' => '16:10:20 pm 25/02/2014', + 'param1' => '', + 'param2' => '', + 'param3' => '', + 'param4' => '', + 'param5' => '', + 'TipoTC' => '', + 'data' => + { 'anyoExpiracion' => '(2) **', + 'apellidos' => 'Reyes Garza', + 'calleyNumero' => 'Anatole France 311', + 'celular' => '5550123456', + 'colonia' => 'Polanco', + 'cp' => '11560', + 'cvt' => '(3) ***', + 'email' => 'comprador@correo.com', + 'estado' => 'Distrito Federal', + 'idPedido' => '1', + 'idServicio' => '3', + 'idSucursal' => '60f961360ca187d533d5adba7d969d6334771370', + 'idUsuario' => '62ad6f592ecf2faa87ef2437ed85a4d175e73c58', + 'mesExpiracion' => '(2) **', + 'monto' => '1.00', + 'municipio' => 'Miguel Hidalgo', + 'nombre' => 'Juan', + 'numeroTarjeta' => '(16) **** **** ****1111', + 'pais' => 'Mexico', + 'telefono' => '5550220910', + 'transFechaHora' => '1393366220', + 'bin' => '(6) ***1' }, + 'dataVal' => + { 'email' => 'comprador@correo.com', + 'telefono' => '5550220910', + 'celular' => '5550123456', + 'calleyNumero' => 'Anatole France 311', + 'colonia' => 'Polanco', + 'municipio' => 'Miguel Hidalgo', + 'estado' => 'Distrito Federal', + 'pais' => 'Mexico', + 'idCaja' => '', + 'numeroTarjeta' => '', + 'cvt' => '', + 'anyoExpiracion' => '', + 'mesExpiracion' => '', + 'https' => 'on' }, + 'status' => 'success' } } }.to_json end def invalid_json_response diff --git a/test/unit/gateways/pay_conex_test.rb b/test/unit/gateways/pay_conex_test.rb index 0269f29396d..867fc14df1d 100644 --- a/test/unit/gateways/pay_conex_test.rb +++ b/test/unit/gateways/pay_conex_test.rb @@ -140,7 +140,7 @@ def test_failed_store def test_card_present_purchase_passes_track_data stub_comms do @gateway.purchase(@amount, credit_card_with_track_data('4000100011112224')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/card_tracks/, data) end.respond_with(successful_card_present_purchase_response) end diff --git a/test/unit/gateways/pay_gate_xml_test.rb b/test/unit/gateways/pay_gate_xml_test.rb index 157cd2bd89b..39ef9455139 100644 --- a/test/unit/gateways/pay_gate_xml_test.rb +++ b/test/unit/gateways/pay_gate_xml_test.rb @@ -10,11 +10,11 @@ def setup # May need to generate a unique order id as server responds with duplicate order detected @options = { - :order_id => Time.now.getutc, - :billing_address => address, - :email => 'john.doe@example.com', - :ip => '127.0.0.1', - :description => 'Store Purchase', + order_id: Time.now.getutc, + billing_address: address, + email: 'john.doe@example.com', + ip: '127.0.0.1', + description: 'Store Purchase' } end @@ -101,5 +101,4 @@ def successful_refund_response ENDOFXML end - end diff --git a/test/unit/gateways/pay_hub_test.rb b/test/unit/gateways/pay_hub_test.rb index 0226cea3ec0..3f8317e5d75 100644 --- a/test/unit/gateways/pay_hub_test.rb +++ b/test/unit/gateways/pay_hub_test.rb @@ -137,7 +137,7 @@ def test_expired_card end def test_card_declined - ['05', '61', '62', '65', '93'].each do |error_code| + %w[05 61 62 65 93].each do |error_code| @gateway.expects(:ssl_request).returns(response_for_error_codes(error_code)) response = @gateway.purchase(@amount, @credit_card, @options) @@ -147,7 +147,7 @@ def test_card_declined end def test_call_issuer - ['01', '02'].each do |error_code| + %w[01 02].each do |error_code| @gateway.expects(:ssl_request).returns(response_for_error_codes(error_code)) response = @gateway.purchase(@amount, @credit_card, @options) @@ -157,7 +157,7 @@ def test_call_issuer end def test_pickup_card - ['04', '07', '41', '43'].each do |error_code| + %w[04 07 41 43].each do |error_code| @gateway.expects(:ssl_request).returns(response_for_error_codes(error_code)) response = @gateway.purchase(@amount, @credit_card, @options) @@ -190,7 +190,7 @@ def test_cvv_codes def test_unsuccessful_request @gateway.expects(:ssl_request).returns(failed_purchase_or_authorize_response) - @gateway.options.merge!({:mode => 'live', :test => false}) + @gateway.options.merge!({ mode: 'live', test: false }) assert response = @gateway.purchase(@amount, @credit_card, @options) assert_failure response @@ -200,7 +200,7 @@ def test_unsuccessful_request def test_unsuccessful_authorize @gateway.expects(:ssl_request).returns(failed_purchase_or_authorize_response) - @gateway.options.merge!({:mode => 'live', :test => false}) + @gateway.options.merge!({ mode: 'live', test: false }) response = @gateway.authorize(@amount, @credit_card, @options) assert_failure response diff --git a/test/unit/gateways/pay_junction_test.rb b/test/unit/gateways/pay_junction_test.rb index 16a3139be79..045f2221ab2 100644 --- a/test/unit/gateways/pay_junction_test.rb +++ b/test/unit/gateways/pay_junction_test.rb @@ -8,14 +8,14 @@ def setup Base.mode = :test @gateway = PayJunctionGateway.new( - :login => 'pj-ql-01', - :password => 'pj-ql-01p' - ) + login: 'pj-ql-01', + password: 'pj-ql-01p' + ) @credit_card = credit_card @options = { - :billing_address => address, - :description => 'Test purchase' + billing_address: address, + description: 'Test purchase' } @amount = 100 end @@ -23,16 +23,16 @@ def setup def test_detect_test_credentials_when_in_production Base.mode = :production - live_gw = PayJunctionGateway.new( - :login => 'l', - :password => 'p' - ) + live_gw = PayJunctionGateway.new( + login: 'l', + password: 'p' + ) assert_false live_gw.test? test_gw = PayJunctionGateway.new( - :login => 'pj-ql-01', - :password => 'pj-ql-01p' - ) + login: 'pj-ql-01', + password: 'pj-ql-01p' + ) assert test_gw.test? end @@ -84,7 +84,7 @@ def test_add_creditcard_with_track_data @credit_card.track_data = 'Tracking data' 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 'dc_track=Tracking+data', data assert_no_match(/dc_name=/, data) assert_no_match(/dc_number=/, data) @@ -97,108 +97,108 @@ def test_add_creditcard_with_track_data private def successful_authorization_response - <<-RESPONSE -dc_merchant_name=PayJunction - (demo)dc_merchant_address=3 W. Carrillodc_merchant_city=Santa Barbaradc_merchant_state=CAdc_merchant_zip=93101dc_merchant_phone=800-601-0230dc_device_id=1174dc_transaction_date=2007-11-28 19:22:33.791634dc_transaction_action=chargedc_approval_code=TAS193dc_response_code=00dc_response_message=APPROVAL TAS193 dc_transaction_id=3144302dc_posture=holddc_invoice_number=9f76c4e4bd66a36dc5aeb4bd7b3a02fadc_notes=--START QUICK-LINK DEBUG-- -----Vars Received---- -dc_expiration_month => * -dc_expiration_year => * -dc_invoice => 9f76c4e4bd66a36dc5aeb4bd7b3a02fa -dc_logon => pj-ql-01 -dc_name => Cody Fauser -dc_number => * -dc_password => * -dc_transaction_amount => 4.00 -dc_transaction_type => AUTHORIZATION -dc_verification_number => * -dc_version => 1.2 -----End Vars---- - -----Start Response Sent---- -dc_merchant_name=PayJunction - (demo) -dc_merchant_address=3 W. Carrillo -dc_merchant_city=Santa Barbara -dc_merchant_state=CA -dc_merchant_zip=93101 -dc_merchant_phone=800-601-0230 -dc_device_id=1174 -dc_transaction_date=2007-11-28 19:22:33.791634 -dc_transaction_action=charge -dc_approval_code=TAS193 -dc_response_code=00 -dc_response_message=APPROVAL TAS193 -dc_transaction_id=3144302 -dc_posture=hold -dc_invoice_number=9f76c4e4bd66a36dc5aeb4bd7b3a02fa -dc_notes=null -dc_card_name=cody fauser -dc_card_brand=VSA -dc_card_exp=XX/XX -dc_card_number=XXXX-XXXX-XXXX-3344 -dc_card_address= -dc_card_city= -dc_card_zipcode= -dc_card_state= -dc_card_country= -dc_base_amount=4.00 -dc_tax_amount=0.00 -dc_capture_amount=4.00 -dc_cashback_amount=0.00 -dc_shipping_amount=0.00 -----End Response Sent---- -dc_card_name=cody fauserdc_card_brand=VSAdc_card_exp=XX/XXdc_card_number=XXXX-XXXX-XXXX-3344dc_card_address=dc_card_city=dc_card_zipcode=dc_card_state=dc_card_country=dc_base_amount=4.00dc_tax_amount=0.00dc_capture_amount=4.00dc_cashback_amount=0.00dc_shipping_amount=0.00 + <<~RESPONSE + dc_merchant_name=PayJunction - (demo)dc_merchant_address=3 W. Carrillodc_merchant_city=Santa Barbaradc_merchant_state=CAdc_merchant_zip=93101dc_merchant_phone=800-601-0230dc_device_id=1174dc_transaction_date=2007-11-28 19:22:33.791634dc_transaction_action=chargedc_approval_code=TAS193dc_response_code=00dc_response_message=APPROVAL TAS193 dc_transaction_id=3144302dc_posture=holddc_invoice_number=9f76c4e4bd66a36dc5aeb4bd7b3a02fadc_notes=--START QUICK-LINK DEBUG-- + ----Vars Received---- + dc_expiration_month => * + dc_expiration_year => * + dc_invoice => 9f76c4e4bd66a36dc5aeb4bd7b3a02fa + dc_logon => pj-ql-01 + dc_name => Cody Fauser + dc_number => * + dc_password => * + dc_transaction_amount => 4.00 + dc_transaction_type => AUTHORIZATION + dc_verification_number => * + dc_version => 1.2 + ----End Vars---- + + ----Start Response Sent---- + dc_merchant_name=PayJunction - (demo) + dc_merchant_address=3 W. Carrillo + dc_merchant_city=Santa Barbara + dc_merchant_state=CA + dc_merchant_zip=93101 + dc_merchant_phone=800-601-0230 + dc_device_id=1174 + dc_transaction_date=2007-11-28 19:22:33.791634 + dc_transaction_action=charge + dc_approval_code=TAS193 + dc_response_code=00 + dc_response_message=APPROVAL TAS193 + dc_transaction_id=3144302 + dc_posture=hold + dc_invoice_number=9f76c4e4bd66a36dc5aeb4bd7b3a02fa + dc_notes=null + dc_card_name=cody fauser + dc_card_brand=VSA + dc_card_exp=XX/XX + dc_card_number=XXXX-XXXX-XXXX-3344 + dc_card_address= + dc_card_city= + dc_card_zipcode= + dc_card_state= + dc_card_country= + dc_base_amount=4.00 + dc_tax_amount=0.00 + dc_capture_amount=4.00 + dc_cashback_amount=0.00 + dc_shipping_amount=0.00 + ----End Response Sent---- + dc_card_name=cody fauserdc_card_brand=VSAdc_card_exp=XX/XXdc_card_number=XXXX-XXXX-XXXX-3344dc_card_address=dc_card_city=dc_card_zipcode=dc_card_state=dc_card_country=dc_base_amount=4.00dc_tax_amount=0.00dc_capture_amount=4.00dc_cashback_amount=0.00dc_shipping_amount=0.00 RESPONSE end def successful_refund_response - <<-RESPONSE -dc_merchant_name=PayJunction - (demo)dc_merchant_address=3 W. Carrillodc_merchant_city=Santa Barbaradc_merchant_state=CAdc_merchant_zip=93101dc_merchant_phone=800-601-0230dc_device_id=1174dc_transaction_date=2007-11-28 19:22:33.791634dc_transaction_action=creditdc_approval_code=TAS193dc_response_code=00dc_response_message=APPROVAL TAS193 dc_transaction_id=3144302dc_posture=holddc_invoice_number=9f76c4e4bd66a36dc5aeb4bd7b3a02fadc_notes=--START QUICK-LINK DEBUG-- -----Vars Received---- -dc_expiration_month => * -dc_expiration_year => * -dc_invoice => 9f76c4e4bd66a36dc5aeb4bd7b3a02fa -dc_logon => pj-ql-01 -dc_name => Cody Fauser -dc_number => * -dc_password => * -dc_transaction_amount => 4.00 -dc_transaction_type => CREDIT -dc_verification_number => * -dc_version => 1.2 -----End Vars---- - -----Start Response Sent---- -dc_merchant_name=PayJunction - (demo) -dc_merchant_address=3 W. Carrillo -dc_merchant_city=Santa Barbara -dc_merchant_state=CA -dc_merchant_zip=93101 -dc_merchant_phone=800-601-0230 -dc_device_id=1174 -dc_transaction_date=2007-11-28 19:22:33.791634 -dc_transaction_action=charge -dc_approval_code=TAS193 -dc_response_code=00 -dc_response_message=APPROVAL TAS193 -dc_transaction_id=3144302 -dc_posture=hold -dc_invoice_number=9f76c4e4bd66a36dc5aeb4bd7b3a02fa -dc_notes=null -dc_card_name=cody fauser -dc_card_brand=VSA -dc_card_exp=XX/XX -dc_card_number=XXXX-XXXX-XXXX-3344 -dc_card_address= -dc_card_city= -dc_card_zipcode= -dc_card_state= -dc_card_country= -dc_base_amount=4.00 -dc_tax_amount=0.00 -dc_capture_amount=4.00 -dc_cashback_amount=0.00 -dc_shipping_amount=0.00 -----End Response Sent---- -dc_card_name=cody fauserdc_card_brand=VSAdc_card_exp=XX/XXdc_card_number=XXXX-XXXX-XXXX-3344dc_card_address=dc_card_city=dc_card_zipcode=dc_card_state=dc_card_country=dc_base_amount=4.00dc_tax_amount=0.00dc_capture_amount=4.00dc_cashback_amount=0.00dc_shipping_amount=0.00 + <<~RESPONSE + dc_merchant_name=PayJunction - (demo)dc_merchant_address=3 W. Carrillodc_merchant_city=Santa Barbaradc_merchant_state=CAdc_merchant_zip=93101dc_merchant_phone=800-601-0230dc_device_id=1174dc_transaction_date=2007-11-28 19:22:33.791634dc_transaction_action=creditdc_approval_code=TAS193dc_response_code=00dc_response_message=APPROVAL TAS193 dc_transaction_id=3144302dc_posture=holddc_invoice_number=9f76c4e4bd66a36dc5aeb4bd7b3a02fadc_notes=--START QUICK-LINK DEBUG-- + ----Vars Received---- + dc_expiration_month => * + dc_expiration_year => * + dc_invoice => 9f76c4e4bd66a36dc5aeb4bd7b3a02fa + dc_logon => pj-ql-01 + dc_name => Cody Fauser + dc_number => * + dc_password => * + dc_transaction_amount => 4.00 + dc_transaction_type => CREDIT + dc_verification_number => * + dc_version => 1.2 + ----End Vars---- + + ----Start Response Sent---- + dc_merchant_name=PayJunction - (demo) + dc_merchant_address=3 W. Carrillo + dc_merchant_city=Santa Barbara + dc_merchant_state=CA + dc_merchant_zip=93101 + dc_merchant_phone=800-601-0230 + dc_device_id=1174 + dc_transaction_date=2007-11-28 19:22:33.791634 + dc_transaction_action=charge + dc_approval_code=TAS193 + dc_response_code=00 + dc_response_message=APPROVAL TAS193 + dc_transaction_id=3144302 + dc_posture=hold + dc_invoice_number=9f76c4e4bd66a36dc5aeb4bd7b3a02fa + dc_notes=null + dc_card_name=cody fauser + dc_card_brand=VSA + dc_card_exp=XX/XX + dc_card_number=XXXX-XXXX-XXXX-3344 + dc_card_address= + dc_card_city= + dc_card_zipcode= + dc_card_state= + dc_card_country= + dc_base_amount=4.00 + dc_tax_amount=0.00 + dc_capture_amount=4.00 + dc_cashback_amount=0.00 + dc_shipping_amount=0.00 + ----End Response Sent---- + dc_card_name=cody fauserdc_card_brand=VSAdc_card_exp=XX/XXdc_card_number=XXXX-XXXX-XXXX-3344dc_card_address=dc_card_city=dc_card_zipcode=dc_card_state=dc_card_country=dc_base_amount=4.00dc_tax_amount=0.00dc_capture_amount=4.00dc_cashback_amount=0.00dc_shipping_amount=0.00 RESPONSE end diff --git a/test/unit/gateways/pay_junction_v2_test.rb b/test/unit/gateways/pay_junction_v2_test.rb index 99a40a808ec..7e27979f33b 100644 --- a/test/unit/gateways/pay_junction_v2_test.rb +++ b/test/unit/gateways/pay_junction_v2_test.rb @@ -5,9 +5,10 @@ def setup @gateway = PayJunctionV2Gateway.new(api_login: 'api_login', api_password: 'api_password', api_key: 'api_key') @amount = 99 - @credit_card = credit_card('4444333322221111', month: 01, year: 2020, verification_value: 999) + @credit_card = credit_card('4444333322221111', month: 01, year: 2022, verification_value: 999) @options = { - order_id: generate_unique_id + order_id: generate_unique_id, + billing_address: address } end @@ -205,6 +206,20 @@ def test_failed_store assert_match %r{Card Number is not a valid card number}, response.message end + def test_add_address + post = { card: { billingAddress: {} } } + @gateway.send(:add_address, post, @options) + assert_equal @options[:billing_address][:first_name], post[:billingFirstName] + assert_equal @options[:billing_address][:last_name], post[:billingLastName] + assert_equal @options[:billing_address][:company], post[:billingCompanyName] + assert_equal @options[:billing_address][:phone_number], post[:billingPhone] + assert_equal @options[:billing_address][:address1], post[:billingAddress] + assert_equal @options[:billing_address][:city], post[:billingCity] + assert_equal @options[:billing_address][:state], post[:billingState] + assert_equal @options[:billing_address][:country], post[:billingCountry] + assert_equal @options[:billing_address][:zip], post[:billingZip] + end + def test_scrub assert @gateway.supports_scrubbing? assert_equal @gateway.scrub(pre_scrubbed), post_scrubbed diff --git a/test/unit/gateways/pay_secure_test.rb b/test/unit/gateways/pay_secure_test.rb index a49bf1a60f0..37e3db47250 100644 --- a/test/unit/gateways/pay_secure_test.rb +++ b/test/unit/gateways/pay_secure_test.rb @@ -1,18 +1,17 @@ require 'test_helper' class PaySecureTest < Test::Unit::TestCase - def setup @gateway = PaySecureGateway.new( - :login => 'login', - :password => 'password' - ) + login: 'login', + password: 'password' + ) @credit_card = credit_card @options = { - :order_id => '1000', - :billing_address => address, - :description => 'Test purchase' + order_id: '1000', + billing_address: address, + description: 'Test purchase' } @amount = 100 end @@ -51,22 +50,22 @@ def test_cvv_result_not_supported private def successful_purchase_response - <<-RESPONSE -Status: Accepted -SettlementDate: 2007-10-09 -AUTHNUM: 2778 -ErrorString: No Error -CardBin: 1 -ERROR: 0 -TransID: SimProxy 54041670 + <<~RESPONSE + Status: Accepted + SettlementDate: 2007-10-09 + AUTHNUM: 2778 + ErrorString: No Error + CardBin: 1 + ERROR: 0 + TransID: SimProxy 54041670 RESPONSE end def failure_response - <<-RESPONSE -Status: Declined -ErrorString: Field value '8f796cb29a1be32af5ce12d4ca7425c2' does not match required format. -ERROR: 1 + <<~RESPONSE + Status: Declined + ErrorString: Field value '8f796cb29a1be32af5ce12d4ca7425c2' does not match required format. + ERROR: 1 RESPONSE end end diff --git a/test/unit/gateways/paybox_direct_test.rb b/test/unit/gateways/paybox_direct_test.rb index e6e29d1ad93..a10fab948bc 100644 --- a/test/unit/gateways/paybox_direct_test.rb +++ b/test/unit/gateways/paybox_direct_test.rb @@ -5,19 +5,18 @@ class PayboxDirectTest < Test::Unit::TestCase def setup @gateway = PayboxDirectGateway.new( - :login => 'l', - :password => 'p' - ) + login: 'l', + password: 'p' + ) @credit_card = credit_card('1111222233334444', - :brand => 'visa' - ) + brand: 'visa') @amount = 100 @options = { - :order_id => '1', - :billing_address => address, - :description => 'Store Purchase' + order_id: '1', + billing_address: address, + description: 'Store Purchase' } end @@ -82,7 +81,7 @@ def test_unsuccessful_request end def test_keep_the_card_code_not_considered_fraudulent - @gateway.expects(:ssl_post).returns(purchase_response('00104')) + @gateway.expects(:ssl_post).returns(purchase_response('00103')) assert response = @gateway.purchase(@amount, @credit_card, @options) assert_failure response @@ -113,7 +112,7 @@ def test_version private # Place raw successful response from gateway here - def purchase_response(code='00000') + def purchase_response(code = '00000') "NUMTRANS=0720248861&NUMAPPEL=0713790302&NUMQUESTION=0000790217&SITE=1999888&RANG=99&AUTORISATION=XXXXXX&CODEREPONSE=#{code}&COMMENTAIRE=Demande trait?e avec succ?s ✔漢" end diff --git a/test/unit/gateways/payeezy_test.rb b/test/unit/gateways/payeezy_test.rb index 229e842424e..79fbaad50c7 100644 --- a/test/unit/gateways/payeezy_test.rb +++ b/test/unit/gateways/payeezy_test.rb @@ -12,8 +12,8 @@ def setup @check = check @amount = 100 @options = { - :billing_address => address, - :ta_token => '123' + billing_address: address, + ta_token: '123' } @options_stored_credentials = { cardbrand_original_transaction_id: 'abc123', @@ -22,6 +22,14 @@ def setup initiator: 'MERCHANT', auth_type_override: 'A' } + @options_standardized_stored_credentials = { + stored_credential: { + network_transaction_id: 'abc123', + initial_transaction: false, + reason_type: 'recurring', + initiator: 'cardholder' + } + } @authorization = 'ET1700|106625152|credit_card|4738' @reversal_id = SecureRandom.random_number(1000000).to_s end @@ -113,7 +121,7 @@ def test_successful_purchase_defaulting_check_number response = stub_comms do @gateway.purchase(@amount, check_without_number, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/001/, data) end.respond_with(successful_purchase_echeck_response) @@ -126,7 +134,19 @@ def test_successful_purchase_defaulting_check_number def test_successful_purchase_with_stored_credentials response = stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(@options_stored_credentials)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| + assert_match(/stored_credentials/, data) + end.respond_with(successful_purchase_stored_credentials_response) + + assert_success response + assert response.test? + assert_equal 'Transaction Normal - Approved', response.message + end + + def test_successful_purchase_with_standardized_stored_credentials + response = stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(@options_standardized_stored_credentials)) + end.check_request do |_endpoint, data, _headers| assert_match(/stored_credentials/, data) end.respond_with(successful_purchase_stored_credentials_response) @@ -143,6 +163,15 @@ def test_failed_purchase assert_equal response.error_code, 'card_expired' end + def test_failed_purchase_with_insufficient_funds + response = stub_comms do + @gateway.purchase(530200, @credit_card, @options) + end.respond_with(failed_purchase_response_for_insufficient_funds) + + assert_failure response + assert_equal '302', response.error_code + end + def test_successful_authorize @gateway.expects(:ssl_post).returns(successful_authorize_response) assert response = @gateway.authorize(@amount, @credit_card, @options) @@ -196,7 +225,7 @@ def test_failed_refund def test_successful_void response = stub_comms do @gateway.void(@authorization, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| json = '{"transaction_type":"void","method":"credit_card","transaction_tag":"106625152","currency_code":"USD","amount":"4738"}' assert_match json, data end.respond_with(successful_void_response) @@ -207,7 +236,7 @@ def test_successful_void def test_successful_void_with_reversal_id stub_comms do @gateway.void(@authorization, @options.merge(reversal_id: @reversal_id)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| json = "{\"transaction_type\":\"void\",\"method\":\"credit_card\",\"reversal_id\":\"#{@reversal_id}\",\"currency_code\":\"USD\",\"amount\":\"4738\"}" assert_match json, data end.respond_with(successful_void_response) @@ -239,16 +268,18 @@ def test_invalid_transaction_tag assert response = @gateway.capture(@amount, @authorization) assert_instance_of Response, response assert_failure response - assert_equal response.error_code, 'server_error' + error_msg = response.params['Error']['messages'] + error_code = error_msg.map { |x| x.values[0] } + assert_equal error_code[0], 'server_error' assert_equal response.message, 'ProcessedBad Request (69) - Invalid Transaction Tag' end def test_supported_countries - assert_equal ['CA', 'US'].sort, PayeezyGateway.supported_countries.sort + assert_equal %w[CA US].sort, PayeezyGateway.supported_countries.sort end def test_supported_cardtypes - assert_equal [:visa, :master, :american_express, :discover, :jcb, :diners_club], PayeezyGateway.supported_cardtypes + assert_equal %i[visa master american_express discover jcb diners_club], PayeezyGateway.supported_cardtypes end def test_avs_result @@ -268,7 +299,7 @@ def test_cvv_result def test_requests_include_verification_string stub_comms do @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| json_address = '{"street":"456 My Street","city":"Ottawa","state_province":"ON","zip_postal_code":"K1C2N6","country":"CA"}' assert_match json_address, data end.respond_with(successful_purchase_response) @@ -306,186 +337,186 @@ def test_scrub_echeck private def pre_scrubbed - <<-TRANSCRIPT - opening connection to api-cert.payeezy.com:443... - opened - starting SSL for api-cert.payeezy.com:443... - SSL established - <- "POST /v1/transactions HTTP/1.1\r\nContent-Type: application/json\r\nApikey: oKB61AAxbN3xwC6gVAH3dp58FmioHSAT\r\nToken: fdoa-a480ce8951daa73262734cf102641994c1e55e7cdf4c02b6\r\nNonce: 5803993876.636232\r\nTimestamp: 1449523748359\r\nAuthorization: NGRlZjJkMWNlMDc5NGI5OTVlYTQxZDRkOGQ4NjRhNmZhNDgwZmIyNTZkMWJhN2M3MDdkNDI0ZWI1OGUwMGExMA==\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-cert.payeezy.com\r\nContent-Length: 365\r\n\r\n" - <- "{\"transaction_type\":\"purchase\",\"merchant_ref\":null,\"method\":\"credit_card\",\"credit_card\":{\"type\":\"Visa\",\"cardholder_name\":\"Longbob Longsen\",\"card_number\":\"4242424242424242\",\"exp_date\":\"0916\",\"cvv\":\"123\"},\"billing_address\":{\"street\":\"456 My Street\",\"city\":\"Ottawa\",\"state_province\":\"ON\",\"zip_postal_code\":\"K1C2N6\",\"country\":\"CA\"},\"currency_code\":\"USD\",\"amount\":\"100\"}" - -> "HTTP/1.1 201 Created\r\n" - -> "Access-Control-Allow-Headers: Content-Type, apikey, token\r\n" - -> "Access-Control-Allow-Methods: GET, PUT, POST, DELETE\r\n" - -> "Access-Control-Allow-Origin: http://localhost:8080\r\n" - -> "Access-Control-Max-Age: 3628800\r\n" - -> "Access-Control-Request-Headers: origin, x-requested-with, accept, content-type\r\n" - -> "Content-Language: en-US\r\n" - -> "Content-Type: application/json;charset=UTF-8\r\n" - -> "Date: Mon, 07 Dec 2015 21:29:08 GMT\r\n" - -> "OPTR_CXT: 0100010000e4b64c5c-53c6-4f8b-aab6-b7950e2a40c100000000-0000-0000-0000-000000000000-1 HTTP ;\r\n" - -> "Server: Apigee Router\r\n" - -> "X-Archived-Client-IP: 10.180.205.250\r\n" - -> "X-Backside-Transport: OK OK,OK OK\r\n" - -> "X-Client-IP: 10.180.205.250,54.236.202.5\r\n" - -> "X-Global-Transaction-ID: 74768541\r\n" - -> "X-Powered-By: Servlet/3.0\r\n" - -> "Content-Length: 549\r\n" - -> "Connection: Close\r\n" - -> "\r\n" - reading 549 bytes... - -> "{\"correlation_id\":\"228.1449523748595\",\"transaction_status\":\"approved\",\"validation_status\":\"success\",\"transaction_type\":\"purchase\",\"transaction_id\":\"ET189831\",\"transaction_tag\":\"69607700\",\"method\":\"credit_card\",\"amount\":\"100\",\"currency\":\"USD\",\"avs\":\"4\",\"cvv2\":\"M\",\"token\":{\"token_type\":\"FDToken\",\"token_data\":{\"value\":\"1950935021264242\"}},\"card\":{\"type\":\"Visa\",\"cardholder_name\":\"Longbob Longsen\",\"card_number\":\"4242\",\"exp_date\":\"0916\"},\"bank_resp_code\":\"100\",\"bank_message\":\"Approved\",\"gateway_resp_code\":\"00\",\"gateway_message\":\"Transaction Normal\"}" - read 549 bytes - Conn close + <<~TRANSCRIPT + opening connection to api-cert.payeezy.com:443... + opened + starting SSL for api-cert.payeezy.com:443... + SSL established + <- "POST /v1/transactions HTTP/1.1\r\nContent-Type: application/json\r\nApikey: oKB61AAxbN3xwC6gVAH3dp58FmioHSAT\r\nToken: fdoa-a480ce8951daa73262734cf102641994c1e55e7cdf4c02b6\r\nNonce: 5803993876.636232\r\nTimestamp: 1449523748359\r\nAuthorization: NGRlZjJkMWNlMDc5NGI5OTVlYTQxZDRkOGQ4NjRhNmZhNDgwZmIyNTZkMWJhN2M3MDdkNDI0ZWI1OGUwMGExMA==\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-cert.payeezy.com\r\nContent-Length: 365\r\n\r\n" + <- "{\"transaction_type\":\"purchase\",\"merchant_ref\":null,\"method\":\"credit_card\",\"credit_card\":{\"type\":\"Visa\",\"cardholder_name\":\"Longbob Longsen\",\"card_number\":\"4242424242424242\",\"exp_date\":\"0916\",\"cvv\":\"123\"},\"billing_address\":{\"street\":\"456 My Street\",\"city\":\"Ottawa\",\"state_province\":\"ON\",\"zip_postal_code\":\"K1C2N6\",\"country\":\"CA\"},\"currency_code\":\"USD\",\"amount\":\"100\"}" + -> "HTTP/1.1 201 Created\r\n" + -> "Access-Control-Allow-Headers: Content-Type, apikey, token\r\n" + -> "Access-Control-Allow-Methods: GET, PUT, POST, DELETE\r\n" + -> "Access-Control-Allow-Origin: http://localhost:8080\r\n" + -> "Access-Control-Max-Age: 3628800\r\n" + -> "Access-Control-Request-Headers: origin, x-requested-with, accept, content-type\r\n" + -> "Content-Language: en-US\r\n" + -> "Content-Type: application/json;charset=UTF-8\r\n" + -> "Date: Mon, 07 Dec 2015 21:29:08 GMT\r\n" + -> "OPTR_CXT: 0100010000e4b64c5c-53c6-4f8b-aab6-b7950e2a40c100000000-0000-0000-0000-000000000000-1 HTTP ;\r\n" + -> "Server: Apigee Router\r\n" + -> "X-Archived-Client-IP: 10.180.205.250\r\n" + -> "X-Backside-Transport: OK OK,OK OK\r\n" + -> "X-Client-IP: 10.180.205.250,54.236.202.5\r\n" + -> "X-Global-Transaction-ID: 74768541\r\n" + -> "X-Powered-By: Servlet/3.0\r\n" + -> "Content-Length: 549\r\n" + -> "Connection: Close\r\n" + -> "\r\n" + reading 549 bytes... + -> "{\"correlation_id\":\"228.1449523748595\",\"transaction_status\":\"approved\",\"validation_status\":\"success\",\"transaction_type\":\"purchase\",\"transaction_id\":\"ET189831\",\"transaction_tag\":\"69607700\",\"method\":\"credit_card\",\"amount\":\"100\",\"currency\":\"USD\",\"avs\":\"4\",\"cvv2\":\"M\",\"token\":{\"token_type\":\"FDToken\",\"token_data\":{\"value\":\"1950935021264242\"}},\"card\":{\"type\":\"Visa\",\"cardholder_name\":\"Longbob Longsen\",\"card_number\":\"4242\",\"exp_date\":\"0916\"},\"bank_resp_code\":\"100\",\"bank_message\":\"Approved\",\"gateway_resp_code\":\"00\",\"gateway_message\":\"Transaction Normal\"}" + read 549 bytes + Conn close TRANSCRIPT end def post_scrubbed - <<-TRANSCRIPT - opening connection to api-cert.payeezy.com:443... - opened - starting SSL for api-cert.payeezy.com:443... - SSL established - <- "POST /v1/transactions HTTP/1.1\r\nContent-Type: application/json\r\nApikey: [FILTERED]\r\nToken: [FILTERED]\r\nNonce: 5803993876.636232\r\nTimestamp: 1449523748359\r\nAuthorization: NGRlZjJkMWNlMDc5NGI5OTVlYTQxZDRkOGQ4NjRhNmZhNDgwZmIyNTZkMWJhN2M3MDdkNDI0ZWI1OGUwMGExMA==\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-cert.payeezy.com\r\nContent-Length: 365\r\n\r\n" - <- "{\"transaction_type\":\"purchase\",\"merchant_ref\":null,\"method\":\"credit_card\",\"credit_card\":{\"type\":\"Visa\",\"cardholder_name\":\"Longbob Longsen\",\"card_number\":\"[FILTERED]\",\"exp_date\":\"0916\",\"cvv\":\"[FILTERED]\"},\"billing_address\":{\"street\":\"456 My Street\",\"city\":\"Ottawa\",\"state_province\":\"ON\",\"zip_postal_code\":\"K1C2N6\",\"country\":\"CA\"},\"currency_code\":\"USD\",\"amount\":\"100\"}" - -> "HTTP/1.1 201 Created\r\n" - -> "Access-Control-Allow-Headers: Content-Type, apikey, token\r\n" - -> "Access-Control-Allow-Methods: GET, PUT, POST, DELETE\r\n" - -> "Access-Control-Allow-Origin: http://localhost:8080\r\n" - -> "Access-Control-Max-Age: 3628800\r\n" - -> "Access-Control-Request-Headers: origin, x-requested-with, accept, content-type\r\n" - -> "Content-Language: en-US\r\n" - -> "Content-Type: application/json;charset=UTF-8\r\n" - -> "Date: Mon, 07 Dec 2015 21:29:08 GMT\r\n" - -> "OPTR_CXT: 0100010000e4b64c5c-53c6-4f8b-aab6-b7950e2a40c100000000-0000-0000-0000-000000000000-1 HTTP ;\r\n" - -> "Server: Apigee Router\r\n" - -> "X-Archived-Client-IP: 10.180.205.250\r\n" - -> "X-Backside-Transport: OK OK,OK OK\r\n" - -> "X-Client-IP: 10.180.205.250,54.236.202.5\r\n" - -> "X-Global-Transaction-ID: 74768541\r\n" - -> "X-Powered-By: Servlet/3.0\r\n" - -> "Content-Length: 549\r\n" - -> "Connection: Close\r\n" - -> "\r\n" - reading 549 bytes... - -> "{\"correlation_id\":\"228.1449523748595\",\"transaction_status\":\"approved\",\"validation_status\":\"success\",\"transaction_type\":\"purchase\",\"transaction_id\":\"ET189831\",\"transaction_tag\":\"69607700\",\"method\":\"credit_card\",\"amount\":\"100\",\"currency\":\"USD\",\"avs\":\"4\",\"cvv2\":\"M\",\"token\":{\"token_type\":\"FDToken\",\"token_data\":{\"value\":\"1950935021264242\"}},\"card\":{\"type\":\"Visa\",\"cardholder_name\":\"Longbob Longsen\",\"card_number\":\"[FILTERED]\",\"exp_date\":\"0916\"},\"bank_resp_code\":\"100\",\"bank_message\":\"Approved\",\"gateway_resp_code\":\"00\",\"gateway_message\":\"Transaction Normal\"}" - read 549 bytes - Conn close + <<~TRANSCRIPT + opening connection to api-cert.payeezy.com:443... + opened + starting SSL for api-cert.payeezy.com:443... + SSL established + <- "POST /v1/transactions HTTP/1.1\r\nContent-Type: application/json\r\nApikey: [FILTERED]\r\nToken: [FILTERED]\r\nNonce: 5803993876.636232\r\nTimestamp: 1449523748359\r\nAuthorization: NGRlZjJkMWNlMDc5NGI5OTVlYTQxZDRkOGQ4NjRhNmZhNDgwZmIyNTZkMWJhN2M3MDdkNDI0ZWI1OGUwMGExMA==\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-cert.payeezy.com\r\nContent-Length: 365\r\n\r\n" + <- "{\"transaction_type\":\"purchase\",\"merchant_ref\":null,\"method\":\"credit_card\",\"credit_card\":{\"type\":\"Visa\",\"cardholder_name\":\"Longbob Longsen\",\"card_number\":\"[FILTERED]\",\"exp_date\":\"0916\",\"cvv\":\"[FILTERED]\"},\"billing_address\":{\"street\":\"456 My Street\",\"city\":\"Ottawa\",\"state_province\":\"ON\",\"zip_postal_code\":\"K1C2N6\",\"country\":\"CA\"},\"currency_code\":\"USD\",\"amount\":\"100\"}" + -> "HTTP/1.1 201 Created\r\n" + -> "Access-Control-Allow-Headers: Content-Type, apikey, token\r\n" + -> "Access-Control-Allow-Methods: GET, PUT, POST, DELETE\r\n" + -> "Access-Control-Allow-Origin: http://localhost:8080\r\n" + -> "Access-Control-Max-Age: 3628800\r\n" + -> "Access-Control-Request-Headers: origin, x-requested-with, accept, content-type\r\n" + -> "Content-Language: en-US\r\n" + -> "Content-Type: application/json;charset=UTF-8\r\n" + -> "Date: Mon, 07 Dec 2015 21:29:08 GMT\r\n" + -> "OPTR_CXT: 0100010000e4b64c5c-53c6-4f8b-aab6-b7950e2a40c100000000-0000-0000-0000-000000000000-1 HTTP ;\r\n" + -> "Server: Apigee Router\r\n" + -> "X-Archived-Client-IP: 10.180.205.250\r\n" + -> "X-Backside-Transport: OK OK,OK OK\r\n" + -> "X-Client-IP: 10.180.205.250,54.236.202.5\r\n" + -> "X-Global-Transaction-ID: 74768541\r\n" + -> "X-Powered-By: Servlet/3.0\r\n" + -> "Content-Length: 549\r\n" + -> "Connection: Close\r\n" + -> "\r\n" + reading 549 bytes... + -> "{\"correlation_id\":\"228.1449523748595\",\"transaction_status\":\"approved\",\"validation_status\":\"success\",\"transaction_type\":\"purchase\",\"transaction_id\":\"ET189831\",\"transaction_tag\":\"69607700\",\"method\":\"credit_card\",\"amount\":\"100\",\"currency\":\"USD\",\"avs\":\"4\",\"cvv2\":\"M\",\"token\":{\"token_type\":\"FDToken\",\"token_data\":{\"value\":\"1950935021264242\"}},\"card\":{\"type\":\"Visa\",\"cardholder_name\":\"Longbob Longsen\",\"card_number\":\"[FILTERED]\",\"exp_date\":\"0916\"},\"bank_resp_code\":\"100\",\"bank_message\":\"Approved\",\"gateway_resp_code\":\"00\",\"gateway_message\":\"Transaction Normal\"}" + read 549 bytes + Conn close TRANSCRIPT end def pre_scrubbed_echeck - <<-TRANSCRIPT - {\"transaction_type\":\"purchase\",\"merchant_ref\":null,\"method\":\"tele_check\",\"tele_check\":{\"check_number\":\"1\",\"check_type\":\"P\",\"routing_number\":\"244183602\",\"account_number\":\"15378535\",\"accountholder_name\":\"Jim Smith\"},\"billing_address\":{\"street\":\"456 My Street\",\"city\":\"Ottawa\",\"state_province\":\"ON\",\"zip_postal_code\":\"K1C2N6\",\"country\":\"CA\"},\"currency_code\":\"USD\",\"amount\":\"100\"}" - -> "HTTP/1.1 201 Created\r\n" - -> "Access-Control-Allow-Headers: Content-Type, apikey, token\r\n" - -> "Access-Control-Allow-Methods: GET, PUT, POST, DELETE\r\n" - -> "Access-Control-Allow-Origin: http://localhost:8080\r\n" - -> "Access-Control-Max-Age: 3628800\r\n" - -> "Access-Control-Request-Headers: origin, x-requested-with, accept, content-type\r\n" - -> "Content-Language: en-US\r\n" - -> "Content-Type: application/json;charset=UTF-8\r\n" - -> "Date: Wed, 09 Dec 2015 19:33:14 GMT\r\n" - -> "OPTR_CXT: 0100010000094b4179-bed8-4068-b077-d8679a20046f00000000-0000-0000-0000-000000000000-1 HTTP ;\r\n" - -> "Server: Apigee Router\r\n" - -> "X-Archived-Client-IP: 10.180.205.250\r\n" - -> "X-Backside-Transport: OK OK,OK OK\r\n" - -> "X-Client-IP: 10.180.205.250,107.23.55.229\r\n" - -> "X-Global-Transaction-ID: 97138449\r\n" - -> "X-Powered-By: Servlet/3.0\r\n" - -> "Content-Length: 491\r\n" - -> "Connection: Close\r\n" - -> "\r\n" - reading 491 bytes... - -> "{\"correlation_id\":\"228.1449689594381\",\"transaction_status\":\"approved\",\"validation_status\":\"success\",\"transaction_type\":\"purchase\",\"transaction_id\":\"ET196703\",\"transaction_tag\":\"69865571\",\"method\":\"tele_check\",\"amount\":\"100\",\"currency\":\"USD\",\"bank_resp_code\":\"100\",\"bank_message\":\"Approved\",\"gateway_resp_code\":\"00\",\"gateway_message\":\"Transaction Normal\",\"tele_check\":{\"accountholder_name\":\"Jim Smith\",\"check_number\":\"1\",\"check_type\":\"P\",\"account_number\":\"8535\",\"routing_number\":\"244183602\"}} + <<~TRANSCRIPT + {\"transaction_type\":\"purchase\",\"merchant_ref\":null,\"method\":\"tele_check\",\"tele_check\":{\"check_number\":\"1\",\"check_type\":\"P\",\"routing_number\":\"244183602\",\"account_number\":\"15378535\",\"accountholder_name\":\"Jim Smith\"},\"billing_address\":{\"street\":\"456 My Street\",\"city\":\"Ottawa\",\"state_province\":\"ON\",\"zip_postal_code\":\"K1C2N6\",\"country\":\"CA\"},\"currency_code\":\"USD\",\"amount\":\"100\"}" + -> "HTTP/1.1 201 Created\r\n" + -> "Access-Control-Allow-Headers: Content-Type, apikey, token\r\n" + -> "Access-Control-Allow-Methods: GET, PUT, POST, DELETE\r\n" + -> "Access-Control-Allow-Origin: http://localhost:8080\r\n" + -> "Access-Control-Max-Age: 3628800\r\n" + -> "Access-Control-Request-Headers: origin, x-requested-with, accept, content-type\r\n" + -> "Content-Language: en-US\r\n" + -> "Content-Type: application/json;charset=UTF-8\r\n" + -> "Date: Wed, 09 Dec 2015 19:33:14 GMT\r\n" + -> "OPTR_CXT: 0100010000094b4179-bed8-4068-b077-d8679a20046f00000000-0000-0000-0000-000000000000-1 HTTP ;\r\n" + -> "Server: Apigee Router\r\n" + -> "X-Archived-Client-IP: 10.180.205.250\r\n" + -> "X-Backside-Transport: OK OK,OK OK\r\n" + -> "X-Client-IP: 10.180.205.250,107.23.55.229\r\n" + -> "X-Global-Transaction-ID: 97138449\r\n" + -> "X-Powered-By: Servlet/3.0\r\n" + -> "Content-Length: 491\r\n" + -> "Connection: Close\r\n" + -> "\r\n" + reading 491 bytes... + -> "{\"correlation_id\":\"228.1449689594381\",\"transaction_status\":\"approved\",\"validation_status\":\"success\",\"transaction_type\":\"purchase\",\"transaction_id\":\"ET196703\",\"transaction_tag\":\"69865571\",\"method\":\"tele_check\",\"amount\":\"100\",\"currency\":\"USD\",\"bank_resp_code\":\"100\",\"bank_message\":\"Approved\",\"gateway_resp_code\":\"00\",\"gateway_message\":\"Transaction Normal\",\"tele_check\":{\"accountholder_name\":\"Jim Smith\",\"check_number\":\"1\",\"check_type\":\"P\",\"account_number\":\"8535\",\"routing_number\":\"244183602\"}} TRANSCRIPT end def post_scrubbed_echeck - <<-TRANSCRIPT - {\"transaction_type\":\"purchase\",\"merchant_ref\":null,\"method\":\"tele_check\",\"tele_check\":{\"check_number\":\"1\",\"check_type\":\"P\",\"routing_number\":\"[FILTERED]\",\"account_number\":\"[FILTERED]\",\"accountholder_name\":\"Jim Smith\"},\"billing_address\":{\"street\":\"456 My Street\",\"city\":\"Ottawa\",\"state_province\":\"ON\",\"zip_postal_code\":\"K1C2N6\",\"country\":\"CA\"},\"currency_code\":\"USD\",\"amount\":\"100\"}" - -> "HTTP/1.1 201 Created\r\n" - -> "Access-Control-Allow-Headers: Content-Type, apikey, token\r\n" - -> "Access-Control-Allow-Methods: GET, PUT, POST, DELETE\r\n" - -> "Access-Control-Allow-Origin: http://localhost:8080\r\n" - -> "Access-Control-Max-Age: 3628800\r\n" - -> "Access-Control-Request-Headers: origin, x-requested-with, accept, content-type\r\n" - -> "Content-Language: en-US\r\n" - -> "Content-Type: application/json;charset=UTF-8\r\n" - -> "Date: Wed, 09 Dec 2015 19:33:14 GMT\r\n" - -> "OPTR_CXT: 0100010000094b4179-bed8-4068-b077-d8679a20046f00000000-0000-0000-0000-000000000000-1 HTTP ;\r\n" - -> "Server: Apigee Router\r\n" - -> "X-Archived-Client-IP: 10.180.205.250\r\n" - -> "X-Backside-Transport: OK OK,OK OK\r\n" - -> "X-Client-IP: 10.180.205.250,107.23.55.229\r\n" - -> "X-Global-Transaction-ID: 97138449\r\n" - -> "X-Powered-By: Servlet/3.0\r\n" - -> "Content-Length: 491\r\n" - -> "Connection: Close\r\n" - -> "\r\n" - reading 491 bytes... - -> "{\"correlation_id\":\"228.1449689594381\",\"transaction_status\":\"approved\",\"validation_status\":\"success\",\"transaction_type\":\"purchase\",\"transaction_id\":\"ET196703\",\"transaction_tag\":\"69865571\",\"method\":\"tele_check\",\"amount\":\"100\",\"currency\":\"USD\",\"bank_resp_code\":\"100\",\"bank_message\":\"Approved\",\"gateway_resp_code\":\"00\",\"gateway_message\":\"Transaction Normal\",\"tele_check\":{\"accountholder_name\":\"Jim Smith\",\"check_number\":\"1\",\"check_type\":\"P\",\"account_number\":\"[FILTERED]\",\"routing_number\":\"[FILTERED]\"}} + <<~TRANSCRIPT + {\"transaction_type\":\"purchase\",\"merchant_ref\":null,\"method\":\"tele_check\",\"tele_check\":{\"check_number\":\"1\",\"check_type\":\"P\",\"routing_number\":\"[FILTERED]\",\"account_number\":\"[FILTERED]\",\"accountholder_name\":\"Jim Smith\"},\"billing_address\":{\"street\":\"456 My Street\",\"city\":\"Ottawa\",\"state_province\":\"ON\",\"zip_postal_code\":\"K1C2N6\",\"country\":\"CA\"},\"currency_code\":\"USD\",\"amount\":\"100\"}" + -> "HTTP/1.1 201 Created\r\n" + -> "Access-Control-Allow-Headers: Content-Type, apikey, token\r\n" + -> "Access-Control-Allow-Methods: GET, PUT, POST, DELETE\r\n" + -> "Access-Control-Allow-Origin: http://localhost:8080\r\n" + -> "Access-Control-Max-Age: 3628800\r\n" + -> "Access-Control-Request-Headers: origin, x-requested-with, accept, content-type\r\n" + -> "Content-Language: en-US\r\n" + -> "Content-Type: application/json;charset=UTF-8\r\n" + -> "Date: Wed, 09 Dec 2015 19:33:14 GMT\r\n" + -> "OPTR_CXT: 0100010000094b4179-bed8-4068-b077-d8679a20046f00000000-0000-0000-0000-000000000000-1 HTTP ;\r\n" + -> "Server: Apigee Router\r\n" + -> "X-Archived-Client-IP: 10.180.205.250\r\n" + -> "X-Backside-Transport: OK OK,OK OK\r\n" + -> "X-Client-IP: 10.180.205.250,107.23.55.229\r\n" + -> "X-Global-Transaction-ID: 97138449\r\n" + -> "X-Powered-By: Servlet/3.0\r\n" + -> "Content-Length: 491\r\n" + -> "Connection: Close\r\n" + -> "\r\n" + reading 491 bytes... + -> "{\"correlation_id\":\"228.1449689594381\",\"transaction_status\":\"approved\",\"validation_status\":\"success\",\"transaction_type\":\"purchase\",\"transaction_id\":\"ET196703\",\"transaction_tag\":\"69865571\",\"method\":\"tele_check\",\"amount\":\"100\",\"currency\":\"USD\",\"bank_resp_code\":\"100\",\"bank_message\":\"Approved\",\"gateway_resp_code\":\"00\",\"gateway_message\":\"Transaction Normal\",\"tele_check\":{\"accountholder_name\":\"Jim Smith\",\"check_number\":\"1\",\"check_type\":\"P\",\"account_number\":\"[FILTERED]\",\"routing_number\":\"[FILTERED]\"}} TRANSCRIPT end def pre_scrubbed_store - <<-TRANSCRIPT - opening connection to api-cert.payeezy.com:443... - opened - starting SSL for api-cert.payeezy.com:443... - SSL established - <- "GET /v1/securitytokens?apikey=UyDMTXx6TD9WErF6ynw7xeEfCAn8fcGs&js_security_key=js-f4c4b54f08d6c44c8cad3ea80bbf92c4f4c4b54f08d6c44c&ta_token=120&callback=Payeezy.callback&type=FDToken&credit_card.type=Visa&credit_card.cardholder_name=Longbob+Longsen&credit_card.card_number=4242424242424242&credit_card.exp_date=0919&credit_card.cvv=123 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: api-cert.payeezy.com\r\n\r\n" - -> "HTTP/1.1 200 Success\r\n" - -> "Content-Language: en-US\r\n" - -> "Content-Type: application/json\r\n" - -> "correlation_id: 228.1574930196886\r\n" - -> "Date: Fri, 12 Jan 2018 09:28:22 GMT\r\n" - -> "statuscode: 201\r\n" - -> "X-Archived-Client-IP: 10.180.205.250\r\n" - -> "X-Backside-Transport: OK OK,OK OK\r\n" - -> "X-Client-IP: 10.180.205.250,54.218.45.37\r\n" - -> "X-Global-Transaction-ID: 463881989\r\n" - -> "X-Powered-By: Servlet/3.0\r\n" - -> "Content-Length: 266\r\n" - -> "Connection: Close\r\n" - -> "\r\n" - reading 266 bytes... - -> "\n Payeezy.callback({\n \t\"status\":201,\n \t\"results\":{\"correlation_id\":\"228.1574930196886\",\"status\":\"success\",\"type\":\"FDToken\",\"token\":{\"type\":\"Visa\",\"cardholder_name\":\"Longbob Longsen\",\"exp_date\":\"0919\",\"value\":\"2158545373614242\"}}\n })\n " - read 266 bytes - Conn close + <<~TRANSCRIPT + opening connection to api-cert.payeezy.com:443... + opened + starting SSL for api-cert.payeezy.com:443... + SSL established + <- "GET /v1/securitytokens?apikey=UyDMTXx6TD9WErF6ynw7xeEfCAn8fcGs&js_security_key=js-f4c4b54f08d6c44c8cad3ea80bbf92c4f4c4b54f08d6c44c&ta_token=120&callback=Payeezy.callback&type=FDToken&credit_card.type=Visa&credit_card.cardholder_name=Longbob+Longsen&credit_card.card_number=4242424242424242&credit_card.exp_date=0919&credit_card.cvv=123 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: api-cert.payeezy.com\r\n\r\n" + -> "HTTP/1.1 200 Success\r\n" + -> "Content-Language: en-US\r\n" + -> "Content-Type: application/json\r\n" + -> "correlation_id: 228.1574930196886\r\n" + -> "Date: Fri, 12 Jan 2018 09:28:22 GMT\r\n" + -> "statuscode: 201\r\n" + -> "X-Archived-Client-IP: 10.180.205.250\r\n" + -> "X-Backside-Transport: OK OK,OK OK\r\n" + -> "X-Client-IP: 10.180.205.250,54.218.45.37\r\n" + -> "X-Global-Transaction-ID: 463881989\r\n" + -> "X-Powered-By: Servlet/3.0\r\n" + -> "Content-Length: 266\r\n" + -> "Connection: Close\r\n" + -> "\r\n" + reading 266 bytes... + -> "\n Payeezy.callback({\n \t\"status\":201,\n \t\"results\":{\"correlation_id\":\"228.1574930196886\",\"status\":\"success\",\"type\":\"FDToken\",\"token\":{\"type\":\"Visa\",\"cardholder_name\":\"Longbob Longsen\",\"exp_date\":\"0919\",\"value\":\"2158545373614242\"}}\n })\n " + read 266 bytes + Conn close TRANSCRIPT end def post_scrubbed_store - <<-TRANSCRIPT - opening connection to api-cert.payeezy.com:443... - opened - starting SSL for api-cert.payeezy.com:443... - SSL established - <- "GET /v1/securitytokens?apikey=[FILTERED]js_security_key=js-f4c4b54f08d6c44c8cad3ea80bbf92c4f4c4b54f08d6c44c&ta_token=120&callback=Payeezy.callback&type=FDToken&credit_card.type=Visa&credit_card.cardholder_name=Longbob+Longsen&credit_card.card_number=[FILTERED]credit_card.exp_date=0919&credit_card.cvv=[FILTERED] 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: api-cert.payeezy.com\r\n\r\n" - -> "HTTP/1.1 200 Success\r\n" - -> "Content-Language: en-US\r\n" - -> "Content-Type: application/json\r\n" - -> "correlation_id: 228.1574930196886\r\n" - -> "Date: Fri, 12 Jan 2018 09:28:22 GMT\r\n" - -> "statuscode: 201\r\n" - -> "X-Archived-Client-IP: 10.180.205.250\r\n" - -> "X-Backside-Transport: OK OK,OK OK\r\n" - -> "X-Client-IP: 10.180.205.250,54.218.45.37\r\n" - -> "X-Global-Transaction-ID: 463881989\r\n" - -> "X-Powered-By: Servlet/3.0\r\n" - -> "Content-Length: 266\r\n" - -> "Connection: Close\r\n" - -> "\r\n" - reading 266 bytes... - -> "\n Payeezy.callback({\n \t\"status\":201,\n \t\"results\":{\"correlation_id\":\"228.1574930196886\",\"status\":\"success\",\"type\":\"FDToken\",\"token\":{\"type\":\"Visa\",\"cardholder_name\":\"Longbob Longsen\",\"exp_date\":\"0919\",\"value\":\"2158545373614242\"}}\n })\n " - read 266 bytes - Conn close + <<~TRANSCRIPT + opening connection to api-cert.payeezy.com:443... + opened + starting SSL for api-cert.payeezy.com:443... + SSL established + <- "GET /v1/securitytokens?apikey=[FILTERED]js_security_key=js-f4c4b54f08d6c44c8cad3ea80bbf92c4f4c4b54f08d6c44c&ta_token=120&callback=Payeezy.callback&type=FDToken&credit_card.type=Visa&credit_card.cardholder_name=Longbob+Longsen&credit_card.card_number=[FILTERED]credit_card.exp_date=0919&credit_card.cvv=[FILTERED] 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: api-cert.payeezy.com\r\n\r\n" + -> "HTTP/1.1 200 Success\r\n" + -> "Content-Language: en-US\r\n" + -> "Content-Type: application/json\r\n" + -> "correlation_id: 228.1574930196886\r\n" + -> "Date: Fri, 12 Jan 2018 09:28:22 GMT\r\n" + -> "statuscode: 201\r\n" + -> "X-Archived-Client-IP: 10.180.205.250\r\n" + -> "X-Backside-Transport: OK OK,OK OK\r\n" + -> "X-Client-IP: 10.180.205.250,54.218.45.37\r\n" + -> "X-Global-Transaction-ID: 463881989\r\n" + -> "X-Powered-By: Servlet/3.0\r\n" + -> "Content-Length: 266\r\n" + -> "Connection: Close\r\n" + -> "\r\n" + reading 266 bytes... + -> "\n Payeezy.callback({\n \t\"status\":201,\n \t\"results\":{\"correlation_id\":\"228.1574930196886\",\"status\":\"success\",\"type\":\"FDToken\",\"token\":{\"type\":\"Visa\",\"cardholder_name\":\"Longbob Longsen\",\"exp_date\":\"0919\",\"value\":\"2158545373614242\"}}\n })\n " + read 266 bytes + Conn close TRANSCRIPT end def successful_purchase_response - <<-RESPONSE - {\"method\":\"credit_card\",\"amount\":\"1\",\"currency\":\"USD\",\"avs\":\"4\",\"card\":{\"type\":\"Visa\",\"cardholder_name\":\"Bobsen 995\",\"card_number\":\"4242\",\"exp_date\":\"0816\"},\"token\":{\"token_type\":\"transarmor\",\"token_data\":{\"value\":\"0152552999534242\"}},\"transaction_status\":\"approved\",\"validation_status\":\"success\",\"transaction_type\":\"purchase\",\"transaction_id\":\"ET114541\",\"transaction_tag\":\"55083431\",\"bank_resp_code\":\"100\",\"bank_message\":\"Approved\",\"gateway_resp_code\":\"00\",\"gateway_message\":\"Transaction Normal\",\"correlation_id\":\"124.1433862672836\"} + <<~RESPONSE + {\"method\":\"credit_card\",\"amount\":\"1\",\"currency\":\"USD\",\"avs\":\"4\",\"card\":{\"type\":\"Visa\",\"cardholder_name\":\"Bobsen 995\",\"card_number\":\"4242\",\"exp_date\":\"0816\"},\"token\":{\"token_type\":\"transarmor\",\"token_data\":{\"value\":\"0152552999534242\"}},\"transaction_status\":\"approved\",\"validation_status\":\"success\",\"transaction_type\":\"purchase\",\"transaction_id\":\"ET114541\",\"transaction_tag\":\"55083431\",\"bank_resp_code\":\"100\",\"bank_message\":\"Approved\",\"gateway_resp_code\":\"00\",\"gateway_message\":\"Transaction Normal\",\"correlation_id\":\"124.1433862672836\"} RESPONSE end @@ -494,309 +525,313 @@ def successful_purchase_stored_credentials_response end def successful_purchase_echeck_response - <<-RESPONSE - {\"correlation_id\":\"228.1449688619062\",\"transaction_status\":\"approved\",\"validation_status\":\"success\",\"transaction_type\":\"purchase\",\"transaction_id\":\"ET133078\",\"transaction_tag\":\"69864362\",\"method\":\"tele_check\",\"amount\":\"100\",\"currency\":\"USD\",\"bank_resp_code\":\"100\",\"bank_message\":\"Approved\",\"gateway_resp_code\":\"00\",\"gateway_message\":\"Transaction Normal\",\"tele_check\":{\"accountholder_name\":\"Jim Smith\",\"check_number\":\"1\",\"check_type\":\"P\",\"account_number\":\"8535\",\"routing_number\":\"244183602\"}} + <<~RESPONSE + {\"correlation_id\":\"228.1449688619062\",\"transaction_status\":\"approved\",\"validation_status\":\"success\",\"transaction_type\":\"purchase\",\"transaction_id\":\"ET133078\",\"transaction_tag\":\"69864362\",\"method\":\"tele_check\",\"amount\":\"100\",\"currency\":\"USD\",\"bank_resp_code\":\"100\",\"bank_message\":\"Approved\",\"gateway_resp_code\":\"00\",\"gateway_message\":\"Transaction Normal\",\"tele_check\":{\"accountholder_name\":\"Jim Smith\",\"check_number\":\"1\",\"check_type\":\"P\",\"account_number\":\"8535\",\"routing_number\":\"244183602\"}} RESPONSE end def successful_store_response - <<-RESPONSE - {\"correlation_id\":\"124.1792879391754\",\"status\":\"success\",\"type\":\"FDToken\",\"token\":{\"type\":\"Visa\",\"cardholder_name\":\"Longbob Longsen\",\"exp_date\":\"0919\",\"value\":\"9045348309244242\"}} + <<~RESPONSE + {\"correlation_id\":\"124.1792879391754\",\"status\":\"success\",\"type\":\"FDToken\",\"token\":{\"type\":\"Visa\",\"cardholder_name\":\"Longbob Longsen\",\"exp_date\":\"0919\",\"value\":\"9045348309244242\"}} RESPONSE end def failed_store_response - <<-RESPONSE - {\"correlation_id\":\"124.1792940806770\",\"status\":\"failed\",\"Error\":{\"messages\":[{\"code\":\"invalid_card_number\",\"description\":\"The credit card number check failed\"}]},\"type\":\"FDToken\"} + <<~RESPONSE + {\"correlation_id\":\"124.1792940806770\",\"status\":\"failed\",\"Error\":{\"messages\":[{\"code\":\"invalid_card_number\",\"description\":\"The credit card number check failed\"}]},\"type\":\"FDToken\"} RESPONSE end def failed_purchase_response - yamlexcep = <<-RESPONSE ---- !ruby/exception:ActiveMerchant::ResponseError -response: !ruby/object:Net::HTTPBadRequest - http_version: '1.1' - code: '400' - message: Bad Request - header: - content-language: - - en-US - content-type: - - application/json - date: - - Tue, 09 Jun 2015 15:46:44 GMT - optr_cxt: - - 0100010000eb11d301-785c-449b-b060-6d0b4638d54d00000000-0000-0000-0000-000000000000-1 HTTP ; - x-archived-client-ip: - - 10.174.197.250 - x-backside-transport: - - FAIL FAIL,FAIL FAIL - x-client-ip: - - 10.174.197.250,54.236.202.5 - x-powered-by: - - Servlet/3.0 - content-length: - - '384' - connection: - - Close - body: '{"method":"credit_card","amount":"10000000","currency":"USD","card":{"type":"Visa","cvv":"000","cardholder_name":"Bobsen - 5675","card_number":"4242","exp_date":"0810"},"transaction_status":"Not Processed","validation_status":"failed","transaction_type":"purchase","Error":{"messages":[{"code":"card_expired","description":"The - card has expired"}]},"correlation_id":"124.1433864804381"}' - read: true - uri: - decode_content: true - socket: - body_exist: true -message: + yamlexcep = <<~RESPONSE + --- !ruby/exception:ActiveMerchant::ResponseError + response: !ruby/object:Net::HTTPBadRequest + http_version: '1.1' + code: '400' + message: Bad Request + header: + content-language: + - en-US + content-type: + - application/json + date: + - Tue, 09 Jun 2015 15:46:44 GMT + optr_cxt: + - 0100010000eb11d301-785c-449b-b060-6d0b4638d54d00000000-0000-0000-0000-000000000000-1 HTTP ; + x-archived-client-ip: + - 10.174.197.250 + x-backside-transport: + - FAIL FAIL,FAIL FAIL + x-client-ip: + - 10.174.197.250,54.236.202.5 + x-powered-by: + - Servlet/3.0 + content-length: + - '384' + connection: + - Close + body: '{"method":"credit_card","amount":"10000000","currency":"USD","card":{"type":"Visa","cvv":"000","cardholder_name":"Bobsen + 5675","card_number":"4242","exp_date":"0810"},"transaction_status":"Not Processed","validation_status":"failed","transaction_type":"purchase","Error":{"messages":[{"code":"card_expired","description":"The + card has expired"}]},"correlation_id":"124.1433864804381"}' + read: true + uri: + decode_content: true + socket: + body_exist: true + message: RESPONSE YAML.safe_load(yamlexcep, ['Net::HTTPBadRequest', 'ActiveMerchant::ResponseError']) end + def failed_purchase_response_for_insufficient_funds + '{"correlation_id":"124.1342365067332","transaction_status":"declined","validation_status":"success","transaction_type":"purchase","transaction_tag":"4611610442","method":"credit_card","amount":"530200","currency":"USD","avs":"4","cvv2":"M","token":{"token_type":"FDToken", "token_data":{"value":"0788934280684242"}},"card":{"type":"Visa","cardholder_name":"Longbob Longsen","card_number":"4242","exp_date":"0922"},"bank_resp_code":"302","bank_message":"Insufficient Funds","gateway_resp_code":"00","gateway_message":"Transaction Normal"}' + end + def successful_authorize_response - <<-RESPONSE + <<~RESPONSE {\"correlation_id\":\"228.1449517682800\",\"transaction_status\":\"approved\",\"validation_status\":\"success\",\"transaction_type\":\"authorize\",\"transaction_id\":\"ET156862\",\"transaction_tag\":\"69601979\",\"method\":\"credit_card\",\"amount\":\"100\",\"currency\":\"USD\",\"avs\":\"4\",\"cvv2\":\"M\",\"token\":{\"token_type\":\"FDToken\",\"token_data\":{\"value\":\"1446473518714242\"}},\"card\":{\"type\":\"Visa\",\"cardholder_name\":\"Longbob Longsen\",\"card_number\":\"4242\",\"exp_date\":\"0916\"},\"bank_resp_code\":\"100\",\"bank_message\":\"Approved\",\"gateway_resp_code\":\"00\",\"gateway_message\":\"Transaction Normal\"} RESPONSE end def failed_authorize_response - <<-RESPONSE + <<~RESPONSE {\"correlation_id\":\"228.1449522605561\",\"transaction_status\":\"declined\",\"validation_status\":\"success\",\"transaction_type\":\"authorize\",\"transaction_tag\":\"69607256\",\"method\":\"credit_card\",\"amount\":\"501300\",\"currency\":\"USD\",\"avs\":\"4\",\"cvv2\":\"M\",\"token\":{\"token_type\":\"FDToken\",\"token_data\":{\"value\":\"0843687226934242\"}},\"card\":{\"type\":\"Visa\",\"cardholder_name\":\"Longbob Longsen\",\"card_number\":\"4242\",\"exp_date\":\"0916\"},\"bank_resp_code\":\"013\",\"bank_message\":\"Transaction not approved\",\"gateway_resp_code\":\"00\",\"gateway_message\":\"Transaction Normal\"} RESPONSE end def successful_capture_response - <<-RESPONSE + <<~RESPONSE {\"correlation_id\":\"228.1449517473876\",\"transaction_status\":\"approved\",\"validation_status\":\"success\",\"transaction_type\":\"capture\",\"transaction_id\":\"ET176427\",\"transaction_tag\":\"69601874\",\"method\":\"credit_card\",\"amount\":\"100\",\"currency\":\"USD\",\"cvv2\":\"I\",\"token\":{\"token_type\":\"FDToken\",\"token_data\":{\"value\":\"8129044621504242\"}},\"bank_resp_code\":\"100\",\"bank_message\":\"Approved\",\"gateway_resp_code\":\"00\",\"gateway_message\":\"Transaction Normal\"} RESPONSE end def successful_refund_response - <<-RESPONSE - {\"method\":\"credit_card\",\"amount\":\"1\",\"currency\":\"USD\",\"cvv2\":\"I\",\"token\":{\"token_type\":\"transarmor\",\"token_data\":{\"value\":\"9968749582724242\"}},\"transaction_status\":\"approved\",\"validation_status\":\"success\",\"transaction_type\":\"refund\",\"transaction_id\":\"55084328\",\"transaction_tag\":\"55084328\",\"bank_resp_code\":\"100\",\"bank_message\":\"Approved\",\"gateway_resp_code\":\"00\",\"gateway_message\":\"Transaction Normal\",\"correlation_id\":\"124.1433864648126\"} + <<~RESPONSE + {\"method\":\"credit_card\",\"amount\":\"1\",\"currency\":\"USD\",\"cvv2\":\"I\",\"token\":{\"token_type\":\"transarmor\",\"token_data\":{\"value\":\"9968749582724242\"}},\"transaction_status\":\"approved\",\"validation_status\":\"success\",\"transaction_type\":\"refund\",\"transaction_id\":\"55084328\",\"transaction_tag\":\"55084328\",\"bank_resp_code\":\"100\",\"bank_message\":\"Approved\",\"gateway_resp_code\":\"00\",\"gateway_message\":\"Transaction Normal\",\"correlation_id\":\"124.1433864648126\"} RESPONSE end def successful_refund_echeck_response - <<-RESPONSE - {\"correlation_id\":\"228.1449688783287\",\"transaction_status\":\"approved\",\"validation_status\":\"success\",\"transaction_type\":\"refund\",\"transaction_id\":\"69864710\",\"transaction_tag\":\"69864710\",\"method\":\"tele_check\",\"amount\":\"50\",\"currency\":\"USD\",\"bank_resp_code\":\"100\",\"bank_message\":\"Approved\",\"gateway_resp_code\":\"00\",\"gateway_message\":\"Transaction Normal\"} + <<~RESPONSE + {\"correlation_id\":\"228.1449688783287\",\"transaction_status\":\"approved\",\"validation_status\":\"success\",\"transaction_type\":\"refund\",\"transaction_id\":\"69864710\",\"transaction_tag\":\"69864710\",\"method\":\"tele_check\",\"amount\":\"50\",\"currency\":\"USD\",\"bank_resp_code\":\"100\",\"bank_message\":\"Approved\",\"gateway_resp_code\":\"00\",\"gateway_message\":\"Transaction Normal\"} RESPONSE end def below_minimum_response - <<-RESPONSE - {\"correlation_id\":\"123.1234678982\",\"transaction_status\":\"declined\",\"validation_status\":\"success\",\"transaction_type\":\"authorize\",\"transaction_tag\":\"92384753\",\"method\":\"credit_card\",\"amount\":\"250\",\"currency\":\"USD\",\"card\":{\"type\":\"Mastercard\",\"cardholder_name\":\"Omri Test\",\"card_number\":\"[FILTERED]\",\"exp_date\":\"0123\"},\"gateway_resp_code\":\"36\",\"gateway_message\":\"Below Minimum Sale\"} + <<~RESPONSE + {\"correlation_id\":\"123.1234678982\",\"transaction_status\":\"declined\",\"validation_status\":\"success\",\"transaction_type\":\"authorize\",\"transaction_tag\":\"92384753\",\"method\":\"credit_card\",\"amount\":\"250\",\"currency\":\"USD\",\"card\":{\"type\":\"Mastercard\",\"cardholder_name\":\"Omri Test\",\"card_number\":\"[FILTERED]\",\"exp_date\":\"0123\"},\"gateway_resp_code\":\"36\",\"gateway_message\":\"Below Minimum Sale\"} RESPONSE end def failed_refund_response - yamlexcep = <<-RESPONSE ---- !ruby/exception:ActiveMerchant::ResponseError -response: !ruby/object:Net::HTTPBadRequest - http_version: '1.1' - code: '400' - message: Bad Request - header: - content-language: - - en-US - content-type: - - application/json - date: - - Tue, 09 Jun 2015 15:46:44 GMT - optr_cxt: - - 0100010000eb11d301-785c-449b-b060-6d0b4638d54d00000000-0000-0000-0000-000000000000-1 HTTP ; - x-archived-client-ip: - - 10.174.197.250 - x-backside-transport: - - FAIL FAIL,FAIL FAIL - x-client-ip: - - 10.174.197.250,54.236.202.5 - x-powered-by: - - Servlet/3.0 - content-length: - - '384' - connection: - - Close - body: '{"correlation_id":"228.1449520714925","Error":{"messages":[{"code":"missing_transaction_tag","description":"The transaction tag is not provided"}]},"transaction_status":"Not Processed","validation_status":"failed","transaction_type":"refund","amount":"50","currency":"USD"}' - read: true - uri: - decode_content: true - socket: - body_exist: true -message: + yamlexcep = <<~RESPONSE + --- !ruby/exception:ActiveMerchant::ResponseError + response: !ruby/object:Net::HTTPBadRequest + http_version: '1.1' + code: '400' + message: Bad Request + header: + content-language: + - en-US + content-type: + - application/json + date: + - Tue, 09 Jun 2015 15:46:44 GMT + optr_cxt: + - 0100010000eb11d301-785c-449b-b060-6d0b4638d54d00000000-0000-0000-0000-000000000000-1 HTTP ; + x-archived-client-ip: + - 10.174.197.250 + x-backside-transport: + - FAIL FAIL,FAIL FAIL + x-client-ip: + - 10.174.197.250,54.236.202.5 + x-powered-by: + - Servlet/3.0 + content-length: + - '384' + connection: + - Close + body: '{"correlation_id":"228.1449520714925","Error":{"messages":[{"code":"missing_transaction_tag","description":"The transaction tag is not provided"}]},"transaction_status":"Not Processed","validation_status":"failed","transaction_type":"refund","amount":"50","currency":"USD"}' + read: true + uri: + decode_content: true + socket: + body_exist: true + message: RESPONSE YAML.safe_load(yamlexcep, ['Net::HTTPBadRequest', 'ActiveMerchant::ResponseError']) end def successful_void_response - <<-RESPONSE - {\"method\":\"credit_card\",\"amount\":\"1\",\"currency\":\"USD\",\"cvv2\":\"I\",\"token\":{\"token_type\":\"transarmor\",\"token_data\":{\"value\":\"9594258319174242\"}},\"transaction_status\":\"approved\",\"validation_status\":\"success\",\"transaction_type\":\"void\",\"transaction_id\":\"ET196233\",\"transaction_tag\":\"55083674\",\"bank_resp_code\":\"100\",\"bank_message\":\"Approved\",\"gateway_resp_code\":\"00\",\"gateway_message\":\"Transaction Normal\",\"correlation_id\":\"124.1433863576596\"} + <<~RESPONSE + {\"method\":\"credit_card\",\"amount\":\"1\",\"currency\":\"USD\",\"cvv2\":\"I\",\"token\":{\"token_type\":\"transarmor\",\"token_data\":{\"value\":\"9594258319174242\"}},\"transaction_status\":\"approved\",\"validation_status\":\"success\",\"transaction_type\":\"void\",\"transaction_id\":\"ET196233\",\"transaction_tag\":\"55083674\",\"bank_resp_code\":\"100\",\"bank_message\":\"Approved\",\"gateway_resp_code\":\"00\",\"gateway_message\":\"Transaction Normal\",\"correlation_id\":\"124.1433863576596\"} RESPONSE end def failed_void_response - yamlexcep = <<-RESPONSE ---- !ruby/exception:ActiveMerchant::ResponseError -response: !ruby/object:Net::HTTPBadRequest - http_version: '1.1' - code: '400' - message: Bad Request - header: - content-language: - - en-US - content-type: - - application/json - date: - - Tue, 09 Jun 2015 15:46:44 GMT - optr_cxt: - - 0100010000eb11d301-785c-449b-b060-6d0b4638d54d00000000-0000-0000-0000-000000000000-1 HTTP ; - x-archived-client-ip: - - 10.174.197.250 - x-backside-transport: - - FAIL FAIL,FAIL FAIL - x-client-ip: - - 10.174.197.250,54.236.202.5 - x-powered-by: - - Servlet/3.0 - content-length: - - '384' - connection: - - Close - body: '{"correlation_id":"228.1449520846984","Error":{"messages":[{"code":"missing_transaction_id","description":"The transaction id is not provided"},{"code":"missing_transaction_tag","description":"The transaction tag is not provided"}]},"transaction_status":"Not Processed","validation_status":"failed","transaction_type":"void","amount":"0","currency":"USD"}' - read: true - uri: - decode_content: true - socket: - body_exist: true -message: + yamlexcep = <<~RESPONSE + --- !ruby/exception:ActiveMerchant::ResponseError + response: !ruby/object:Net::HTTPBadRequest + http_version: '1.1' + code: '400' + message: Bad Request + header: + content-language: + - en-US + content-type: + - application/json + date: + - Tue, 09 Jun 2015 15:46:44 GMT + optr_cxt: + - 0100010000eb11d301-785c-449b-b060-6d0b4638d54d00000000-0000-0000-0000-000000000000-1 HTTP ; + x-archived-client-ip: + - 10.174.197.250 + x-backside-transport: + - FAIL FAIL,FAIL FAIL + x-client-ip: + - 10.174.197.250,54.236.202.5 + x-powered-by: + - Servlet/3.0 + content-length: + - '384' + connection: + - Close + body: '{"correlation_id":"228.1449520846984","Error":{"messages":[{"code":"missing_transaction_id","description":"The transaction id is not provided"},{"code":"missing_transaction_tag","description":"The transaction tag is not provided"}]},"transaction_status":"Not Processed","validation_status":"failed","transaction_type":"void","amount":"0","currency":"USD"}' + read: true + uri: + decode_content: true + socket: + body_exist: true + message: RESPONSE YAML.safe_load(yamlexcep, ['Net::HTTPBadRequest', 'ActiveMerchant::ResponseError']) end def failed_capture_response - yamlexcep = <<-RESPONSE ---- !ruby/exception:ActiveMerchant::ResponseError -response: !ruby/object:Net::HTTPBadRequest - http_version: '1.1' - code: '400' - message: Bad Request - header: - content-language: - - en-US - content-type: - - application/json - date: - - Tue, 09 Jun 2015 17:33:50 GMT - optr_cxt: - - 0100010000d084138f-24f3-4686-8a51-3c17406a572500000000-0000-0000-0000-000000000000-1 HTTP ; - x-archived-client-ip: - - 10.174.197.250 - x-backside-transport: - - FAIL FAIL,FAIL FAIL - x-client-ip: - - 10.174.197.250,107.23.55.229 - x-powered-by: - - Servlet/3.0 - content-length: - - '190' - connection: - - Close - body: '{"transaction_status":"Not Processed","Error":{"messages":[{"code":"server_error","description":"ProcessedBad - Request (69) - Invalid Transaction Tag"}]},"correlation_id":"124.1433871231542"}' - read: true - uri: - decode_content: true - socket: - body_exist: true -message: + yamlexcep = <<~RESPONSE + --- !ruby/exception:ActiveMerchant::ResponseError + response: !ruby/object:Net::HTTPBadRequest + http_version: '1.1' + code: '400' + message: Bad Request + header: + content-language: + - en-US + content-type: + - application/json + date: + - Tue, 09 Jun 2015 17:33:50 GMT + optr_cxt: + - 0100010000d084138f-24f3-4686-8a51-3c17406a572500000000-0000-0000-0000-000000000000-1 HTTP ; + x-archived-client-ip: + - 10.174.197.250 + x-backside-transport: + - FAIL FAIL,FAIL FAIL + x-client-ip: + - 10.174.197.250,107.23.55.229 + x-powered-by: + - Servlet/3.0 + content-length: + - '190' + connection: + - Close + body: '{"transaction_status":"Not Processed","Error":{"messages":[{"code":"server_error","description":"ProcessedBad + Request (69) - Invalid Transaction Tag"}]},"correlation_id":"124.1433871231542"}' + read: true + uri: + decode_content: true + socket: + body_exist: true + message: RESPONSE YAML.safe_load(yamlexcep, ['Net::HTTPBadRequest', 'ActiveMerchant::ResponseError']) end def invalid_token_response - yamlexcep = <<-RESPONSE ---- !ruby/exception:ActiveMerchant::ResponseError -response: !ruby/object:Net::HTTPUnauthorized - http_version: '1.1' - code: '401' - message: Unauthorized - header: - content-language: - - en-US - content-type: - - application/json;charset=utf-8 - date: - - Tue, 23 Jun 2015 15:13:02 GMT - optr_cxt: - - 435543224354-37b2-4369-9cfe-26543635465346346-0000-0000-0000-000000000000-1 HTTP ; - x-archived-client-ip: - - 10.180.205.250 - x-backside-transport: - - FAIL FAIL,FAIL FAIL - x-client-ip: - - 10.180.205.250,107.23.55.229 - x-powered-by: - - Servlet/3.0 - content-length: - - '25' - connection: - - Close - body: '{"error":"Access denied"}' - read: true - uri: - decode_content: true - socket: - body_exist: true -message: + yamlexcep = <<~RESPONSE + --- !ruby/exception:ActiveMerchant::ResponseError + response: !ruby/object:Net::HTTPUnauthorized + http_version: '1.1' + code: '401' + message: Unauthorized + header: + content-language: + - en-US + content-type: + - application/json;charset=utf-8 + date: + - Tue, 23 Jun 2015 15:13:02 GMT + optr_cxt: + - 435543224354-37b2-4369-9cfe-26543635465346346-0000-0000-0000-000000000000-1 HTTP ; + x-archived-client-ip: + - 10.180.205.250 + x-backside-transport: + - FAIL FAIL,FAIL FAIL + x-client-ip: + - 10.180.205.250,107.23.55.229 + x-powered-by: + - Servlet/3.0 + content-length: + - '25' + connection: + - Close + body: '{"error":"Access denied"}' + read: true + uri: + decode_content: true + socket: + body_exist: true + message: RESPONSE YAML.safe_load(yamlexcep, ['Net::HTTPUnauthorized', 'ActiveMerchant::ResponseError']) end def invalid_token_response_integration - yamlexcep = <<-RESPONSE ---- !ruby/exception:ActiveMerchant::ResponseError -response: !ruby/object:Net::HTTPUnauthorized - http_version: '1.1' - code: '401' - message: Unauthorized - header: - content-type: - - application/json - content-length: - - '125' - connection: - - Close - body: '{\"fault\":{\"faultstring\":\"Invalid ApiKey for given resource\",\"detail\":{\"errorcode\":\"oauth.v2.InvalidApiKeyForGivenResource\"}}}' - read: true - uri: - decode_content: true - socket: - body_exist: true -message: + yamlexcep = <<~RESPONSE + --- !ruby/exception:ActiveMerchant::ResponseError + response: !ruby/object:Net::HTTPUnauthorized + http_version: '1.1' + code: '401' + message: Unauthorized + header: + content-type: + - application/json + content-length: + - '125' + connection: + - Close + body: '{\"fault\":{\"faultstring\":\"Invalid ApiKey for given resource\",\"detail\":{\"errorcode\":\"oauth.v2.InvalidApiKeyForGivenResource\"}}}' + read: true + uri: + decode_content: true + socket: + body_exist: true + message: RESPONSE YAML.safe_load(yamlexcep, ['Net::HTTPUnauthorized', 'ActiveMerchant::ResponseError']) end def bad_credentials_response - yamlexcep = <<-RESPONSE ---- !ruby/exception:ActiveMerchant::ResponseError -response: !ruby/object:Net::HTTPForbidden - http_version: '1.1' - code: '403' - message: Forbidden - header: - content-type: - - application/json - content-length: - - '51' - connection: - - Close - body: '{"code":"403", "message":"HMAC validation Failure"}' - read: true - uri: - decode_content: true - socket: - body_exist: true -message: + yamlexcep = <<~RESPONSE + --- !ruby/exception:ActiveMerchant::ResponseError + response: !ruby/object:Net::HTTPForbidden + http_version: '1.1' + code: '403' + message: Forbidden + header: + content-type: + - application/json + content-length: + - '51' + connection: + - Close + body: '{"code":"403", "message":"HMAC validation Failure"}' + read: true + uri: + decode_content: true + socket: + body_exist: true + message: RESPONSE YAML.safe_load(yamlexcep, ['Net::HTTPForbidden', 'ActiveMerchant::ResponseError']) end diff --git a/test/unit/gateways/payex_test.rb b/test/unit/gateways/payex_test.rb index a567c1a08c1..d3b5e071ed4 100644 --- a/test/unit/gateways/payex_test.rb +++ b/test/unit/gateways/payex_test.rb @@ -3,15 +3,15 @@ class PayexTest < Test::Unit::TestCase def setup @gateway = PayexGateway.new( - :account => 'account', - :encryption_key => 'encryption_key' - ) + account: 'account', + encryption_key: 'encryption_key' + ) @credit_card = credit_card @amount = 1000 @options = { - :order_id => '1234', + order_id: '1234' } end @@ -98,7 +98,7 @@ def test_unsuccessful_refund def test_successful_store @gateway.expects(:ssl_post).times(3).returns(successful_store_response, successful_initialize_response, successful_purchase_response) - assert response = @gateway.store(@credit_card, @options.merge({merchant_ref: '9876'})) + assert response = @gateway.store(@credit_card, @options.merge({ merchant_ref: '9876' })) assert_success response assert_equal 'OK', response.message assert_equal 'bcea4ac8d1f44640bff7a8c93caa249c', response.authorization @@ -115,7 +115,7 @@ def test_successful_unstore def test_successful_purchase_with_stored_card @gateway.expects(:ssl_post).returns(successful_autopay_response) - assert response = @gateway.purchase(@amount, 'fakeauth', @options.merge({order_id: '5678'})) + assert response = @gateway.purchase(@amount, 'fakeauth', @options.merge({ order_id: '5678' })) assert_success response assert_equal 'OK', response.message assert_equal '2624657', response.authorization diff --git a/test/unit/gateways/payflow_express_test.rb b/test/unit/gateways/payflow_express_test.rb index ef8fab1fcb4..0e74a0aaa87 100644 --- a/test/unit/gateways/payflow_express_test.rb +++ b/test/unit/gateways/payflow_express_test.rb @@ -15,19 +15,18 @@ def setup Base.mode = :test @gateway = PayflowExpressGateway.new( - :login => 'LOGIN', - :password => 'PASSWORD' + login: 'LOGIN', + password: 'PASSWORD' ) - @address = { :address1 => '1234 My Street', - :address2 => 'Apt 1', - :company => 'Widgets Inc', - :city => 'Ottawa', - :state => 'ON', - :zip => 'K1C2N6', - :country => 'Canada', - :phone => '(555)555-5555' - } + @address = { address1: '1234 My Street', + address2: 'Apt 1', + company: 'Widgets Inc', + city: 'Ottawa', + state: 'ON', + zip: 'K1C2N6', + country: 'Canada', + phone: '(555)555-5555' } end def teardown @@ -42,9 +41,9 @@ def test_overriding_test_mode Base.mode = :production gateway = PayflowExpressGateway.new( - :login => 'LOGIN', - :password => 'PASSWORD', - :test => true + login: 'LOGIN', + password: 'PASSWORD', + test: true ) assert gateway.test? @@ -54,8 +53,8 @@ def test_using_production_mode Base.mode = :production gateway = PayflowExpressGateway.new( - :login => 'LOGIN', - :password => 'PASSWORD' + login: 'LOGIN', + password: 'PASSWORD' ) assert !gateway.test? @@ -64,24 +63,24 @@ def test_using_production_mode def test_live_redirect_url Base.mode = :production assert_equal LIVE_REDIRECT_URL, @gateway.redirect_url_for('1234567890') - assert_equal LIVE_REDIRECT_URL_MOBILE, @gateway.redirect_url_for('1234567890', :mobile => true) + assert_equal LIVE_REDIRECT_URL_MOBILE, @gateway.redirect_url_for('1234567890', mobile: true) end def test_test_redirect_url assert_equal TEST_REDIRECT_URL, @gateway.redirect_url_for('1234567890') - assert_equal TEST_REDIRECT_URL_MOBILE, @gateway.redirect_url_for('1234567890', :mobile => true) + assert_equal TEST_REDIRECT_URL_MOBILE, @gateway.redirect_url_for('1234567890', mobile: true) end def test_live_redirect_url_without_review Base.mode = :production - assert_equal LIVE_REDIRECT_URL_WITHOUT_REVIEW, @gateway.redirect_url_for('1234567890', :review => false) - assert_equal LIVE_REDIRECT_URL_MOBILE_WITHOUT_REVIEW, @gateway.redirect_url_for('1234567890', :review => false, :mobile => true) + assert_equal LIVE_REDIRECT_URL_WITHOUT_REVIEW, @gateway.redirect_url_for('1234567890', review: false) + assert_equal LIVE_REDIRECT_URL_MOBILE_WITHOUT_REVIEW, @gateway.redirect_url_for('1234567890', review: false, mobile: true) end def test_test_redirect_url_without_review assert_equal :test, Base.mode - assert_equal TEST_REDIRECT_URL_WITHOUT_REVIEW, @gateway.redirect_url_for('1234567890', :review => false) - assert_equal TEST_REDIRECT_URL_MOBILE_WITHOUT_REVIEW, @gateway.redirect_url_for('1234567890', :review => false, :mobile => true) + assert_equal TEST_REDIRECT_URL_WITHOUT_REVIEW, @gateway.redirect_url_for('1234567890', review: false) + assert_equal TEST_REDIRECT_URL_MOBILE_WITHOUT_REVIEW, @gateway.redirect_url_for('1234567890', review: false, mobile: true) end def test_invalid_get_express_details_request @@ -143,7 +142,7 @@ def test_get_express_details_with_ship_to_name end def test_get_express_details_with_invalid_xml - @gateway.expects(:ssl_post).returns(successful_get_express_details_response(:street => 'Main & Magic')) + @gateway.expects(:ssl_post).returns(successful_get_express_details_response(street: 'Main & Magic')) response = @gateway.details_for('EC-2OPN7UJGFWK9OYFV') assert_instance_of PayflowExpressResponse, response assert_success response @@ -162,95 +161,95 @@ def test_button_source private - def successful_get_express_details_response(options={:street => '111 Main St.'}) - <<-RESPONSE - - - TEST - verisign - - - 0 - Approved - - Buyer1@paypal.com - 12345678901234567 - EC-2OPN7UJGFWK9OYFV - 0 - verified - Joe - 555-555-5555 - -
- #{options[:street]} - San Jose - CA - 95100 - US -
-
- 9c3706997455e -
- -
-
-
-
+ def successful_get_express_details_response(options = { street: '111 Main St.' }) + <<~RESPONSE + + + TEST + verisign + + + 0 + Approved + + Buyer1@paypal.com + 12345678901234567 + EC-2OPN7UJGFWK9OYFV + 0 + verified + Joe + 555-555-5555 + +
+ #{options[:street]} + San Jose + CA + 95100 + US +
+
+ 9c3706997455e +
+ +
+
+
+
RESPONSE end def successful_get_express_details_response_with_ship_to_name - <<-RESPONSE - - - TEST - verisign - - - 0 - Approved - - Buyer1@paypal.com - 12345678901234567 - EC-2OPN7UJGFWK9OYFV - 0 - verified - Joe - 555-555-5555 - -
- 111 Main St. - San Jose - CA - 95100 - US -
-
- 9c3706997455e -
- - -
-
-
-
+ <<~RESPONSE + + + TEST + verisign + + + 0 + Approved + + Buyer1@paypal.com + 12345678901234567 + EC-2OPN7UJGFWK9OYFV + 0 + verified + Joe + 555-555-5555 + +
+ 111 Main St. + San Jose + CA + 95100 + US +
+
+ 9c3706997455e +
+ + +
+
+
+
RESPONSE end def invalid_get_express_details_response - <<-RESPONSE - - - TEST - verisign - - - 7 - Field format error: Invalid Token - - - - + <<~RESPONSE + + + TEST + verisign + + + 7 + Field format error: Invalid Token + + + + RESPONSE end end diff --git a/test/unit/gateways/payflow_express_uk_test.rb b/test/unit/gateways/payflow_express_uk_test.rb index 60a18a88be8..ef28d6b4d53 100644 --- a/test/unit/gateways/payflow_express_uk_test.rb +++ b/test/unit/gateways/payflow_express_uk_test.rb @@ -3,8 +3,8 @@ class PayflowExpressUkTest < Test::Unit::TestCase def setup @gateway = PayflowExpressUkGateway.new( - :login => 'LOGIN', - :password => 'PASSWORD' + login: 'LOGIN', + password: 'PASSWORD' ) end @@ -65,93 +65,93 @@ def test_get_express_details_with_ship_to_name private def successful_get_express_details_response - <<-RESPONSE - - - - markcoop - paypaluk - - - 0 - - Match - Match - - Approved - - paul@test.com - LYWCMEN4FA7ZQ - EC-2OPN7UJGFWK9OYFV - 0 - unverified - paul - -
- 10 keyworth avenue - hinterland - Tyne and Wear - sr5 2uh - GB -
-
- 1ea22ef3873ba -
- - - - - -
-
-
-
+ <<~RESPONSE + + + + markcoop + paypaluk + + + 0 + + Match + Match + + Approved + + paul@test.com + LYWCMEN4FA7ZQ + EC-2OPN7UJGFWK9OYFV + 0 + unverified + paul + +
+ 10 keyworth avenue + hinterland + Tyne and Wear + sr5 2uh + GB +
+
+ 1ea22ef3873ba +
+ + + + + +
+
+
+
RESPONSE end def successful_get_express_details_response_with_ship_to_name - <<-RESPONSE - - - - markcoop - paypaluk - - - 0 - - Match - Match - - Approved - - paul@test.com - LYWCMEN4FA7ZQ - EC-2OPN7UJGFWK9OYFV - 0 - unverified - paul - -
- 10 keyworth avenue - hinterland - Tyne and Wear - sr5 2uh - GB -
-
- 1ea22ef3873ba -
- - - - - - -
-
-
-
+ <<~RESPONSE + + + + markcoop + paypaluk + + + 0 + + Match + Match + + Approved + + paul@test.com + LYWCMEN4FA7ZQ + EC-2OPN7UJGFWK9OYFV + 0 + unverified + paul + +
+ 10 keyworth avenue + hinterland + Tyne and Wear + sr5 2uh + GB +
+
+ 1ea22ef3873ba +
+ + + + + + +
+
+
+
RESPONSE end end diff --git a/test/unit/gateways/payflow_test.rb b/test/unit/gateways/payflow_test.rb index c02d8e61af4..c006f9c2b55 100644 --- a/test/unit/gateways/payflow_test.rb +++ b/test/unit/gateways/payflow_test.rb @@ -7,14 +7,14 @@ def setup Base.mode = :test @gateway = PayflowGateway.new( - :login => 'LOGIN', - :password => 'PASSWORD' + login: 'LOGIN', + password: 'PASSWORD' ) @amount = 100 @credit_card = credit_card('4242424242424242') - @options = { :billing_address => address.merge(:first_name => 'Longbob', :last_name => 'Longsen') } - @check = check(:name => 'Jim Smith') + @options = { billing_address: address.merge(first_name: 'Longbob', last_name: 'Longsen') } + @check = check(name: 'Jim Smith') @l2_json = '{ "Tender": { "ACH": { @@ -58,7 +58,7 @@ def test_failed_authorization def test_authorization_with_three_d_secure_option response = stub_comms do @gateway.authorize(@amount, @credit_card, @options.merge(three_d_secure_option)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_three_d_secure REXML::Document.new(data), authorize_buyer_auth_result_path end.respond_with(successful_authorization_response) assert_equal 'Approved', response.message @@ -69,6 +69,9 @@ def test_authorization_with_three_d_secure_option end def test_successful_authorization_with_more_options + partner_id = 'partner_id' + PayflowGateway.application_id = partner_id + options = @options.merge( { order_id: '123', @@ -81,12 +84,13 @@ def test_successful_authorization_with_more_options 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 %r(123), data assert_match %r(Description string), data assert_match %r(OrderDesc string), data assert_match %r(Comment string), data assert_match %r(), data + assert_match %r(), data end.respond_with(successful_authorization_response) assert_equal 'Approved', response.message assert_success response @@ -107,7 +111,7 @@ def test_successful_purchase_with_fraud_review def test_successful_purchase_with_three_d_secure_option response = stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(three_d_secure_option)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_three_d_secure REXML::Document.new(data), purchase_buyer_auth_result_path end.respond_with(successful_purchase_with_fraud_review_response) assert_success response @@ -120,7 +124,7 @@ def test_successful_purchase_with_level_2_fields 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(6355059797), data assert_match %r(), data.tr("\n ", '') end.respond_with(successful_l2_response) @@ -135,7 +139,7 @@ def test_successful_purchase_with_level_3_fields 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(20190104), data assert_match %r(3.23), data assert_match %r(), data.tr("\n ", '') @@ -151,7 +155,7 @@ def test_successful_purchase_with_level_2_3_fields 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(20190104), data assert_match %r(3.23), data assert_match %r(6355059797), data @@ -229,9 +233,9 @@ def test_overriding_test_mode Base.mode = :production gateway = PayflowGateway.new( - :login => 'LOGIN', - :password => 'PASSWORD', - :test => true + login: 'LOGIN', + password: 'PASSWORD', + test: true ) assert gateway.test? @@ -241,8 +245,8 @@ def test_using_production_mode Base.mode = :production gateway = PayflowGateway.new( - :login => 'LOGIN', - :password => 'PASSWORD' + login: 'LOGIN', + password: 'PASSWORD' ) refute gateway.test? @@ -250,26 +254,26 @@ def test_using_production_mode def test_partner_class_accessor assert_equal 'PayPal', PayflowGateway.partner - gateway = PayflowGateway.new(:login => 'test', :password => 'test') + gateway = PayflowGateway.new(login: 'test', password: 'test') assert_equal 'PayPal', gateway.options[:partner] end def test_partner_class_accessor_used_when_passed_in_partner_is_blank assert_equal 'PayPal', PayflowGateway.partner - gateway = PayflowGateway.new(:login => 'test', :password => 'test', :partner => '') + gateway = PayflowGateway.new(login: 'test', password: 'test', partner: '') assert_equal 'PayPal', gateway.options[:partner] end def test_passed_in_partner_overrides_class_accessor assert_equal 'PayPal', PayflowGateway.partner - gateway = PayflowGateway.new(:login => 'test', :password => 'test', :partner => 'PayPalUk') + gateway = PayflowGateway.new(login: 'test', password: 'test', partner: 'PayPalUk') assert_equal 'PayPalUk', gateway.options[:partner] end def test_express_instance gateway = PayflowGateway.new( - :login => 'test', - :password => 'password' + login: 'test', + password: 'password' ) express = gateway.express assert_instance_of PayflowExpressGateway, express @@ -283,11 +287,11 @@ def test_default_currency end def test_supported_countries - assert_equal ['US', 'CA', 'NZ', 'AU'], PayflowGateway.supported_countries + assert_equal %w[US CA NZ AU], PayflowGateway.supported_countries end def test_supported_card_types - assert_equal [:visa, :master, :american_express, :jcb, :discover, :diners_club], PayflowGateway.supported_cardtypes + assert_equal %i[visa master american_express jcb discover diners_club], PayflowGateway.supported_cardtypes end def test_successful_verify @@ -309,9 +313,8 @@ def test_initial_recurring_transaction_missing_parameters assert_raises ArgumentError do assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do @gateway.recurring(@amount, @credit_card, - :periodicity => :monthly, - :initial_transaction => { } - ) + periodicity: :monthly, + initial_transaction: {}) end end end @@ -320,9 +323,8 @@ def test_initial_purchase_missing_amount assert_raises ArgumentError do assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do @gateway.recurring(@amount, @credit_card, - :periodicity => :monthly, - :initial_transaction => { :amount => :purchase } - ) + periodicity: :monthly, + initial_transaction: { amount: :purchase }) end end end @@ -347,7 +349,7 @@ def test_successful_recurring_action @gateway.stubs(:ssl_post).returns(successful_recurring_response) response = assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.recurring(@amount, @credit_card, :periodicity => :monthly) + @gateway.recurring(@amount, @credit_card, periodicity: :monthly) end assert_instance_of PayflowResponse, response @@ -361,7 +363,7 @@ def test_successful_recurring_modify_action @gateway.stubs(:ssl_post).returns(successful_recurring_response) response = assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.recurring(@amount, nil, :profile_id => 'RT0000000009', :periodicity => :monthly) + @gateway.recurring(@amount, nil, profile_id: 'RT0000000009', periodicity: :monthly) end assert_instance_of PayflowResponse, response @@ -375,7 +377,7 @@ def test_successful_recurring_modify_action_with_retry_num_days @gateway.stubs(:ssl_post).returns(successful_recurring_response) response = assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.recurring(@amount, nil, :profile_id => 'RT0000000009', :retry_num_days => 3, :periodicity => :monthly) + @gateway.recurring(@amount, nil, profile_id: 'RT0000000009', retry_num_days: 3, periodicity: :monthly) end assert_instance_of PayflowResponse, response @@ -389,7 +391,7 @@ def test_falied_recurring_modify_action_with_starting_at_in_the_past @gateway.stubs(:ssl_post).returns(start_date_error_recurring_response) response = assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.recurring(@amount, nil, :profile_id => 'RT0000000009', :starting_at => Date.yesterday, :periodicity => :monthly) + @gateway.recurring(@amount, nil, profile_id: 'RT0000000009', starting_at: Date.yesterday, periodicity: :monthly) end assert_instance_of PayflowResponse, response @@ -404,7 +406,7 @@ def test_falied_recurring_modify_action_with_starting_at_missing_and_changed_per @gateway.stubs(:ssl_post).returns(start_date_missing_recurring_response) response = assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.recurring(@amount, nil, :profile_id => 'RT0000000009', :periodicity => :yearly) + @gateway.recurring(@amount, nil, profile_id: 'RT0000000009', periodicity: :yearly) end assert_instance_of PayflowResponse, response @@ -419,7 +421,7 @@ def test_recurring_profile_payment_history_inquiry @gateway.stubs(:ssl_post).returns(successful_payment_history_recurring_response) response = assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.recurring_inquiry('RT0000000009', :history => true) + @gateway.recurring_inquiry('RT0000000009', history: true) end assert_equal 1, response.payment_history.size assert_equal '1', response.payment_history.first['payment_num'] @@ -427,7 +429,7 @@ def test_recurring_profile_payment_history_inquiry end def test_recurring_profile_payment_history_inquiry_contains_the_proper_xml - request = @gateway.send(:build_recurring_request, :inquiry, nil, :profile_id => 'RT0000000009', :history => true) + request = @gateway.send(:build_recurring_request, :inquiry, nil, profile_id: 'RT0000000009', history: true) assert_match %r(Y 'maestro' + brand: 'maestro' ) @gateway.send(:add_credit_card, xml, credit_card, @options.merge(three_d_secure_option)) @@ -446,7 +448,7 @@ def test_add_credit_card_with_three_d_secure_frictionless xml = Builder::XmlMarkup.new credit_card = credit_card( '5641820000000005', - :brand => 'maestro' + brand: 'maestro' ) @gateway.send(:add_credit_card, xml, credit_card, @options.merge(three_d_secure_option_frictionless)) @@ -476,7 +478,7 @@ def test_timeout_is_same_in_header_and_xml end def test_name_field_are_included_instead_of_first_and_last - @gateway.expects(:ssl_post).returns(successful_authorization_response).with do |url, data| + @gateway.expects(:ssl_post).returns(successful_authorization_response).with do |_url, data| data !~ /FirstName/ && data !~ /LastName/ && data =~ // end response = @gateway.authorize(@amount, @credit_card, @options) @@ -484,8 +486,8 @@ def test_name_field_are_included_instead_of_first_and_last end def test_passed_in_verbosity - assert_nil PayflowGateway.new(:login => 'test', :password => 'test').options[:verbosity] - gateway = PayflowGateway.new(:login => 'test', :password => 'test', :verbosity => 'HIGH') + assert_nil PayflowGateway.new(login: 'test', password: 'test').options[:verbosity] + gateway = PayflowGateway.new(login: 'test', password: 'test', verbosity: 'HIGH') assert_equal 'HIGH', gateway.options[:verbosity] @gateway.expects(:ssl_post).returns(verbose_transaction_response) response = @gateway.purchase(100, @credit_card, @options) @@ -513,252 +515,252 @@ def test_scrub private def pre_scrubbed - <<-EOS -opening connection to pilot-payflowpro.paypal.com:443... -opened -starting SSL for pilot-payflowpro.paypal.com:443... -SSL established -<- "POST / HTTP/1.1\r\nContent-Type: text/xml\r\nContent-Length: 1017\r\nX-Vps-Client-Timeout: 60\r\nX-Vps-Vit-Integration-Product: ActiveMerchant\r\nX-Vps-Vit-Runtime-Version: 2.1.7\r\nX-Vps-Request-Id: 3b2f9831949b48b4b0b89a33a60f9b0c\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: pilot-payflowpro.paypal.com\r\n\r\n" -<- "spreedlyIntegrationsPayPalMEDIUMcody@example.comJim Smithcody@example.com(555)555-5555codyexample
456 My StreetOttawaONCAK1C2N6
MasterCard5105105105105100201909Longbob123
spreedlyIntegrationsL9DjqEKjXCkU
" --> "HTTP/1.1 200 OK\r\n" --> "Connection: close\r\n" --> "Server: VPS-3.033.00\r\n" --> "X-VPS-Request-ID: 3b2f9831949b48b4b0b89a33a60f9b0c\r\n" --> "Date: Thu, 01 Mar 2018 15:42:15 GMT\r\n" --> "Content-type: text/xml\r\n" --> "Content-length: 267\r\n" --> "\r\n" -reading 267 bytes... --> "4Invalid amount" -read 267 bytes -Conn close - EOS + <<~REQUEST + opening connection to pilot-payflowpro.paypal.com:443... + opened + starting SSL for pilot-payflowpro.paypal.com:443... + SSL established + <- "POST / HTTP/1.1\r\nContent-Type: text/xml\r\nContent-Length: 1017\r\nX-Vps-Client-Timeout: 60\r\nX-Vps-Vit-Integration-Product: ActiveMerchant\r\nX-Vps-Vit-Runtime-Version: 2.1.7\r\nX-Vps-Request-Id: 3b2f9831949b48b4b0b89a33a60f9b0c\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: pilot-payflowpro.paypal.com\r\n\r\n" + <- "spreedlyIntegrationsPayPalMEDIUMcody@example.comJim Smithcody@example.com(555)555-5555codyexample
456 My StreetOttawaONCAK1C2N6
MasterCard5105105105105100201909Longbob123
spreedlyIntegrationsL9DjqEKjXCkU
" + -> "HTTP/1.1 200 OK\r\n" + -> "Connection: close\r\n" + -> "Server: VPS-3.033.00\r\n" + -> "X-VPS-Request-ID: 3b2f9831949b48b4b0b89a33a60f9b0c\r\n" + -> "Date: Thu, 01 Mar 2018 15:42:15 GMT\r\n" + -> "Content-type: text/xml\r\n" + -> "Content-length: 267\r\n" + -> "\r\n" + reading 267 bytes... + -> "4Invalid amount" + read 267 bytes + Conn close + REQUEST end def post_scrubbed - <<-EOS -opening connection to pilot-payflowpro.paypal.com:443... -opened -starting SSL for pilot-payflowpro.paypal.com:443... -SSL established -<- "POST / HTTP/1.1\r\nContent-Type: text/xml\r\nContent-Length: 1017\r\nX-Vps-Client-Timeout: 60\r\nX-Vps-Vit-Integration-Product: ActiveMerchant\r\nX-Vps-Vit-Runtime-Version: 2.1.7\r\nX-Vps-Request-Id: 3b2f9831949b48b4b0b89a33a60f9b0c\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: pilot-payflowpro.paypal.com\r\n\r\n" -<- "spreedlyIntegrationsPayPalMEDIUMcody@example.comJim Smithcody@example.com(555)555-5555codyexample
456 My StreetOttawaONCAK1C2N6
MasterCard[FILTERED]201909Longbob[FILTERED]
spreedlyIntegrations[FILTERED]
" --> "HTTP/1.1 200 OK\r\n" --> "Connection: close\r\n" --> "Server: VPS-3.033.00\r\n" --> "X-VPS-Request-ID: 3b2f9831949b48b4b0b89a33a60f9b0c\r\n" --> "Date: Thu, 01 Mar 2018 15:42:15 GMT\r\n" --> "Content-type: text/xml\r\n" --> "Content-length: 267\r\n" --> "\r\n" -reading 267 bytes... --> "4Invalid amount" -read 267 bytes -Conn close - EOS + <<~REQUEST + opening connection to pilot-payflowpro.paypal.com:443... + opened + starting SSL for pilot-payflowpro.paypal.com:443... + SSL established + <- "POST / HTTP/1.1\r\nContent-Type: text/xml\r\nContent-Length: 1017\r\nX-Vps-Client-Timeout: 60\r\nX-Vps-Vit-Integration-Product: ActiveMerchant\r\nX-Vps-Vit-Runtime-Version: 2.1.7\r\nX-Vps-Request-Id: 3b2f9831949b48b4b0b89a33a60f9b0c\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: pilot-payflowpro.paypal.com\r\n\r\n" + <- "spreedlyIntegrationsPayPalMEDIUMcody@example.comJim Smithcody@example.com(555)555-5555codyexample
456 My StreetOttawaONCAK1C2N6
MasterCard[FILTERED]201909Longbob[FILTERED]
spreedlyIntegrations[FILTERED]
" + -> "HTTP/1.1 200 OK\r\n" + -> "Connection: close\r\n" + -> "Server: VPS-3.033.00\r\n" + -> "X-VPS-Request-ID: 3b2f9831949b48b4b0b89a33a60f9b0c\r\n" + -> "Date: Thu, 01 Mar 2018 15:42:15 GMT\r\n" + -> "Content-type: text/xml\r\n" + -> "Content-length: 267\r\n" + -> "\r\n" + reading 267 bytes... + -> "4Invalid amount" + read 267 bytes + Conn close + REQUEST end def pre_scrubbed_check - <<-EOS -opening connection to pilot-payflowpro.paypal.com:443... -opened -starting SSL for pilot-payflowpro.paypal.com:443... -SSL established -<- "POST / HTTP/1.1\r\nContent-Type: text/xml\r\nContent-Length: 658\r\nX-Vps-Client-Timeout: 60\r\nX-Vps-Vit-Integration-Product: ActiveMerchant\r\nX-Vps-Vit-Runtime-Version: 2.1.7\r\nX-Vps-Request-Id: 863021e6890a0660238ef22d0a21c5f2\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: pilot-payflowpro.paypal.com\r\n\r\n" -<- "spreedlyIntegrationsPayPalMEDIUMJim SmithC1234567801111111118spreedlyIntegrationsL9DjqEKjXCkU" --> "HTTP/1.1 200 OK\r\n" --> "Connection: close\r\n" --> "Server: VPS-3.033.00\r\n" --> "X-VPS-Request-ID: 863021e6890a0660238ef22d0a21c5f2\r\n" --> "Date: Thu, 01 Mar 2018 15:45:59 GMT\r\n" --> "Content-type: text/xml\r\n" --> "Content-length: 267\r\n" --> "\r\n" -reading 267 bytes... --> "4Invalid amount" -read 267 bytes -Conn close - EOS + <<~REQUEST + opening connection to pilot-payflowpro.paypal.com:443... + opened + starting SSL for pilot-payflowpro.paypal.com:443... + SSL established + <- "POST / HTTP/1.1\r\nContent-Type: text/xml\r\nContent-Length: 658\r\nX-Vps-Client-Timeout: 60\r\nX-Vps-Vit-Integration-Product: ActiveMerchant\r\nX-Vps-Vit-Runtime-Version: 2.1.7\r\nX-Vps-Request-Id: 863021e6890a0660238ef22d0a21c5f2\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: pilot-payflowpro.paypal.com\r\n\r\n" + <- "spreedlyIntegrationsPayPalMEDIUMJim SmithC1234567801111111118spreedlyIntegrationsL9DjqEKjXCkU" + -> "HTTP/1.1 200 OK\r\n" + -> "Connection: close\r\n" + -> "Server: VPS-3.033.00\r\n" + -> "X-VPS-Request-ID: 863021e6890a0660238ef22d0a21c5f2\r\n" + -> "Date: Thu, 01 Mar 2018 15:45:59 GMT\r\n" + -> "Content-type: text/xml\r\n" + -> "Content-length: 267\r\n" + -> "\r\n" + reading 267 bytes... + -> "4Invalid amount" + read 267 bytes + Conn close + REQUEST end def post_scrubbed_check - <<-EOS -opening connection to pilot-payflowpro.paypal.com:443... -opened -starting SSL for pilot-payflowpro.paypal.com:443... -SSL established -<- "POST / HTTP/1.1\r\nContent-Type: text/xml\r\nContent-Length: 658\r\nX-Vps-Client-Timeout: 60\r\nX-Vps-Vit-Integration-Product: ActiveMerchant\r\nX-Vps-Vit-Runtime-Version: 2.1.7\r\nX-Vps-Request-Id: 863021e6890a0660238ef22d0a21c5f2\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: pilot-payflowpro.paypal.com\r\n\r\n" -<- "spreedlyIntegrationsPayPalMEDIUMJim SmithC[FILTERED]111111118spreedlyIntegrations[FILTERED]" --> "HTTP/1.1 200 OK\r\n" --> "Connection: close\r\n" --> "Server: VPS-3.033.00\r\n" --> "X-VPS-Request-ID: 863021e6890a0660238ef22d0a21c5f2\r\n" --> "Date: Thu, 01 Mar 2018 15:45:59 GMT\r\n" --> "Content-type: text/xml\r\n" --> "Content-length: 267\r\n" --> "\r\n" -reading 267 bytes... --> "4Invalid amount" -read 267 bytes -Conn close - EOS + <<~REQUEST + opening connection to pilot-payflowpro.paypal.com:443... + opened + starting SSL for pilot-payflowpro.paypal.com:443... + SSL established + <- "POST / HTTP/1.1\r\nContent-Type: text/xml\r\nContent-Length: 658\r\nX-Vps-Client-Timeout: 60\r\nX-Vps-Vit-Integration-Product: ActiveMerchant\r\nX-Vps-Vit-Runtime-Version: 2.1.7\r\nX-Vps-Request-Id: 863021e6890a0660238ef22d0a21c5f2\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: pilot-payflowpro.paypal.com\r\n\r\n" + <- "spreedlyIntegrationsPayPalMEDIUMJim SmithC[FILTERED]111111118spreedlyIntegrations[FILTERED]" + -> "HTTP/1.1 200 OK\r\n" + -> "Connection: close\r\n" + -> "Server: VPS-3.033.00\r\n" + -> "X-VPS-Request-ID: 863021e6890a0660238ef22d0a21c5f2\r\n" + -> "Date: Thu, 01 Mar 2018 15:45:59 GMT\r\n" + -> "Content-type: text/xml\r\n" + -> "Content-length: 267\r\n" + -> "\r\n" + reading 267 bytes... + -> "4Invalid amount" + read 267 bytes + Conn close + REQUEST end def successful_recurring_response - <<-XML - - 0 - Approved - paypal - R7960E739F80 - ActiveMerchant - RT0000000009 - + <<~XML + + 0 + Approved + paypal + R7960E739F80 + ActiveMerchant + RT0000000009 + XML end def start_date_error_recurring_response - <<-XML - - 0 - Field format error: START or NEXTPAYMENTDATE older than last payment date - paypal - R7960E739F80 - ActiveMerchant - RT0000000009 - + <<~XML + + 0 + Field format error: START or NEXTPAYMENTDATE older than last payment date + paypal + R7960E739F80 + ActiveMerchant + RT0000000009 + XML end def start_date_missing_recurring_response - <<-XML - - 0 - Field format error: START field missing - paypal - R7960E739F80 - ActiveMerchant - RT0000000009 - + <<~XML + + 0 + Field format error: START field missing + paypal + R7960E739F80 + ActiveMerchant + RT0000000009 + XML end def successful_payment_history_recurring_response - <<-XML - - 0 - paypal - R7960E739F80 - ActiveMerchant - RT0000000009 - - 1 - V18A0D3048AF - 12-Jan-08 04:30 AM - 0 - C - - 6 - - + <<~XML + + 0 + paypal + R7960E739F80 + ActiveMerchant + RT0000000009 + + 1 + V18A0D3048AF + 12-Jan-08 04:30 AM + 0 + C + + 6 + + XML end def successful_authorization_response - <<-XML - - 0 - Approved - verisign - 000 - AP - VUJN1A6E11D9 - N - Match - 094016 - ActiveMerchant - Y - Match - Match - + <<~XML + + 0 + Approved + verisign + 000 + AP + VUJN1A6E11D9 + N + Match + 094016 + ActiveMerchant + Y + Match + Match + XML end def successful_l3_response - <<-XML - - spreedlyIntegrations - paypal - - - 0 - - Z - M - A - - - No Rules Triggered - - - No Rules Triggered - - N - - No Match - Match - - Match - Approved - A71AAC3B60A1 - 240PNI - - - + <<~XML + + spreedlyIntegrations + paypal + + + 0 + + Z + M + A + + + No Rules Triggered + + + No Rules Triggered + + N + + No Match + Match + + Match + Approved + A71AAC3B60A1 + 240PNI + + + XML end def successful_l2_response - <<-XML - - spreedlyIntegrations - paypal - - - 0 - - A - - Approved - A1ADADCE9B12 - - - + <<~XML + + spreedlyIntegrations + paypal + + + 0 + + A + + Approved + A1ADADCE9B12 + + + XML end def failed_authorization_response - <<-XML - - 12 - Declined - verisign - 000 - AP - VUJN1A6E11D9 - N - Match - 094016 - ActiveMerchant - Y - Match - Match - + <<~XML + + 12 + Declined + verisign + 000 + AP + VUJN1A6E11D9 + N + Match + 094016 + ActiveMerchant + Y + Match + Match + XML end def successful_purchase_with_fraud_review_response - <<-XML + <<~XML spreedly @@ -798,82 +800,82 @@ def successful_purchase_with_fraud_review_response end def successful_duplicate_response - <<-XML - - - - ActiveMerchant - paypal - - - 0 - - A - M - A - - N - - Match - No Match - - Match - Approved - V18A0CBB04CF - 692PNI - - - - - + <<~XML + + + + ActiveMerchant + paypal + + + 0 + + A + M + A + + N + + Match + No Match + + Match + Approved + V18A0CBB04CF + 692PNI + + + + + XML end def verbose_transaction_response - <<-XML - - - - ActiveMerchant - paypal - - - 0 - - U - M - A - - - No Rules Triggered - - - No Rules Triggered - - X - - Service Not Available - Service Not Available - - Match - Approved - A70A6C93C4C8 - 242PNI - 1.00 - 12 - 2014-06-25 09:33:41 - 4242 - 0714 - 0 - - 0 - Longbob - Longsen - - - - - + <<~XML + + + + ActiveMerchant + paypal + + + 0 + + U + M + A + + + No Rules Triggered + + + No Rules Triggered + + X + + Service Not Available + Service Not Available + + Match + Approved + A70A6C93C4C8 + 242PNI + 1.00 + 12 + 2014-06-25 09:33:41 + 4242 + 0714 + 0 + + 0 + Longbob + Longsen + + + + + XML end @@ -907,29 +909,29 @@ def purchase_buyer_auth_result_path def three_d_secure_option { - :three_d_secure => { - :authentication_id => 'QvDbSAxSiaQs241899E0', - :authentication_response_status => 'Y', - :pareq => 'pareq block', - :acs_url => 'https://bankacs.bank.com/ascurl', - :eci => '02', - :cavv => 'jGvQIvG/5UhjAREALGYa6Vu/hto=', - :xid => 'UXZEYlNBeFNpYVFzMjQxODk5RTA=' - } + three_d_secure: { + authentication_id: 'QvDbSAxSiaQs241899E0', + authentication_response_status: 'Y', + pareq: 'pareq block', + acs_url: 'https://bankacs.bank.com/ascurl', + eci: '02', + cavv: 'jGvQIvG/5UhjAREALGYa6Vu/hto=', + xid: 'UXZEYlNBeFNpYVFzMjQxODk5RTA=' + } } end def three_d_secure_option_frictionless { - :three_d_secure => { - :authentication_id => 'QvDbSAxSiaQs241899E0', - :directory_response_status => 'C', - :pareq => 'pareq block', - :acs_url => 'https://bankacs.bank.com/ascurl', - :eci => '02', - :cavv => 'jGvQIvG/5UhjAREALGYa6Vu/hto=', - :xid => 'UXZEYlNBeFNpYVFzMjQxODk5RTA=' - } + three_d_secure: { + authentication_id: 'QvDbSAxSiaQs241899E0', + directory_response_status: 'C', + pareq: 'pareq block', + acs_url: 'https://bankacs.bank.com/ascurl', + eci: '02', + cavv: 'jGvQIvG/5UhjAREALGYa6Vu/hto=', + xid: 'UXZEYlNBeFNpYVFzMjQxODk5RTA=' + } } end end diff --git a/test/unit/gateways/payflow_uk_test.rb b/test/unit/gateways/payflow_uk_test.rb index 9d50c599edd..0b6f812d752 100644 --- a/test/unit/gateways/payflow_uk_test.rb +++ b/test/unit/gateways/payflow_uk_test.rb @@ -3,8 +3,8 @@ class PayflowUkTest < Test::Unit::TestCase def setup @gateway = PayflowUkGateway.new( - :login => 'LOGIN', - :password => 'PASSWORD' + login: 'LOGIN', + password: 'PASSWORD' ) end @@ -25,6 +25,6 @@ def test_supported_countries end def test_supported_card_types - assert_equal [:visa, :master, :american_express, :discover], PayflowUkGateway.supported_cardtypes + assert_equal %i[visa master american_express discover], PayflowUkGateway.supported_cardtypes end end diff --git a/test/unit/gateways/payment_express_test.rb b/test/unit/gateways/payment_express_test.rb index cf15aa1ad92..830dae0f2c9 100644 --- a/test/unit/gateways/payment_express_test.rb +++ b/test/unit/gateways/payment_express_test.rb @@ -5,19 +5,19 @@ class PaymentExpressTest < Test::Unit::TestCase def setup @gateway = PaymentExpressGateway.new( - :login => 'LOGIN', - :password => 'PASSWORD' + login: 'LOGIN', + password: 'PASSWORD' ) @visa = credit_card - @solo = credit_card('6334900000000005', :brand => 'maestro') + @solo = credit_card('6334900000000005', brand: 'maestro') @options = { - :order_id => generate_unique_id, - :billing_address => address, - :email => 'cody@example.com', - :description => 'Store purchase' + order_id: generate_unique_id, + billing_address: address, + email: 'cody@example.com', + description: 'Store purchase' } @amount = 100 @@ -45,6 +45,16 @@ def test_successful_authorization assert_equal '00000004011a2478', response.authorization end + def test_successful_validation + @gateway.expects(:ssl_post).returns(successful_validation_response) + + assert response = @gateway.verify(@visa, @options) + assert_success response + assert response.test? + assert_equal 'The Transaction was approved', response.message + assert_equal '0000000c025d2744', response.authorization + end + def test_purchase_request_should_include_cvc2_presence @gateway.expects(:commit).with do |type, request| type == :purchase && request.to_s =~ %r{1<\/Cvc2Presence>} @@ -74,9 +84,9 @@ def test_successful_card_store end def test_successful_card_store_with_custom_billing_id - @gateway.expects(:ssl_post).returns(successful_store_response(:billing_id => 'my-custom-id')) + @gateway.expects(:ssl_post).returns(successful_store_response(billing_id: 'my-custom-id')) - assert response = @gateway.store(@visa, :billing_id => 'my-custom-id') + assert response = @gateway.store(@visa, billing_id: 'my-custom-id') assert_success response assert response.test? assert_equal 'my-custom-id', response.token @@ -107,14 +117,14 @@ def test_purchase_using_dps_billing_id_token def test_purchase_using_merchant_specified_billing_id_token @gateway = PaymentExpressGateway.new( - :login => 'LOGIN', - :password => 'PASSWORD', - :use_custom_payment_token => true + login: 'LOGIN', + password: 'PASSWORD', + use_custom_payment_token: true ) - @gateway.expects(:ssl_post).returns(successful_store_response({:billing_id => 'TEST1234'})) + @gateway.expects(:ssl_post).returns(successful_store_response({ billing_id: 'TEST1234' })) - assert response = @gateway.store(@visa, {:billing_id => 'TEST1234'}) + assert response = @gateway.store(@visa, { billing_id: 'TEST1234' }) assert_equal 'TEST1234', response.token @gateway.expects(:ssl_post).returns(successful_billing_id_token_purchase_response) @@ -130,7 +140,7 @@ def test_supported_countries end def test_supported_card_types - assert_equal [ :visa, :master, :american_express, :diners_club, :jcb ], PaymentExpressGateway.supported_cardtypes + assert_equal %i[visa master american_express diners_club jcb], PaymentExpressGateway.supported_cardtypes end def test_avs_result_not_supported @@ -158,9 +168,9 @@ def test_expect_no_optional_fields_by_default def test_pass_optional_txn_data options = { - :txn_data1 => 'Transaction Data 1', - :txn_data2 => 'Transaction Data 2', - :txn_data3 => 'Transaction Data 3' + txn_data1: 'Transaction Data 1', + txn_data2: 'Transaction Data 2', + txn_data3: 'Transaction Data 3' } perform_each_transaction_type_with_request_body_assertions(options) do |body| @@ -172,9 +182,9 @@ def test_pass_optional_txn_data def test_pass_optional_txn_data_truncated_to_255_chars options = { - :txn_data1 => 'Transaction Data 1-01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345-EXTRA', - :txn_data2 => 'Transaction Data 2-01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345-EXTRA', - :txn_data3 => 'Transaction Data 3-01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345-EXTRA' + txn_data1: 'Transaction Data 1-01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345-EXTRA', + txn_data2: 'Transaction Data 2-01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345-EXTRA', + txn_data3: 'Transaction Data 3-01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345-EXTRA' } truncated_addendum = '01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345' @@ -187,7 +197,7 @@ def test_pass_optional_txn_data_truncated_to_255_chars end def test_pass_client_type_as_symbol_for_web - options = {:client_type => :web} + options = { client_type: :web } perform_each_transaction_type_with_request_body_assertions(options) do |body| assert_match(/Web<\/ClientType>/, body) @@ -195,7 +205,7 @@ def test_pass_client_type_as_symbol_for_web end def test_pass_client_type_as_symbol_for_ivr - options = {:client_type => :ivr} + options = { client_type: :ivr } perform_each_transaction_type_with_request_body_assertions(options) do |body| assert_match(/IVR<\/ClientType>/, body) @@ -203,7 +213,7 @@ def test_pass_client_type_as_symbol_for_ivr end def test_pass_client_type_as_symbol_for_moto - options = {:client_type => :moto} + options = { client_type: :moto } perform_each_transaction_type_with_request_body_assertions(options) do |body| assert_match(/MOTO<\/ClientType>/, body) @@ -211,7 +221,7 @@ def test_pass_client_type_as_symbol_for_moto end def test_pass_client_type_as_symbol_for_unattended - options = {:client_type => :unattended} + options = { client_type: :unattended } perform_each_transaction_type_with_request_body_assertions(options) do |body| assert_match(/Unattended<\/ClientType>/, body) @@ -219,7 +229,7 @@ def test_pass_client_type_as_symbol_for_unattended end def test_pass_client_type_as_symbol_for_internet - options = {:client_type => :internet} + options = { client_type: :internet } perform_each_transaction_type_with_request_body_assertions(options) do |body| assert_match(/Internet<\/ClientType>/, body) @@ -227,7 +237,7 @@ def test_pass_client_type_as_symbol_for_internet end def test_pass_client_type_as_symbol_for_recurring - options = {:client_type => :recurring} + options = { client_type: :recurring } perform_each_transaction_type_with_request_body_assertions(options) do |body| assert_match(/Recurring<\/ClientType>/, body) @@ -235,7 +245,7 @@ def test_pass_client_type_as_symbol_for_recurring end def test_pass_client_type_as_symbol_for_unknown_type_omits_element - options = {:client_type => :unknown} + options = { client_type: :unknown } perform_each_transaction_type_with_request_body_assertions(options) do |body| assert_no_match(//, body) @@ -243,7 +253,7 @@ def test_pass_client_type_as_symbol_for_unknown_type_omits_element end def test_pass_ip_as_client_info - options = {:ip => '192.168.0.1'} + options = { ip: '192.168.0.1' } perform_each_transaction_type_with_request_body_assertions(options) do |body| assert_match(/192.168.0.1<\/ClientInfo>/, body) @@ -252,64 +262,64 @@ def test_pass_ip_as_client_info def test_purchase_truncates_order_id_to_16_chars stub_comms do - @gateway.purchase(@amount, @visa, {:order_id => '16chars---------EXTRA'}) - end.check_request do |endpoint, data, headers| + @gateway.purchase(@amount, @visa, { order_id: '16chars---------EXTRA' }) + end.check_request do |_endpoint, data, _headers| assert_match(/16chars---------<\/TxnId>/, data) end.respond_with(successful_authorization_response) end def test_authorize_truncates_order_id_to_16_chars stub_comms do - @gateway.authorize(@amount, @visa, {:order_id => '16chars---------EXTRA'}) - end.check_request do |endpoint, data, headers| + @gateway.authorize(@amount, @visa, { order_id: '16chars---------EXTRA' }) + end.check_request do |_endpoint, data, _headers| assert_match(/16chars---------<\/TxnId>/, data) end.respond_with(successful_authorization_response) end def test_capture_truncates_order_id_to_16_chars stub_comms do - @gateway.capture(@amount, 'identification', {:order_id => '16chars---------EXTRA'}) - end.check_request do |endpoint, data, headers| + @gateway.capture(@amount, 'identification', { order_id: '16chars---------EXTRA' }) + end.check_request do |_endpoint, data, _headers| assert_match(/16chars---------<\/TxnId>/, data) end.respond_with(successful_authorization_response) end def test_refund_truncates_order_id_to_16_chars stub_comms do - @gateway.refund(@amount, 'identification', {:description => 'refund', :order_id => '16chars---------EXTRA'}) - end.check_request do |endpoint, data, headers| + @gateway.refund(@amount, 'identification', { description: 'refund', order_id: '16chars---------EXTRA' }) + end.check_request do |_endpoint, data, _headers| assert_match(/16chars---------<\/TxnId>/, data) end.respond_with(successful_authorization_response) end def test_purchase_truncates_description_to_50_chars stub_comms do - @gateway.purchase(@amount, @visa, {:description => '50chars-------------------------------------------EXTRA'}) - end.check_request do |endpoint, data, headers| + @gateway.purchase(@amount, @visa, { description: '50chars-------------------------------------------EXTRA' }) + end.check_request do |_endpoint, data, _headers| assert_match(/50chars-------------------------------------------<\/MerchantReference>/, data) end.respond_with(successful_authorization_response) end def test_authorize_truncates_description_to_50_chars stub_comms do - @gateway.authorize(@amount, @visa, {:description => '50chars-------------------------------------------EXTRA'}) - end.check_request do |endpoint, data, headers| + @gateway.authorize(@amount, @visa, { description: '50chars-------------------------------------------EXTRA' }) + end.check_request do |_endpoint, data, _headers| assert_match(/50chars-------------------------------------------<\/MerchantReference>/, data) end.respond_with(successful_authorization_response) end def test_capture_truncates_description_to_50_chars stub_comms do - @gateway.capture(@amount, 'identification', {:description => '50chars-------------------------------------------EXTRA'}) - end.check_request do |endpoint, data, headers| + @gateway.capture(@amount, 'identification', { description: '50chars-------------------------------------------EXTRA' }) + end.check_request do |_endpoint, data, _headers| assert_match(/50chars-------------------------------------------<\/MerchantReference>/, data) end.respond_with(successful_authorization_response) end def test_refund_truncates_description_to_50_chars stub_comms do - @gateway.capture(@amount, 'identification', {:description => '50chars-------------------------------------------EXTRA'}) - end.check_request do |endpoint, data, headers| + @gateway.capture(@amount, 'identification', { description: '50chars-------------------------------------------EXTRA' }) + end.check_request do |_endpoint, data, _headers| assert_match(/50chars-------------------------------------------<\/MerchantReference>/, data) end.respond_with(successful_authorization_response) end @@ -324,35 +334,35 @@ def perform_each_transaction_type_with_request_body_assertions(options = {}) # purchase stub_comms do @gateway.purchase(@amount, @visa, options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| yield data end.respond_with(successful_authorization_response) # authorize stub_comms do @gateway.authorize(@amount, @visa, options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| yield data end.respond_with(successful_authorization_response) # capture stub_comms do @gateway.capture(@amount, 'identification', options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| yield data end.respond_with(successful_authorization_response) # refund stub_comms do - @gateway.refund(@amount, 'identification', {:description => 'description'}.merge(options)) - end.check_request do |endpoint, data, headers| + @gateway.refund(@amount, 'identification', { description: 'description' }.merge(options)) + end.check_request do |_endpoint, data, _headers| yield data end.respond_with(successful_authorization_response) # store stub_comms do @gateway.store(@visa, options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| yield data end.respond_with(successful_store_response) end @@ -366,74 +376,398 @@ def invalid_credentials_response end def successful_authorization_response - <<-RESPONSE - - - 1 - Test Transaction - M - Visa - 0 - 0 - 015921 - 1.23 - 1 - NZD - WestpacTrust - 1 - NZD - 1.00 - WestpacTrust - 30102000 - 1 - DPS - 20050811 - Purchase - 411111 - 0807 - - 20050811 - 060039 - 9000 - Test - 1 - 2 - APPROVED - The Transaction was approved - The Transaction was approved - APPROVED - The Transaction was approved - The Transaction was approved - 9997 - 00000004011a2478 - 0 - - - 011a2478 - - 00 - APPROVED - The Transaction was approved - 1 - 00000004011a2478 - + <<~RESPONSE + + + 1 + Test Transaction + M + Visa + 0 + 0 + 015921 + 1.23 + 1 + NZD + WestpacTrust + 1 + NZD + 1.00 + WestpacTrust + 30102000 + 1 + DPS + 20050811 + Purchase + 411111 + 0807 + + 20050811 + 060039 + 9000 + Test + 1 + 2 + APPROVED + The Transaction was approved + The Transaction was approved + APPROVED + The Transaction was approved + The Transaction was approved + 9997 + 00000004011a2478 + 0 + + + 011a2478 + + 00 + APPROVED + The Transaction was approved + 1 + 00000004011a2478 + + RESPONSE + end + + def successful_validation_response + <<~RESPONSE + + + 1 + 00 + 20210126161020 + 20210127051020 + NZT + Store purchase + Visa + 0 + 0 + 051020XXX + 0.00 + 1.00 + 554 + NZD + 554 + NZD + 1.00 + LONGBOB LONGSEN + 20210127 + Auth + 411111........11 + 2BC20210 + 0922 + + 20210127 + 051020 + 9001 + Undefined + 00 + APPROVED + 1 + 2 + APPROVED + The Transaction was approved + The Transaction was approved + APPROVED + The Transaction was approved + The Transaction was approved + + + 0 + + + + + + + U + K1C2N6 + 456 My Street + E + E - AVS data is invalid, or AVS not allowed for this card type + Attempt + 10000000-10003813 + 451734 + 9997 + 0000000c025d2744 + 0 + + + + + + 9310200000000010 + 0 + 025d2744 + 0000000c + + 0000000000000000 + -1 + + + + + 0000000000000000 + -1 + + 00 + APPROVED + Transaction Approved + 1 + 0000000c025d2744 + + 5f3d2cde30deeef0 + RESPONSE end def successful_store_response(options = {}) - %(1Visa0002381203accf5c000000030.01554554NZD1.00NZDBOB BOBSEN20070323Auth424242........420809200703230238129000Test12APPROVEDThe Transaction was approvedThe Transaction was approvedAPPROVEDThe Transaction was approvedThe Transaction was approved09999999999-999999991283599970000000303accf5c00000030000141581#{options[:billing_id]}03accf5c0000000300APPROVEDThe Transaction was approved10000000303accf5c) + <<~RESPONSE + + + 1 + + Visa + 0 + 0 + 02381203accf5c00000003 + 0.01 + 554 + 554 + NZD + 1.00 + NZD + BOB BOBSEN + 20070323 + Auth + 424242........42 + 0809 + + 20070323 + 023812 + 9000 + Test + 1 + 2 + APPROVED + The Transaction was approved + The Transaction was approved + APPROVED + The Transaction was approved + The Transaction was approved + + + 0 + + + + + + 9999999999-99999999 + 12835 + 9997 + 0000000303accf5c + 0 + 0000030000141581 + #{options[:billing_id]} + 03accf5c + 00000003 + + 00 + APPROVED + The Transaction was approved + 1 + 0000000303accf5c + + + RESPONSE end def unsuccessful_store_response(options = {}) - %(0000.01554554NZD1.00NZDLONGBOB LONGSEN19800101Validate000000........000808900000INVALID CARD NUMBERAn Invalid Card Number was entered. Check the card numberAn Invalid Card Number was entered. Check the card numberINVALID CARD NUMBERAn Invalid Card Number was entered. Check the card numberAn Invalid Card Number was entered. Check the card number09999999999-999999990999700000000000000003QKINVALID CARD NUMBERAn Invalid Card Number was entered. Check the card number0) + <<~RESPONSE + + + 0 + + + 0 + 0 + + 0.01 + 554 + 554 + NZD + 1.00 + NZD + LONGBOB LONGSEN + 19800101 + Validate + 000000........00 + 0808 + + + + 9000 + + 0 + 0 + INVALID CARD NUMBER + An Invalid Card Number was entered. Check the card number + An Invalid Card Number was entered. Check the card number + INVALID CARD NUMBER + An Invalid Card Number was entered. Check the card number + An Invalid Card Number was entered. Check the card number + + + 0 + + + + + + 9999999999-99999999 + 0 + 9997 + + 0 + + + 00000000 + 00000003 + + QK + INVALID CARD NUMBER + An Invalid Card Number was entered. Check the card number + 0 + + + + RESPONSE end def successful_dps_billing_id_token_purchase_response - %(1Visa0003081710.00554554NZD1.00NZDLONGBOB LONGSEN20070323Purchase424242........420808200703230308179000Test12APPROVEDThe Transaction was approvedThe Transaction was approvedAPPROVEDThe Transaction was approvedThe Transaction was approved09999999999-999999991285999970000000303ace8db0000003000014158103ace8db0000000300APPROVEDThe Transaction was approved10000000303ace8db) + <<~RESPONSE + + + 1 + + Visa + 0 + 0 + 030817 + 10.00 + 554 + 554 + NZD + 1.00 + NZD + LONGBOB LONGSEN + 20070323 + Purchase + 424242........42 + 0808 + + 20070323 + 030817 + 9000 + Test + 1 + 2 + APPROVED + The Transaction was approved + The Transaction was approved + APPROVED + The Transaction was approved + The Transaction was approved + + + 0 + + + + + + 9999999999-99999999 + 12859 + 9997 + 0000000303ace8db + 0 + 0000030000141581 + + 03ace8db + 00000003 + + 00 + APPROVED + The Transaction was approved + 1 + 0000000303ace8db + + + RESPONSE end def successful_billing_id_token_purchase_response - %(1Visa0003081710.00554554NZD1.00NZDLONGBOB LONGSEN20070323Purchase424242........420808200703230308179000Test12APPROVEDThe Transaction was approvedThe Transaction was approvedAPPROVEDThe Transaction was approvedThe Transaction was approved09999999999-999999991285999970000000303ace8db0TEST123403ace8db0000000300APPROVEDThe Transaction was approved10000000303ace8db) + <<~RESPONSE + + + 1 + + Visa + 0 + 0 + 030817 + 10.00 + 554 + 554 + NZD + 1.00 + NZD + LONGBOB LONGSEN + 20070323 + Purchase + 424242........42 + 0808 + + 20070323 + 030817 + 9000 + Test + 1 + 2 + APPROVED + The Transaction was approved + The Transaction was approved + APPROVED + The Transaction was approved + The Transaction was approved + + + 0 + + + + + + 9999999999-99999999 + 12859 + 9997 + 0000000303ace8db + 0 + + TEST1234 + 03ace8db + 00000003 + + 00 + APPROVED + The Transaction was approved + 1 + 0000000303ace8db + + + RESPONSE end def transcript diff --git a/test/unit/gateways/paymentez_test.rb b/test/unit/gateways/paymentez_test.rb index 3e6df5428e6..5c486b96805 100644 --- a/test/unit/gateways/paymentez_test.rb +++ b/test/unit/gateways/paymentez_test.rb @@ -7,13 +7,12 @@ def setup @gateway = PaymentezGateway.new(application_code: 'foo', app_key: 'bar') @credit_card = credit_card @elo_credit_card = credit_card('6362970000457013', - :month => 10, - :year => 2020, - :first_name => 'John', - :last_name => 'Smith', - :verification_value => '737', - :brand => 'elo' - ) + month: 10, + year: 2020, + first_name: 'John', + last_name: 'Smith', + verification_value: '737', + brand: 'elo') @amount = 100 @options = { @@ -23,6 +22,29 @@ def setup description: 'Store Purchase', email: 'a@b.com' } + + @cavv = 'example-cavv-value' + @xid = 'three-ds-v1-trans-id' + @eci = '01' + @three_ds_v1_version = '1.0.2' + @three_ds_v2_version = '2.1.0' + @three_ds_server_trans_id = 'three-ds-v2-trans-id' + @authentication_response_status = 'Y' + + @three_ds_v1_mpi = { + cavv: @cavv, + eci: @eci, + version: @three_ds_v1_version, + xid: @xid + } + + @three_ds_v2_mpi = { + cavv: @cavv, + eci: @eci, + version: @three_ds_v2_version, + three_ds_server_trans_id: @three_ds_server_trans_id, + authentication_response_status: @authentication_response_status + } end def test_successful_purchase @@ -55,6 +77,41 @@ def test_successful_purchase_with_token assert response.test? end + def test_purchase_3ds1_mpi_fields + @options[:three_d_secure] = @three_ds_v1_mpi + + expected_auth_data = { + cavv: @cavv, + xid: @xid, + eci: @eci, + version: @three_ds_v1_version + } + + @gateway.expects(:commit_transaction).with do |_, post_data| + post_data['extra_params'][:auth_data] == expected_auth_data + end + + @gateway.purchase(@amount, @credit_card, @options) + end + + def test_purchase_3ds2_mpi_fields + @options[:three_d_secure] = @three_ds_v2_mpi + + expected_auth_data = { + cavv: @cavv, + eci: @eci, + version: @three_ds_v2_version, + reference_id: @three_ds_server_trans_id, + status: @authentication_response_status + } + + @gateway.expects(:commit_transaction).with() do |_, post_data| + post_data['extra_params'][:auth_data] == expected_auth_data + end + + @gateway.purchase(@amount, @credit_card, @options) + end + def test_failed_purchase @gateway.expects(:ssl_post).returns(failed_purchase_response) @@ -99,6 +156,41 @@ def test_successful_authorize_with_token assert response.test? end + def test_authorize_3ds1_mpi_fields + @options[:three_d_secure] = @three_ds_v1_mpi + + expected_auth_data = { + cavv: @cavv, + xid: @xid, + eci: @eci, + version: @three_ds_v1_version + } + + @gateway.expects(:commit_transaction).with() do |_, post_data| + post_data['extra_params'][:auth_data] == expected_auth_data + end + + @gateway.authorize(@amount, @credit_card, @options) + end + + def test_authorize_3ds2_mpi_fields + @options[:three_d_secure] = @three_ds_v2_mpi + + expected_auth_data = { + cavv: @cavv, + eci: @eci, + version: @three_ds_v2_version, + reference_id: @three_ds_server_trans_id, + status: @authentication_response_status + } + + @gateway.expects(:commit_transaction).with() do |_, post_data| + post_data['extra_params'][:auth_data] == expected_auth_data + end + + @gateway.authorize(@amount, @credit_card, @options) + end + def test_failed_authorize @gateway.expects(:ssl_post).returns(failed_authorize_response) @@ -157,6 +249,7 @@ def test_partial_refund assert_match(/"amount":1.0/, data) end.respond_with(successful_refund_response) assert_success response + assert_equal 'Completed', response.message assert response.test? end @@ -165,6 +258,7 @@ def test_failed_refund response = @gateway.refund(@amount, '1234', @options) assert_failure response + assert_equal 'Invalid Status', response.message assert response.test? end @@ -173,6 +267,7 @@ def test_successful_void response = @gateway.void('1234', @options) assert_success response + assert_equal 'Completed', response.message assert response.test? end @@ -180,6 +275,7 @@ def test_failed_void @gateway.expects(:ssl_post).returns(failed_void_response) response = @gateway.void('1234', @options) + assert_equal 'Invalid Status', response.message assert_failure response end @@ -508,11 +604,11 @@ def successful_void_response end def failed_void_response - '{"error": {"type": "Carrier not supported", "help": "", "description": "{}"}}' + '{"status": "failure", "detail": "Invalid Status"}' end - alias_method :successful_refund_response, :successful_void_response - alias_method :failed_refund_response, :failed_void_response + alias successful_refund_response successful_void_response + alias failed_refund_response failed_void_response def already_stored_response '{"error": {"type": "Card already added: 14436664108567261211", "help": "If you want to update the card, first delete it", "description": "{}"}}' diff --git a/test/unit/gateways/paymill_test.rb b/test/unit/gateways/paymill_test.rb index f44e8b07c30..40fd6191ee2 100644 --- a/test/unit/gateways/paymill_test.rb +++ b/test/unit/gateways/paymill_test.rb @@ -2,7 +2,7 @@ class PaymillTest < Test::Unit::TestCase def setup - @gateway = PaymillGateway.new(:public_key => 'PUBLIC', :private_key => 'PRIVATE') + @gateway = PaymillGateway.new(public_key: 'PUBLIC', private_key: 'PRIVATE') @credit_card = credit_card @amount = 100 @@ -776,5 +776,4 @@ def transcript def scrubbed_transcript 'connection_uri=https://test-token.paymill.com?account.number=[FILTERED]&account.expiry.month=09&account.expiry.year=2016&account.verification=[FILTERED]' end - end diff --git a/test/unit/gateways/paypal/paypal_common_api_test.rb b/test/unit/gateways/paypal/paypal_common_api_test.rb index 49751604ab9..da1592285f4 100644 --- a/test/unit/gateways/paypal/paypal_common_api_test.rb +++ b/test/unit/gateways/paypal/paypal_common_api_test.rb @@ -18,20 +18,20 @@ def setup CommonPaypalGateway.pem_file = nil @gateway = CommonPaypalGateway.new( - :login => 'cody', - :password => 'test', - :pem => 'PEM' + login: 'cody', + password: 'test', + pem: 'PEM' ) @address = { - :address1 => '1234 My Street', - :address2 => 'Apt 1', - :company => 'Widgets Inc', - :city => 'Ottawa', - :state => 'ON', - :zip => 'K1C2N6', - :country => 'Canada', - :phone => '(555)555-5555' + address1: '1234 My Street', + address2: 'Apt 1', + company: 'Widgets Inc', + city: 'Ottawa', + state: 'ON', + zip: 'K1C2N6', + country: 'Canada', + phone: '(555)555-5555' } end @@ -44,34 +44,68 @@ def wrap_xml(&block) end def test_add_payment_details_adds_express_only_payment_details_when_necessary - options = {:express_request => true} + options = { express_request: true } @gateway.expects(:add_express_only_payment_details) @gateway.send(:add_payment_details, xml_builder, 100, 'USD', options) end def test_add_payment_details_adds_items_details - options = {:items => [1]} + options = { items: [1] } @gateway.expects(:add_payment_details_items_xml) @gateway.send(:add_payment_details, xml_builder, 100, 'USD', options) end def test_add_payment_details_adds_address - options = {:shipping_address => @address} + options = { shipping_address: @address } @gateway.expects(:add_address) @gateway.send(:add_payment_details, xml_builder, 100, 'USD', options) end def test_add_payment_details_adds_items_details_elements - options = {:items => [{:name => 'foo'}]} + options = { items: [{ name: 'foo' }] } request = wrap_xml do |xml| @gateway.send(:add_payment_details, xml, 100, 'USD', options) end assert_equal 'foo', REXML::XPath.first(request, '//n2:PaymentDetails/n2:PaymentDetailsItem/n2:Name').text end + def test_add_payment_details_adds_order_total_elements + options = { + subtotal: 25, + shipping: 5, + handling: 2, + tax: 1 + } + request = wrap_xml do |xml| + @gateway.send(:add_payment_details, xml, 100, 'USD', options) + end + + assert_equal '25', REXML::XPath.first(request, '//n2:PaymentDetails/n2:ItemTotal').text + assert_equal '5', REXML::XPath.first(request, '//n2:PaymentDetails/n2:ShippingTotal').text + assert_equal '2', REXML::XPath.first(request, '//n2:PaymentDetails/n2:HandlingTotal').text + assert_equal '1', REXML::XPath.first(request, '//n2:PaymentDetails/n2:TaxTotal').text + end + + def test_add_payment_details_does_not_add_order_total_elements_when_any_element_is_nil + options = { + subtotal: nil, + shipping: 5, + handling: 2, + tax: 1 + } + request = wrap_xml do |xml| + @gateway.send(:add_payment_details, xml, 100, 'USD', options) + end + + assert_equal nil, REXML::XPath.first(request, '//n2:PaymentDetails/n2:ItemTotal') + assert_equal nil, REXML::XPath.first(request, '//n2:PaymentDetails/n2:ShippingTotal') + assert_equal nil, REXML::XPath.first(request, '//n2:PaymentDetails/n2:HandlingTotal') + assert_equal nil, REXML::XPath.first(request, '//n2:PaymentDetails/n2:TaxTotal') + end + def test_add_express_only_payment_details_adds_non_blank_fields request = wrap_xml do |xml| - @gateway.send(:add_express_only_payment_details, xml, {:payment_action => 'Sale', :payment_request_id => ''}) + @gateway.send(:add_express_only_payment_details, xml, { payment_action: 'Sale', payment_request_id: '' }) end assert_equal 'Sale', REXML::XPath.first(request, '//n2:PaymentAction').text assert_nil REXML::XPath.first(request, '//n2:PaymentRequestID') @@ -85,7 +119,7 @@ def test_build_request_wrapper_plain end def test_build_request_wrapper_with_request_details - result = @gateway.send(:build_request_wrapper, 'Action', :request_details => true) do |xml| + result = @gateway.send(:build_request_wrapper, 'Action', request_details: true) do |xml| xml.tag! 'n2:TransactionID', 'baz' end assert_equal 'baz', REXML::XPath.first(REXML::Document.new(result), '//ActionReq/ActionRequest/n2:ActionRequestDetails/n2:TransactionID').text @@ -101,24 +135,24 @@ def test_build_get_balance assert_equal '1', REXML::XPath.first(request, '//GetBalanceReq/GetBalanceRequest/ReturnAllCurrencies').text end - def test_balance_cleans_up_currencies_values_like_1 + def test_balance_cleans_up_currencies_values_like_one @gateway.stubs(:commit) - [1, '1', true].each do |values_like_1| + [1, '1', true].each do |values_like_one| @gateway.expects(:build_get_balance).with('1') - @gateway.balance(values_like_1) + @gateway.balance(values_like_one) end end - def test_balance_cleans_up_currencies_values_like_0 + def test_balance_cleans_up_currencies_values_like_zero @gateway.stubs(:commit) - [0, '0', false, nil, :foo].each do |values_like_0| + [0, '0', false, nil, :foo].each do |values_like_zero| @gateway.expects(:build_get_balance).with('0') - @gateway.balance(values_like_0) + @gateway.balance(values_like_zero) end end def test_build_do_authorize_request - request = REXML::Document.new(@gateway.send(:build_do_authorize, 123, 100, :currency => 'USD')) + request = REXML::Document.new(@gateway.send(:build_do_authorize, 123, 100, currency: 'USD')) assert_equal '123', REXML::XPath.first(request, '//DoAuthorizationReq/DoAuthorizationRequest/TransactionID').text assert_equal '1.00', REXML::XPath.first(request, '//DoAuthorizationReq/DoAuthorizationRequest/Amount').text end @@ -137,10 +171,10 @@ def test_transaction_search_requires def test_build_transaction_search_request options = { - :start_date => DateTime.new(2012, 2, 21, 0), - :end_date => DateTime.new(2012, 3, 21, 0), - :receiver => 'foo@example.com', - :first_name => 'Robert' + start_date: DateTime.new(2012, 2, 21, 0), + end_date: DateTime.new(2012, 3, 21, 0), + receiver: 'foo@example.com', + first_name: 'Robert' } request = REXML::Document.new(@gateway.send(:build_transaction_search, options)) assert_match %r{^2012-02-21T\d{2}:00:00Z$}, REXML::XPath.first(request, '//TransactionSearchReq/TransactionSearchRequest/StartDate').text @@ -152,17 +186,16 @@ def test_build_reference_transaction_request assert_raise ArgumentError do @gateway.reference_transaction(100) end - @gateway.reference_transaction(100, :reference_id => 'id') + @gateway.reference_transaction(100, reference_id: 'id') end def test_build_reference_transaction_gets_ip request = REXML::Document.new(@gateway.send(:build_reference_transaction_request, 100, - :reference_id => 'id', - :ip => '127.0.0.1')) + reference_id: 'id', + ip: '127.0.0.1')) assert_equal '100', REXML::XPath.first(request, '//n2:PaymentDetails/n2:OrderTotal').text assert_equal 'id', REXML::XPath.first(request, '//DoReferenceTransactionReq/DoReferenceTransactionRequest/n2:DoReferenceTransactionRequestDetails/n2:ReferenceID').text assert_equal '127.0.0.1', REXML::XPath.first(request, '//DoReferenceTransactionReq/DoReferenceTransactionRequest/n2:DoReferenceTransactionRequestDetails/n2:IPAddress').text end - end diff --git a/test/unit/gateways/paypal_digital_goods_test.rb b/test/unit/gateways/paypal_digital_goods_test.rb index 4b433f38843..605fcadb518 100644 --- a/test/unit/gateways/paypal_digital_goods_test.rb +++ b/test/unit/gateways/paypal_digital_goods_test.rb @@ -8,9 +8,9 @@ class PaypalDigitalGoodsTest < Test::Unit::TestCase def setup @gateway = PaypalDigitalGoodsGateway.new( - :login => 'cody', - :password => 'test', - :pem => 'PEM' + login: 'cody', + password: 'test', + pem: 'PEM' ) Base.mode = :test @@ -35,42 +35,42 @@ def test_test_redirect_url def test_setup_request_invalid_requests assert_raise ArgumentError do @gateway.setup_purchase(100, - :ip => '127.0.0.1', - :description => 'Test Title', - :return_url => 'http://return.url', - :cancel_return_url => 'http://cancel.url') + ip: '127.0.0.1', + description: 'Test Title', + return_url: 'http://return.url', + cancel_return_url: 'http://cancel.url') end assert_raise ArgumentError do @gateway.setup_purchase(100, - :ip => '127.0.0.1', - :description => 'Test Title', - :return_url => 'http://return.url', - :cancel_return_url => 'http://cancel.url', - :items => [ ]) + ip: '127.0.0.1', + description: 'Test Title', + return_url: 'http://return.url', + cancel_return_url: 'http://cancel.url', + items: []) end assert_raise ArgumentError do @gateway.setup_purchase(100, - :ip => '127.0.0.1', - :description => 'Test Title', - :return_url => 'http://return.url', - :cancel_return_url => 'http://cancel.url', - :items => [ Hash.new ]) + ip: '127.0.0.1', + description: 'Test Title', + return_url: 'http://return.url', + cancel_return_url: 'http://cancel.url', + items: [Hash.new]) end assert_raise ArgumentError do @gateway.setup_purchase(100, - :ip => '127.0.0.1', - :description => 'Test Title', - :return_url => 'http://return.url', - :cancel_return_url => 'http://cancel.url', - :items => [ { :name => 'Charge', - :number => '1', - :quantity => '1', - :amount => 100, - :description => 'Description', - :category => 'Physical' } ]) + ip: '127.0.0.1', + description: 'Test Title', + return_url: 'http://return.url', + cancel_return_url: 'http://cancel.url', + items: [{ name: 'Charge', + number: '1', + quantity: '1', + amount: 100, + description: 'Description', + category: 'Physical' }]) end end @@ -78,16 +78,16 @@ def test_build_setup_request_valid @gateway.expects(:ssl_post).returns(successful_setup_response) @gateway.setup_purchase(100, - :ip => '127.0.0.1', - :description => 'Test Title', - :return_url => 'http://return.url', - :cancel_return_url => 'http://cancel.url', - :items => [ { :name => 'Charge', - :number => '1', - :quantity => '1', - :amount => 100, - :description => 'Description', - :category => 'Digital' } ]) + ip: '127.0.0.1', + description: 'Test Title', + return_url: 'http://return.url', + cancel_return_url: 'http://cancel.url', + items: [{ name: 'Charge', + number: '1', + quantity: '1', + amount: 100, + description: 'Description', + category: 'Digital' }]) end private @@ -118,5 +118,4 @@ def successful_setup_response " end - end diff --git a/test/unit/gateways/paypal_express_test.rb b/test/unit/gateways/paypal_express_test.rb index 6d5fc21f225..e34be947916 100644 --- a/test/unit/gateways/paypal_express_test.rb +++ b/test/unit/gateways/paypal_express_test.rb @@ -14,20 +14,20 @@ class PaypalExpressTest < Test::Unit::TestCase def setup @gateway = PaypalExpressGateway.new( - :login => 'cody', - :password => 'test', - :pem => 'PEM' + login: 'cody', + password: 'test', + pem: 'PEM' ) @address = { - :address1 => '1234 My Street', - :address2 => 'Apt 1', - :company => 'Widgets Inc', - :city => 'Ottawa', - :state => 'ON', - :zip => 'K1C2N6', - :country => 'Canada', - :phone => '(555)555-5555' + address1: '1234 My Street', + address2: 'Apt 1', + company: 'Widgets Inc', + city: 'Ottawa', + state: 'ON', + zip: 'K1C2N6', + country: 'Canada', + phone: '(555)555-5555' } Base.mode = :test @@ -40,40 +40,40 @@ def teardown def test_live_redirect_url Base.mode = :production assert_equal LIVE_REDIRECT_URL, @gateway.redirect_url_for('1234567890') - assert_equal LIVE_REDIRECT_URL_MOBILE, @gateway.redirect_url_for('1234567890', :mobile => true) + assert_equal LIVE_REDIRECT_URL_MOBILE, @gateway.redirect_url_for('1234567890', mobile: true) end def test_live_redirect_url_without_review Base.mode = :production - assert_equal LIVE_REDIRECT_URL_WITHOUT_REVIEW, @gateway.redirect_url_for('1234567890', :review => false) - assert_equal LIVE_REDIRECT_URL_MOBILE_WITHOUT_REVIEW, @gateway.redirect_url_for('1234567890', :review => false, :mobile => true) + assert_equal LIVE_REDIRECT_URL_WITHOUT_REVIEW, @gateway.redirect_url_for('1234567890', review: false) + assert_equal LIVE_REDIRECT_URL_MOBILE_WITHOUT_REVIEW, @gateway.redirect_url_for('1234567890', review: false, mobile: true) end def test_force_sandbox_redirect_url Base.mode = :production gateway = PaypalExpressGateway.new( - :login => 'cody', - :password => 'test', - :pem => 'PEM', - :test => true + login: 'cody', + password: 'test', + pem: 'PEM', + test: true ) assert gateway.test? assert_equal TEST_REDIRECT_URL, gateway.redirect_url_for('1234567890') - assert_equal TEST_REDIRECT_URL_MOBILE, gateway.redirect_url_for('1234567890', :mobile => true) + assert_equal TEST_REDIRECT_URL_MOBILE, gateway.redirect_url_for('1234567890', mobile: true) end def test_test_redirect_url assert_equal :test, Base.mode assert_equal TEST_REDIRECT_URL, @gateway.redirect_url_for('1234567890') - assert_equal TEST_REDIRECT_URL_MOBILE, @gateway.redirect_url_for('1234567890', :mobile => true) + assert_equal TEST_REDIRECT_URL_MOBILE, @gateway.redirect_url_for('1234567890', mobile: true) end def test_test_redirect_url_without_review assert_equal :test, Base.mode - assert_equal TEST_REDIRECT_URL_WITHOUT_REVIEW, @gateway.redirect_url_for('1234567890', :review => false) - assert_equal TEST_REDIRECT_URL_MOBILE_WITHOUT_REVIEW, @gateway.redirect_url_for('1234567890', :review => false, :mobile => true) + assert_equal TEST_REDIRECT_URL_WITHOUT_REVIEW, @gateway.redirect_url_for('1234567890', review: false) + assert_equal TEST_REDIRECT_URL_MOBILE_WITHOUT_REVIEW, @gateway.redirect_url_for('1234567890', review: false, mobile: true) end def test_get_express_details @@ -111,7 +111,7 @@ def test_express_response_missing_address def test_authorization @gateway.expects(:ssl_post).returns(successful_authorization_response) - response = @gateway.authorize(300, :token => 'EC-6WS104951Y388951L', :payer_id => 'FWRVKNRRZ3WUC') + response = @gateway.authorize(300, token: 'EC-6WS104951Y388951L', payer_id: 'FWRVKNRRZ3WUC') assert response.success? assert_not_nil response.authorization assert response.test? @@ -130,25 +130,25 @@ def test_uk_partner end def test_includes_description - xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, { :description => 'a description' })) + xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, { description: 'a description' })) assert_equal 'a description', REXML::XPath.first(xml, '//n2:PaymentDetails/n2:OrderDescription').text end def test_includes_order_id - xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, { :order_id => '12345' })) + xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, { order_id: '12345' })) assert_equal '12345', REXML::XPath.first(xml, '//n2:PaymentDetails/n2:InvoiceID').text end def test_includes_correct_payment_action - xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, { })) + xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, {})) assert_equal 'SetExpressCheckout', REXML::XPath.first(xml, '//n2:PaymentDetails/n2:PaymentAction').text end def test_includes_custom_tag_if_specified - xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, {:custom => 'Foo'})) + xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, { custom: 'Foo' })) assert_equal 'Foo', REXML::XPath.first(xml, '//n2:PaymentDetails/n2:Custom').text end @@ -167,21 +167,20 @@ def test_does_not_include_items_if_not_specified def test_items_are_included_if_specified_in_build_setup_request xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, { - :currency => 'GBP', - :items => [ + currency: 'GBP', + items: [ { - :name => 'item one', - :description => 'item one description', - :amount => 10000, - :number => 1, - :quantity => 3 + name: 'item one', + description: 'item one description', + amount: 10000, + number: 1, + quantity: 3 }, - { :name => 'item two', - :description => 'item two description', - :amount => 20000, - :number => 2, - :quantity => 4 - } + { name: 'item two', + description: 'item two description', + amount: 20000, + number: 2, + quantity: 4 } ] })) @@ -207,7 +206,7 @@ def test_does_not_include_callback_url_if_not_specified end def test_callback_url_is_included_if_specified_in_build_setup_request - xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, {:callback_url => 'http://example.com/update_callback'})) + xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, { callback_url: 'http://example.com/update_callback' })) assert_equal 'http://example.com/update_callback', REXML::XPath.first(xml, '//n2:CallbackURL').text end @@ -219,7 +218,7 @@ def test_does_not_include_callback_timeout_if_not_specified end def test_callback_timeout_is_included_if_specified_in_build_setup_request - xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, {:callback_timeout => 2})) + xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, { callback_timeout: 2 })) assert_equal '2', REXML::XPath.first(xml, '//n2:CallbackTimeout').text end @@ -231,7 +230,7 @@ def test_does_not_include_callback_version_if_not_specified end def test_callback_version_is_included_if_specified_in_build_setup_request - xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, {:callback_version => '53.0'})) + xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, { callback_version: '53.0' })) assert_equal '53.0', REXML::XPath.first(xml, '//n2:CallbackVersion').text end @@ -245,20 +244,20 @@ def test_does_not_include_flatrate_shipping_options_if_not_specified def test_flatrate_shipping_options_are_included_if_specified_in_build_setup_request xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, { - :currency => 'AUD', - :shipping_options => [ + currency: 'AUD', + shipping_options: [ { - :default => true, - :name => 'first one', - :amount => 1000 + default: true, + name: 'first one', + amount: 1000 }, { - :default => false, - :name => 'second one', - :amount => 2000 + default: false, + name: 'second one', + amount: 2000 } ] - })) + })) assert_equal 'true', REXML::XPath.first(xml, '//n2:FlatRateShippingOptions/n2:ShippingOptionIsDefault').text assert_equal 'first one', REXML::XPath.first(xml, '//n2:FlatRateShippingOptions/n2:ShippingOptionName').text @@ -274,15 +273,15 @@ def test_flatrate_shipping_options_are_included_if_specified_in_build_setup_requ def test_address_is_included_if_specified xml = REXML::Document.new(@gateway.send(:build_setup_request, 'Sale', 0, { - :currency => 'GBP', - :address => { - :name => 'John Doe', - :address1 => '123 somewhere', - :city => 'Townville', - :country => 'Canada', - :zip => 'k1l4p2', - :phone => '1231231231' - } + currency: 'GBP', + address: { + name: 'John Doe', + address1: '123 somewhere', + city: 'Townville', + country: 'Canada', + zip: 'k1l4p2', + phone: '1231231231' + } })) assert_equal 'John Doe', REXML::XPath.first(xml, '//n2:PaymentDetails/n2:ShipToAddress/n2:Name').text @@ -301,12 +300,12 @@ def test_handle_non_zero_amount def test_amount_format_for_jpy_currency @gateway.expects(:ssl_post).with(anything, regexp_matches(/n2:OrderTotal currencyID=.JPY.>1<\/n2:OrderTotal>/), {}).returns(successful_authorization_response) - response = @gateway.authorize(100, :token => 'EC-6WS104951Y388951L', :payer_id => 'FWRVKNRRZ3WUC', :currency => 'JPY') + response = @gateway.authorize(100, token: 'EC-6WS104951Y388951L', payer_id: 'FWRVKNRRZ3WUC', currency: 'JPY') assert response.success? end def test_removes_fractional_amounts_with_twd_currency - xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 150, {:currency => 'TWD'})) + xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 150, { currency: 'TWD' })) assert_equal '1', REXML::XPath.first(xml, '//n2:OrderTotal').text end @@ -314,28 +313,28 @@ def test_removes_fractional_amounts_with_twd_currency def test_fractional_discounts_are_correctly_calculated_with_jpy_currency xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 14250, { - :items => [ + items: [ { - :name => 'item one', - :description => 'description', - :amount => 15000, - :number => 1, - :quantity => 1 + name: 'item one', + description: 'description', + amount: 15000, + number: 1, + quantity: 1 }, { - :name => 'Discount', - :description => 'Discount', - :amount => -750, - :number => 2, - :quantity => 1 + name: 'Discount', + description: 'Discount', + amount: -750, + number: 2, + quantity: 1 } ], - :subtotal => 14250, - :currency => 'JPY', - :shipping => 0, - :handling => 0, - :tax => 0 - })) + subtotal: 14250, + currency: 'JPY', + shipping: 0, + handling: 0, + tax: 0 + })) assert_equal '142', REXML::XPath.first(xml, '//n2:OrderTotal').text assert_equal '142', REXML::XPath.first(xml, '//n2:ItemTotal').text @@ -347,28 +346,28 @@ def test_fractional_discounts_are_correctly_calculated_with_jpy_currency def test_non_fractional_discounts_are_correctly_calculated_with_jpy_currency xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 14300, { - :items => [ + items: [ { - :name => 'item one', - :description => 'description', - :amount => 15000, - :number => 1, - :quantity => 1 + name: 'item one', + description: 'description', + amount: 15000, + number: 1, + quantity: 1 }, { - :name => 'Discount', - :description => 'Discount', - :amount => -700, - :number => 2, - :quantity => 1 + name: 'Discount', + description: 'Discount', + amount: -700, + number: 2, + quantity: 1 } ], - :subtotal => 14300, - :currency => 'JPY', - :shipping => 0, - :handling => 0, - :tax => 0 - })) + subtotal: 14300, + currency: 'JPY', + shipping: 0, + handling: 0, + tax: 0 + })) assert_equal '143', REXML::XPath.first(xml, '//n2:OrderTotal').text assert_equal '143', REXML::XPath.first(xml, '//n2:ItemTotal').text @@ -380,28 +379,28 @@ def test_non_fractional_discounts_are_correctly_calculated_with_jpy_currency def test_fractional_discounts_are_correctly_calculated_with_usd_currency xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 14250, { - :items => [ - { - :name => 'item one', - :description => 'description', - :amount => 15000, - :number => 1, - :quantity => 1 - }, - { - :name => 'Discount', - :description => 'Discount', - :amount => -750, - :number => 2, - :quantity => 1 - } - ], - :subtotal => 14250, - :currency => 'USD', - :shipping => 0, - :handling => 0, - :tax => 0 - })) + items: [ + { + name: 'item one', + description: 'description', + amount: 15000, + number: 1, + quantity: 1 + }, + { + name: 'Discount', + description: 'Discount', + amount: -750, + number: 2, + quantity: 1 + } + ], + subtotal: 14250, + currency: 'USD', + shipping: 0, + handling: 0, + tax: 0 + })) assert_equal '142.50', REXML::XPath.first(xml, '//n2:OrderTotal').text assert_equal '142.50', REXML::XPath.first(xml, '//n2:ItemTotal').text @@ -411,33 +410,33 @@ def test_fractional_discounts_are_correctly_calculated_with_usd_currency end def test_does_not_add_allow_note_if_not_specified - xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, { })) + xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, {})) assert_nil REXML::XPath.first(xml, '//n2:AllowNote') end def test_adds_allow_note_if_specified - allow_notes_xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, { :allow_note => true })) - do_not_allow_notes_xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, { :allow_note => false })) + allow_notes_xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, { allow_note: true })) + do_not_allow_notes_xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, { allow_note: false })) assert_equal '1', REXML::XPath.first(allow_notes_xml, '//n2:AllowNote').text assert_equal '0', REXML::XPath.first(do_not_allow_notes_xml, '//n2:AllowNote').text end def test_handle_locale_code - xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, { :locale => 'GB' })) + xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, { locale: 'GB' })) assert_equal 'GB', REXML::XPath.first(xml, '//n2:LocaleCode').text end def test_handle_non_standard_locale_code - xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, { :locale => 'IL' })) + xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, { locale: 'IL' })) assert_equal 'he_IL', REXML::XPath.first(xml, '//n2:LocaleCode').text end def test_does_not_include_locale_in_request_unless_provided_in_options - xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, { :locale => nil })) + xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 0, { locale: nil })) assert_nil REXML::XPath.first(xml, '//n2:LocaleCode') end @@ -456,23 +455,23 @@ def test_button_source def test_items_are_included_if_specified_in_build_sale_or_authorization_request xml = REXML::Document.new(@gateway.send(:build_sale_or_authorization_request, 'Sale', 100, { - :items => [ + items: [ { - :name => 'item one', - :description => 'item one description', - :amount => 10000, - :number => 1, - :quantity => 3 + name: 'item one', + description: 'item one description', + amount: 10000, + number: 1, + quantity: 3 }, { - :name => 'item two', - :description => 'item two description', - :amount => 20000, - :number => 2, - :quantity => 4 + name: 'item two', + description: 'item two description', + amount: 20000, + number: 2, + quantity: 4 } ] - })) + })) assert_equal 'item one', REXML::XPath.first(xml, '//n2:PaymentDetails/n2:PaymentDetailsItem/n2:Name').text assert_equal 'item one description', REXML::XPath.first(xml, '//n2:PaymentDetails/n2:PaymentDetailsItem/n2:Description').text @@ -550,11 +549,11 @@ def test_build_reference_transaction_test PaypalExpressGateway.application_id = 'ActiveMerchant_FOO' xml = REXML::Document.new(@gateway.send(:build_reference_transaction_request, 'Sale', 2000, { - :reference_id => 'ref_id', - :payment_type => 'Any', - :invoice_id => 'invoice_id', - :description => 'Description', - :ip => '127.0.0.1' + reference_id: 'ref_id', + payment_type: 'Any', + invoice_id: 'invoice_id', + description: 'Description', + ip: '127.0.0.1' })) assert_equal '124', REXML::XPath.first(xml, '//DoReferenceTransactionReq/DoReferenceTransactionRequest/n2:Version').text @@ -577,23 +576,23 @@ def test_build_details_billing_agreement_request_test def test_authorize_reference_transaction @gateway.expects(:ssl_post).returns(successful_authorize_reference_transaction_response) - response = @gateway.authorize_reference_transaction(2000, - { - :reference_id => 'ref_id', - :payment_type => 'Any', - :invoice_id => 'invoice_id', - :description => 'Description', - :ip => '127.0.0.1' }) + response = @gateway.authorize_reference_transaction(2000, reference_id: 'ref_id') assert_equal 'Success', response.params['ack'] assert_equal 'Success', response.message assert_equal '9R43552341412482K', response.authorization end + def test_authorize_reference_transaction_requires_fields + assert_raise ArgumentError do + @gateway.authorize_reference_transaction(2000, {}) + end + end + def test_reference_transaction @gateway.expects(:ssl_post).returns(successful_reference_transaction_response) - response = @gateway.reference_transaction(2000, { :reference_id => 'ref_id' }) + response = @gateway.reference_transaction(2000, { reference_id: 'ref_id' }) assert_equal 'Success', response.params['ack'] assert_equal 'Success', response.message @@ -609,18 +608,16 @@ def test_reference_transaction_requires_fields def test_error_code_for_single_error @gateway.expects(:ssl_post).returns(response_with_error) response = @gateway.setup_authorization(100, - :return_url => 'http://example.com', - :cancel_return_url => 'http://example.com' - ) + return_url: 'http://example.com', + cancel_return_url: 'http://example.com') assert_equal '10736', response.params['error_codes'] end def test_ensure_only_unique_error_codes @gateway.expects(:ssl_post).returns(response_with_duplicate_errors) response = @gateway.setup_authorization(100, - :return_url => 'http://example.com', - :cancel_return_url => 'http://example.com' - ) + return_url: 'http://example.com', + cancel_return_url: 'http://example.com') assert_equal '10736', response.params['error_codes'] end @@ -628,22 +625,21 @@ def test_ensure_only_unique_error_codes def test_error_codes_for_multiple_errors @gateway.expects(:ssl_post).returns(response_with_errors) response = @gateway.setup_authorization(100, - :return_url => 'http://example.com', - :cancel_return_url => 'http://example.com' - ) + return_url: 'http://example.com', + cancel_return_url: 'http://example.com') - assert_equal ['10736', '10002'], response.params['error_codes'].split(',') + assert_equal %w[10736 10002], response.params['error_codes'].split(',') end def test_allow_guest_checkout - xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 10, {:allow_guest_checkout => true})) + xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 10, { allow_guest_checkout: true })) assert_equal 'Sole', REXML::XPath.first(xml, '//n2:SolutionType').text assert_equal 'Billing', REXML::XPath.first(xml, '//n2:LandingPage').text end def test_paypal_chooses_landing_page - xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 10, {:allow_guest_checkout => true, :paypal_chooses_landing_page=> true})) + xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 10, { allow_guest_checkout: true, paypal_chooses_landing_page: true })) assert_equal 'Sole', REXML::XPath.first(xml, '//n2:SolutionType').text assert_nil REXML::XPath.first(xml, '//n2:LandingPage') @@ -656,7 +652,7 @@ def test_not_adds_brand_name_if_not_specified end def test_adds_brand_name_if_specified - xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 10, {:brand_name => 'Acme'})) + xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 10, { brand_name: 'Acme' })) assert_equal 'Acme', REXML::XPath.first(xml, '//n2:BrandName').text end @@ -674,15 +670,15 @@ def test_not_adds_buyer_optin_if_not_specified end def test_adds_buyer_optin_if_specified - allow_optin_xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 10, {:allow_buyer_optin => true})) - do_not_allow_optin_xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 10, {:allow_buyer_optin => false})) + allow_optin_xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 10, { allow_buyer_optin: true })) + do_not_allow_optin_xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 10, { allow_buyer_optin: false })) assert_equal '1', REXML::XPath.first(allow_optin_xml, '//n2:BuyerEmailOptInEnable').text assert_equal '0', REXML::XPath.first(do_not_allow_optin_xml, '//n2:BuyerEmailOptInEnable').text end def test_add_total_type_if_specified - total_type_xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 10, {:total_type => 'EstimatedTotal'})) + total_type_xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 10, { total_type: 'EstimatedTotal' })) no_total_type_xml = REXML::Document.new(@gateway.send(:build_setup_request, 'SetExpressCheckout', 10, {})) assert_equal 'EstimatedTotal', REXML::XPath.first(total_type_xml, '//n2:TotalType').text @@ -691,55 +687,54 @@ def test_add_total_type_if_specified def test_structure_correct all_options_enabled = { - :allow_guest_checkout => true, - :max_amount => 50, - :locale => 'AU', - :page_style => 'test-gray', - :header_image => 'https://example.com/my_business', - :header_background_color => 'CAFE00', - :header_border_color => 'CAFE00', - :background_color => 'CAFE00', - :email => 'joe@example.com', - :billing_agreement => {:type => 'MerchantInitiatedBilling', :description => '9.99 per month for a year'}, - :allow_note => true, - :allow_buyer_optin => true, - :subtotal => 35, - :shipping => 10, - :handling => 0, - :tax => 5, - :total_type => 'EstimatedTotal', - :items => [ - { - :name => 'item one', - :number => 'number 1', - :quantity => 3, - :amount => 35, - :description => 'one description', - :url => 'http://example.com/number_1' - } - ], - :address => - { - :name => 'John Doe', - :address1 => 'Apartment 1', - :address2 => '1 Road St', - :city => 'First City', - :state => 'NSW', - :country => 'AU', - :zip => '2000', - :phone => '555 5555' - }, - :callback_url => 'http://example.com/update_callback', - :callback_timeout => 2, - :callback_version => '53.0', - :funding_sources => {:source => 'BML'}, - :shipping_options => [ - { - :default => true, - :name => 'first one', - :amount => 10 - } - ] + allow_guest_checkout: true, + max_amount: 50, + locale: 'AU', + page_style: 'test-gray', + header_image: 'https://example.com/my_business', + header_background_color: 'CAFE00', + header_border_color: 'CAFE00', + background_color: 'CAFE00', + email: 'joe@example.com', + billing_agreement: { type: 'MerchantInitiatedBilling', description: '9.99 per month for a year' }, + allow_note: true, + allow_buyer_optin: true, + subtotal: 35, + shipping: 10, + handling: 0, + tax: 5, + total_type: 'EstimatedTotal', + items: [ + { + name: 'item one', + number: 'number 1', + quantity: 3, + amount: 35, + description: 'one description', + url: 'http://example.com/number_1' + } + ], + address: { + name: 'John Doe', + address1: 'Apartment 1', + address2: '1 Road St', + city: 'First City', + state: 'NSW', + country: 'AU', + zip: '2000', + phone: '555 5555' + }, + callback_url: 'http://example.com/update_callback', + callback_timeout: 2, + callback_version: '53.0', + funding_sources: { source: 'BML' }, + shipping_options: [ + { + default: true, + name: 'first one', + amount: 10 + } + ] } doc = Nokogiri::XML(@gateway.send(:build_setup_request, 'Sale', 10, all_options_enabled)) @@ -755,480 +750,480 @@ def test_structure_correct private def successful_create_billing_agreement_response - <<-RESPONSE - - - - - - - - - - OMGOMGOMG - - - - - - - 2013-02-28T16:34:47Z - Success - 8007ac99c51af - 72 - 5331358 - B-3R788221G4476823M - - - + <<~RESPONSE + + + + + + + + + + OMGOMGOMG + + + + + + + 2013-02-28T16:34:47Z + Success + 8007ac99c51af + 72 + 5331358 + B-3R788221G4476823M + + + RESPONSE end def successful_authorize_reference_transaction_response - <<-RESPONSE - - - - - - - - - OMGOMGOMG - - - - - - - 2011-05-23T21:36:32Z - Success - 4d6d3af55369b - 72 - 1863577 - - B-3R788221G4476823M - - 9R43552341412482K - - - mercht-pmt - instant - 2011-05-23T21:36:32Z - 190.00 - 5.81 - 0.00 - - Completed - none - none - Ineligible - None - - - - - + <<~RESPONSE + + + + + + + + + OMGOMGOMG + + + + + + + 2011-05-23T21:36:32Z + Success + 4d6d3af55369b + 72 + 1863577 + + B-3R788221G4476823M + + 9R43552341412482K + + + mercht-pmt + instant + 2011-05-23T21:36:32Z + 190.00 + 5.81 + 0.00 + + Completed + none + none + Ineligible + None + + + + + RESPONSE end def successful_reference_transaction_response - <<-RESPONSE - - - - - - - - - OMGOMGOMG - - - - - - - 2011-05-23T21:36:32Z - Success - 4d6d3af55369b - 72 - 1863577 - - B-3R788221G4476823M - - 9R43552341412482K - - - mercht-pmt - instant - 2011-05-23T21:36:32Z - 190.00 - 5.81 - 0.00 - - Completed - none - none - Ineligible - None - - - - - + <<~RESPONSE + + + + + + + + + OMGOMGOMG + + + + + + + 2011-05-23T21:36:32Z + Success + 4d6d3af55369b + 72 + 1863577 + + B-3R788221G4476823M + + 9R43552341412482K + + + mercht-pmt + instant + 2011-05-23T21:36:32Z + 190.00 + 5.81 + 0.00 + + Completed + none + none + Ineligible + None + + + + + RESPONSE end def successful_details_response - <<-RESPONSE - - - - - - - - - - - - - - - - 2011-03-01T20:19:35Z - Success - 84aff0e17b6f - 62.0 - 1741654 - - EC-2XE90996XX9870316 - - buyer@jadedpallet.com - FWRVKNRRZ3WUC - verified - - - Fred - - Brooks - - - US - -
- Fred Brooks - 1 Infinite Loop - - Cupertino - CA - US - United States - 95014 - PayPal - Confirmed -
-
- 1230123 - 416-618-9984 - - 19.00 - 19.00 - 0.00 - 0.00 - 0.00 - - Fred Brooks - 1234 Penny Lane - - Jonsetown - NC - US - United States - 123-456-7890 - 23456 - - PayPal - - Confirmed - - - Shopify T-Shirt - 1 - 0.00 - 19.00 - - - 0.00 - 0.00 - false - This is a test note - - - - - - - Callback - false - true - 2.95 - default - - PaymentActionNotInitiated - -
-
-
-
+ <<~RESPONSE + + + + + + + + + + + + + + + + 2011-03-01T20:19:35Z + Success + 84aff0e17b6f + 62.0 + 1741654 + + EC-2XE90996XX9870316 + + buyer@jadedpallet.com + FWRVKNRRZ3WUC + verified + + + Fred + + Brooks + + + US + +
+ Fred Brooks + 1 Infinite Loop + + Cupertino + CA + US + United States + 95014 + PayPal + Confirmed +
+
+ 1230123 + 416-618-9984 + + 19.00 + 19.00 + 0.00 + 0.00 + 0.00 + + Fred Brooks + 1234 Penny Lane + + Jonsetown + NC + US + United States + 123-456-7890 + 23456 + + PayPal + + Confirmed + + + Shopify T-Shirt + 1 + 0.00 + 19.00 + + + 0.00 + 0.00 + false + This is a test note + + + + + + + Callback + false + true + 2.95 + default + + PaymentActionNotInitiated + +
+
+
+
RESPONSE end def successful_authorization_response - <<-RESPONSE - - - - - - - - - - - - - - - 2007-02-13T00:18:50Z - Success - 62450a4266d04 - 2.000000 - 1.0006 - - EC-6WS104951Y388951L - - 8B266858CH956410C - - - express-checkout - instant - 2007-02-13T00:18:48Z - 3.00 - 0.00 - - Pending - authorization - none - - - - - + <<~RESPONSE + + + + + + + + + + + + + + + 2007-02-13T00:18:50Z + Success + 62450a4266d04 + 2.000000 + 1.0006 + + EC-6WS104951Y388951L + + 8B266858CH956410C + + + express-checkout + instant + 2007-02-13T00:18:48Z + 3.00 + 0.00 + + Pending + authorization + none + + + + + RESPONSE end def response_with_error - <<-RESPONSE - - - - - - - - - - - - - - - 2008-04-02T17:38:02Z - Failure - cdb720feada30 - - Shipping Address Invalid City State Postal Code - A match of the Shipping Address City, State, and Postal Code failed. - 10736 - Error - - 2.000000 - 543066 - - - + <<~RESPONSE + + + + + + + + + + + + + + + 2008-04-02T17:38:02Z + Failure + cdb720feada30 + + Shipping Address Invalid City State Postal Code + A match of the Shipping Address City, State, and Postal Code failed. + 10736 + Error + + 2.000000 + 543066 + + + RESPONSE end def response_with_errors - <<-RESPONSE - - - - - - - - - - - - - - - 2008-04-02T17:38:02Z - Failure - cdb720feada30 - - Shipping Address Invalid City State Postal Code - A match of the Shipping Address City, State, and Postal Code failed. - 10736 - Error - - - Authentication/Authorization Failed - You do not have permissions to make this API call - 10002 - Error - - 2.000000 - 543066 - - - + <<~RESPONSE + + + + + + + + + + + + + + + 2008-04-02T17:38:02Z + Failure + cdb720feada30 + + Shipping Address Invalid City State Postal Code + A match of the Shipping Address City, State, and Postal Code failed. + 10736 + Error + + + Authentication/Authorization Failed + You do not have permissions to make this API call + 10002 + Error + + 2.000000 + 543066 + + + RESPONSE end def response_with_duplicate_errors - <<-RESPONSE - - - - - - - - - - - - - - - 2008-04-02T17:38:02Z - Failure - cdb720feada30 - - Shipping Address Invalid City State Postal Code - A match of the Shipping Address City, State, and Postal Code failed. - 10736 - Error - - - Shipping Address Invalid City State Postal Code - A match of the Shipping Address City, State, and Postal Code failed. - 10736 - Error - - 2.000000 - 543066 - - - + <<~RESPONSE + + + + + + + + + + + + + + + 2008-04-02T17:38:02Z + Failure + cdb720feada30 + + Shipping Address Invalid City State Postal Code + A match of the Shipping Address City, State, and Postal Code failed. + 10736 + Error + + + Shipping Address Invalid City State Postal Code + A match of the Shipping Address City, State, and Postal Code failed. + 10736 + Error + + 2.000000 + 543066 + + + RESPONSE end def successful_cancel_billing_agreement_response - <<-RESPONSE - 2013-06-04T16:24:31ZSuccessaecbb96bd4658726118442B-3RU433629T663020SWow. Amazing.Canceledduff@example.comVZNKJ2ZWMYK2EverifiedDuffJonesUS
PayPalNone
+ <<~RESPONSE + 2013-06-04T16:24:31ZSuccessaecbb96bd4658726118442B-3RU433629T663020SWow. Amazing.Canceledduff@example.comVZNKJ2ZWMYK2EverifiedDuffJonesUS
PayPalNone
RESPONSE end def failed_cancel_billing_agreement_response - <<-RESPONSE - 2013-06-04T16:25:06ZFailure5ec2d55830b40Billing - Agreement was cancelledBilling Agreement was cancelled10201Error726118442unverified
PayPalNone
+ <<~RESPONSE + 2013-06-04T16:25:06ZFailure5ec2d55830b40Billing + Agreement was cancelledBilling Agreement was cancelled10201Error726118442unverified
PayPalNone
RESPONSE end def successful_billing_agreement_details_response - <<-RESPONSE - - 2014-05-08T09:22:03Z - Successf84ed24f5bd6d - 7210918103 - B-6VE21702A47915521My active merchant custom description - Activeivan.rostovsky.xan@gmail.comSW3AR2WYZ3NJWverifiedIvanRostovsky - US -
- PayPal - None -
+ <<~RESPONSE + + 2014-05-08T09:22:03Z + Successf84ed24f5bd6d + 7210918103 + B-6VE21702A47915521My active merchant custom description + Activeivan.rostovsky.xan@gmail.comSW3AR2WYZ3NJWverifiedIvanRostovsky + US +
+ PayPal + None +
RESPONSE end def failure_billing_agreement_details_response - <<-RESPONSE + <<~RESPONSE activemerchant-cert-test_api1.example.comERDD3JRFU5H5DQXS - - 124 - - http://example.com/return - http://example.com/cancel - 0 - 0 - 0 - buyer@jadedpallet.com - - 5.00 - Stuff that you purchased, yo! - 230000 - Authorization - - - - - -2018-05-24T20:23:54ZSuccessb6dd2a043921b12446549960EC-7KR85820NC734104L + <<~TRANSCRIPT + activemerchant-cert-test_api1.example.comERDD3JRFU5H5DQXS + + 124 + + http://example.com/return + http://example.com/cancel + 0 + 0 + 0 + buyer@jadedpallet.com + + 5.00 + Stuff that you purchased, yo! + 230000 + Authorization + + + + + + 2018-05-24T20:23:54ZSuccessb6dd2a043921b12446549960EC-7KR85820NC734104L TRANSCRIPT end def post_scrubbed - <<-TRANSCRIPT -[FILTERED][FILTERED] - - 124 - - http://example.com/return - http://example.com/cancel - 0 - 0 - 0 - buyer@jadedpallet.com - - 5.00 - Stuff that you purchased, yo! - 230000 - Authorization - - - - - -2018-05-24T20:23:54ZSuccessb6dd2a043921b12446549960EC-7KR85820NC734104L + <<~TRANSCRIPT + [FILTERED][FILTERED] + + 124 + + http://example.com/return + http://example.com/cancel + 0 + 0 + 0 + buyer@jadedpallet.com + + 5.00 + Stuff that you purchased, yo! + 230000 + Authorization + + + + + + 2018-05-24T20:23:54ZSuccessb6dd2a043921b12446549960EC-7KR85820NC734104L TRANSCRIPT end end diff --git a/test/unit/gateways/paypal_test.rb b/test/unit/gateways/paypal_test.rb index 6f963e6419e..a7165ef3b42 100644 --- a/test/unit/gateways/paypal_test.rb +++ b/test/unit/gateways/paypal_test.rb @@ -8,19 +8,19 @@ def setup @amount = 100 @gateway = PaypalGateway.new( - :login => 'cody', - :password => 'test', - :pem => 'PEM' + login: 'cody', + password: 'test', + pem: 'PEM' ) @credit_card = credit_card('4242424242424242') - @options = { :billing_address => address, :ip => '127.0.0.1' } - @recurring_required_fields = {:start_date => Date.today, :frequency => :Month, :period => 'Month', :description => 'A description'} + @options = { billing_address: address, ip: '127.0.0.1' } + @recurring_required_fields = { start_date: Date.today, frequency: :Month, period: 'Month', description: 'A description' } end def test_no_ip_address assert_raise(ArgumentError) do - @gateway.purchase(@amount, @credit_card, :billing_address => address) + @gateway.purchase(@amount, @credit_card, billing_address: address) end end @@ -63,7 +63,7 @@ def test_recurring_requires_period def test_update_recurring_requires_profile_id assert_raise(ArgumentError) do assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.update_recurring(:amount => 100) + @gateway.update_recurring(amount: 100) end end end @@ -71,7 +71,7 @@ def test_update_recurring_requires_profile_id def test_cancel_recurring_requires_profile_id assert_raise(ArgumentError) do assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.cancel_recurring(nil, :note => 'Note') + @gateway.cancel_recurring(nil, note: 'Note') end end end @@ -87,7 +87,7 @@ def test_status_recurring_requires_profile_id def test_suspend_recurring_requires_profile_id assert_raise(ArgumentError) do assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.suspend_recurring(nil, :note => 'Note') + @gateway.suspend_recurring(nil, note: 'Note') end end end @@ -95,14 +95,14 @@ def test_suspend_recurring_requires_profile_id def test_reactivate_recurring_requires_profile_id assert_raise(ArgumentError) do assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.reactivate_recurring(nil, :note => 'Note') + @gateway.reactivate_recurring(nil, note: 'Note') end end end def test_successful_purchase_with_auth_signature - @gateway = PaypalGateway.new(:login => 'cody', :password => 'test', :pem => 'PEM', :auth_signature => 123) - expected_header = {'X-PP-AUTHORIZATION' => 123, 'X-PAYPAL-MESSAGE-PROTOCOL' => 'SOAP11'} + @gateway = PaypalGateway.new(login: 'cody', password: 'test', pem: 'PEM', auth_signature: 123) + expected_header = { 'X-PP-AUTHORIZATION' => 123, 'X-PAYPAL-MESSAGE-PROTOCOL' => 'SOAP11' } @gateway.expects(:ssl_post).with(anything, anything, expected_header).returns(successful_purchase_response) @gateway.expects(:add_credentials).never @@ -110,7 +110,7 @@ def test_successful_purchase_with_auth_signature end def test_successful_purchase_without_auth_signature - @gateway = PaypalGateway.new(:login => 'cody', :password => 'test', :pem => 'PEM') + @gateway = PaypalGateway.new(login: 'cody', password: 'test', pem: 'PEM') @gateway.expects(:ssl_post).returns(successful_purchase_response) @gateway.expects(:add_credentials) @@ -136,7 +136,7 @@ def test_successful_reference_purchase ref_id = response.authorization - gateway2 = PaypalGateway.new(:login => 'cody', :password => 'test', :pem => 'PEM') + gateway2 = PaypalGateway.new(login: 'cody', password: 'test', pem: 'PEM') gateway2.expects(:ssl_post).returns(successful_reference_purchase_response) assert response = gateway2.purchase(@amount, ref_id, @options) assert_instance_of Response, response @@ -157,7 +157,7 @@ def test_failed_purchase def test_descriptors_passed stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(soft_descriptor: 'Eggcellent', soft_descriptor_city: 'New York')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{Eggcellent}, data) assert_match(%r{New York}, data) end.respond_with(successful_purchase_response) @@ -198,19 +198,19 @@ def test_paypal_timeout_error def test_pem_file_accessor PaypalGateway.pem_file = '123456' - gateway = PaypalGateway.new(:login => 'test', :password => 'test') + gateway = PaypalGateway.new(login: 'test', password: 'test') assert_equal '123456', gateway.options[:pem] end def test_passed_in_pem_overrides_class_accessor PaypalGateway.pem_file = '123456' - gateway = PaypalGateway.new(:login => 'test', :password => 'test', :pem => 'Clobber') + gateway = PaypalGateway.new(login: 'test', password: 'test', pem: 'Clobber') assert_equal 'Clobber', gateway.options[:pem] end def test_ensure_options_are_transferred_to_express_instance PaypalGateway.pem_file = '123456' - gateway = PaypalGateway.new(:login => 'test', :password => 'password') + gateway = PaypalGateway.new(login: 'test', password: 'password') express = gateway.express assert_instance_of PaypalExpressGateway, express assert_equal 'test', express.options[:login] @@ -219,11 +219,11 @@ def test_ensure_options_are_transferred_to_express_instance end def test_supported_countries - assert_equal ['CA', 'NZ', 'GB', 'US'], PaypalGateway.supported_countries + assert_equal %w[CA NZ GB US], PaypalGateway.supported_countries end def test_supported_card_types - assert_equal [:visa, :master, :american_express, :discover], PaypalGateway.supported_cardtypes + assert_equal %i[visa master american_express discover], PaypalGateway.supported_cardtypes end def test_button_source @@ -261,10 +261,9 @@ def test_button_source_via_credentials_with_no_application_id def test_item_total_shipping_handling_and_tax_not_included_unless_all_are_present xml = @gateway.send(:build_sale_or_authorization_request, 'Authorization', @amount, @credit_card, - :tax => @amount, - :shipping => @amount, - :handling => @amount - ) + tax: @amount, + shipping: @amount, + handling: @amount) doc = REXML::Document.new(xml) assert_nil REXML::XPath.first(doc, '//n2:PaymentDetails/n2:TaxTotal') @@ -272,11 +271,10 @@ def test_item_total_shipping_handling_and_tax_not_included_unless_all_are_presen def test_item_total_shipping_handling_and_tax xml = @gateway.send(:build_sale_or_authorization_request, 'Authorization', @amount, @credit_card, - :tax => @amount, - :shipping => @amount, - :handling => @amount, - :subtotal => 200 - ) + tax: @amount, + shipping: @amount, + handling: @amount, + subtotal: 200) doc = REXML::Document.new(xml) assert_equal '1.00', REXML::XPath.first(doc, '//n2:PaymentDetails/n2:TaxTotal').text @@ -284,19 +282,19 @@ def test_item_total_shipping_handling_and_tax def test_should_use_test_certificate_endpoint gateway = PaypalGateway.new( - :login => 'cody', - :password => 'test', - :pem => 'PEM' - ) + login: 'cody', + password: 'test', + pem: 'PEM' + ) assert_equal PaypalGateway::URLS[:test][:certificate], gateway.send(:endpoint_url) end def test_should_use_live_certificate_endpoint gateway = PaypalGateway.new( - :login => 'cody', - :password => 'test', - :pem => 'PEM' - ) + login: 'cody', + password: 'test', + pem: 'PEM' + ) gateway.expects(:test?).returns(false) assert_equal PaypalGateway::URLS[:live][:certificate], gateway.send(:endpoint_url) @@ -304,20 +302,20 @@ def test_should_use_live_certificate_endpoint def test_should_use_test_signature_endpoint gateway = PaypalGateway.new( - :login => 'cody', - :password => 'test', - :signature => 'SIG' - ) + login: 'cody', + password: 'test', + signature: 'SIG' + ) assert_equal PaypalGateway::URLS[:test][:signature], gateway.send(:endpoint_url) end def test_should_use_live_signature_endpoint gateway = PaypalGateway.new( - :login => 'cody', - :password => 'test', - :signature => 'SIG' - ) + login: 'cody', + password: 'test', + signature: 'SIG' + ) gateway.expects(:test?).returns(false) assert_equal PaypalGateway::URLS[:live][:signature], gateway.send(:endpoint_url) @@ -325,7 +323,7 @@ def test_should_use_live_signature_endpoint def test_should_raise_argument_when_credentials_not_present assert_raises(ArgumentError) do - PaypalGateway.new(:login => 'cody', :password => 'test') + PaypalGateway.new(login: 'cody', password: 'test') end end @@ -372,14 +370,14 @@ def test_authentication_failed_response def test_amount_format_for_jpy_currency @gateway.expects(:ssl_post).with(anything, regexp_matches(/n2:OrderTotal currencyID=.JPY.>1<\/n2:OrderTotal>/), {}).returns(successful_purchase_response) - response = @gateway.purchase(100, @credit_card, @options.merge(:currency => 'JPY')) + response = @gateway.purchase(100, @credit_card, @options.merge(currency: 'JPY')) assert response.success? end def test_successful_create_profile @gateway.expects(:ssl_post).returns(successful_create_profile_paypal_response) response = assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.recurring(@amount, @credit_card, :description => 'some description', :start_date => Time.now, :frequency => 12, :period => 'Month') + @gateway.recurring(@amount, @credit_card, description: 'some description', start_date: Time.now, frequency: 12, period: 'Month') end assert_instance_of Response, response assert response.success? @@ -391,7 +389,7 @@ def test_successful_create_profile def test_failed_create_profile @gateway.expects(:ssl_post).returns(failed_create_profile_paypal_response) response = assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.recurring(@amount, @credit_card, :description => 'some description', :start_date => Time.now, :frequency => 12, :period => 'Month') + @gateway.recurring(@amount, @credit_card, description: 'some description', start_date: Time.now, frequency: 12, period: 'Month') end assert_instance_of Response, response assert !response.success? @@ -401,42 +399,42 @@ def test_failed_create_profile end def test_update_recurring_delegation - @gateway.expects(:build_change_profile_request).with('I-G7A2FF8V75JY', :amount => 200) + @gateway.expects(:build_change_profile_request).with('I-G7A2FF8V75JY', amount: 200) @gateway.stubs(:commit) assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.update_recurring(:profile_id => 'I-G7A2FF8V75JY', :amount => 200) + @gateway.update_recurring(profile_id: 'I-G7A2FF8V75JY', amount: 200) end end def test_update_recurring_response @gateway.expects(:ssl_post).returns(successful_update_recurring_payment_profile_response) response = assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.update_recurring(:profile_id => 'I-G7A2FF8V75JY', :amount => 200) + @gateway.update_recurring(profile_id: 'I-G7A2FF8V75JY', amount: 200) end assert response.success? end def test_cancel_recurring_delegation - @gateway.expects(:build_manage_profile_request).with('I-G7A2FF8V75JY', 'Cancel', :note => 'A Note').returns(:cancel_request) + @gateway.expects(:build_manage_profile_request).with('I-G7A2FF8V75JY', 'Cancel', note: 'A Note').returns(:cancel_request) @gateway.expects(:commit).with('ManageRecurringPaymentsProfileStatus', :cancel_request) assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.cancel_recurring('I-G7A2FF8V75JY', :note => 'A Note') + @gateway.cancel_recurring('I-G7A2FF8V75JY', note: 'A Note') end end def test_suspend_recurring_delegation - @gateway.expects(:build_manage_profile_request).with('I-G7A2FF8V75JY', 'Suspend', :note => 'A Note').returns(:request) + @gateway.expects(:build_manage_profile_request).with('I-G7A2FF8V75JY', 'Suspend', note: 'A Note').returns(:request) @gateway.expects(:commit).with('ManageRecurringPaymentsProfileStatus', :request) assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.suspend_recurring('I-G7A2FF8V75JY', :note => 'A Note') + @gateway.suspend_recurring('I-G7A2FF8V75JY', note: 'A Note') end end def test_reactivate_recurring_delegation - @gateway.expects(:build_manage_profile_request).with('I-G7A2FF8V75JY', 'Reactivate', :note => 'A Note').returns(:request) + @gateway.expects(:build_manage_profile_request).with('I-G7A2FF8V75JY', 'Reactivate', note: 'A Note').returns(:request) @gateway.expects(:commit).with('ManageRecurringPaymentsProfileStatus', :request) assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.reactivate_recurring('I-G7A2FF8V75JY', :note => 'A Note') + @gateway.reactivate_recurring('I-G7A2FF8V75JY', note: 'A Note') end end @@ -458,17 +456,17 @@ def test_status_recurring_response end def test_bill_outstanding_amoung_delegation - @gateway.expects(:build_bill_outstanding_amount).with('I-G7A2FF8V75JY', :amount => 400).returns(:request) + @gateway.expects(:build_bill_outstanding_amount).with('I-G7A2FF8V75JY', amount: 400).returns(:request) @gateway.expects(:commit).with('BillOutstandingAmount', :request) assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.bill_outstanding_amount('I-G7A2FF8V75JY', :amount => 400) + @gateway.bill_outstanding_amount('I-G7A2FF8V75JY', amount: 400) end end def test_bill_outstanding_amoung_response @gateway.expects(:ssl_post).returns(successful_bill_outstanding_amount) response = assert_deprecation_warning(Gateway::RECURRING_DEPRECATION_MESSAGE) do - @gateway.bill_outstanding_amount('I-G7A2FF8V75JY', :amount => 400) + @gateway.bill_outstanding_amount('I-G7A2FF8V75JY', amount: 400) end assert response.success? end @@ -476,20 +474,20 @@ def test_bill_outstanding_amoung_response def test_mass_pay_transfer_recipient_types stub_comms do @gateway.transfer 1000, 'fred@example.com' - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_no_match %r{ReceiverType}, data end.respond_with(successful_purchase_response) stub_comms do - @gateway.transfer 1000, 'fred@example.com', :receiver_type => 'EmailAddress' - end.check_request do |endpoint, data, headers| + @gateway.transfer 1000, 'fred@example.com', receiver_type: 'EmailAddress' + end.check_request do |_endpoint, data, _headers| assert_match %r{EmailAddress}, data assert_match %r{fred@example\.com}, data end.respond_with(successful_purchase_response) stub_comms do - @gateway.transfer 1000, 'fred@example.com', :receiver_type => 'UserID' - end.check_request do |endpoint, data, headers| + @gateway.transfer 1000, 'fred@example.com', receiver_type: 'UserID' + end.check_request do |_endpoint, data, _headers| assert_match %r{UserID}, data assert_match %r{fred@example\.com}, data end.respond_with(successful_purchase_response) @@ -553,7 +551,7 @@ def test_supports_scrubbing? def test_includes_cvv_tag 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{CVV2}, data) end.respond_with(successful_purchase_response) end @@ -562,20 +560,20 @@ def test_blank_cvv_not_sent @credit_card.verification_value = nil stub_comms do @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_no_match(%r{CVV2}, data) end.respond_with(successful_purchase_response) @credit_card.verification_value = ' ' stub_comms do @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_no_match(%r{CVV2}, data) end.respond_with(successful_purchase_response) end def test_card_declined - ['15005', '10754', '10752', '10759', '10761', '15002', '11084'].each do |error_code| + %w[15005 10754 10752 10759 10761 15002 11084].each do |error_code| @gateway.expects(:ssl_request).returns(response_with_error_code(error_code)) response = @gateway.purchase(@amount, @credit_card, @options) @@ -613,8 +611,8 @@ def test_error_code_with_no_mapping_returns_standardized_processing_error def test_3ds_version_1_request stub_comms do - @gateway.purchase(@amount, @credit_card, @options.merge(three_d_secure_option)) - end.check_request do |endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, @options.merge(three_d_secure_option(version: '1.0.2', xid: 'xid'))) + end.check_request do |_endpoint, data, _headers| assert_match %r{124}, data assert_match %r{Y}, data assert_match %r{cavv}, data @@ -623,10 +621,23 @@ def test_3ds_version_1_request end.respond_with(successful_purchase_response) end + def test_3ds_version_2_request + stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(three_d_secure_option(version: '2.1.0', ds_transaction_id: 'ds_transaction_id'))) + end.check_request do |_endpoint, data, _headers| + assert_match %r{214.0}, data + assert_match %r{Y}, data + assert_match %r{cavv}, data + assert_match %r{eci}, data + assert_match %r{2.1.0}, data + assert_match %r{ds_transaction_id}, data + end.respond_with(successful_purchase_response) + end + private def pre_scrubbed - <<-PRE_SCRUBBED + <<~PRE_SCRUBBED opening connection to api-3t.sandbox.paypal.com:443... opened starting SSL for api-3t.sandbox.paypal.com:443... @@ -648,7 +659,7 @@ def pre_scrubbed end def post_scrubbed - <<-POST_SCRUBBED + <<~POST_SCRUBBED opening connection to api-3t.sandbox.paypal.com:443... opened starting SSL for api-3t.sandbox.paypal.com:443... @@ -670,773 +681,775 @@ def post_scrubbed end def successful_purchase_response - <<-RESPONSE - - - - - - - - - - - - - - - 2008-01-06T23:41:25Z - Success - fee61882e6f47 - 2.000000 - 1.0006 - 3.00 - X - M - 62U664727W5914806 - - - + <<~RESPONSE + + + + + + + + + + + + + + + 2008-01-06T23:41:25Z + Success + fee61882e6f47 + 2.000000 + 1.0006 + 3.00 + X + M + 62U664727W5914806 + + + RESPONSE end def successful_reference_purchase_response - <<-RESPONSE - - - - - - - - - - - - - - - 2008-01-06T23:41:25Z - Success - fee61882e6f47 - 2.000000 - 1.0006 - 3.00 - X - M - 62U664727W5915049 - - - + <<~RESPONSE + + + + + + + + + + + + + + + 2008-01-06T23:41:25Z + Success + fee61882e6f47 + 2.000000 + 1.0006 + 3.00 + X + M + 62U664727W5915049 + + + RESPONSE end def failed_purchase_response - <<-RESPONSE - - - - - - - - - - - - - - - 2008-01-06T23:41:25Z - Failure - fee61882e6f47 - 2.000000 - 1.0006 - 3.00 - X - M - - - + <<~RESPONSE + + + + + + + + + + + + + + + 2008-01-06T23:41:25Z + Failure + fee61882e6f47 + 2.000000 + 1.0006 + 3.00 + X + M + + + RESPONSE end def successful_zero_dollar_auth_response - <<-RESPONSE - - - - - - - - - - - - - - - - 2014-06-27T18:14:48Z - SuccessWithWarning - e33ce283dd3d3 - - Credit card verified. - This card authorization verification is not a payment transaction. - 10574 - Warning - - 72 - 11660982 - 0.00 - XM - 86D41672SH9764158 - - - + <<~RESPONSE + + + + + + + + + + + + + + + + 2014-06-27T18:14:48Z + SuccessWithWarning + e33ce283dd3d3 + + Credit card verified. + This card authorization verification is not a payment transaction. + 10574 + Warning + + 72 + 11660982 + 0.00 + XM + 86D41672SH9764158 + + + RESPONSE end def failed_zero_dollar_auth_response - <<-RESPONSE - - - - - - - - - - - - - - - - 2014-06-27T18:25:51Z - Failure - 5dda14853a55d - - Invalid Data - This transaction cannot be processed. Please enter a valid credit card number and type. - 10527 - Error - - 72 - 11660982 - 0.00 - - - + <<~RESPONSE + + + + + + + + + + + + + + + + 2014-06-27T18:25:51Z + Failure + 5dda14853a55d + + Invalid Data + This transaction cannot be processed. Please enter a valid credit card number and type. + 10527 + Error + + 72 + 11660982 + 0.00 + + + RESPONSE end def successful_one_dollar_auth_response - <<-RESPONSE - - - - - - - - - - - - - - - - 2014-06-27T18:39:40Z - Success - 814bcb1ced3d - 72 - 11660982 - 1.00 - X - M - 521683708W7313256 - - - + <<~RESPONSE + + + + + + + + + + + + + + + + 2014-06-27T18:39:40Z + Success + 814bcb1ced3d + 72 + 11660982 + 1.00 + X + M + 521683708W7313256 + + + RESPONSE end def failed_one_dollar_auth_response - <<-RESPONSE - - - - - - - - - - - - - - - - 2014-06-27T18:47:18Z - Failure - f3ab2d6fc76e4 - - Invalid Data - This transaction cannot be processed. Please enter a valid credit card number and type. - 10527 - Error - - 72 - 11660982 - 1.00 - - - + <<~RESPONSE + + + + + + + + + + + + + + + + 2014-06-27T18:47:18Z + Failure + f3ab2d6fc76e4 + + Invalid Data + This transaction cannot be processed. Please enter a valid credit card number and type. + 10527 + Error + + 72 + 11660982 + 1.00 + + + RESPONSE end def response_with_error_code(error_code) - <<-RESPONSE - - - - - - - - - - - - - - - - 2014-06-27T18:47:18Z - Failure - f3ab2d6fc76e4 - - Invalid Data - This transaction cannot be processed. Please enter a valid credit card number and type. - #{error_code} - Error - - 72 - 11660982 - 1.00 - - - + <<~RESPONSE + + + + + + + + + + + + + + + + 2014-06-27T18:47:18Z + Failure + f3ab2d6fc76e4 + + Invalid Data + This transaction cannot be processed. Please enter a valid credit card number and type. + #{error_code} + Error + + 72 + 11660982 + 1.00 + + + RESPONSE end def successful_void_response - <<-RESPONSE - - - - - - - - - - - - - - - - 2014-06-27T18:39:41Z - Success - 5c184c86a25bc - 72 - 11624049 - 521683708W7313256 - - - + <<~RESPONSE + + + + + + + + + + + + + + + + 2014-06-27T18:39:41Z + Success + 5c184c86a25bc + 72 + 11624049 + 521683708W7313256 + + + RESPONSE end def failed_void_response - <<-RESPONSE - - - - - - - - - - - - - - - - 2014-06-27T18:50:11Z - Failure - e99444d222eaf - - Transaction refused because of an invalid argument. See additional error messages for details. - The transaction id is not valid - 10004 - Error - - 72 - 11624049 - - - - + <<~RESPONSE + + + + + + + + + + + + + + + + 2014-06-27T18:50:11Z + Failure + e99444d222eaf + + Transaction refused because of an invalid argument. See additional error messages for details. + The transaction id is not valid + 10004 + Error + + 72 + 11624049 + + + + RESPONSE end def paypal_timeout_error_response - <<-RESPONSE - - - - - - - - - - - - - - - SOAP-ENV:Server - Internal error - Timeout processing request - - - + <<~RESPONSE + + + + + + + + + + + + + + + SOAP-ENV:Server + Internal error + Timeout processing request + + + RESPONSE end def successful_reauthorization_response - <<-RESPONSE - - - - - - - - - - - - - - - - 2007-03-04T23:34:42Z - Success - e444ddb7b3ed9 - 2.000000 - 1.0006 - 1TX27389GX108740X - - - + <<~RESPONSE + + + + + + + + + + + + + + + + 2007-03-04T23:34:42Z + Success + e444ddb7b3ed9 + 2.000000 + 1.0006 + 1TX27389GX108740X + + + RESPONSE end def successful_with_warning_reauthorization_response - <<-RESPONSE - - - - - - - - - - - - - - - - 2007-03-04T23:34:42Z - SuccessWithWarning - e444ddb7b3ed9 - 2.000000 - 1.0006 - 1TX27389GX108740X - - - + <<~RESPONSE + + + + + + + + + + + + + + + + 2007-03-04T23:34:42Z + SuccessWithWarning + e444ddb7b3ed9 + 2.000000 + 1.0006 + 1TX27389GX108740X + + + RESPONSE end def fraud_review_response - <<-RESPONSE - - - - - - - - - An5ns1Kso7MWUdW4ErQKJJJ4qi4-Azffuo82oMt-Cv9I8QTOs-lG5sAv - - - - - - - 2008-07-04T19:27:39Z - SuccessWithWarning - 205d8397e7ed - - Payment Pending your review in Fraud Management Filters - Payment Pending your review in Fraud Management Filters - 11610 - Warning - - 50.0 - 623197 - 1500.00 - X - M - 5V117995ER6796022 - - - + <<~RESPONSE + + + + + + + + + An5ns1Kso7MWUdW4ErQKJJJ4qi4-Azffuo82oMt-Cv9I8QTOs-lG5sAv + + + + + + + 2008-07-04T19:27:39Z + SuccessWithWarning + 205d8397e7ed + + Payment Pending your review in Fraud Management Filters + Payment Pending your review in Fraud Management Filters + 11610 + Warning + + 50.0 + 623197 + 1500.00 + X + M + 5V117995ER6796022 + + + RESPONSE end def failed_capture_due_to_pending_fraud_review - <<-RESPONSE - - - - - - - - - - - - - - - 2008-07-04T21:45:35Z - Failure - 32a3855bd35b7 - - Transaction must be accepted in Fraud Management Filters before capture. - - 11612 - Error - - 52.000000 - 588340 - - - none - none - None - none - none - - - - - + <<~RESPONSE + + + + + + + + + + + + + + + 2008-07-04T21:45:35Z + Failure + 32a3855bd35b7 + + Transaction must be accepted in Fraud Management Filters before capture. + + 11612 + Error + + 52.000000 + 588340 + + + none + none + None + none + none + + + + + RESPONSE end def authentication_failed_response - <<-RESPONSE - - - - - - - - - - - - - - - 2008-08-12T19:40:59Z - Failure - b874109bfd11 - - Authentication/Authorization Failed - You do not have permissions to make this API call - 10002 - Error - - 52.000000 - 628921 - - - + <<~RESPONSE + + + + + + + + + + + + + + + 2008-08-12T19:40:59Z + Failure + b874109bfd11 + + Authentication/Authorization Failed + You do not have permissions to make this API call + 10002 + Error + + 52.000000 + 628921 + + + RESPONSE end def successful_create_profile_paypal_response - <<-RESPONSE - - - - - - - - - - - - - 2011-08-28T18:59:40Z - Success - 4b8eaecc084b - 59.0 - 2085867 - - I-G7A2FF8V75JY - ActiveProfile - - - - + <<~RESPONSE + + + + + + + + + + + + + 2011-08-28T18:59:40Z + Success + 4b8eaecc084b + 59.0 + 2085867 + + I-G7A2FF8V75JY + ActiveProfile + + + + RESPONSE end def failed_create_profile_paypal_response - <<-RESPONSE - - - - - - - - - - - - - - - - 2011-08-28T18:59:40Z - This is a test failure - 4b8eaecc084b - 59.0 - 2085867 - - I-G7A2FF8V75JY - ActiveProfile - - - - - " + <<~RESPONSE + + + + + + + + + + + + + + + + 2011-08-28T18:59:40Z + This is a test failure + 4b8eaecc084b + 59.0 + 2085867 + + I-G7A2FF8V75JY + ActiveProfile + + + + + " RESPONSE end def successful_details_response - <<-RESPONSE - - - - - - - - - - - - - - - 2011-03-01T20:19:35Z - Success - 84aff0e17b6f - 62.0 - 1741654 - - EC-2XE90996XX9870316 - - buyer@jadedpallet.com - FWRVKNRRZ3WUC - verified - - - Fred - - Brooks - - - US - -
- Fred Brooks - 1 Infinite Loop - - Cupertino - CA - US - United States - 95014 - PayPal - Confirmed -
-
- 1230123 - 416-618-9984 - - 19.00 - 19.00 - 0.00 - 0.00 - 0.00 - - Fred Brooks - 1234 Penny Lane - - Jonsetown - NC - US - United States - 123-456-7890 - 23456 - - PayPal - - Confirmed - - - Shopify T-Shirt - 1 - 0.00 - 19.00 - - - 0.00 - 0.00 - false - - - - - - PaymentActionNotInitiated -
-
-
-
+ <<~RESPONSE + + + + + + + + + + + + + + + 2011-03-01T20:19:35Z + Success + 84aff0e17b6f + 62.0 + 1741654 + + EC-2XE90996XX9870316 + + buyer@jadedpallet.com + FWRVKNRRZ3WUC + verified + + + Fred + + Brooks + + + US + +
+ Fred Brooks + 1 Infinite Loop + + Cupertino + CA + US + United States + 95014 + PayPal + Confirmed +
+
+ 1230123 + 416-618-9984 + + 19.00 + 19.00 + 0.00 + 0.00 + 0.00 + + Fred Brooks + 1234 Penny Lane + + Jonsetown + NC + US + United States + 123-456-7890 + 23456 + + PayPal + + Confirmed + + + Shopify T-Shirt + 1 + 0.00 + 19.00 + + + 0.00 + 0.00 + false + + + + + + PaymentActionNotInitiated +
+
+
+
RESPONSE end def successful_update_recurring_payment_profile_response - <<-RESPONSE - - - 2012-03-19T20:30:02Z - Success - 9ad0f67c1127c - 72 - 2649250 - - I-M1L3RX91DPDD - - - + <<~RESPONSE + + + 2012-03-19T20:30:02Z + Success + 9ad0f67c1127c + 72 + 2649250 + + I-M1L3RX91DPDD + + + RESPONSE end def successful_manage_recurring_payment_profile_response - <<-RESPONSE - - - 2012-03-19T20:41:03ZSuccess3c02ea62138c4722649250I-M1L3RX91DPDD + <<~RESPONSE + + + 2012-03-19T20:41:03ZSuccess3c02ea62138c4722649250I-M1L3RX91DPDD RESPONSE end def successful_bill_outstanding_amount - <<-RESPONSE - 2012-03-19T20:50:49ZSuccess2c1cbe06d718e722649250I-M1L3RX91DPDD + <<~RESPONSE + 2012-03-19T20:50:49ZSuccess2c1cbe06d718e722649250I-M1L3RX91DPDD RESPONSE end def successful_get_recurring_payments_profile_response - <<-RESPONSE - 2012-03-19T21:34:40ZSuccess6f24b53c49232722649250I-M1L3RX91DPDDCancelledProfileA descriptionNoAutoBill0Ryan BatesPayPalUnconfirmed2012-03-19T11:00:00ZMonth101.230.000.001-11.231Visa357612013unverifiedRyanBates
PayPalUnconfirmed
00
Month101.230.000.000.000.000.000.001970-01-01T00:00:00Z
+ <<~RESPONSE + 2012-03-19T21:34:40ZSuccess6f24b53c49232722649250I-M1L3RX91DPDDCancelledProfileA descriptionNoAutoBill0Ryan BatesPayPalUnconfirmed2012-03-19T11:00:00ZMonth101.230.000.001-11.231Visa357612013unverifiedRyanBates
PayPalUnconfirmed
00
Month101.230.000.000.000.000.000.001970-01-01T00:00:00Z
RESPONSE end - def three_d_secure_option + def three_d_secure_option(version:, xid: nil, ds_transaction_id: nil) { - three_d_secure: { - trans_status: 'Y', - eci: 'eci', - cavv: 'cavv', - xid: 'xid' - } + three_d_secure: { + authentication_response_status: 'Y', + eci: 'eci', + cavv: 'cavv', + xid: xid, + ds_transaction_id: ds_transaction_id, + version: version + } } end end diff --git a/test/unit/gateways/payscout_test.rb b/test/unit/gateways/payscout_test.rb index f5cb64b3a3f..6fc666505f1 100644 --- a/test/unit/gateways/payscout_test.rb +++ b/test/unit/gateways/payscout_test.rb @@ -3,17 +3,17 @@ class PayscoutTest < Test::Unit::TestCase def setup @gateway = PayscoutGateway.new( - :username => 'xxx', - :password => 'xxx' - ) + username: 'xxx', + password: 'xxx' + ) @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 @@ -230,7 +230,7 @@ def test_add_currency_from_money def test_add_invoice post = {} - options = {description: 'Order Description', order_id: '123'} + options = { description: 'Order Description', order_id: '123' } @gateway.send(:add_invoice, post, options) assert_equal 'Order Description', post[:orderdescription] @@ -281,25 +281,25 @@ def test_parse end def test_message_from_for_approved_response - assert_equal 'The transaction has been approved', @gateway.send(:message_from, {'response' => '1'}) + assert_equal 'The transaction has been approved', @gateway.send(:message_from, { 'response' => '1' }) end def test_message_from_for_declined_response - assert_equal 'The transaction has been declined', @gateway.send(:message_from, {'response' => '2'}) + assert_equal 'The transaction has been declined', @gateway.send(:message_from, { 'response' => '2' }) end def test_message_from_for_failed_response - assert_equal 'Error message', @gateway.send(:message_from, {'response' => '3', 'responsetext' => 'Error message'}) + assert_equal 'Error message', @gateway.send(:message_from, { 'response' => '3', 'responsetext' => 'Error message' }) end def test_success - assert @gateway.send(:success?, {'response' => '1'}) - refute @gateway.send(:success?, {'response' => '2'}) - refute @gateway.send(:success?, {'response' => '3'}) + assert @gateway.send(:success?, { 'response' => '1' }) + refute @gateway.send(:success?, { 'response' => '2' }) + refute @gateway.send(:success?, { 'response' => '3' }) end def test_post_data - parameters = {param1: 'value1', param2: 'value2'} + parameters = { param1: 'value1', param2: 'value2' } result = @gateway.send(:post_data, 'auth', parameters) assert_match 'username=xxx', result diff --git a/test/unit/gateways/paystation_test.rb b/test/unit/gateways/paystation_test.rb index c32716c1383..ccb6a3525a1 100644 --- a/test/unit/gateways/paystation_test.rb +++ b/test/unit/gateways/paystation_test.rb @@ -4,17 +4,17 @@ class PaystationTest < Test::Unit::TestCase include CommStub def setup @gateway = PaystationGateway.new( - :paystation_id => 'some_id_number', - :gateway_id => 'another_id_number' - ) + paystation_id: 'some_id_number', + gateway_id: 'another_id_number' + ) @credit_card = credit_card @amount = 100 @options = { - :order_id => '1', - :customer => 'Joe Bloggs, Customer ID #56', - :description => 'Store Purchase' + order_id: '1', + customer: 'Joe Bloggs, Customer ID #56', + description: 'Store Purchase' } end @@ -41,7 +41,7 @@ def test_unsuccessful_request def test_successful_store @gateway.expects(:ssl_post).returns(successful_store_response) - assert response = @gateway.store(@credit_card, @options.merge(:token => 'justatest1310263135')) + assert response = @gateway.store(@credit_card, @options.merge(token: 'justatest1310263135')) assert_success response assert response.test? @@ -74,7 +74,7 @@ def test_successful_authorization def test_successful_capture @gateway.expects(:ssl_post).returns(successful_capture_response) - assert response = @gateway.capture(@amount, '0009062250-01', @options.merge(:credit_card_verification => 123)) + assert response = @gateway.capture(@amount, '0009062250-01', @options.merge(credit_card_verification: 123)) assert_success response end @@ -89,7 +89,7 @@ def test_successful_refund refund = stub_comms do @gateway.refund(@amount, response.authorization, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/0008813023-01/, data) end.respond_with(successful_refund_response) @@ -425,5 +425,4 @@ def pre_scrubbed def post_scrubbed 'pstn_pi=609035&pstn_gi=PUSHPAY&pstn_2p=t&pstn_nr=t&pstn_df=yymm&pstn_ms=a755b9c84a530aee91dc3077f57294b0&pstn_mo=Store+Purchase&pstn_mr=&pstn_am=&pstn_cu=NZD&pstn_cn=[FILTERED]&pstn_ct=visa&pstn_ex=1305&pstn_cc=[FILTERED]&pstn_tm=T&paystation=_empty' end - end diff --git a/test/unit/gateways/payu_in_test.rb b/test/unit/gateways/payu_in_test.rb index 876bae34162..b2d3c981cc9 100644 --- a/test/unit/gateways/payu_in_test.rb +++ b/test/unit/gateways/payu_in_test.rb @@ -16,7 +16,7 @@ def setup } end - def assert_parameter(parameter, expected_value, data, options={}) + def assert_parameter(parameter, expected_value, data, options = {}) assert (data =~ %r{(?:^|&)#{parameter}=([^&]*)(?:&|$)}), "Unable to find #{parameter} in #{data}" value = CGI.unescape($1 || '') case expected_value @@ -25,9 +25,7 @@ def assert_parameter(parameter, expected_value, data, options={}) else assert_equal expected_value.to_s, value, "#{parameter} value does not match expected" end - if options[:length] - assert_equal options[:length], value.length, "#{parameter} value of #{value} is the wrong length" - end + assert_equal options[:length], value.length, "#{parameter} value of #{value} is the wrong length" if options[:length] end def test_successful_purchase @@ -205,7 +203,7 @@ def test_input_constraint_cleanup phone: ('a-' + ('1' * 51)) } ) - end.check_request do |endpoint, data, headers| + end.check_request do |endpoint, data, _headers| case endpoint when /_payment/ assert_parameter('txnid', /^a/, data, length: 30) @@ -293,7 +291,7 @@ def test_failed_purchase def test_successful_refund response = stub_comms do @gateway.refund(100, 'abc') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_parameter('command', 'cancel_refund_transaction', data) assert_parameter('var1', 'abc', data) assert_parameter('var2', /./, data) @@ -345,108 +343,108 @@ def test_invalid_json private def pre_scrubbed - <<-PRE_SCRUBBED -opening connection to test.payu.in:443... -opened -starting SSL for test.payu.in:443... -SSL established -<- "POST /_payment HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept-Encoding: identity\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: test.payu.in\r\nContent-Length: 460\r\n\r\n" -<- "amount=1.00&txnid=19ceaa9a230d3057dba07b78ad5c7d46&productinfo=Store+Purchase&surl=http%3A%2F%2Fexample.com&furl=http%3A%2F%2Fexample.com&pg=CC&firstname=Longbob&bankcode=VISA&ccnum=5123456789012346&ccvv=123&ccname=Longbob+Longsen&ccexpmon=5&ccexpyr=2017&email=unknown%40example.com&phone=11111111111&key=Gzv04m&txn_s2s_flow=1&hash=a255c1b5107556b7f00b7c5bbebf92392ec4d2c0675253ca20ef459d4259775efbeae039b59357ddd42374d278dedb432f2e9c238acc6358afe9b22cf908fbb3" --> "HTTP/1.1 200 OK\r\n" --> "Date: Fri, 08 May 2015 15:41:17 GMT\r\n" --> "Server: Apache\r\n" --> "P3P: CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"\r\n" --> "Set-Cookie: PHPSESSID=ud24vi12os6m7f7g0lpmked4a0; path=/; secure; HttpOnly\r\n" --> "Expires: Thu, 19 Nov 1981 08:52:00 GMT\r\n" --> "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n" --> "Pragma: no-cache\r\n" --> "Vary: Accept-Encoding\r\n" --> "Content-Length: 691\r\n" --> "Connection: close\r\n" --> "Content-Type: text/html; charset=UTF-8\r\n" --> "\r\n" -reading 691 bytes... --> "" --> "{\"status\":\"success\",\"response\":{\"form_post_vars\":{\"transactionId\":\"b84436e889cf6864a9fa2ab267f3f76a766ad6437b017ccb5093e8217996b814\",\"pgId\":\"8\",\"eci\":\"7\",\"nonEnrolled\":1,\"nonDomestic\":0,\"bank\":\"VISA\",\"cccat\":\"creditcard\",\"ccnum\":\"4b5c9002295c6cd8e5289e2f9c312dc737810a747b84e71665cf077c78fe245a\",\"ccname\":\"53ab689fdb1b025c7e9c53c6b4a6e27f51e0d627579e7c12af2cb6cbc4944cc0\",\"ccvv\":\"f31c6a1d6582f44ee1be4a3e1126b9cb08d1e7006f7afe083d7270b00dcb933f\",\"ccexpmon\":\"5ddf3702e74f473ec89762f6efece025737c2ab999e695cf10496e6fa3946079\",\"ccexpyr\":\"5da83563fcaa945063dc4c2094c48e800badf7c8246c9d13b43757fe99d63e6d\",\"is_seamless\":\"1\"},\"post_uri\":\"https:\\/\\/test.payu.in\\/hdfc_not_enrolled\",\"enrolled\":\"0\"}}" -read 691 bytes -Conn close -opening connection to test.payu.in:443... -opened -starting SSL for test.payu.in:443... -SSL established -<- "POST /hdfc_not_enrolled HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept-Encoding: identity\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: test.payu.in\r\nContent-Length: 520\r\n\r\n" -<- "transactionId=b84436e889cf6864a9fa2ab267f3f76a766ad6437b017ccb5093e8217996b814&pgId=8&eci=7&nonEnrolled=1&nonDomestic=0&bank=VISA&cccat=creditcard&ccnum=4b5c9002295c6cd8e5289e2f9c312dc737810a747b84e71665cf077c78fe245a&ccname=53ab689fdb1b025c7e9c53c6b4a6e27f51e0d627579e7c12af2cb6cbc4944cc0&ccvv=f31c6a1d6582f44ee1be4a3e1126b9cb08d1e7006f7afe083d7270b00dcb933f&ccexpmon=5ddf3702e74f473ec89762f6efece025737c2ab999e695cf10496e6fa3946079&ccexpyr=5da83563fcaa945063dc4c2094c48e800badf7c8246c9d13b43757fe99d63e6d&is_seamless=1" --> "HTTP/1.1 200 OK\r\n" --> "Date: Fri, 08 May 2015 15:41:27 GMT\r\n" --> "Server: Apache\r\n" --> "P3P: CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"\r\n" --> "Set-Cookie: PHPSESSID=n717g1mr5lvht96ukdobu6m344; path=/; secure; HttpOnly\r\n" --> "Expires: Thu, 19 Nov 1981 08:52:00 GMT\r\n" --> "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n" --> "Pragma: no-cache\r\n" --> "Vary: Accept-Encoding\r\n" --> "Content-Length: 1012\r\n" --> "Connection: close\r\n" --> "Content-Type: text/html; charset=UTF-8\r\n" --> "\r\n" -reading 1012 bytes... --> "" --> "{\"status\":\"success\",\"result\":\"mihpayid=403993715511983692&mode=CC&status=success&key=Gzv04m&txnid=19ceaa9a230d3057dba07b78ad5c7d46&amount=1.00&addedon=2015-05-08+21%3A11%3A17&productinfo=Store+Purchase&firstname=Longbob&lastname=&address1=&address2=&city=&state=&country=&zipcode=&email=unknown%40example.com&phone=11111111111&udf1=&udf2=&udf3=&udf4=&udf5=&udf6=&udf7=&udf8=&udf9=&udf10=&card_token=&card_no=512345XXXXXX2346&field0=&field1=512816420000&field2=999999&field3=6816991112151281&field4=-1&field5=&field6=&field7=&field8=&field9=SUCCESS&PG_TYPE=HDFCPG&error=E000&error_Message=No+Error&net_amount_debit=1&unmappedstatus=success&hash=c0d3e5346c37ddd32bb3b386ed1d0709a612d304180e7a25dcbf047cc1c3a4e9de9940af0179c6169c0038b2a826d7ea4b868fcbc4e435928e8cbd25da3c1e56&bank_ref_no=6816991112151281&bank_ref_num=6816991112151281&bankcode=VISA&surl=http%3A%2F%2Fexample.com&curl=http%3A%2F%2Fexample.com&furl=http%3A%2F%2Fexample.com&card_hash=f25e4f9ea802050c23423966d35adc54046f651f0d9a2b837b49c75f964d1fa7\"}" -read 1012 bytes -Conn close + <<~PRE_SCRUBBED + opening connection to test.payu.in:443... + opened + starting SSL for test.payu.in:443... + SSL established + <- "POST /_payment HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept-Encoding: identity\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: test.payu.in\r\nContent-Length: 460\r\n\r\n" + <- "amount=1.00&txnid=19ceaa9a230d3057dba07b78ad5c7d46&productinfo=Store+Purchase&surl=http%3A%2F%2Fexample.com&furl=http%3A%2F%2Fexample.com&pg=CC&firstname=Longbob&bankcode=VISA&ccnum=5123456789012346&ccvv=123&ccname=Longbob+Longsen&ccexpmon=5&ccexpyr=2017&email=unknown%40example.com&phone=11111111111&key=Gzv04m&txn_s2s_flow=1&hash=a255c1b5107556b7f00b7c5bbebf92392ec4d2c0675253ca20ef459d4259775efbeae039b59357ddd42374d278dedb432f2e9c238acc6358afe9b22cf908fbb3" + -> "HTTP/1.1 200 OK\r\n" + -> "Date: Fri, 08 May 2015 15:41:17 GMT\r\n" + -> "Server: Apache\r\n" + -> "P3P: CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"\r\n" + -> "Set-Cookie: PHPSESSID=ud24vi12os6m7f7g0lpmked4a0; path=/; secure; HttpOnly\r\n" + -> "Expires: Thu, 19 Nov 1981 08:52:00 GMT\r\n" + -> "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n" + -> "Pragma: no-cache\r\n" + -> "Vary: Accept-Encoding\r\n" + -> "Content-Length: 691\r\n" + -> "Connection: close\r\n" + -> "Content-Type: text/html; charset=UTF-8\r\n" + -> "\r\n" + reading 691 bytes... + -> "" + -> "{\"status\":\"success\",\"response\":{\"form_post_vars\":{\"transactionId\":\"b84436e889cf6864a9fa2ab267f3f76a766ad6437b017ccb5093e8217996b814\",\"pgId\":\"8\",\"eci\":\"7\",\"nonEnrolled\":1,\"nonDomestic\":0,\"bank\":\"VISA\",\"cccat\":\"creditcard\",\"ccnum\":\"4b5c9002295c6cd8e5289e2f9c312dc737810a747b84e71665cf077c78fe245a\",\"ccname\":\"53ab689fdb1b025c7e9c53c6b4a6e27f51e0d627579e7c12af2cb6cbc4944cc0\",\"ccvv\":\"f31c6a1d6582f44ee1be4a3e1126b9cb08d1e7006f7afe083d7270b00dcb933f\",\"ccexpmon\":\"5ddf3702e74f473ec89762f6efece025737c2ab999e695cf10496e6fa3946079\",\"ccexpyr\":\"5da83563fcaa945063dc4c2094c48e800badf7c8246c9d13b43757fe99d63e6d\",\"is_seamless\":\"1\"},\"post_uri\":\"https:\\/\\/test.payu.in\\/hdfc_not_enrolled\",\"enrolled\":\"0\"}}" + read 691 bytes + Conn close + opening connection to test.payu.in:443... + opened + starting SSL for test.payu.in:443... + SSL established + <- "POST /hdfc_not_enrolled HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept-Encoding: identity\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: test.payu.in\r\nContent-Length: 520\r\n\r\n" + <- "transactionId=b84436e889cf6864a9fa2ab267f3f76a766ad6437b017ccb5093e8217996b814&pgId=8&eci=7&nonEnrolled=1&nonDomestic=0&bank=VISA&cccat=creditcard&ccnum=4b5c9002295c6cd8e5289e2f9c312dc737810a747b84e71665cf077c78fe245a&ccname=53ab689fdb1b025c7e9c53c6b4a6e27f51e0d627579e7c12af2cb6cbc4944cc0&ccvv=f31c6a1d6582f44ee1be4a3e1126b9cb08d1e7006f7afe083d7270b00dcb933f&ccexpmon=5ddf3702e74f473ec89762f6efece025737c2ab999e695cf10496e6fa3946079&ccexpyr=5da83563fcaa945063dc4c2094c48e800badf7c8246c9d13b43757fe99d63e6d&is_seamless=1" + -> "HTTP/1.1 200 OK\r\n" + -> "Date: Fri, 08 May 2015 15:41:27 GMT\r\n" + -> "Server: Apache\r\n" + -> "P3P: CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"\r\n" + -> "Set-Cookie: PHPSESSID=n717g1mr5lvht96ukdobu6m344; path=/; secure; HttpOnly\r\n" + -> "Expires: Thu, 19 Nov 1981 08:52:00 GMT\r\n" + -> "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n" + -> "Pragma: no-cache\r\n" + -> "Vary: Accept-Encoding\r\n" + -> "Content-Length: 1012\r\n" + -> "Connection: close\r\n" + -> "Content-Type: text/html; charset=UTF-8\r\n" + -> "\r\n" + reading 1012 bytes... + -> "" + -> "{\"status\":\"success\",\"result\":\"mihpayid=403993715511983692&mode=CC&status=success&key=Gzv04m&txnid=19ceaa9a230d3057dba07b78ad5c7d46&amount=1.00&addedon=2015-05-08+21%3A11%3A17&productinfo=Store+Purchase&firstname=Longbob&lastname=&address1=&address2=&city=&state=&country=&zipcode=&email=unknown%40example.com&phone=11111111111&udf1=&udf2=&udf3=&udf4=&udf5=&udf6=&udf7=&udf8=&udf9=&udf10=&card_token=&card_no=512345XXXXXX2346&field0=&field1=512816420000&field2=999999&field3=6816991112151281&field4=-1&field5=&field6=&field7=&field8=&field9=SUCCESS&PG_TYPE=HDFCPG&error=E000&error_Message=No+Error&net_amount_debit=1&unmappedstatus=success&hash=c0d3e5346c37ddd32bb3b386ed1d0709a612d304180e7a25dcbf047cc1c3a4e9de9940af0179c6169c0038b2a826d7ea4b868fcbc4e435928e8cbd25da3c1e56&bank_ref_no=6816991112151281&bank_ref_num=6816991112151281&bankcode=VISA&surl=http%3A%2F%2Fexample.com&curl=http%3A%2F%2Fexample.com&furl=http%3A%2F%2Fexample.com&card_hash=f25e4f9ea802050c23423966d35adc54046f651f0d9a2b837b49c75f964d1fa7\"}" + read 1012 bytes + Conn close PRE_SCRUBBED end def post_scrubbed - <<-POST_SCRUBBED -opening connection to test.payu.in:443... -opened -starting SSL for test.payu.in:443... -SSL established -<- "POST /_payment HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept-Encoding: identity\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: test.payu.in\r\nContent-Length: 460\r\n\r\n" -<- "amount=1.00&txnid=19ceaa9a230d3057dba07b78ad5c7d46&productinfo=Store+Purchase&surl=http%3A%2F%2Fexample.com&furl=http%3A%2F%2Fexample.com&pg=CC&firstname=Longbob&bankcode=VISA&ccnum=[FILTERED]&ccvv=[FILTERED]&ccname=Longbob+Longsen&ccexpmon=5&ccexpyr=2017&email=unknown%40example.com&phone=11111111111&key=Gzv04m&txn_s2s_flow=1&hash=a255c1b5107556b7f00b7c5bbebf92392ec4d2c0675253ca20ef459d4259775efbeae039b59357ddd42374d278dedb432f2e9c238acc6358afe9b22cf908fbb3" --> "HTTP/1.1 200 OK\r\n" --> "Date: Fri, 08 May 2015 15:41:17 GMT\r\n" --> "Server: Apache\r\n" --> "P3P: CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"\r\n" --> "Set-Cookie: PHPSESSID=ud24vi12os6m7f7g0lpmked4a0; path=/; secure; HttpOnly\r\n" --> "Expires: Thu, 19 Nov 1981 08:52:00 GMT\r\n" --> "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n" --> "Pragma: no-cache\r\n" --> "Vary: Accept-Encoding\r\n" --> "Content-Length: 691\r\n" --> "Connection: close\r\n" --> "Content-Type: text/html; charset=UTF-8\r\n" --> "\r\n" -reading 691 bytes... --> "" --> "{\"status\":\"success\",\"response\":{\"form_post_vars\":{\"transactionId\":\"b84436e889cf6864a9fa2ab267f3f76a766ad6437b017ccb5093e8217996b814\",\"pgId\":\"8\",\"eci\":\"7\",\"nonEnrolled\":1,\"nonDomestic\":0,\"bank\":\"VISA\",\"cccat\":\"creditcard\",\"ccnum\":\"[FILTERED]\",\"ccname\":\"53ab689fdb1b025c7e9c53c6b4a6e27f51e0d627579e7c12af2cb6cbc4944cc0\",\"ccvv\":\"[FILTERED]\",\"ccexpmon\":\"5ddf3702e74f473ec89762f6efece025737c2ab999e695cf10496e6fa3946079\",\"ccexpyr\":\"5da83563fcaa945063dc4c2094c48e800badf7c8246c9d13b43757fe99d63e6d\",\"is_seamless\":\"1\"},\"post_uri\":\"https:\\/\\/test.payu.in\\/hdfc_not_enrolled\",\"enrolled\":\"0\"}}" -read 691 bytes -Conn close -opening connection to test.payu.in:443... -opened -starting SSL for test.payu.in:443... -SSL established -<- "POST /hdfc_not_enrolled HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept-Encoding: identity\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: test.payu.in\r\nContent-Length: 520\r\n\r\n" -<- "transactionId=b84436e889cf6864a9fa2ab267f3f76a766ad6437b017ccb5093e8217996b814&pgId=8&eci=7&nonEnrolled=1&nonDomestic=0&bank=VISA&cccat=creditcard&ccnum=[FILTERED]&ccname=53ab689fdb1b025c7e9c53c6b4a6e27f51e0d627579e7c12af2cb6cbc4944cc0&ccvv=[FILTERED]&ccexpmon=5ddf3702e74f473ec89762f6efece025737c2ab999e695cf10496e6fa3946079&ccexpyr=5da83563fcaa945063dc4c2094c48e800badf7c8246c9d13b43757fe99d63e6d&is_seamless=1" --> "HTTP/1.1 200 OK\r\n" --> "Date: Fri, 08 May 2015 15:41:27 GMT\r\n" --> "Server: Apache\r\n" --> "P3P: CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"\r\n" --> "Set-Cookie: PHPSESSID=n717g1mr5lvht96ukdobu6m344; path=/; secure; HttpOnly\r\n" --> "Expires: Thu, 19 Nov 1981 08:52:00 GMT\r\n" --> "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n" --> "Pragma: no-cache\r\n" --> "Vary: Accept-Encoding\r\n" --> "Content-Length: 1012\r\n" --> "Connection: close\r\n" --> "Content-Type: text/html; charset=UTF-8\r\n" --> "\r\n" -reading 1012 bytes... --> "" --> "{\"status\":\"success\",\"result\":\"mihpayid=403993715511983692&mode=CC&status=success&key=Gzv04m&txnid=19ceaa9a230d3057dba07b78ad5c7d46&amount=1.00&addedon=2015-05-08+21%3A11%3A17&productinfo=Store+Purchase&firstname=Longbob&lastname=&address1=&address2=&city=&state=&country=&zipcode=&email=unknown%40example.com&phone=11111111111&udf1=&udf2=&udf3=&udf4=&udf5=&udf6=&udf7=&udf8=&udf9=&udf10=&card_token=&card_no=512345XXXXXX2346&field0=&field1=512816420000&field2=999999&field3=6816991112151281&field4=-1&field5=&field6=&field7=&field8=&field9=SUCCESS&PG_TYPE=HDFCPG&error=E000&error_Message=No+Error&net_amount_debit=1&unmappedstatus=success&hash=c0d3e5346c37ddd32bb3b386ed1d0709a612d304180e7a25dcbf047cc1c3a4e9de9940af0179c6169c0038b2a826d7ea4b868fcbc4e435928e8cbd25da3c1e56&bank_ref_no=6816991112151281&bank_ref_num=6816991112151281&bankcode=VISA&surl=http%3A%2F%2Fexample.com&curl=http%3A%2F%2Fexample.com&furl=http%3A%2F%2Fexample.com&card_hash=[FILTERED]\"}" -read 1012 bytes -Conn close + <<~POST_SCRUBBED + opening connection to test.payu.in:443... + opened + starting SSL for test.payu.in:443... + SSL established + <- "POST /_payment HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept-Encoding: identity\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: test.payu.in\r\nContent-Length: 460\r\n\r\n" + <- "amount=1.00&txnid=19ceaa9a230d3057dba07b78ad5c7d46&productinfo=Store+Purchase&surl=http%3A%2F%2Fexample.com&furl=http%3A%2F%2Fexample.com&pg=CC&firstname=Longbob&bankcode=VISA&ccnum=[FILTERED]&ccvv=[FILTERED]&ccname=Longbob+Longsen&ccexpmon=5&ccexpyr=2017&email=unknown%40example.com&phone=11111111111&key=Gzv04m&txn_s2s_flow=1&hash=a255c1b5107556b7f00b7c5bbebf92392ec4d2c0675253ca20ef459d4259775efbeae039b59357ddd42374d278dedb432f2e9c238acc6358afe9b22cf908fbb3" + -> "HTTP/1.1 200 OK\r\n" + -> "Date: Fri, 08 May 2015 15:41:17 GMT\r\n" + -> "Server: Apache\r\n" + -> "P3P: CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"\r\n" + -> "Set-Cookie: PHPSESSID=ud24vi12os6m7f7g0lpmked4a0; path=/; secure; HttpOnly\r\n" + -> "Expires: Thu, 19 Nov 1981 08:52:00 GMT\r\n" + -> "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n" + -> "Pragma: no-cache\r\n" + -> "Vary: Accept-Encoding\r\n" + -> "Content-Length: 691\r\n" + -> "Connection: close\r\n" + -> "Content-Type: text/html; charset=UTF-8\r\n" + -> "\r\n" + reading 691 bytes... + -> "" + -> "{\"status\":\"success\",\"response\":{\"form_post_vars\":{\"transactionId\":\"b84436e889cf6864a9fa2ab267f3f76a766ad6437b017ccb5093e8217996b814\",\"pgId\":\"8\",\"eci\":\"7\",\"nonEnrolled\":1,\"nonDomestic\":0,\"bank\":\"VISA\",\"cccat\":\"creditcard\",\"ccnum\":\"[FILTERED]\",\"ccname\":\"53ab689fdb1b025c7e9c53c6b4a6e27f51e0d627579e7c12af2cb6cbc4944cc0\",\"ccvv\":\"[FILTERED]\",\"ccexpmon\":\"5ddf3702e74f473ec89762f6efece025737c2ab999e695cf10496e6fa3946079\",\"ccexpyr\":\"5da83563fcaa945063dc4c2094c48e800badf7c8246c9d13b43757fe99d63e6d\",\"is_seamless\":\"1\"},\"post_uri\":\"https:\\/\\/test.payu.in\\/hdfc_not_enrolled\",\"enrolled\":\"0\"}}" + read 691 bytes + Conn close + opening connection to test.payu.in:443... + opened + starting SSL for test.payu.in:443... + SSL established + <- "POST /hdfc_not_enrolled HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept-Encoding: identity\r\nAccept: */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: test.payu.in\r\nContent-Length: 520\r\n\r\n" + <- "transactionId=b84436e889cf6864a9fa2ab267f3f76a766ad6437b017ccb5093e8217996b814&pgId=8&eci=7&nonEnrolled=1&nonDomestic=0&bank=VISA&cccat=creditcard&ccnum=[FILTERED]&ccname=53ab689fdb1b025c7e9c53c6b4a6e27f51e0d627579e7c12af2cb6cbc4944cc0&ccvv=[FILTERED]&ccexpmon=5ddf3702e74f473ec89762f6efece025737c2ab999e695cf10496e6fa3946079&ccexpyr=5da83563fcaa945063dc4c2094c48e800badf7c8246c9d13b43757fe99d63e6d&is_seamless=1" + -> "HTTP/1.1 200 OK\r\n" + -> "Date: Fri, 08 May 2015 15:41:27 GMT\r\n" + -> "Server: Apache\r\n" + -> "P3P: CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"\r\n" + -> "Set-Cookie: PHPSESSID=n717g1mr5lvht96ukdobu6m344; path=/; secure; HttpOnly\r\n" + -> "Expires: Thu, 19 Nov 1981 08:52:00 GMT\r\n" + -> "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n" + -> "Pragma: no-cache\r\n" + -> "Vary: Accept-Encoding\r\n" + -> "Content-Length: 1012\r\n" + -> "Connection: close\r\n" + -> "Content-Type: text/html; charset=UTF-8\r\n" + -> "\r\n" + reading 1012 bytes... + -> "" + -> "{\"status\":\"success\",\"result\":\"mihpayid=403993715511983692&mode=CC&status=success&key=Gzv04m&txnid=19ceaa9a230d3057dba07b78ad5c7d46&amount=1.00&addedon=2015-05-08+21%3A11%3A17&productinfo=Store+Purchase&firstname=Longbob&lastname=&address1=&address2=&city=&state=&country=&zipcode=&email=unknown%40example.com&phone=11111111111&udf1=&udf2=&udf3=&udf4=&udf5=&udf6=&udf7=&udf8=&udf9=&udf10=&card_token=&card_no=512345XXXXXX2346&field0=&field1=512816420000&field2=999999&field3=6816991112151281&field4=-1&field5=&field6=&field7=&field8=&field9=SUCCESS&PG_TYPE=HDFCPG&error=E000&error_Message=No+Error&net_amount_debit=1&unmappedstatus=success&hash=c0d3e5346c37ddd32bb3b386ed1d0709a612d304180e7a25dcbf047cc1c3a4e9de9940af0179c6169c0038b2a826d7ea4b868fcbc4e435928e8cbd25da3c1e56&bank_ref_no=6816991112151281&bank_ref_num=6816991112151281&bankcode=VISA&surl=http%3A%2F%2Fexample.com&curl=http%3A%2F%2Fexample.com&furl=http%3A%2F%2Fexample.com&card_hash=[FILTERED]\"}" + read 1012 bytes + Conn close POST_SCRUBBED end diff --git a/test/unit/gateways/payu_latam_test.rb b/test/unit/gateways/payu_latam_test.rb index d4ea5d0664e..8945152bd4e 100644 --- a/test/unit/gateways/payu_latam_test.rb +++ b/test/unit/gateways/payu_latam_test.rb @@ -12,7 +12,7 @@ def setup @pending_card = credit_card('4097440000000004', verification_value: '222', first_name: 'PENDING', last_name: '') @no_cvv_visa_card = credit_card('4097440000000004', verification_value: ' ') @no_cvv_amex_card = credit_card('4097440000000004', verification_value: ' ', brand: 'american_express') - @cabal_credit_card = credit_card('5896570000000004', :verification_value => '123', :first_name => 'APPROVED', :last_name => '', :brand => 'cabal') + @cabal_credit_card = credit_card('5896570000000004', verification_value: '123', first_name: 'APPROVED', last_name: '', brand: 'cabal') @options = { dni_number: '5415668464654', @@ -53,7 +53,7 @@ def test_successful_purchase def test_successful_purchase_with_specified_language stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(language: 'es')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/"language":"es"/, data) end.respond_with(successful_purchase_response) end @@ -76,6 +76,22 @@ def test_failed_purchase assert_equal 'DECLINED', response.params['transactionResponse']['state'] end + def test_failed_purchase_correct_message_when_payment_network_response_error_present + @gateway.expects(:ssl_post).returns(failed_purchase_response_when_payment_network_response_error_expected) + + response = @gateway.purchase(@amount, @credit_card, @options) + assert_failure response + assert_equal 'CONTACT_THE_ENTITY | Contactar con entidad emisora', response.message + assert_equal 'Contactar con entidad emisora', response.params['transactionResponse']['paymentNetworkResponseErrorMessage'] + + @gateway.expects(:ssl_post).returns(failed_purchase_response_when_payment_network_response_error_not_expected) + + response = @gateway.purchase(@amount, @credit_card, @options) + assert_failure response + assert_equal 'CONTACT_THE_ENTITY', response.message + assert_nil response.params['transactionResponse']['paymentNetworkResponseErrorMessage'] + end + def test_successful_authorize @gateway.expects(:ssl_post).returns(successful_authorize_response) @@ -88,7 +104,7 @@ def test_successful_authorize def test_successful_authorize_with_specified_language stub_comms do @gateway.authorize(@amount, @credit_card, @options.merge(language: 'es')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/"language":"es"/, data) end.respond_with(successful_purchase_response) end @@ -122,8 +138,19 @@ def test_pending_refund def test_pending_refund_with_specified_language stub_comms do @gateway.refund(@amount, '7edbaf68-8f3a-4ae7-b9c7-d1e27e314999', @options.merge(language: 'es')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/"language":"es"/, data) + assert_match(/"type":"REFUND"/, data) + end.respond_with(pending_refund_response) + end + + def test_partial_refund + stub_comms do + @gateway.refund(2000, '7edbaf68-8f3a-4ae7-b9c7-d1e27e314999', @options.merge(partial_refund: true)) + end.check_request do |_endpoint, data, _headers| + assert_match(/"type":"PARTIAL_REFUND"/, data) + assert_match(/"TX_VALUE"/, data) + assert_match(/"value":"20.00"/, data) end.respond_with(pending_refund_response) end @@ -146,7 +173,7 @@ def test_successful_void def test_successful_void_with_specified_language stub_comms do @gateway.void('7edbaf68-8f3a-4ae7-b9c7-d1e27e314999', @options.merge(language: 'es')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/"language":"es"/, data) end.respond_with(successful_void_response) end @@ -162,7 +189,7 @@ def test_failed_void def test_successful_purchase_with_dni_number 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(/"dniNumber":"5415668464654"/, data) end.respond_with(successful_purchase_response) end @@ -170,7 +197,7 @@ def test_successful_purchase_with_dni_number def test_successful_purchase_with_merchant_buyer_id 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(/"merchantBuyerId":"1"/, data) end.respond_with(successful_purchase_response) end @@ -186,8 +213,8 @@ def test_verify_bad_credentials end def test_request_using_visa_card_with_no_cvv - @gateway.expects(:ssl_post).with { |url, body, headers| - body.match '"securityCode":"000"' + @gateway.expects(:ssl_post).with { |_url, body, _headers| + body =~ /"securityCode":"000"/ body.match '"processWithoutCvv2":true' }.returns(successful_purchase_response) response = @gateway.purchase(@amount, @no_cvv_visa_card, @options) @@ -197,8 +224,8 @@ def test_request_using_visa_card_with_no_cvv end def test_request_using_amex_card_with_no_cvv - @gateway.expects(:ssl_post).with { |url, body, headers| - body.match '"securityCode":"0000"' + @gateway.expects(:ssl_post).with { |_url, body, _headers| + body =~ /"securityCode":"0000"/ body.match '"processWithoutCvv2":true' }.returns(successful_purchase_response) response = @gateway.purchase(@amount, @no_cvv_amex_card, @options) @@ -208,8 +235,8 @@ def test_request_using_amex_card_with_no_cvv end def test_request_passes_cvv_option - @gateway.expects(:ssl_post).with { |url, body, headers| - body.match '"securityCode":"777"' + @gateway.expects(:ssl_post).with { |_url, body, _headers| + body =~ /"securityCode":"777"/ !body.match '"processWithoutCvv2"' }.returns(successful_purchase_response) options = @options.merge(cvv: '777') @@ -230,7 +257,7 @@ def test_successful_capture def test_successful_capture_with_specified_language stub_comms do @gateway.capture(@amount, '4000|authorization', @options.merge(language: 'es')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/"language":"es"/, data) end.respond_with(successful_purchase_response) end @@ -238,7 +265,7 @@ def test_successful_capture_with_specified_language def test_successful_partial_capture stub_comms do @gateway.capture(@amount - 1, '4000|authorization', @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_equal '39.99', JSON.parse(data)['transaction']['additionalValues']['TX_VALUE']['value'] end.respond_with(successful_purchase_response) end @@ -272,7 +299,7 @@ def test_partial_buyer_hash_info stub_comms do @gateway.purchase(@amount, @credit_card, @options.update(options_buyer)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/\"buyer\":{\"fullName\":\"Jorge Borges\",\"dniNumber\":\"5415668464456\",\"dniType\":null,\"merchantBuyerId\":\"1\",\"emailAddress\":\"axaxaxas@mlo.org\",\"contactPhone\":\"7563126\",\"shippingAddress\":{\"street1\":\"Calle 200\",\"street2\":\"N107\",\"city\":\"Sao Paulo\",\"state\":\"SP\",\"country\":\"BR\",\"postalCode\":\"01019-030\",\"phone\":\"\(11\)756312345\"}}/, data) end.respond_with(successful_purchase_response) end @@ -280,11 +307,39 @@ def test_partial_buyer_hash_info def test_buyer_fields_default_to_payer 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(/\"buyer\":{\"fullName\":\"APPROVED\",\"dniNumber\":\"5415668464654\",\"dniType\":\"TI\",\"merchantBuyerId\":\"1\",\"emailAddress\":\"username@domain.com\",\"contactPhone\":\"7563126\"/, data) end.respond_with(successful_purchase_response) end + def test_request_with_blank_billing_address_fields + options = { + dni_number: '5415668464654', + dni_type: 'TI', + merchant_buyer_id: '1', + currency: 'ARS', + order_id: generate_unique_id, + description: 'Active Merchant Transaction', + billing_address: address( + address1: 'Viamonte', + address2: nil, + city: 'Plata', + state: 'Buenos Aires', + country: '', + zip: '64000', + phone: '7563126' + ) + } + + stub_comms do + @gateway.purchase(@amount, @credit_card, options) + end.check_request do |_endpoint, data, _headers| + assert_match(/"merchantBuyerId":"1"/, data) + assert_match(/"street2":null/, data) + refute_match(/"country"/, data) + end.respond_with(successful_purchase_response) + end + def test_brazil_required_fields gateway = PayuLatamGateway.new(merchant_id: 'merchant_id', account_id: 'account_id', api_login: 'api_login', api_key: 'api_key', payment_country: 'BR') @@ -315,7 +370,7 @@ def test_brazil_required_fields stub_comms(gateway) do gateway.purchase(@amount, @credit_card, @options.update(options_brazil)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/\"cnpj\":\"32593371000110\"/, data) end.respond_with(successful_purchase_response) end @@ -349,7 +404,7 @@ def test_colombia_required_fields stub_comms(gateway) do gateway.purchase(@amount, @credit_card, @options.update(options_colombia)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/\"additionalValues\":{\"TX_VALUE\":{\"value\":\"40.00\",\"currency\":\"COP\"},\"TX_TAX\":{\"value\":0,\"currency\":\"COP\"},\"TX_TAX_RETURN_BASE\":{\"value\":0,\"currency\":\"COP\"}}/, data) end.respond_with(successful_purchase_response) end @@ -382,7 +437,7 @@ def test_mexico_required_fields stub_comms(gateway) do gateway.purchase(@amount, @credit_card, @options.update(options_mexico)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/\"birthdate\":\"1985-05-25\"/, data) end.respond_with(successful_purchase_response) end @@ -538,6 +593,60 @@ def failed_purchase_response RESPONSE end + def failed_purchase_response_when_payment_network_response_error_expected + <<-RESPONSE + { + "code": "SUCCESS", + "error": null, + "transactionResponse": { + "orderId": 7354347, + "transactionId": "15b6cec0-9eec-4564-b6b9-c846b868203e", + "state": "DECLINED", + "paymentNetworkResponseCode": "290", + "paymentNetworkResponseErrorMessage": "Contactar con entidad emisora", + "trazabilityCode": null, + "authorizationCode": null, + "pendingReason": null, + "responseCode": "CONTACT_THE_ENTITY", + "errorCode": null, + "responseMessage": null, + "transactionDate": null, + "transactionTime": null, + "operationDate": null, + "referenceQuestionnaire": null, + "extraParameters": null + } + } + RESPONSE + end + + def failed_purchase_response_when_payment_network_response_error_not_expected + <<-RESPONSE + { + "code": "SUCCESS", + "error": null, + "transactionResponse": { + "orderId": 7354347, + "transactionId": "15b6cec0-9eec-4564-b6b9-c846b868203e", + "state": "DECLINED", + "paymentNetworkResponseCode": null, + "paymentNetworkResponseErrorMessage": null, + "trazabilityCode": null, + "authorizationCode": null, + "pendingReason": null, + "responseCode": "CONTACT_THE_ENTITY", + "errorCode": null, + "responseMessage": null, + "transactionDate": null, + "transactionTime": null, + "operationDate": null, + "referenceQuestionnaire": null, + "extraParameters": null + } + } + RESPONSE + end + def successful_authorize_response <<-RESPONSE { diff --git a/test/unit/gateways/payway_dot_com_test.rb b/test/unit/gateways/payway_dot_com_test.rb new file mode 100644 index 00000000000..f412260aa57 --- /dev/null +++ b/test/unit/gateways/payway_dot_com_test.rb @@ -0,0 +1,1404 @@ +require 'test_helper' + +class PaywayDotComTest < Test::Unit::TestCase + def setup + @gateway = PaywayDotComGateway.new( + login: 'sprerestwsdev', + password: 'sprerestwsdev1!', + company_id: '3' + ) + @credit_card = credit_card + @amount = 100 + + @options = { + order_id: '1', + billing_address: address, + description: 'Store Purchase', + source_id: '67' + } + end + + def test_successful_purchase + @gateway.expects(:ssl_request).returns(successful_purchase_response) + + response = @gateway.purchase(@amount, @credit_card, @options) + assert_success response + assert_equal '5000', response.message[0, 4] + assert_equal '0987654321', response.params['cardTransaction']['authorizationCode'] + assert_equal '', response.error_code + assert response.test? + assert_equal 'Z', response.avs_result['code'] + assert_equal 'M', response.cvv_result['code'] + 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 '5035', response.message[0, 4] + assert_equal Gateway::STANDARD_ERROR_CODE[:invalid_number], response.error_code + end + + def test_successful_authorize + @gateway.expects(:ssl_request).returns(successful_authorize_response) + + auth_only = @gateway.authorize(103, @credit_card, @options) + assert_success auth_only + assert_equal '5000', auth_only.message[0, 4] + end + + def test_successful_authorize_and_capture + @gateway.expects(:ssl_request).returns(successful_authorize_and_capture_response) + + auth = @gateway.authorize(104, @credit_card, @options) + assert_success auth + + @gateway.expects(:ssl_request).returns(successful_capture_response) + + assert capture = @gateway.capture(@amount, auth.authorization, @options) + assert_success capture + assert_equal '5000', capture.message[0, 4] + end + + def test_failed_authorize + @gateway.expects(:ssl_request).returns(failed_authorize_response) + + response = @gateway.authorize(105, @credit_card, @options) + assert_failure response + assert_equal '5035', response.message[0, 4] + end + + def test_failed_capture + @gateway.expects(:ssl_request).returns(failed_capture_response) + + response = @gateway.capture(106, '') + assert_failure response + assert_equal '5025', response.message[0, 4] + end + + def test_successful_credit + @gateway.expects(:ssl_request).returns(successful_credit_response) + + credit = @gateway.credit(107, @credit_card, @options) + assert_success credit + assert_equal '5000', credit.message[0, 4] + end + + def test_failed_credit + @gateway.expects(:ssl_request).returns(failed_credit_response) + + response = @gateway.credit(108, @credit_card, @options) + assert_failure response + assert_equal '5035', response.message[0, 4] + end + + def test_successful_void + @gateway.expects(:ssl_request).returns(successful_auth_for_void_response) + + auth = @gateway.authorize(109, @credit_card, @options) + assert_success auth + + @gateway.expects(:ssl_request).returns(successful_void_auth_response) + + assert void = @gateway.void(auth.authorization, @options) + assert_success void + assert_equal '5000', void.message[0, 4] + end + + def test_failed_void + @gateway.expects(:ssl_request).returns(failed_void_response) + + response = @gateway.void('') + assert_failure response + assert_equal '5025', response.message[0, 4] + end + + def test_successful_void_of_sale + @gateway.expects(:ssl_request).returns(successful_sale_for_void_response) + + sale = @gateway.purchase(110, @credit_card, @options) + assert_success sale + + @gateway.expects(:ssl_request).returns(successful_void_sale_response) + + assert void = @gateway.void(sale.authorization, @options) + assert_success void + assert_equal '5000', void.message[0, 4] + end + + def test_successful_void_of_credit + @gateway.expects(:ssl_request).returns(successful_credit_for_void_response) + + credit = @gateway.credit(111, @credit_card, @options) + assert_success credit + + @gateway.expects(:ssl_request).returns(successful_credit_void_response) + + assert void = @gateway.void(credit.authorization, @options) + assert_success void + assert_equal '5000', void.message[0, 4] + end + + def test_invalid_login + @gateway2 = PaywayDotComGateway.new(login: '', password: '', company_id: '') + @gateway2.expects(:ssl_request).returns(failed_invalid_login_response) + + assert response = @gateway2.purchase(@amount, @credit_card, @options) + assert_failure response + assert_match %r{5001}, response.message[0, 4] + end + + def test_scrub + assert @gateway.supports_scrubbing? + assert_equal @gateway.scrub(pre_scrubbed), post_scrubbed + end + + private + + def pre_scrubbed + %q( + opening connection to devedgilpayway.net:443... + opened + starting SSL for devedgilpayway.net:443... + SSL established, protocol: TLSv1.2, cipher: AES256-GCM-SHA384 + <- "{\"userName\":\"sprerestwsdev\",\"password\":\"sprerestwsdev1!\",\"companyId\":\"3\",\"accountInputMode\":\"primaryAccountNumber\",\"cardAccount\":{\"accountNumber\":\"4000100011112224\",\"fsv\":\"737\",\"expirationDate\":\"092022\",\"email\":null,\"firstName\":\"Jim\",\"lastName\":\"Smith\",\"address\":\"456 My Street Apt 1\",\"city\":\"Ottawa\",\"state\":\"ON\",\"zip\":\"K1C2N6\",\"phone\":\"(555)555-5555\"},\"cardTransaction\":{\"amount\":\"100\",\"eciType\":\"1\",\"idSource\":\"67\"},\"request\":\"sale\"}" + -> "HTTP/1.1 200 \r\n" + -> "Access-Control-Allow-Origin: *\r\n" + -> "Access-Control-Expose-Headers: Access-Control-Allow-Origin,Access-Control-Allow-Credentials\r\n" + -> "Content-Encoding: application/json\r\n" + -> "Content-Type: application/json\r\n" + -> "Content-Length: 2051\r\n" + ) + end + + def post_scrubbed + %q( + opening connection to devedgilpayway.net:443... + opened + starting SSL for devedgilpayway.net:443... + SSL established, protocol: TLSv1.2, cipher: AES256-GCM-SHA384 + <- "{\"userName\":\"sprerestwsdev\",\"password\":\"[FILTERED]\",\"companyId\":\"3\",\"accountInputMode\":\"primaryAccountNumber\",\"cardAccount\":{\"accountNumber\":\"[FILTERED]\",\"fsv\":\"[FILTERED]\",\"expirationDate\":\"092022\",\"email\":null,\"firstName\":\"Jim\",\"lastName\":\"Smith\",\"address\":\"456 My Street Apt 1\",\"city\":\"Ottawa\",\"state\":\"ON\",\"zip\":\"K1C2N6\",\"phone\":\"(555)555-5555\"},\"cardTransaction\":{\"amount\":\"100\",\"eciType\":\"1\",\"idSource\":\"67\"},\"request\":\"sale\"}" + -> "HTTP/1.1 200 \r\n" + -> "Access-Control-Allow-Origin: *\r\n" + -> "Access-Control-Expose-Headers: Access-Control-Allow-Origin,Access-Control-Allow-Credentials\r\n" + -> "Content-Encoding: application/json\r\n" + -> "Content-Type: application/json\r\n" + -> "Content-Length: 2051\r\n" + ) + end + + def successful_purchase_response + '{ + "cardAccount": { + "accountNotes1": "", + "accountNotes2": "", + "accountNotes3": "", + "accountNumber": "400010******2224", + "account_number_masked": "400010******2224", + "address": "456 My Street Apt 1", + "auLastUpdate": "1999-01-01 00:00:00-05", + "auUpdateType": 0, + "cardType": 1, + "city": "Ottawa", + "commercialCardType": 0, + "divisionId": 7, + "email": "", + "expirationDate": "0922", + "firstFour": "4000", + "firstName": "Jim", + "fsv": "", + "inputMode": 1, + "lastFour": "2224", + "lastName": "Smith", + "lastUsed": "1999-01-01 00:00:00-05", + "middleName": "", + "onlinePaymentCryptogram": "", + "p2peInput": "", + "paywayToken": 10163736, + "phone": "5555555555", + "state": "ON", + "status": 2, + "zip": "K1C2N6" + }, + "cardTransaction": { + "addressVerificationResults": "I4", + "amount": 100, + "authorizationCode": "0987654321", + "authorizedTime": "2021-02-08 00:00:00-05", + "capturedTime": "2021-02-08 18:17:49", + "cbMode": 2, + "eciType": 1, + "fraudSecurityResults": "M", + "fsvIndicator": "", + "name": "6720210208181749349115", + "pfpstatus": 3601, + "pfpstatusString": "PFP Not Enabled", + "processorErrorMessage": "", + "processorOrderId": "", + "processorRecurringAdvice": "", + "processorResponseDate": "", + "processorResultCode": "", + "processorSequenceNumber": 0, + "processorSoftDescriptor": "", + "referenceNumber": "123456", + "resultCode": 0, + "sessionToken_string": "0", + "settledTime": "1999-01-01 00:00", + "sourceId": 67, + "status": 4, + "tax": 0, + "testResultAVS": "", + "testResultFSV": "", + "transactionNotes1": "", + "transactionNotes2": "", + "transactionNotes3": "" + }, + "paywayCode": "5000", + "paywayMessage": "" + }' + end + + def failed_purchase_response + '{ + "cardAccount": { + "accountNotes1": "", + "accountNotes2": "", + "accountNotes3": "", + "accountNumber": "400030******2221", + "account_number_masked": "400030******2221", + "address": "456 My Street Apt 1", + "auLastUpdate": "1999-01-01 00:00", + "auUpdateType": 0, + "cardType": 1, + "city": "Ottawa", + "commercialCardType": 0, + "divisionId": 7, + "email": "", + "expirationDate": "0922", + "firstFour": "4000", + "firstName": "Jim", + "fsv": "123", + "inputMode": 1, + "lastFour": "2221", + "lastName": "Smith", + "lastUsed": "1999-01-01 00:00", + "middleName": "", + "onlinePaymentCryptogram": "", + "p2peInput": "", + "paywayToken": 0, + "phone": "5555555555", + "state": "ON", + "status": 2, + "zip": "K1C2N6" + }, + "cardTransaction": { + "addressVerificationResults": "", + "amount": 0, + "authorizationCode": "", + "authorizedTime": "1999-01-01", + "capturedTime": "1999-01-01", + "cbMode": 0, + "eciType": 0, + "fraudSecurityResults": "", + "fsvIndicator": "", + "name": "", + "pfpstatus": 3601, + "pfpstatusString": "PFP Not Enabled", + "processorErrorMessage": "", + "processorOrderId": "", + "processorRecurringAdvice": "", + "processorResponseDate": "", + "processorResultCode": "", + "processorSequenceNumber": 0, + "processorSoftDescriptor": "", + "referenceNumber": "", + "resultCode": 1, + "sessionToken_string": "0", + "settledTime": "1999-01-01 00:00", + "sourceId": 0, + "status": 0, + "tax": 0, + "testResultAVS": "", + "testResultFSV": "", + "transactionNotes1": "", + "transactionNotes2": "", + "transactionNotes3": "" + }, + "paywayCode": "5035", + "paywayMessage": "Invalid account number: 4000300011112221" + }' + end + + def successful_authorize_response + '{ + "cardAccount": { + "accountNotes1": "", + "accountNotes2": "", + "accountNotes3": "", + "accountNumber": "400010******2224", + "account_number_masked": "400010******2224", + "address": "456 My Street Apt 1", + "auLastUpdate": "1999-01-01 00:00", + "auUpdateType": 0, + "cardType": 1, + "city": "Ottawa", + "commercialCardType": 0, + "divisionId": 7, + "email": "", + "expirationDate": "0922", + "firstFour": "4000", + "firstName": "Jim", + "fsv": "737", + "inputMode": 1, + "lastFour": "2224", + "lastName": "Smith", + "lastUsed": "1999-01-01 00:00", + "middleName": "", + "onlinePaymentCryptogram": "", + "p2peInput": "", + "paywayToken": 10163736, + "phone": "5555555555", + "state": "ON", + "status": 0, + "zip": "K1C2N6" + }, + "cardTransaction": { + "addressVerificationResults": "", + "amount": 103, + "authorizationCode": "0987654321", + "authorizedTime": "2021-02-09", + "capturedTime": "1999-01-01 00:00:00-05", + "cbMode": 2, + "eciType": 1, + "fraudSecurityResults": "", + "fsvIndicator": "", + "name": "6720210209084239789167", + "pfpstatus": 3601, + "pfpstatusString": "PFP Not Enabled", + "processorErrorMessage": "", + "processorOrderId": "", + "processorRecurringAdvice": "", + "processorResponseDate": "", + "processorResultCode": "", + "processorSequenceNumber": 0, + "processorSoftDescriptor": "", + "referenceNumber": "123456", + "resultCode": 0, + "sessionToken_string": "0", + "settledTime": "1999-01-01 00:00", + "sourceId": 67, + "status": 3, + "tax": 0, + "testResultAVS": "", + "testResultFSV": "", + "transactionNotes1": "", + "transactionNotes2": "", + "transactionNotes3": "" + }, + "paywayCode": "5000", + "paywayMessage": "" + }' + end + + def successful_authorize_and_capture_response + '{ + "cardAccount": { + "accountNotes1": "", + "accountNotes2": "", + "accountNotes3": "", + "accountNumber": "400010******2224", + "account_number_masked": "400010******2224", + "address": "456 My Street Apt 1", + "auLastUpdate": "1999-01-01 00:00", + "auUpdateType": 0, + "cardType": 1, + "city": "Ottawa", + "commercialCardType": 0, + "divisionId": 7, + "email": "", + "expirationDate": "0922", + "firstFour": "4000", + "firstName": "Jim", + "fsv": "737", + "inputMode": 1, + "lastFour": "2224", + "lastName": "Smith", + "lastUsed": "1999-01-01 00:00", + "middleName": "", + "onlinePaymentCryptogram": "", + "p2peInput": "", + "paywayToken": 10163736, + "phone": "5555555555", + "state": "ON", + "status": 0, + "zip": "K1C2N6" + }, + "cardTransaction": { + "addressVerificationResults": "", + "amount": 104, + "authorizationCode": "0987654321", + "authorizedTime": "2021-02-09", + "capturedTime": "1999-01-01 00:00:00-05", + "cbMode": 2, + "eciType": 1, + "fraudSecurityResults": "", + "fsvIndicator": "", + "name": "6720210209085526437200", + "pfpstatus": 3601, + "pfpstatusString": "PFP Not Enabled", + "processorErrorMessage": "", + "processorOrderId": "", + "processorRecurringAdvice": "", + "processorResponseDate": "", + "processorResultCode": "", + "processorSequenceNumber": 0, + "processorSoftDescriptor": "", + "referenceNumber": "123456", + "resultCode": 0, + "sessionToken_string": "0", + "settledTime": "1999-01-01 00:00", + "sourceId": 67, + "status": 3, + "tax": 0, + "testResultAVS": "", + "testResultFSV": "", + "transactionNotes1": "", + "transactionNotes2": "", + "transactionNotes3": "" + }, + "paywayCode": "5000", + "paywayMessage": "" + }' + end + + def successful_capture_response + '{ + "cardAccount": { + "accountNotes1": "", + "accountNotes2": "", + "accountNotes3": "", + "accountNumber": "400010******2224", + "account_number_masked": "400010******2224", + "address": "456 My Street Apt 1", + "auLastUpdate": "1999-01-01 00:00:00-05", + "auUpdateType": 0, + "cardType": 1, + "city": "Ottawa", + "commercialCardType": 0, + "divisionId": 7, + "email": "", + "expirationDate": "0922", + "firstFour": "4000", + "firstName": "Jim", + "fsv": "", + "inputMode": 1, + "lastFour": "2224", + "lastName": "Smith", + "lastUsed": "1999-01-01 00:00:00-05", + "middleName": "", + "onlinePaymentCryptogram": "", + "p2peInput": "", + "paywayToken": 10163736, + "phone": "5555555555", + "state": "ON", + "status": 2, + "zip": "K1C2N6" + }, + "cardTransaction": { + "addressVerificationResults": "", + "amount": 104, + "authorizationCode": "0987654321", + "authorizedTime": "2021-02-09 00:00:00-05", + "capturedTime": "2021-02-09 08:55:26", + "cbMode": 2, + "eciType": 1, + "fraudSecurityResults": "", + "fsvIndicator": "", + "name": "6720210209085526437200", + "pfpstatus": 3601, + "pfpstatusString": "PFP Not Enabled", + "processorErrorMessage": "", + "processorOrderId": "", + "processorRecurringAdvice": "", + "processorResponseDate": "", + "processorResultCode": "", + "processorSequenceNumber": 0, + "processorSoftDescriptor": "", + "referenceNumber": "123456", + "resultCode": 0, + "sessionToken_string": "0", + "settledTime": "1999-01-01 00:00", + "sourceId": 67, + "status": 4, + "tax": 0, + "testResultAVS": "", + "testResultFSV": "", + "transactionNotes1": "", + "transactionNotes2": "", + "transactionNotes3": "" + }, + "paywayCode": "5000", + "paywayMessage": "" + }' + end + + def failed_authorize_response + '{ + "cardAccount": { + "accountNotes1": "", + "accountNotes2": "", + "accountNotes3": "", + "accountNumber": "400030******2221", + "account_number_masked": "400030******2221", + "address": "456 My Street Apt 1", + "auLastUpdate": "1999-01-01 00:00", + "auUpdateType": 0, + "cardType": 1, + "city": "Ottawa", + "commercialCardType": 0, + "divisionId": 7, + "email": "", + "expirationDate": "0922", + "firstFour": "4000", + "firstName": "Jim", + "fsv": "123", + "inputMode": 1, + "lastFour": "2221", + "lastName": "Smith", + "lastUsed": "1999-01-01 00:00", + "middleName": "", + "onlinePaymentCryptogram": "", + "p2peInput": "", + "paywayToken": 0, + "phone": "5555555555", + "state": "ON", + "status": 2, + "zip": "K1C2N6" + }, + "cardTransaction": { + "addressVerificationResults": "", + "amount": 0, + "authorizationCode": "", + "authorizedTime": "1999-01-01", + "capturedTime": "1999-01-01", + "cbMode": 0, + "eciType": 0, + "fraudSecurityResults": "", + "fsvIndicator": "", + "name": "", + "pfpstatus": 3601, + "pfpstatusString": "PFP Not Enabled", + "processorErrorMessage": "", + "processorOrderId": "", + "processorRecurringAdvice": "", + "processorResponseDate": "", + "processorResultCode": "", + "processorSequenceNumber": 0, + "processorSoftDescriptor": "", + "referenceNumber": "", + "resultCode": 1, + "sessionToken_string": "0", + "settledTime": "1999-01-01 00:00", + "sourceId": 0, + "status": 0, + "tax": 0, + "testResultAVS": "", + "testResultFSV": "", + "transactionNotes1": "", + "transactionNotes2": "", + "transactionNotes3": "" + }, + "paywayCode": "5035", + "paywayMessage": "Invalid account number: 4000300011112221" + }' + end + + def failed_capture_response + '{ + "cardAccount": { + "accountNotes1": "", + "accountNotes2": "", + "accountNotes3": "", + "accountNumber": "", + "account_number_masked": "", + "address": "", + "auLastUpdate": "1999-01-01 00:00", + "auUpdateType": 0, + "cardType": 8, + "city": "", + "commercialCardType": 0, + "divisionId": 0, + "email": "", + "expirationDate": "", + "firstFour": "", + "firstName": "", + "fsv": "", + "inputMode": 1, + "lastFour": "", + "lastName": "", + "lastUsed": "1999-01-01 00:00", + "middleName": "", + "onlinePaymentCryptogram": "", + "p2peInput": "", + "paywayToken": 0, + "phone": "", + "state": "", + "status": 0, + "zip": "" + }, + "cardTransaction": { + "addressVerificationResults": "", + "amount": 0, + "authorizationCode": "", + "authorizedTime": "1999-01-01", + "capturedTime": "1999-01-01", + "cbMode": 0, + "eciType": 0, + "fraudSecurityResults": "", + "fsvIndicator": "", + "name": "", + "pfpstatus": 3601, + "pfpstatusString": "PFP Not Enabled", + "processorErrorMessage": "", + "processorOrderId": "", + "processorRecurringAdvice": "", + "processorResponseDate": "", + "processorResultCode": "", + "processorSequenceNumber": 0, + "processorSoftDescriptor": "", + "referenceNumber": "", + "resultCode": 1, + "sessionToken_string": "0", + "settledTime": "1999-01-01 00:00", + "sourceId": 0, + "status": 0, + "tax": 0, + "testResultAVS": "", + "testResultFSV": "", + "transactionNotes1": "", + "transactionNotes2": "", + "transactionNotes3": "" + }, + "paywayCode": "5025", + "paywayMessage": "failed to read transaction with source 0 and name " + }' + end + + def successful_credit_response + '{ + "cardAccount": { + "accountNotes1": "", + "accountNotes2": "", + "accountNotes3": "", + "accountNumber": "400010******2224", + "account_number_masked": "400010******2224", + "address": "456 My Street Apt 1", + "auLastUpdate": "1999-01-01 00:00", + "auUpdateType": 0, + "cardType": 1, + "city": "Ottawa", + "commercialCardType": 0, + "divisionId": 7, + "email": "", + "expirationDate": "0922", + "firstFour": "4000", + "firstName": "Jim", + "fsv": "737", + "inputMode": 1, + "lastFour": "2224", + "lastName": "Smith", + "lastUsed": "1999-01-01 00:00", + "middleName": "", + "onlinePaymentCryptogram": "", + "p2peInput": "", + "paywayToken": 10163736, + "phone": "5555555555", + "state": "ON", + "status": 0, + "zip": "K1C2N6" + }, + "cardTransaction": { + "addressVerificationResults": "", + "amount": 107, + "authorizationCode": "0987654321", + "authorizedTime": "2021-02-09 13:09:23", + "capturedTime": "2021-02-09 13:09:23", + "cbMode": 2, + "eciType": 1, + "fraudSecurityResults": "", + "fsvIndicator": "", + "name": "6720210209130923241131", + "pfpstatus": 3601, + "pfpstatusString": "PFP Not Enabled", + "processorErrorMessage": "", + "processorOrderId": "", + "processorRecurringAdvice": "", + "processorResponseDate": "", + "processorResultCode": "", + "processorSequenceNumber": 0, + "processorSoftDescriptor": "", + "referenceNumber": "123456", + "resultCode": 0, + "sessionToken_string": "0", + "settledTime": "1999-01-01 00:00", + "sourceId": 67, + "status": 4, + "tax": 0, + "testResultAVS": "", + "testResultFSV": "", + "transactionNotes1": "", + "transactionNotes2": "", + "transactionNotes3": "" + }, + "paywayCode": "5000", + "paywayMessage": "" + }' + end + + def failed_credit_response + '{ + "cardAccount": { + "accountNotes1": "", + "accountNotes2": "", + "accountNotes3": "", + "accountNumber": "400030******2221", + "account_number_masked": "400030******2221", + "address": "456 My Street Apt 1", + "auLastUpdate": "1999-01-01 00:00", + "auUpdateType": 0, + "cardType": 1, + "city": "Ottawa", + "commercialCardType": 0, + "divisionId": 7, + "email": "", + "expirationDate": "0922", + "firstFour": "4000", + "firstName": "Jim", + "fsv": "123", + "inputMode": 1, + "lastFour": "2221", + "lastName": "Smith", + "lastUsed": "1999-01-01 00:00", + "middleName": "", + "onlinePaymentCryptogram": "", + "p2peInput": "", + "paywayToken": 0, + "phone": "5555555555", + "state": "ON", + "status": 2, + "zip": "K1C2N6" + }, + "cardTransaction": { + "addressVerificationResults": "", + "amount": 0, + "authorizationCode": "", + "authorizedTime": "1999-01-01", + "capturedTime": "1999-01-01", + "cbMode": 0, + "eciType": 0, + "fraudSecurityResults": "", + "fsvIndicator": "", + "name": "", + "pfpstatus": 3601, + "pfpstatusString": "PFP Not Enabled", + "processorErrorMessage": "", + "processorOrderId": "", + "processorRecurringAdvice": "", + "processorResponseDate": "", + "processorResultCode": "", + "processorSequenceNumber": 0, + "processorSoftDescriptor": "", + "referenceNumber": "", + "resultCode": 1, + "sessionToken_string": "0", + "settledTime": "1999-01-01 00:00", + "sourceId": 0, + "status": 0, + "tax": 0, + "testResultAVS": "", + "testResultFSV": "", + "transactionNotes1": "", + "transactionNotes2": "", + "transactionNotes3": "" + }, + "paywayCode": "5035", + "paywayMessage": "Invalid account number: 4000300011112221" + }' + end + + def successful_auth_for_void_response + '{ + "cardAccount": { + "accountNotes1": "", + "accountNotes2": "", + "accountNotes3": "", + "accountNumber": "400010******2224", + "account_number_masked": "400010******2224", + "address": "456 My Street Apt 1", + "auLastUpdate": "1999-01-01 00:00", + "auUpdateType": 0, + "cardType": 1, + "city": "Ottawa", + "commercialCardType": 0, + "divisionId": 7, + "email": "", + "expirationDate": "0922", + "firstFour": "4000", + "firstName": "Jim", + "fsv": "737", + "inputMode": 1, + "lastFour": "2224", + "lastName": "Smith", + "lastUsed": "1999-01-01 00:00", + "middleName": "", + "onlinePaymentCryptogram": "", + "p2peInput": "", + "paywayToken": 10163736, + "phone": "5555555555", + "state": "ON", + "status": 0, + "zip": "K1C2N6" + }, + "cardTransaction": { + "addressVerificationResults": "", + "amount": 108, + "authorizationCode": "0987654321", + "authorizedTime": "2021-02-09", + "capturedTime": "1999-01-01 00:00:00-05", + "cbMode": 2, + "eciType": 1, + "fraudSecurityResults": "", + "fsvIndicator": "", + "name": "6720210209135306469560", + "pfpstatus": 3601, + "pfpstatusString": "PFP Not Enabled", + "processorErrorMessage": "", + "processorOrderId": "", + "processorRecurringAdvice": "", + "processorResponseDate": "", + "processorResultCode": "", + "processorSequenceNumber": 0, + "processorSoftDescriptor": "", + "referenceNumber": "123456", + "resultCode": 0, + "sessionToken_string": "0", + "settledTime": "1999-01-01 00:00", + "sourceId": 67, + "status": 3, + "tax": 0, + "testResultAVS": "", + "testResultFSV": "", + "transactionNotes1": "", + "transactionNotes2": "", + "transactionNotes3": "" + }, + "paywayCode": "5000", + "paywayMessage": "" + }' + end + + def successful_void_auth_response + '{ + "cardAccount": { + "accountNotes1": "", + "accountNotes2": "", + "accountNotes3": "", + "accountNumber": "400010******2224", + "account_number_masked": "400010******2224", + "address": "456 My Street Apt 1", + "auLastUpdate": "1999-01-01 00:00:00-05", + "auUpdateType": 0, + "cardType": 1, + "city": "Ottawa", + "commercialCardType": 0, + "divisionId": 7, + "email": "", + "expirationDate": "0922", + "firstFour": "4000", + "firstName": "Jim", + "fsv": "", + "inputMode": 1, + "lastFour": "2224", + "lastName": "Smith", + "lastUsed": "1999-01-01 00:00:00-05", + "middleName": "", + "onlinePaymentCryptogram": "", + "p2peInput": "", + "paywayToken": 10163736, + "phone": "5555555555", + "state": "ON", + "status": 2, + "zip": "K1C2N6" + }, + "cardTransaction": { + "addressVerificationResults": "", + "amount": 108, + "authorizationCode": "0987654321", + "authorizedTime": "2021-02-09 00:00:00-05", + "capturedTime": "1999-01-01 00:00:00-05", + "cbMode": 2, + "eciType": 1, + "fraudSecurityResults": "", + "fsvIndicator": "", + "name": "6720210209135306469560", + "pfpstatus": 3601, + "pfpstatusString": "PFP Not Enabled", + "processorErrorMessage": "", + "processorOrderId": "", + "processorRecurringAdvice": "", + "processorResponseDate": "", + "processorResultCode": "", + "processorSequenceNumber": 0, + "processorSoftDescriptor": "", + "referenceNumber": "123456", + "resultCode": 0, + "sessionToken_string": "0", + "settledTime": "1999-01-01 00:00", + "sourceId": 67, + "status": 6, + "tax": 0, + "testResultAVS": "", + "testResultFSV": "", + "transactionNotes1": "", + "transactionNotes2": "", + "transactionNotes3": "" + }, + "paywayCode": "5000", + "paywayMessage": "" + }' + end + + def successful_void_response + '{ + "cardAccount": { + "accountNotes1": "", + "accountNotes2": "", + "accountNotes3": "", + "accountNumber": "", + "account_number_masked": "", + "address": "", + "auLastUpdate": "1999-01-01 00:00", + "auUpdateType": 0, + "cardType": 8, + "city": "", + "commercialCardType": 0, + "divisionId": 0, + "email": "", + "expirationDate": "", + "firstFour": "", + "firstName": "", + "fsv": "", + "inputMode": 1, + "lastFour": "", + "lastName": "", + "lastUsed": "1999-01-01 00:00", + "middleName": "", + "onlinePaymentCryptogram": "", + "p2peInput": "", + "paywayToken": 0, + "phone": "", + "state": "", + "status": 0, + "zip": "" + }, + "cardTransaction": { + "addressVerificationResults": "", + "amount": 0, + "authorizationCode": "", + "authorizedTime": "1999-01-01", + "capturedTime": "1999-01-01", + "cbMode": 0, + "eciType": 0, + "fraudSecurityResults": "", + "fsvIndicator": "", + "name": "", + "pfpstatus": 3601, + "pfpstatusString": "PFP Not Enabled", + "processorErrorMessage": "", + "processorOrderId": "", + "processorRecurringAdvice": "", + "processorResponseDate": "", + "processorResultCode": "", + "processorSequenceNumber": 0, + "processorSoftDescriptor": "", + "referenceNumber": "", + "resultCode": 1, + "sessionToken_string": "0", + "settledTime": "1999-01-01 00:00", + "sourceId": 0, + "status": 0, + "tax": 0, + "testResultAVS": "", + "testResultFSV": "", + "transactionNotes1": "", + "transactionNotes2": "", + "transactionNotes3": "" + }, + "paywayCode": "5025", + "paywayMessage": "failed to read transaction with source 0 and name " + }' + end + + def failed_void_response + '{ + "cardAccount": { + "accountNotes1": "", + "accountNotes2": "", + "accountNotes3": "", + "accountNumber": "", + "account_number_masked": "", + "address": "", + "auLastUpdate": "1999-01-01 00:00", + "auUpdateType": 0, + "cardType": 8, + "city": "", + "commercialCardType": 0, + "divisionId": 0, + "email": "", + "expirationDate": "", + "firstFour": "", + "firstName": "", + "fsv": "", + "inputMode": 1, + "lastFour": "", + "lastName": "", + "lastUsed": "1999-01-01 00:00", + "middleName": "", + "onlinePaymentCryptogram": "", + "p2peInput": "", + "paywayToken": 0, + "phone": "", + "state": "", + "status": 0, + "zip": "" + }, + "cardTransaction": { + "addressVerificationResults": "", + "amount": 0, + "authorizationCode": "", + "authorizedTime": "1999-01-01", + "capturedTime": "1999-01-01", + "cbMode": 0, + "eciType": 0, + "fraudSecurityResults": "", + "fsvIndicator": "", + "name": "", + "pfpstatus": 3601, + "pfpstatusString": "PFP Not Enabled", + "processorErrorMessage": "", + "processorOrderId": "", + "processorRecurringAdvice": "", + "processorResponseDate": "", + "processorResultCode": "", + "processorSequenceNumber": 0, + "processorSoftDescriptor": "", + "referenceNumber": "", + "resultCode": 1, + "sessionToken_string": "0", + "settledTime": "1999-01-01 00:00", + "sourceId": 0, + "status": 0, + "tax": 0, + "testResultAVS": "", + "testResultFSV": "", + "transactionNotes1": "", + "transactionNotes2": "", + "transactionNotes3": "" + }, + "paywayCode": "5025", + "paywayMessage": "failed to read transaction with source 0 and name " + }' + end + + def successful_sale_for_void_response + '{ + "cardAccount": { + "accountNotes1": "", + "accountNotes2": "", + "accountNotes3": "", + "accountNumber": "400010******2224", + "account_number_masked": "400010******2224", + "address": "456 My Street Apt 1", + "auLastUpdate": "1999-01-01 00:00:00-05", + "auUpdateType": 0, + "cardType": 1, + "city": "Ottawa", + "commercialCardType": 0, + "divisionId": 7, + "email": "", + "expirationDate": "0922", + "firstFour": "4000", + "firstName": "Jim", + "fsv": "", + "inputMode": 1, + "lastFour": "2224", + "lastName": "Smith", + "lastUsed": "1999-01-01 00:00:00-05", + "middleName": "", + "onlinePaymentCryptogram": "", + "p2peInput": "", + "paywayToken": 10163736, + "phone": "5555555555", + "state": "ON", + "status": 2, + "zip": "K1C2N6" + }, + "cardTransaction": { + "addressVerificationResults": "", + "amount": 109, + "authorizationCode": "0987654321", + "authorizedTime": "2021-02-09 00:00:00-05", + "capturedTime": "2021-02-09 13:00:48", + "cbMode": 2, + "eciType": 1, + "fraudSecurityResults": "", + "fsvIndicator": "", + "name": "6720210209130047957988", + "pfpstatus": 3601, + "pfpstatusString": "PFP Not Enabled", + "processorErrorMessage": "", + "processorOrderId": "", + "processorRecurringAdvice": "", + "processorResponseDate": "", + "processorResultCode": "", + "processorSequenceNumber": 0, + "processorSoftDescriptor": "", + "referenceNumber": "123456", + "resultCode": 0, + "sessionToken_string": "0", + "settledTime": "1999-01-01 00:00", + "sourceId": 67, + "status": 4, + "tax": 0, + "testResultAVS": "", + "testResultFSV": "", + "transactionNotes1": "", + "transactionNotes2": "", + "transactionNotes3": "" + }, + "paywayCode": "5000", + "paywayMessage": "" + }' + end + + def successful_void_sale_response + '{ + "cardAccount": { + "accountNotes1": "", + "accountNotes2": "", + "accountNotes3": "", + "accountNumber": "400010******2224", + "account_number_masked": "400010******2224", + "address": "456 My Street Apt 1", + "auLastUpdate": "1999-01-01 00:00:00-05", + "auUpdateType": 0, + "cardType": 1, + "city": "Ottawa", + "commercialCardType": 0, + "divisionId": 7, + "email": "", + "expirationDate": "0922", + "firstFour": "4000", + "firstName": "Jim", + "fsv": "", + "inputMode": 1, + "lastFour": "2224", + "lastName": "Smith", + "lastUsed": "1999-01-01 00:00:00-05", + "middleName": "", + "onlinePaymentCryptogram": "", + "p2peInput": "", + "paywayToken": 10163736, + "phone": "5555555555", + "state": "ON", + "status": 2, + "zip": "K1C2N6" + }, + "cardTransaction": { + "addressVerificationResults": "", + "amount": 109, + "authorizationCode": "0987654321", + "authorizedTime": "2021-02-09 00:00:00-05", + "capturedTime": "2021-02-09 13:00:48-05", + "cbMode": 2, + "eciType": 1, + "fraudSecurityResults": "", + "fsvIndicator": "", + "name": "6720210209130047957988", + "pfpstatus": 3601, + "pfpstatusString": "PFP Not Enabled", + "processorErrorMessage": "", + "processorOrderId": "", + "processorRecurringAdvice": "", + "processorResponseDate": "", + "processorResultCode": "", + "processorSequenceNumber": 0, + "processorSoftDescriptor": "", + "referenceNumber": "123456", + "resultCode": 0, + "sessionToken_string": "0", + "settledTime": "1999-01-01 00:00", + "sourceId": 67, + "status": 6, + "tax": 0, + "testResultAVS": "", + "testResultFSV": "", + "transactionNotes1": "", + "transactionNotes2": "", + "transactionNotes3": "" + }, + "paywayCode": "5000", + "paywayMessage": "" + }' + end + + def successful_credit_for_void_response + '{ + "cardAccount": { + "accountNotes1": "", + "accountNotes2": "", + "accountNotes3": "", + "accountNumber": "400010******2224", + "account_number_masked": "400010******2224", + "address": "456 My Street Apt 1", + "auLastUpdate": "1999-01-01 00:00", + "auUpdateType": 0, + "cardType": 1, + "city": "Ottawa", + "commercialCardType": 0, + "divisionId": 7, + "email": "", + "expirationDate": "0922", + "firstFour": "4000", + "firstName": "Jim", + "fsv": "737", + "inputMode": 1, + "lastFour": "2224", + "lastName": "Smith", + "lastUsed": "1999-01-01 00:00", + "middleName": "", + "onlinePaymentCryptogram": "", + "p2peInput": "", + "paywayToken": 10163736, + "phone": "5555555555", + "state": "ON", + "status": 0, + "zip": "K1C2N6" + }, + "cardTransaction": { + "addressVerificationResults": "", + "amount": 110, + "authorizationCode": "0987654321", + "authorizedTime": "2021-02-09 13:06:33", + "capturedTime": "2021-02-09 13:06:33", + "cbMode": 2, + "eciType": 1, + "fraudSecurityResults": "", + "fsvIndicator": "", + "name": "6720210209130633236167", + "pfpstatus": 3601, + "pfpstatusString": "PFP Not Enabled", + "processorErrorMessage": "", + "processorOrderId": "", + "processorRecurringAdvice": "", + "processorResponseDate": "", + "processorResultCode": "", + "processorSequenceNumber": 0, + "processorSoftDescriptor": "", + "referenceNumber": "123456", + "resultCode": 0, + "sessionToken_string": "0", + "settledTime": "1999-01-01 00:00", + "sourceId": 67, + "status": 4, + "tax": 0, + "testResultAVS": "", + "testResultFSV": "", + "transactionNotes1": "", + "transactionNotes2": "", + "transactionNotes3": "" + }, + "paywayCode": "5000", + "paywayMessage": "" + }' + end + + def successful_credit_void_response + '{ + "cardAccount": { + "accountNotes1": "", + "accountNotes2": "", + "accountNotes3": "", + "accountNumber": "400010******2224", + "account_number_masked": "400010******2224", + "address": "456 My Street Apt 1", + "auLastUpdate": "1999-01-01 00:00:00-05", + "auUpdateType": 0, + "cardType": 1, + "city": "Ottawa", + "commercialCardType": 0, + "divisionId": 7, + "email": "", + "expirationDate": "0922", + "firstFour": "4000", + "firstName": "Jim", + "fsv": "", + "inputMode": 1, + "lastFour": "2224", + "lastName": "Smith", + "lastUsed": "1999-01-01 00:00:00-05", + "middleName": "", + "onlinePaymentCryptogram": "", + "p2peInput": "", + "paywayToken": 10163736, + "phone": "5555555555", + "state": "ON", + "status": 2, + "zip": "K1C2N6" + }, + "cardTransaction": { + "addressVerificationResults": "", + "amount": 110, + "authorizationCode": "0987654321", + "authorizedTime": "2021-02-09 14:02:51-05", + "capturedTime": "2021-02-09 14:02:51-05", + "cbMode": 2, + "eciType": 1, + "fraudSecurityResults": "", + "fsvIndicator": "", + "name": "672021020914025188146", + "pfpstatus": 3601, + "pfpstatusString": "PFP Not Enabled", + "processorErrorMessage": "", + "processorOrderId": "", + "processorRecurringAdvice": "", + "processorResponseDate": "", + "processorResultCode": "", + "processorSequenceNumber": 0, + "processorSoftDescriptor": "", + "referenceNumber": "123456", + "resultCode": 0, + "sessionToken_string": "0", + "settledTime": "1999-01-01 00:00", + "sourceId": 67, + "status": 6, + "tax": 0, + "testResultAVS": "", + "testResultFSV": "", + "transactionNotes1": "", + "transactionNotes2": "", + "transactionNotes3": "" + }, + "paywayCode": "5000", + "paywayMessage": "" + }' + end + + def failed_invalid_login_response + '{ + "paywayCode": "5001", + "paywayMessage": "Session timed out or other session error. Create new session" + }' + end +end diff --git a/test/unit/gateways/payway_test.rb b/test/unit/gateways/payway_test.rb index 42a1aa25321..14ccfe87ff0 100644 --- a/test/unit/gateways/payway_test.rb +++ b/test/unit/gateways/payway_test.rb @@ -1,28 +1,27 @@ require 'test_helper' class PaywayTest < Test::Unit::TestCase - def setup @gateway = PaywayGateway.new( - :username => '12341234', - :password => 'abcdabcd', - :pem => certificate + username: '12341234', + password: 'abcdabcd', + pem: certificate ) @amount = 1000 @credit_card = ActiveMerchant::Billing::CreditCard.new( - :number => 4564710000000004, - :month => 2, - :year => 2019, - :first_name => 'Bob', - :last_name => 'Smith', - :verification_value => '847', - :brand => 'visa' + number: 4564710000000004, + month: 2, + year: 2019, + first_name: 'Bob', + last_name: 'Smith', + verification_value: '847', + brand: 'visa' ) @options = { - :order_id => 'abc' + order_id: 'abc' } end @@ -209,7 +208,7 @@ def test_bad_merchant def test_store @gateway.stubs(:ssl_post).returns(successful_response_store) - response = @gateway.store(@credit_card, :billing_id => 84517) + response = @gateway.store(@credit_card, billing_id: 84517) assert_instance_of Response, response assert_success response diff --git a/test/unit/gateways/pin_test.rb b/test/unit/gateways/pin_test.rb index 1d448d2203b..87b1fb5b9f3 100644 --- a/test/unit/gateways/pin_test.rb +++ b/test/unit/gateways/pin_test.rb @@ -2,16 +2,30 @@ class PinTest < Test::Unit::TestCase def setup - @gateway = PinGateway.new(:api_key => 'I_THISISNOTAREALAPIKEY') + @gateway = PinGateway.new(api_key: 'I_THISISNOTAREALAPIKEY') @credit_card = credit_card @amount = 100 @options = { - :email => 'roland@pinpayments.com', - :billing_address => address, - :description => 'Store Purchase', - :ip => '127.0.0.1' + email: 'roland@pinpayments.com', + billing_address: address, + description: 'Store Purchase', + ip: '127.0.0.1' + } + + @three_d_secure_v1 = { + version: '1.0.2', + eci: '05', + cavv: '1234', + xid: '1234' + } + + @three_d_secure_v2 = { + version: '2.0.0', + eci: '06', + cavv: 'jEoEjMykRWFCBEAAAVOBSYAAAA=', + ds_transaction_id: 'f92a19e2-485f-4d21-81ea-69a7352f611e' } end @@ -42,7 +56,7 @@ def test_supported_countries end def test_supported_cardtypes - assert_equal [:visa, :master, :american_express], PinGateway.supported_cardtypes + assert_equal %i[visa master american_express], PinGateway.supported_cardtypes end def test_display_name @@ -130,7 +144,7 @@ def test_successful_update def test_successful_refund token = 'ch_encBuMDf17qTabmVjDsQlg' - @gateway.expects(:ssl_request).with(:post, "https://test-api.pinpayments.com/1/charges/#{token}/refunds", {:amount => '100'}.to_json, instance_of(Hash)).returns(successful_refund_response) + @gateway.expects(:ssl_request).with(:post, "https://test-api.pinpayments.com/1/charges/#{token}/refunds", { amount: '100' }.to_json, instance_of(Hash)).returns(successful_refund_response) assert response = @gateway.refund(100, token) assert_equal 'rf_d2C7M6Mn4z2m3APqarNN6w', response.authorization @@ -140,7 +154,7 @@ def test_successful_refund def test_unsuccessful_refund token = 'ch_encBuMDf17qTabmVjDsQlg' - @gateway.expects(:ssl_request).with(:post, "https://test-api.pinpayments.com/1/charges/#{token}/refunds", {:amount => '100'}.to_json, instance_of(Hash)).returns(failed_refund_response) + @gateway.expects(:ssl_request).with(:post, "https://test-api.pinpayments.com/1/charges/#{token}/refunds", { amount: '100' }.to_json, instance_of(Hash)).returns(failed_refund_response) assert response = @gateway.refund(100, token) assert_failure response @@ -176,6 +190,34 @@ def test_successful_capture assert response.test? end + def test_succesful_purchase_with_3ds + post_data = {} + headers = {} + @gateway.stubs(:headers).returns(headers) + @gateway.stubs(:post_data).returns(post_data) + @gateway.expects(:ssl_request).with(:post, 'https://test-api.pinpayments.com/1/charges', post_data, headers).returns(successful_purchase_response) + + assert response = @gateway.purchase(@amount, @credit_card, @options.merge(three_d_secure: @three_d_secure_v1)) + assert_success response + assert_equal 'ch_Kw_JxmVqMeSOQU19_krRdw', response.authorization + assert_equal JSON.parse(successful_purchase_response), response.params + assert response.test? + end + + def test_succesful_authorize_with_3ds + post_data = {} + headers = {} + @gateway.stubs(:headers).returns(headers) + @gateway.stubs(:post_data).returns(post_data) + @gateway.expects(:ssl_request).with(:post, 'https://test-api.pinpayments.com/1/charges', post_data, headers).returns(successful_purchase_response) + + assert response = @gateway.authorize(@amount, @credit_card, @options.merge(three_d_secure: @three_d_secure_v1)) + assert_success response + assert_equal 'ch_Kw_JxmVqMeSOQU19_krRdw', response.authorization + assert_equal JSON.parse(successful_purchase_response), response.params + assert response.test? + end + def test_store_parameters @gateway.expects(:add_creditcard).with(instance_of(Hash), @credit_card) @gateway.expects(:add_address).with(instance_of(Hash), @credit_card, @options) @@ -262,7 +304,7 @@ def test_add_capture @gateway.send(:add_capture, post, @options) assert_equal post[:capture], true - @gateway.send(:add_capture, post, :capture => false) + @gateway.send(:add_capture, post, capture: false) assert_equal post[:capture], false end @@ -291,6 +333,24 @@ def test_add_creditcard_with_customer_token assert_false post.has_key?(:card) end + def test_add_3ds_v1 + post = {} + @gateway.send(:add_3ds, post, @options.merge(three_d_secure: @three_d_secure_v1)) + assert_equal '1.0.2', post[:three_d_secure][:version] + assert_equal '05', post[:three_d_secure][:eci] + assert_equal '1234', post[:three_d_secure][:cavv] + assert_equal '1234', post[:three_d_secure][:transaction_id] + end + + def test_add_3ds_v2 + post = {} + @gateway.send(:add_3ds, post, @options.merge(three_d_secure: @three_d_secure_v2)) + assert_equal '2.0.0', post[:three_d_secure][:version] + assert_equal '06', post[:three_d_secure][:eci] + assert_equal 'jEoEjMykRWFCBEAAAVOBSYAAAA=', post[:three_d_secure][:cavv] + assert_equal 'f92a19e2-485f-4d21-81ea-69a7352f611e', post[:three_d_secure][:transaction_id] + end + def test_post_data post = {} @gateway.send(:add_creditcard, post, @credit_card) @@ -310,7 +370,7 @@ def test_headers expected_headers['X-Safe-Card'] = '1' @gateway.expects(:ssl_request).with(:post, anything, anything, expected_headers).returns(successful_purchase_response) - assert @gateway.purchase(@amount, @credit_card, :partner_key => 'MyPartnerKey', :safe_card => '1') + assert @gateway.purchase(@amount, @credit_card, partner_key: 'MyPartnerKey', safe_card: '1') end def test_transcript_scrubbing @@ -543,5 +603,4 @@ def scrubbed_transcript } }' end - end diff --git a/test/unit/gateways/plugnpay_test.rb b/test/unit/gateways/plugnpay_test.rb index 4760eada3f6..da0170ceef0 100644 --- a/test/unit/gateways/plugnpay_test.rb +++ b/test/unit/gateways/plugnpay_test.rb @@ -1,19 +1,18 @@ require 'test_helper' class PlugnpayTest < Test::Unit::TestCase - def setup Base.mode = :test @gateway = PlugnpayGateway.new( - :login => 'X', - :password => 'Y' + login: 'X', + password: 'Y' ) @credit_card = credit_card @options = { - :billing_address => address, - :description => 'Store purchase' + billing_address: address, + description: 'Store purchase' } @amount = 100 end @@ -43,7 +42,7 @@ def test_capture_partial_amount def test_capture_full_amount @gateway.expects(:ssl_post).with(anything, all_of(regexp_matches(/mode=mark/), regexp_matches(/card_amount=1.00/)), anything).returns('') - @gateway.expects(:parse).returns({'auth_msg' => 'Blah blah blah Transaction may not be reauthorized'}, {}) + @gateway.expects(:parse).returns({ 'auth_msg' => 'Blah blah blah Transaction may not be reauthorized' }, {}) @gateway.capture(@amount, @credit_card, @options) end @@ -70,7 +69,7 @@ def test_refund def test_add_address_outsite_north_america result = PlugnpayGateway::PlugnpayPostData.new - @gateway.send(:add_addresses, result, :billing_address => {:address1 => '164 Waverley Street', :country => 'DE', :state => 'Dortmund'}) + @gateway.send(:add_addresses, result, billing_address: { address1: '164 Waverley Street', country: 'DE', state: 'Dortmund' }) assert_equal result[:state], 'ZZ' assert_equal result[:province], 'Dortmund' @@ -85,7 +84,7 @@ def test_add_address_outsite_north_america def test_add_address result = PlugnpayGateway::PlugnpayPostData.new - @gateway.send(:add_addresses, result, :billing_address => {:address1 => '164 Waverley Street', :country => 'US', :state => 'CO'}) + @gateway.send(:add_addresses, result, billing_address: { address1: '164 Waverley Street', country: 'US', state: 'CO' }) assert_equal result[:card_state], 'CO' assert_equal result[:card_address1], '164 Waverley Street' diff --git a/test/unit/gateways/pro_pay_test.rb b/test/unit/gateways/pro_pay_test.rb index 3064da173bd..f96b6f0a474 100644 --- a/test/unit/gateways/pro_pay_test.rb +++ b/test/unit/gateways/pro_pay_test.rb @@ -89,7 +89,7 @@ def test_failed_refund def test_successful_void response = stub_comms do @gateway.void('auth', @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r(07), data) end.respond_with(successful_void_response) @@ -99,7 +99,7 @@ def test_successful_void def test_failed_void response = stub_comms do @gateway.void('invalid-auth', @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r(07), data) end.respond_with(failed_void_response) @@ -157,7 +157,7 @@ def test_does_not_send_dashed_zip_code 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(/123453456\n\n 5ab9cddef2e4911b77e0c4ffb70f03\n partner\n \n 100\n USD\n 4747474747474747\n 0918\n 999\n Longbob Longsen\n 456 My Street\n Apt 1\n Ottawa\n ON\n K1C2N6\n 32287391\n 04\n \n\n" --> "HTTP/1.1 200 OK\r\n" --> "Cache-Control: max-age=0,no-cache,no-store,must-revalidate\r\n" --> "Pragma: no-cache\r\n" --> "Content-Type: text/xml; charset=utf-8\r\n" --> "Content-Encoding: gzip\r\n" --> "Expires: Thu, 01 Jan 1970 00:00:00 GMT\r\n" --> "Vary: Accept-Encoding\r\n" --> "Server: Microsoft-IIS/7.5\r\n" --> "Set-Cookie: ASP.NET_SessionId=hn1orxwu31yeoym5fkdhac4o; path=/; secure; HttpOnly\r\n" --> "Set-Cookie: sessionValidation=1a1d69b6-6e53-408b-b054-602593da00e7; path=/; secure; HttpOnly\r\n" --> "X-Powered-By: ASP.NET\r\n" --> "X-Frame-Options: SAMEORIGIN\r\n" --> "Date: Tue, 25 Apr 2017 19:44:03 GMT\r\n" --> "Connection: close\r\n" --> "Content-Length: 343\r\n" --> "\r\n" -reading 343 bytes... --> "" -read 343 bytes -Conn close + <<~RESPONSE + opening connection to xmltest.propay.com:443... + opened + starting SSL for xmltest.propay.com:443... + SSL established + <- "POST /API/PropayAPI.aspx 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: xmltest.propay.com\r\nContent-Length: 547\r\n\r\n" + <- "\n\n 5ab9cddef2e4911b77e0c4ffb70f03\n partner\n \n 100\n USD\n 4747474747474747\n 0918\n 999\n Longbob Longsen\n 456 My Street\n Apt 1\n Ottawa\n ON\n K1C2N6\n 32287391\n 04\n \n\n" + -> "HTTP/1.1 200 OK\r\n" + -> "Cache-Control: max-age=0,no-cache,no-store,must-revalidate\r\n" + -> "Pragma: no-cache\r\n" + -> "Content-Type: text/xml; charset=utf-8\r\n" + -> "Content-Encoding: gzip\r\n" + -> "Expires: Thu, 01 Jan 1970 00:00:00 GMT\r\n" + -> "Vary: Accept-Encoding\r\n" + -> "Server: Microsoft-IIS/7.5\r\n" + -> "Set-Cookie: ASP.NET_SessionId=hn1orxwu31yeoym5fkdhac4o; path=/; secure; HttpOnly\r\n" + -> "Set-Cookie: sessionValidation=1a1d69b6-6e53-408b-b054-602593da00e7; path=/; secure; HttpOnly\r\n" + -> "X-Powered-By: ASP.NET\r\n" + -> "X-Frame-Options: SAMEORIGIN\r\n" + -> "Date: Tue, 25 Apr 2017 19:44:03 GMT\r\n" + -> "Connection: close\r\n" + -> "Content-Length: 343\r\n" + -> "\r\n" + reading 343 bytes... + -> "" + read 343 bytes + Conn close RESPONSE end def post_scrubbed - <<-POST_SCRUBBED -opening connection to xmltest.propay.com:443... -opened -starting SSL for xmltest.propay.com:443... -SSL established -<- "POST /API/PropayAPI.aspx 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: xmltest.propay.com\r\nContent-Length: 547\r\n\r\n" -<- "\n\n [FILTERED]\n partner\n \n 100\n USD\n [FILTERED]\n 0918\n [FILTERED]\n Longbob Longsen\n 456 My Street\n Apt 1\n Ottawa\n ON\n K1C2N6\n 32287391\n 04\n \n\n" --> "HTTP/1.1 200 OK\r\n" --> "Cache-Control: max-age=0,no-cache,no-store,must-revalidate\r\n" --> "Pragma: no-cache\r\n" --> "Content-Type: text/xml; charset=utf-8\r\n" --> "Content-Encoding: gzip\r\n" --> "Expires: Thu, 01 Jan 1970 00:00:00 GMT\r\n" --> "Vary: Accept-Encoding\r\n" --> "Server: Microsoft-IIS/7.5\r\n" --> "Set-Cookie: ASP.NET_SessionId=hn1orxwu31yeoym5fkdhac4o; path=/; secure; HttpOnly\r\n" --> "Set-Cookie: sessionValidation=1a1d69b6-6e53-408b-b054-602593da00e7; path=/; secure; HttpOnly\r\n" --> "X-Powered-By: ASP.NET\r\n" --> "X-Frame-Options: SAMEORIGIN\r\n" --> "Date: Tue, 25 Apr 2017 19:44:03 GMT\r\n" --> "Connection: close\r\n" --> "Content-Length: 343\r\n" --> "\r\n" -reading 343 bytes... --> "" -read 343 bytes -Conn close + <<~POST_SCRUBBED + opening connection to xmltest.propay.com:443... + opened + starting SSL for xmltest.propay.com:443... + SSL established + <- "POST /API/PropayAPI.aspx 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: xmltest.propay.com\r\nContent-Length: 547\r\n\r\n" + <- "\n\n [FILTERED]\n partner\n \n 100\n USD\n [FILTERED]\n 0918\n [FILTERED]\n Longbob Longsen\n 456 My Street\n Apt 1\n Ottawa\n ON\n K1C2N6\n 32287391\n 04\n \n\n" + -> "HTTP/1.1 200 OK\r\n" + -> "Cache-Control: max-age=0,no-cache,no-store,must-revalidate\r\n" + -> "Pragma: no-cache\r\n" + -> "Content-Type: text/xml; charset=utf-8\r\n" + -> "Content-Encoding: gzip\r\n" + -> "Expires: Thu, 01 Jan 1970 00:00:00 GMT\r\n" + -> "Vary: Accept-Encoding\r\n" + -> "Server: Microsoft-IIS/7.5\r\n" + -> "Set-Cookie: ASP.NET_SessionId=hn1orxwu31yeoym5fkdhac4o; path=/; secure; HttpOnly\r\n" + -> "Set-Cookie: sessionValidation=1a1d69b6-6e53-408b-b054-602593da00e7; path=/; secure; HttpOnly\r\n" + -> "X-Powered-By: ASP.NET\r\n" + -> "X-Frame-Options: SAMEORIGIN\r\n" + -> "Date: Tue, 25 Apr 2017 19:44:03 GMT\r\n" + -> "Connection: close\r\n" + -> "Content-Length: 343\r\n" + -> "\r\n" + reading 343 bytes... + -> "" + read 343 bytes + Conn close POST_SCRUBBED end diff --git a/test/unit/gateways/psigate_test.rb b/test/unit/gateways/psigate_test.rb index 1bcb49689fb..a8561b40256 100644 --- a/test/unit/gateways/psigate_test.rb +++ b/test/unit/gateways/psigate_test.rb @@ -3,13 +3,13 @@ class PsigateTest < Test::Unit::TestCase def setup @gateway = PsigateGateway.new( - :login => 'teststore', - :password => 'psigate1234' + login: 'teststore', + password: 'psigate1234' ) @amount = 100 @credit_card = credit_card('4111111111111111') - @options = { :order_id => '1', :billing_address => address } + @options = { order_id: '1', billing_address: address } end def test_successful_authorization @@ -70,7 +70,7 @@ def test_supported_countries end def test_supported_card_types - assert_equal [:visa, :master, :american_express], PsigateGateway.supported_cardtypes + assert_equal %i[visa master american_express], PsigateGateway.supported_cardtypes end def test_avs_result @@ -95,92 +95,92 @@ def test_scrub private def successful_authorization_response - <<-RESPONSE - - - Sun Jan 06 23:10:53 EST 2008 - 1000 - PREAUTH - APPROVED - Y:123456:0abcdef:M:X:NNN - - 0.00 - 0.00 - 24.00 - 24.00 - CC - ......4242 - 1bdde305d7658367 - M - X - 123456 - 0abcdef - VISA - NNN - UN - UNKNOWN - UNKNOWN - + <<~RESPONSE + + + Sun Jan 06 23:10:53 EST 2008 + 1000 + PREAUTH + APPROVED + Y:123456:0abcdef:M:X:NNN + + 0.00 + 0.00 + 24.00 + 24.00 + CC + ......4242 + 1bdde305d7658367 + M + X + 123456 + 0abcdef + VISA + NNN + UN + UNKNOWN + UNKNOWN + RESPONSE end def successful_purchase_response - <<-RESPONSE - - - Sun Jan 06 23:15:30 EST 2008 - 1000 - SALE - APPROVED - Y:123456:0abcdef:M:X:NNN - - 0.00 - 0.00 - 24.00 - 24.00 - CC - ......4242 - 1bdde305da3ee234 - M - X - 123456 - 0abcdef - VISA - NNN - UN - UNKNOWN - UNKNOWN - + <<~RESPONSE + + + Sun Jan 06 23:15:30 EST 2008 + 1000 + SALE + APPROVED + Y:123456:0abcdef:M:X:NNN + + 0.00 + 0.00 + 24.00 + 24.00 + CC + ......4242 + 1bdde305da3ee234 + M + X + 123456 + 0abcdef + VISA + NNN + UN + UNKNOWN + UNKNOWN + RESPONSE end def failed_purchase_response - <<-RESPONSE - - - Sun Jan 06 23:24:29 EST 2008 - b3dca49e3ec77e42ab80a0f0f590fff0 - SALE - DECLINED - N:TESTDECLINE - - 0.00 - 0.00 - 24.00 - 24.00 - CC - ......4242 - 1bdde305df991f89 - M - X - TEST - TESTTRANS - VISA - NNN - UN - UNKNOWN - UNKNOWN - + <<~RESPONSE + + + Sun Jan 06 23:24:29 EST 2008 + b3dca49e3ec77e42ab80a0f0f590fff0 + SALE + DECLINED + N:TESTDECLINE + + 0.00 + 0.00 + 24.00 + 24.00 + CC + ......4242 + 1bdde305df991f89 + M + X + TEST + TESTTRANS + VISA + NNN + UN + UNKNOWN + UNKNOWN + RESPONSE end @@ -193,14 +193,14 @@ def xml_capture_fixture end def pre_scrubbed - <<-PRE_SCRUBBED + <<~PRE_SCRUBBED teststorepsigate12341b7b4b36bf61e972a9e6a6be8fff15d8jack@example.comCC024.00424242424242424209141123Jim Smith1234 My StreetApt 1OttawaONK1C2N6CAWidgets Inc ......4242 PRE_SCRUBBED end def post_scrubbed - <<-POST_SCRUBBED + <<~POST_SCRUBBED teststore[FILTERED]1b7b4b36bf61e972a9e6a6be8fff15d8jack@example.comCC024.00[FILTERED]09141[FILTERED]Jim Smith1234 My StreetApt 1OttawaONK1C2N6CAWidgets Inc [FILTERED] POST_SCRUBBED diff --git a/test/unit/gateways/psl_card_test.rb b/test/unit/gateways/psl_card_test.rb index 6a971d1815e..64de15284b2 100644 --- a/test/unit/gateways/psl_card_test.rb +++ b/test/unit/gateways/psl_card_test.rb @@ -1,17 +1,16 @@ require 'test_helper' class PslCardTest < Test::Unit::TestCase - def setup @gateway = PslCardGateway.new( - :login => 'LOGIN', - :password => 'PASSWORD' - ) + login: 'LOGIN', + password: 'PASSWORD' + ) @credit_card = credit_card @options = { - :billing_address => address, - :description => 'Store purchase' + billing_address: address, + description: 'Store purchase' } @amount = 100 end @@ -36,7 +35,7 @@ def test_supported_countries end def test_supported_card_types - assert_equal [ :visa, :master, :american_express, :diners_club, :jcb, :maestro ], PslCardGateway.supported_cardtypes + assert_equal %i[visa master american_express diners_club jcb maestro], PslCardGateway.supported_cardtypes end def test_avs_result diff --git a/test/unit/gateways/qbms_test.rb b/test/unit/gateways/qbms_test.rb index a0604522f88..f526c67865c 100644 --- a/test/unit/gateways/qbms_test.rb +++ b/test/unit/gateways/qbms_test.rb @@ -5,9 +5,10 @@ def setup Base.mode = :test @gateway = QbmsGateway.new( - :login => 'test', - :ticket => 'abc123', - :pem => 'PEM') + login: 'test', + ticket: 'abc123', + pem: 'PEM' + ) @amount = 100 @card = credit_card('4111111111111111') @@ -45,7 +46,7 @@ def test_truncated_address_is_sent with(anything, regexp_matches(/12345 Ridiculously Lengthy Roa\<.*445566778\ address.update(:address1 => '12345 Ridiculously Lengthy Road Name', :zip => '4455667788') } + options = { billing_address: address.update(address1: '12345 Ridiculously Lengthy Road Name', zip: '4455667788') } assert response = @gateway.purchase(@amount, @card, options) assert_success response end @@ -53,7 +54,7 @@ def test_truncated_address_is_sent def test_partial_address_is_ok @gateway.expects(:ssl_post).returns(charge_response) - options = { :billing_address => address.update(:address1 => nil, :zip => nil) } + options = { billing_address: address.update(address1: nil, zip: nil) } assert response = @gateway.purchase(@amount, @card, options) assert_success response end @@ -90,17 +91,17 @@ def test_avs_result assert_equal 'Y', response.avs_result['street_match'] assert_equal 'Y', response.avs_result['postal_match'] - @gateway.expects(:ssl_post).returns(authorization_response(:avs_street => 'Fail')) + @gateway.expects(:ssl_post).returns(authorization_response(avs_street: 'Fail')) assert response = @gateway.authorize(@amount, @card) assert_equal 'N', response.avs_result['street_match'] assert_equal 'Y', response.avs_result['postal_match'] - @gateway.expects(:ssl_post).returns(authorization_response(:avs_zip => 'Fail')) + @gateway.expects(:ssl_post).returns(authorization_response(avs_zip: 'Fail')) assert response = @gateway.authorize(@amount, @card) assert_equal 'Y', response.avs_result['street_match'] assert_equal 'N', response.avs_result['postal_match'] - @gateway.expects(:ssl_post).returns(authorization_response(:avs_street => 'Fail', :avs_zip => 'Fail')) + @gateway.expects(:ssl_post).returns(authorization_response(avs_street: 'Fail', avs_zip: 'Fail')) assert response = @gateway.authorize(@amount, @card) assert_equal 'N', response.avs_result['street_match'] assert_equal 'N', response.avs_result['postal_match'] @@ -111,11 +112,11 @@ def test_cvv_result assert response = @gateway.authorize(@amount, @card) assert_equal 'M', response.cvv_result['code'] - @gateway.expects(:ssl_post).returns(authorization_response(:card_security_code_match => 'Fail')) + @gateway.expects(:ssl_post).returns(authorization_response(card_security_code_match: 'Fail')) assert response = @gateway.authorize(@amount, @card) assert_equal 'N', response.cvv_result['code'] - @gateway.expects(:ssl_post).returns(authorization_response(:card_security_code_match => 'NotAvailable')) + @gateway.expects(:ssl_post).returns(authorization_response(card_security_code_match: 'NotAvailable')) assert response = @gateway.authorize(@amount, @card) assert_equal 'P', response.cvv_result['code'] end @@ -129,7 +130,7 @@ def test_successful_query end def test_failed_signon - @gateway.expects(:ssl_post).returns(query_response(:signon_status_code => 2000)) + @gateway.expects(:ssl_post).returns(query_response(signon_status_code: 2000)) assert response = @gateway.query() assert_instance_of Response, response @@ -137,7 +138,7 @@ def test_failed_signon end def test_failed_authorization - @gateway.expects(:ssl_post).returns(authorization_response(:status_code => 10301)) + @gateway.expects(:ssl_post).returns(authorization_response(status_code: 10301)) assert response = @gateway.authorize(@amount, @card) assert_instance_of Response, response @@ -147,7 +148,7 @@ def test_failed_authorization def test_use_test_url_when_overwriting_with_test_option ActiveMerchant::Billing::Base.mode = :production - @gateway = QbmsGateway.new(:login => 'test', :ticket => 'abc123', :test => true) + @gateway = QbmsGateway.new(login: 'test', ticket: 'abc123', test: true) @gateway.stubs(:parse).returns({}) @gateway.expects(:ssl_post).with(QbmsGateway.test_url, anything, anything).returns(authorization_response) @gateway.authorize(@amount, @card) @@ -173,9 +174,9 @@ def query_response(opts = {}) def authorization_response(opts = {}) opts = { - :avs_street => 'Pass', - :avs_zip => 'Pass', - :card_security_code_match => 'Pass', + avs_street: 'Pass', + avs_zip: 'Pass', + card_security_code_match: 'Pass' }.merge(opts) wrap 'CustomerCreditCardAuth', opts, <<-"XML" @@ -200,9 +201,9 @@ def capture_response(opts = {}) def charge_response(opts = {}) opts = { - :avs_street => 'Pass', - :avs_zip => 'Pass', - :card_security_code_match => 'Pass', + avs_street: 'Pass', + avs_zip: 'Pass', + card_security_code_match: 'Pass' }.merge(opts) wrap 'CustomerCreditCardCharge', opts, <<-"XML" @@ -236,9 +237,9 @@ def credit_response(opts = {}) def wrap(type, opts, xml) opts = { - :signon_status_code => 0, - :request_id => 'x', - :status_code => 0, + signon_status_code: 0, + request_id: 'x', + status_code: 0 }.merge(opts) <<-"XML" diff --git a/test/unit/gateways/quantum_test.rb b/test/unit/gateways/quantum_test.rb index 10bb11ccaf4..3af7c0ae3f7 100644 --- a/test/unit/gateways/quantum_test.rb +++ b/test/unit/gateways/quantum_test.rb @@ -3,16 +3,16 @@ class QuantumTest < Test::Unit::TestCase def setup @gateway = QuantumGateway.new( - :login => '', - :password => '' - ) + login: '', + password: '' + ) @credit_card = credit_card @amount = 100 @options = { - :billing_address => address, - :description => 'Store Purchase' + billing_address: address, + description: 'Store Purchase' } end diff --git a/test/unit/gateways/quickbooks_test.rb b/test/unit/gateways/quickbooks_test.rb index 7d59f157ba5..7e48cce44ef 100644 --- a/test/unit/gateways/quickbooks_test.rb +++ b/test/unit/gateways/quickbooks_test.rb @@ -4,7 +4,7 @@ class QuickBooksTest < Test::Unit::TestCase include CommStub def setup - @gateway = QuickbooksGateway.new( + @oauth_1_gateway = QuickbooksGateway.new( consumer_key: 'consumer_key', consumer_secret: 'consumer_secret', access_token: 'access_token', @@ -12,6 +12,13 @@ def setup realm: 'realm_ID' ) + @oauth_2_gateway = QuickbooksGateway.new( + client_id: 'client_id', + client_secret: 'client_secret', + access_token: 'access_token', + refresh_token: 'refresh_token' + ) + @credit_card = credit_card @amount = 100 @@ -21,105 +28,232 @@ def setup description: 'Store Purchase' } - @authorization = 'ECZ7U0SO423E' + @authorization = 'ECZ7U0SO423E|d40f8a8007ba1af90a656d7f6371f641' + @authorization_no_request_id = 'ECZ7U0SO423E' end def test_successful_purchase - @gateway.expects(:ssl_post).returns(successful_purchase_response) - response = @gateway.purchase(@amount, @credit_card, @options) - assert_success response - - assert_equal 'EF1IQ9GGXS2D', response.authorization - assert response.test? + [@oauth_1_gateway, @oauth_2_gateway].each do |gateway| + gateway.expects(:ssl_post).returns(successful_purchase_response) + response = gateway.purchase(@amount, @credit_card, @options) + assert_success response + + assert_match(/EF1IQ9GGXS2D|/, response.authorization) + assert response.test? + end end def test_failed_purchase - @gateway.expects(:ssl_post).returns(failed_purchase_response) + [@oauth_1_gateway, @oauth_2_gateway].each do |gateway| + gateway.expects(:ssl_post).returns(failed_purchase_response) - response = @gateway.purchase(@amount, @credit_card, @options) - assert_failure response - assert_equal Gateway::STANDARD_ERROR_CODE[:processing_error], response.error_code + response = gateway.purchase(@amount, @credit_card, @options) + assert_failure response + assert_equal Gateway::STANDARD_ERROR_CODE[:processing_error], response.error_code + end end def test_successful_authorize - @gateway.expects(:ssl_post).returns(successful_authorize_response) - response = @gateway.authorize(@amount, @credit_card, @options) - assert_success response - - assert_equal @authorization, response.authorization - assert response.test? + [@oauth_1_gateway, @oauth_2_gateway].each do |gateway| + gateway.expects(:ssl_post).returns(successful_authorize_response) + response = gateway.authorize(@amount, @credit_card, @options) + assert_success response + + assert_match(/ECZ7U0SO423E|/, response.authorization) + assert response.test? + end end def test_failed_authorize - @gateway.expects(:ssl_post).returns(failed_authorize_response) + [@oauth_1_gateway, @oauth_2_gateway].each do |gateway| + gateway.expects(:ssl_post).returns(failed_authorize_response) - response = @gateway.authorize(@amount, @credit_card, @options) - assert_failure response - assert_equal Gateway::STANDARD_ERROR_CODE[:card_declined], response.error_code + response = gateway.authorize(@amount, @credit_card, @options) + assert_failure response + assert_equal Gateway::STANDARD_ERROR_CODE[:card_declined], response.error_code + end end def test_successful_capture - @gateway.expects(:ssl_post).returns(successful_capture_response) + [@oauth_1_gateway, @oauth_2_gateway].each do |gateway| + gateway.expects(:ssl_post).returns(successful_capture_response) - response = @gateway.capture(@amount, @authorization) - assert_success response + response = gateway.capture(@amount, @authorization) + assert_success response + end + end + + def test_successful_capture_when_authorization_does_not_include_request_id + [@oauth_1_gateway, @oauth_2_gateway].each do |gateway| + gateway.expects(:ssl_post).returns(successful_capture_response) + + response = gateway.capture(@amount, @authorization_no_request_id) + assert_success response + end end def test_failed_capture - @gateway.expects(:ssl_post).returns(failed_capture_response) + [@oauth_1_gateway, @oauth_2_gateway].each do |gateway| + gateway.expects(:ssl_post).returns(failed_capture_response) - response = @gateway.capture(@amount, @authorization) - assert_failure response + response = gateway.capture(@amount, @authorization) + assert_failure response + end end def test_successful_refund - @gateway.expects(:ssl_post).returns(successful_refund_response) + [@oauth_1_gateway, @oauth_2_gateway].each do |gateway| + gateway.expects(:ssl_post).returns(successful_refund_response) - response = @gateway.refund(@amount, @authorization) - assert_success response + response = gateway.refund(@amount, @authorization) + assert_success response + end + end + + def test_successful_refund_when_authorization_does_not_include_request_id + [@oauth_1_gateway, @oauth_2_gateway].each do |gateway| + gateway.expects(:ssl_post).returns(successful_refund_response) + + response = gateway.refund(@amount, @authorization_no_request_id) + assert_success response + end end def test_failed_refund - @gateway.expects(:ssl_post).returns(failed_refund_response) + [@oauth_1_gateway, @oauth_2_gateway].each do |gateway| + gateway.expects(:ssl_post).returns(failed_refund_response) - response = @gateway.refund(@amount, @authorization) - assert_failure response + response = gateway.refund(@amount, @authorization) + assert_failure response + end end def test_successful_verify - response = stub_comms do - @gateway.verify(@credit_card) - end.respond_with(successful_authorize_response) + [@oauth_1_gateway, @oauth_2_gateway].each do |gateway| + response = stub_comms(gateway) do + gateway.verify(@credit_card) + end.respond_with(successful_authorize_response) - assert_success response + assert_success response + end end def test_failed_verify - response = stub_comms do - @gateway.verify(@credit_card, @options) - end.respond_with(failed_authorize_response) + [@oauth_1_gateway, @oauth_2_gateway].each do |gateway| + response = stub_comms(gateway) do + gateway.verify(@credit_card, @options) + end.respond_with(failed_authorize_response) + + assert_failure response + assert_not_nil response.message + end + end - assert_failure response - assert_not_nil response.message + def test_successful_void + [@oauth_1_gateway, @oauth_2_gateway].each do |gateway| + response = stub_comms(gateway) do + gateway.void(@authorization) + end.respond_with(successful_void_response) + + assert_success response + end + end + + def test_failed_void + [@oauth_1_gateway, @oauth_2_gateway].each do |gateway| + response = stub_comms(gateway) do + gateway.void(@authorization) + end.respond_with(failed_void_response) + + assert_failure response + end end - def test_scrub - assert @gateway.supports_scrubbing? - assert_equal @gateway.send(:scrub, pre_scrubbed), post_scrubbed + def test_scrub_oauth_1 + assert @oauth_1_gateway.supports_scrubbing? + assert_equal @oauth_1_gateway.send(:scrub, pre_scrubbed), post_scrubbed + end + + def test_scrub_oauth_2 + assert @oauth_2_gateway.supports_scrubbing? + assert_equal @oauth_2_gateway.send(:scrub, pre_scrubbed_oauth_2), post_scrubbed_oauth_2 end def test_scrub_with_small_json - assert_equal @gateway.scrub(pre_scrubbed_small_json), post_scrubbed_small_json + assert_equal @oauth_1_gateway.scrub(pre_scrubbed_small_json), post_scrubbed_small_json end def test_default_context - stub_comms do - @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |_endpoint, data, _headers| - json = JSON.parse(data) - refute json.fetch('context').fetch('mobile') - assert json.fetch('context').fetch('isEcommerce') - end.respond_with(successful_purchase_response) + [@oauth_1_gateway, @oauth_2_gateway].each do |gateway| + stub_comms(gateway) do + gateway.purchase(@amount, @credit_card, @options) + end.check_request do |_endpoint, data, _headers| + json = JSON.parse(data) + refute json.fetch('context').fetch('mobile') + assert json.fetch('context').fetch('isEcommerce') + end.respond_with(successful_purchase_response) + end + end + + def test_refresh_does_not_occur_for_oauth_1 + @oauth_1_gateway.expects(:ssl_post).with( + anything, + Not(regexp_matches(%r{grant_type=refresh_token})), + anything + ).returns(successful_purchase_response) + + response = @oauth_1_gateway.purchase(@amount, @credit_card, @options.merge(allow_refresh: true)) + + assert_success response + + assert_match(/EF1IQ9GGXS2D|/, response.authorization) + assert response.test? + end + + def test_refresh_does_not_occur_when_token_valid_for_oauth_2 + @oauth_2_gateway.expects(:ssl_post).with( + anything, + Not(regexp_matches(%r{grant_type=refresh_token})), + has_entries('Authorization' => 'Bearer access_token') + ).returns(successful_purchase_response) + + response = @oauth_2_gateway.purchase(@amount, @credit_card, @options.merge(allow_refresh: true)) + assert_success response + end + + def test_refresh_does_occur_when_token_invalid_for_oauth_2 + @oauth_2_gateway.expects(:ssl_post).with( + anything, + anything, + has_entries('Authorization' => 'Bearer access_token') + ).returns(authentication_failed_oauth_2_response) + + @oauth_2_gateway.expects(:ssl_post).with( + anything, + all_of(regexp_matches(%r{grant_type=refresh_token})), + anything + ).returns(successful_refresh_token_response) + + @oauth_2_gateway.expects(:ssl_post).with( + anything, + anything, + has_entries('Authorization' => 'Bearer new_access_token') + ).returns(successful_purchase_response) + + response = @oauth_2_gateway.purchase(@amount, @credit_card, @options.merge(allow_refresh: true)) + assert_success response + + assert_match(/EF1IQ9GGXS2D|/, response.authorization) + assert response.test? + end + + def test_authorization_failed_code_results_in_failure + @oauth_2_gateway.expects(:ssl_post).returns(authorization_failed_oauth_2_response) + + response = @oauth_2_gateway.authorize(@amount, @credit_card, @options) + + assert_failure response + assert_equal 'AuthorizationFailed', response.error_code end private @@ -333,6 +467,42 @@ def failed_void_response RESPONSE end + def authentication_failed_oauth_2_response + <<-RESPONSE + { + "code": "AuthenticationFailed", + "type": "INPUT", + "message": null, + "detail": null, + "moreInfo": null + } + RESPONSE + end + + def authorization_failed_oauth_2_response + <<-RESPONSE + { + "code": "AuthorizationFailed", + "type": "INPUT", + "message": null, + "detail": null, + "moreInfo": null + } + RESPONSE + end + + def successful_refresh_token_response + <<-RESPONSE + { + "x_refresh_token_expires_in": 8719040, + "refresh_token": "refresh_token", + "access_token": "new_access_token", + "token_type": "bearer", + "expires_in": 3600 + } + RESPONSE + end + def pre_scrubbed <<-PRE_SCRUBBED opening connection to sandbox.api.intuit.com:443... @@ -394,4 +564,150 @@ def post_scrubbed Conn close POST_SCRUBBED end + + def pre_scrubbed_oauth_2 + %q( + opening connection to sandbox.api.intuit.com:443... + opened + starting SSL for sandbox.api.intuit.com:443... + SSL established + <- "POST /quickbooks/v4/payments/charges HTTP/1.1\r\nContent-Type: application/json\r\nRequest-Id: 3b098cc41f53562ec0f36a0fc7071ff8\r\nAccept: application/json\r\nAuthorization: Bearer eyabcd9ewjie0w9fj9jkewjaiojfiew0..rEVIND9few90zsg.CyFO4k9gR-t5yJsc0lxGrPPLGeO-JRa_5MZ_vG_H5AMlObrPpfhBRK51jUukhh0QOUjgkGm2jJb8c_haieKnkb3nY_W7giZyIG6d5g5XPqRZLhDnMCVVFHZyLIbBT_TDvZWROeOGY10xrDnUY5O05LYnOZc8gq7k_VTHHDrrmyeon3EmerAGjDUhnpp1DJRvR7SLUWgZQOuR997OuaP31_ZesKACzdVSw5QBJAhBeRqGl8LaNjjveQMo1c20CjWr_-c0EWbp0frMAA_UYaxtuzgRRs_opnMr4_PD7axQQevAzftSR1cQfUDAu_uybV5lyiUTfX80B3NBlLihWLiqCD9yWiYmup4TpNbapTL4x9CQz_WobicwWbhIJ7P1IrnxeJh2pW3ijjrBhbgLCCZ-6tcNUsD697ywn3YknT-iTSH-BIpGE_43bEOHyUtwZcIZIeb-6KtZIjQ_fjHfkRz66IrpP0V-XZ7_N5hJ7UIuQ34gOiuxdFJtbiMSUW1GnanJ9aRH8Fbzk_UzrWyuSs.XnsOxzQ\r\nConnection: close\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nUser-Agent: Ruby\r\nHost: sandbox.api.intuit.com\r\nContent-Length: 310\r\n\r\n" + <- "{\"amount\":\"1.00\",\"currency\":\"USD\",\"card\":{\"number\":\"4000100011112224\",\"expMonth\":\"09\",\"expYear\":2020,\"cvc\":\"123\",\"name\":\"Longbob Longsen\",\"address\":{\"streetAddress\":\"456 My Street\",\"city\":\"Ottawa\",\"region\":\"CA\",\"country\":\"US\",\"postalCode\":90210}},\"context\":{\"mobile\":false,\"isEcommerce\":true},\"capture\":\"true\"}" + -> "HTTP/1.1 401 Unauthorized\r\n" + -> "Date: Thu, 17 Oct 2019 15:40:43 GMT\r\n" + -> "Content-Type: application/json\r\n" + -> "Content-Length: 91\r\n" + -> "Connection: close\r\n" + -> "Server: nginx\r\n" + -> "intuit_tid: adca0516-0af2-48cd-a704-095529fe615c\r\n" + -> "WWW-Authenticate: Bearer realm=\"Intuit\", error=\"invalid_token\"\r\n" + -> "\r\n" + reading 91 bytes... + -> "{\"code\":\"AuthenticationFailed\",\"type\":\"INPUT\",\"message\":null,\"detail\":null,\"moreInfo\":null}" + read 91 bytes + Conn close + opening connection to oauth.platform.intuit.com:443... + opened + starting SSL for oauth.platform.intuit.com:443... + SSL established + <- "POST /oauth2/v1/tokens/bearer HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept: application/json\r\nAuthorization: Basic QUI3QWFkWGZYRWZyRE1WN0k2a3RFYXoyT2hCeHdhVkdtZUU5N3pmeGdjSllPUU40Qmo6ZEVJcms2bHozclVvQ05wRXFSbFV6bFd6STBYRUtyeDBYcDdoYVd3RQ==\r\nConnection: close\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nUser-Agent: Ruby\r\nHost: oauth.platform.intuit.com\r\nContent-Length: 89\r\n\r\n" + <- "grant_type=refresh_token&refresh_token=DE123456780s7AvBrjWjfiowji9IIKDU4zE237CmbGO" + -> "HTTP/1.1 200 OK\r\n" + -> "Date: Thu, 17 Oct 2019 15:40:43 GMT\r\n" + -> "Content-Type: application/json;charset=utf-8\r\n" + -> "Content-Length: 1007\r\n" + -> "Connection: close\r\n" + -> "Server: nginx\r\n" + -> "Strict-Transport-Security: max-age=15552000\r\n" + -> "intuit_tid: c9aff174-410e-4683-8a35-2591c659550f\r\n" + -> "Cache-Control: no-cache, no-store\r\n" + -> "Pragma: no-cache\r\n" + -> "X-Frame-Options: SAMEORIGIN\r\n" + -> "X-Content-Type-Options: nosniff\r\n" + -> "X-XSS-Protection: 1; mode=block\r\n" + -> "\r\n" + reading 1007 bytes... + -> "{\"x_refresh_token_expires_in\":8719040,\"refresh_token\":\"DE987654s7AvBrjWOCJYWsifjewaifjeiowja4zE237CmbGO\",\"access_token\":\"abcifejwiajJJJIDJFIEJQ0JDLUhTMjU2IiwiYWxnIjoiZGlyIn0..DIoIqgR5MP51jw.SK_1VawNWV1SC9ZSRu278imQXb-Fsn4K6gJK_IuEcG2p5xf9bj5fO6p8M8cN2HOw8D9TNuqR3u4POypw-QR4xfjiewjaifeDzc_L1D9cR_Zypcss0CWlk3Wl5Sm-Yel6Ej6DZPdMRYDVzFQIy-ugvlcbBMs_TBhPWuidiL7Gdy61iMW-CUG80iy0VN8TrOTTxI7oRlrsKeVF_htYbwfafeYxUnMIMnjz8BxsWHCj2Dj3Osx1d1RScHPlrzQhO8t9s0MpGbpO0Ygiu5H3-E5KC5ihnDtgTFeyyHFx8hPiG_ScbdnYgXQPqJiJIJ47Us9Jv0kXA1YxQr35-vL2IGHa6haofByqLJjXIKlYi-suu1Xl6wlCCZufXvELBcfhdkG4iCKGO3KXOozUkZOav9IqPM7qjGskTzbmR4zMzCmf0ypQbmk-4NXQT3N1Z_mxTX4ebCfjF7h0LjX3sgFcwYtNKS_iLsygU8mPZScCthBH67bO2ce35ZjHr2kHYKKxAYS-wXmiMpFM7NvEkVjoWJarrMF-Q4DB7eLKezmEKuRMDr6Q6_gDEbeyHqqCauEczBriq61LnWlDuqJtySL-amSrADFU7SU8fmD4DhgxU.f0o4123vdcxH_zvzfaewa7Q\",\"token_type\":\"bearer\",\"expires_in\":3600}" + read 1007 bytes + Conn close + opening connection to sandbox.api.intuit.com:443... + opened + starting SSL for sandbox.api.intuit.com:443... + SSL established + <- "POST /quickbooks/v4/payments/charges HTTP/1.1\r\nContent-Type: application/json\r\nRequest-Id: da14d01c3608a0a036c4e7298cb5d56a\r\nAccept: application/json\r\nAuthorization: Bearer abcifejwiajJJJIDJFIEJQ0JDLUhTMjU2IiwiYWxnIjoiZGlyIn0..DIoIqgR5MP51jw.SK_1VawNWV1SC9ZSRu278imQXb-Fsn4K6gJK_IuEcG2p5xf9bj5fO6p8M8cN2HOw8D9TNuqR3u4POypw-QR4xfjiewjaifeDzc_L1D9cR_Zypcss0CWlk3Wl5Sm-Yel6Ej6DZPdMRYDVzFQIy-ugvlcbBMs_TBhPWuidiL7Gdy61iMW-CUG80iy0VN8TrOTTxI7oRlrsKeVF_htYbwfafeYxUnMIMnjz8BxsWHCj2Dj3Osx1d1RScHPlrzQhO8t9s0MpGbpO0Ygiu5H3-E5KC5ihnDtgTFeyyHFx8hPiG_ScbdnYgXQPqJiJIJ47Us9Jv0kXA1YxQr35-vL2IGHa6haofByqLJjXIKlYi-suu1Xl6wlCCZufXvELBcfhdkG4iCKGO3KXOozUkZOav9IqPM7qjGskTzbmR4zMzCmf0ypQbmk-4NXQT3N1Z_mxTX4ebCfjF7h0LjX3sgFcwYtNKS_iLsygU8mPZScCthBH67bO2ce35ZjHr2kHYKKxAYS-wXmiMpFM7NvEkVjoWJarrMF-Q4DB7eLKezmEKuRMDr6Q6_gDEbeyHqqCauEczBriq61LnWlDuqJtySL-amSrADFU7SU8fmD4DhgxU.f0o4123vdcxH_zvzfaewa7Q\r\nConnection: close\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nUser-Agent: Ruby\r\nHost: sandbox.api.intuit.com\r\nContent-Length: 310\r\n\r\n" + <- "{\"amount\":\"1.00\",\"currency\":\"USD\",\"card\":{\"number\":\"4000100011112224\",\"expMonth\":\"09\",\"expYear\":2020,\"cvc\":\"123\",\"name\":\"Longbob Longsen\",\"address\":{\"streetAddress\":\"456 My Street\",\"city\":\"Ottawa\",\"region\":\"CA\",\"country\":\"US\",\"postalCode\":90210}},\"context\":{\"mobile\":false,\"isEcommerce\":true},\"capture\":\"true\"}" + -> "HTTP/1.1 201 Created\r\n" + -> "Date: Thu, 17 Oct 2019 15:40:44 GMT\r\n" + -> "Content-Type: application/json;charset=utf-8\r\n" + -> "Transfer-Encoding: chunked\r\n" + -> "Connection: close\r\n" + -> "Server: nginx\r\n" + -> "Strict-Transport-Security: max-age=15552000\r\n" + -> "intuit_tid: 09ce7b7f-e19a-4567-8d7f-cf6ce81a9c75\r\n" + -> "\r\n" + -> "213\r\n" + reading 531 bytes... + -> "{\"created\":\"2019-10-17T15:40:44Z\",\"status\":\"CAPTURED\",\"amount\":\"1.00\",\"currency\":\"USD\",\"card\":{\"number\":\"xxxxxxxxxxxx2224\",\"name\":\"Longbob Longsen\",\"address\":{\"city\":\"Ottawa\",\"region\":\"CA\",\"country\":\"US\",\"streetAddress\":\"456 My Street\",\"postalCode\":\"90210\"},\"cardType\":\"Visa\",\"expMonth\":\"09\",\"expYear\":\"2020\",\"cvc\":\"xxx\"},\"capture\":true,\"avsStreet\":\"Pass\",\"avsZip\":\"Pass\",\"cardSecurityCodeMatch\":\"NotAvailable\",\"id\":\"ES2Q849Y8KQ9\",\"context\":{\"mobile\":false,\"deviceInfo\":{},\"recurring\":false,\"isEcommerce\":true},\"authCode\":\"574943\"}" + read 531 bytes + reading 2 bytes... + -> "\r\n" + read 2 bytes + -> "0\r\n" + -> "\r\n" + Conn close + ) + end + + def post_scrubbed_oauth_2 + %q( + opening connection to sandbox.api.intuit.com:443... + opened + starting SSL for sandbox.api.intuit.com:443... + SSL established + <- "POST /quickbooks/v4/payments/charges HTTP/1.1\r\nContent-Type: application/json\r\nRequest-Id: 3b098cc41f53562ec0f36a0fc7071ff8\r\nAccept: application/json\r\nAuthorization: Bearer [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: sandbox.api.intuit.com\r\nContent-Length: 310\r\n\r\n" + <- "{\"amount\":\"1.00\",\"currency\":\"USD\",\"card\":{\"number\":\"[FILTERED]\",\"expMonth\":\"09\",\"expYear\":2020,\"cvc\":\"[FILTERED]\",\"name\":\"Longbob Longsen\",\"address\":{\"streetAddress\":\"456 My Street\",\"city\":\"Ottawa\",\"region\":\"CA\",\"country\":\"US\",\"postalCode\":90210}},\"context\":{\"mobile\":false,\"isEcommerce\":true},\"capture\":\"true\"}" + -> "HTTP/1.1 401 Unauthorized\r\n" + -> "Date: Thu, 17 Oct 2019 15:40:43 GMT\r\n" + -> "Content-Type: application/json\r\n" + -> "Content-Length: 91\r\n" + -> "Connection: close\r\n" + -> "Server: nginx\r\n" + -> "intuit_tid: adca0516-0af2-48cd-a704-095529fe615c\r\n" + -> "WWW-Authenticate: Bearer realm=\"Intuit\", error=\"invalid_token\"\r\n" + -> "\r\n" + reading 91 bytes... + -> "{\"code\":\"AuthenticationFailed\",\"type\":\"INPUT\",\"message\":null,\"detail\":null,\"moreInfo\":null}" + read 91 bytes + Conn close + opening connection to oauth.platform.intuit.com:443... + opened + starting SSL for oauth.platform.intuit.com:443... + SSL established + <- "POST /oauth2/v1/tokens/bearer HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept: application/json\r\nAuthorization: Basic [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: oauth.platform.intuit.com\r\nContent-Length: 89\r\n\r\n" + <- "grant_type=refresh_token&refresh_token=[FILTERED]" + -> "HTTP/1.1 200 OK\r\n" + -> "Date: Thu, 17 Oct 2019 15:40:43 GMT\r\n" + -> "Content-Type: application/json;charset=utf-8\r\n" + -> "Content-Length: 1007\r\n" + -> "Connection: close\r\n" + -> "Server: nginx\r\n" + -> "Strict-Transport-Security: max-age=15552000\r\n" + -> "intuit_tid: c9aff174-410e-4683-8a35-2591c659550f\r\n" + -> "Cache-Control: no-cache, no-store\r\n" + -> "Pragma: no-cache\r\n" + -> "X-Frame-Options: SAMEORIGIN\r\n" + -> "X-Content-Type-Options: nosniff\r\n" + -> "X-XSS-Protection: 1; mode=block\r\n" + -> "\r\n" + reading 1007 bytes... + -> "{\"x_refresh_token_expires_in\":8719040,\"refresh_token\":\"[FILTERED]\",\"access_token\":\"[FILTERED]\",\"token_type\":\"bearer\",\"expires_in\":3600}" + read 1007 bytes + Conn close + opening connection to sandbox.api.intuit.com:443... + opened + starting SSL for sandbox.api.intuit.com:443... + SSL established + <- "POST /quickbooks/v4/payments/charges HTTP/1.1\r\nContent-Type: application/json\r\nRequest-Id: da14d01c3608a0a036c4e7298cb5d56a\r\nAccept: application/json\r\nAuthorization: Bearer [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: sandbox.api.intuit.com\r\nContent-Length: 310\r\n\r\n" + <- "{\"amount\":\"1.00\",\"currency\":\"USD\",\"card\":{\"number\":\"[FILTERED]\",\"expMonth\":\"09\",\"expYear\":2020,\"cvc\":\"[FILTERED]\",\"name\":\"Longbob Longsen\",\"address\":{\"streetAddress\":\"456 My Street\",\"city\":\"Ottawa\",\"region\":\"CA\",\"country\":\"US\",\"postalCode\":90210}},\"context\":{\"mobile\":false,\"isEcommerce\":true},\"capture\":\"true\"}" + -> "HTTP/1.1 201 Created\r\n" + -> "Date: Thu, 17 Oct 2019 15:40:44 GMT\r\n" + -> "Content-Type: application/json;charset=utf-8\r\n" + -> "Transfer-Encoding: chunked\r\n" + -> "Connection: close\r\n" + -> "Server: nginx\r\n" + -> "Strict-Transport-Security: max-age=15552000\r\n" + -> "intuit_tid: 09ce7b7f-e19a-4567-8d7f-cf6ce81a9c75\r\n" + -> "\r\n" + -> "213\r\n" + reading 531 bytes... + -> "{\"created\":\"2019-10-17T15:40:44Z\",\"status\":\"CAPTURED\",\"amount\":\"1.00\",\"currency\":\"USD\",\"card\":{\"number\":\"xxxxxxxxxxxx2224\",\"name\":\"Longbob Longsen\",\"address\":{\"city\":\"Ottawa\",\"region\":\"CA\",\"country\":\"US\",\"streetAddress\":\"456 My Street\",\"postalCode\":\"90210\"},\"cardType\":\"Visa\",\"expMonth\":\"09\",\"expYear\":\"2020\",\"cvc\":\"xxx\"},\"capture\":true,\"avsStreet\":\"Pass\",\"avsZip\":\"Pass\",\"cardSecurityCodeMatch\":\"NotAvailable\",\"id\":\"ES2Q849Y8KQ9\",\"context\":{\"mobile\":false,\"deviceInfo\":{},\"recurring\":false,\"isEcommerce\":true},\"authCode\":\"574943\"}" + read 531 bytes + reading 2 bytes... + -> "\r\n" + read 2 bytes + -> "0\r\n" + -> "\r\n" + Conn close + ) + end end diff --git a/test/unit/gateways/quickpay_test.rb b/test/unit/gateways/quickpay_test.rb index f9f2e2d28cd..8209f95c965 100644 --- a/test/unit/gateways/quickpay_test.rb +++ b/test/unit/gateways/quickpay_test.rb @@ -1,7 +1,6 @@ require 'test_helper' class QuickpayTest < Test::Unit::TestCase - def test_error_without_login_option assert_raise ArgumentError do QuickpayGateway.new @@ -9,13 +8,12 @@ def test_error_without_login_option end def test_v4to7 - gateway = QuickpayGateway.new(:login => 50000000, :password => 'secret') + gateway = QuickpayGateway.new(login: 50000000, password: 'secret') assert_instance_of QuickpayV4to7Gateway, gateway end def test_v10 - gateway = QuickpayGateway.new(:login => 100, :api_key => 'APIKEY') + gateway = QuickpayGateway.new(login: 100, api_key: 'APIKEY') assert_instance_of QuickpayV10Gateway, gateway end - end diff --git a/test/unit/gateways/quickpay_v10_test.rb b/test/unit/gateways/quickpay_v10_test.rb index f07f13cc03e..fccafc60268 100644 --- a/test/unit/gateways/quickpay_v10_test.rb +++ b/test/unit/gateways/quickpay_v10_test.rb @@ -4,10 +4,10 @@ class QuickpayV10Test < Test::Unit::TestCase include CommStub def setup - @gateway = QuickpayV10Gateway.new(:api_key => 'APIKEY') + @gateway = QuickpayV10Gateway.new(api_key: 'APIKEY') @credit_card = credit_card('4242424242424242') @amount = 100 - @options = { :order_id => '1', :billing_address => address, :customer_ip => '1.1.1.1' } + @options = { order_id: '1', billing_address: address, customer_ip: '1.1.1.1' } end def parse(body) @@ -28,7 +28,7 @@ def test_successful_purchase assert_success response assert_equal '1145', response.authorization assert response.test? - end.check_request do |endpoint, data, headers| + end.check_request do |endpoint, data, _headers| parsed = parse(data) if parsed['order_id'] assert_match %r{/payments}, endpoint @@ -47,7 +47,7 @@ def test_successful_authorization assert_success response assert_equal '1145', response.authorization assert response.test? - end.check_request do |endpoint, data, headers| + end.check_request do |endpoint, data, _headers| parsed_data = parse(data) if parsed_data['order_id'] assert_match %r{/payments}, endpoint @@ -71,7 +71,7 @@ def test_successful_authorization_with_3ds assert_success response assert_equal '1145', response.authorization assert response.test? - end.check_request do |endpoint, data, headers| + end.check_request do |endpoint, data, _headers| parsed_data = parse(data) if parsed_data['order_id'] assert_match %r{/payments}, endpoint @@ -87,9 +87,9 @@ def test_successful_void assert response = @gateway.void(1145) assert_success response assert response.test? - end.check_request do |endpoint, data, headers| + end.check_request do |endpoint, _data, _headers| assert_match %r{/payments/1145/cancel}, endpoint - end.respond_with({'id' => 1145}.to_json) + end.respond_with({ 'id' => 1145 }.to_json) end def test_failed_authorization @@ -115,7 +115,7 @@ def test_successful_store assert response = @gateway.store(@credit_card, @options) assert_success response assert response.test? - end.check_request do |endpoint, data, headers| + end.check_request do |endpoint, _data, _headers| assert_match %r{/card}, endpoint end.respond_with(successful_store_response, successful_sauthorize_response) end @@ -125,9 +125,9 @@ def test_successful_unstore assert response = @gateway.unstore('123') assert_success response assert response.test? - end.check_request do |endpoint, data, headers| + end.check_request do |endpoint, _data, _headers| assert_match %r{/cards/\d+/cancel}, endpoint - end.respond_with({'id' => '123'}.to_json) + end.respond_with({ 'id' => '123' }.to_json) end def test_successful_verify @@ -141,19 +141,19 @@ def test_successful_verify def test_failed_verify response = stub_comms do @gateway.verify(@credit_card, @options) - end.respond_with(failed_authorization_response, {'id' => 1145}.to_json) + end.respond_with(failed_authorization_response, { 'id' => 1145 }.to_json) assert_failure response assert_equal 'Validation error', response.message end def test_supported_countries klass = @gateway.class - assert_equal ['DE', 'DK', 'ES', 'FI', 'FR', 'FO', 'GB', 'IS', 'NO', 'SE'], klass.supported_countries + assert_equal %w[DE DK ES FI FR FO GB IS NO SE], klass.supported_countries end def test_supported_card_types klass = @gateway.class - assert_equal [:dankort, :forbrugsforeningen, :visa, :master, :american_express, :diners_club, :jcb, :maestro ], klass.supported_cardtypes + assert_equal %i[dankort forbrugsforeningen visa master american_express diners_club jcb maestro], klass.supported_cardtypes end def test_successful_capture @@ -170,90 +170,90 @@ def test_transcript_scrubbing def successful_payment_response { - 'id' =>1145, - 'order_id' =>'310f59c57a', - 'accepted' =>false, - 'test_mode' =>false, - 'branding_id' =>nil, - 'variables' =>{}, - 'acquirer' =>nil, - 'operations' =>[], - 'metadata' =>{}, - 'created_at' =>'2015-03-30T16:56:17Z', - 'balance' =>0, - 'currency' =>'DKK' + 'id' => 1145, + 'order_id' => '310f59c57a', + 'accepted' => false, + 'test_mode' => false, + 'branding_id' => nil, + 'variables' => {}, + 'acquirer' => nil, + 'operations' => [], + 'metadata' => {}, + 'created_at' => '2015-03-30T16:56:17Z', + 'balance' => 0, + 'currency' => 'DKK' }.to_json end def successful_authorization_response { - 'id' => 1145, - 'order_id' => '310f59c57a', - 'accepted' => false, - 'test_mode' => true, - 'branding_id' => nil, - 'variables' => {}, - 'acquirer' => 'clearhaus', - 'operations' => [], - 'metadata' => { - 'type' =>'card', - 'brand' =>'quickpay-test-card', - 'last4' =>'0008', - 'exp_month' =>9, - 'exp_year' =>2016, - 'country' =>'DK', - 'is_3d_secure' =>false, - 'customer_ip' =>nil, - 'customer_country' =>nil - }, - 'created_at' => '2015-03-30T16:56:17Z', - 'balance' => 0, - 'currency' => 'DKK' + 'id' => 1145, + 'order_id' => '310f59c57a', + 'accepted' => false, + 'test_mode' => true, + 'branding_id' => nil, + 'variables' => {}, + 'acquirer' => 'clearhaus', + 'operations' => [], + 'metadata' => { + 'type' => 'card', + 'brand' => 'quickpay-test-card', + 'last4' => '0008', + 'exp_month' => 9, + 'exp_year' => 2016, + 'country' => 'DK', + 'is_3d_secure' => false, + 'customer_ip' => nil, + 'customer_country' => nil + }, + 'created_at' => '2015-03-30T16:56:17Z', + 'balance' => 0, + 'currency' => 'DKK' }.to_json end def successful_capture_response { - 'id' =>1145, - 'order_id' =>'310f59c57a', - 'accepted' =>true, - 'test_mode' =>true, - 'branding_id' =>nil, - 'variables' =>{}, - 'acquirer' =>'clearhaus', - 'operations' =>[], - 'metadata' =>{'type'=>'card', 'brand'=>'quickpay-test-card', 'last4'=>'0008', 'exp_month'=>9, 'exp_year'=>2016, 'country'=>'DK', 'is_3d_secure'=>false, 'customer_ip'=>nil, 'customer_country'=>nil}, - 'created_at' =>'2015-03-30T16:56:17Z', - 'balance' =>0, - 'currency' =>'DKK' + 'id' => 1145, + 'order_id' => '310f59c57a', + 'accepted' => true, + 'test_mode' => true, + 'branding_id' => nil, + 'variables' => {}, + 'acquirer' => 'clearhaus', + 'operations' => [], + 'metadata' => { 'type' => 'card', 'brand' => 'quickpay-test-card', 'last4' => '0008', 'exp_month' => 9, 'exp_year' => 2016, 'country' => 'DK', 'is_3d_secure' => false, 'customer_ip' => nil, 'customer_country' => nil }, + 'created_at' => '2015-03-30T16:56:17Z', + 'balance' => 0, + 'currency' => 'DKK' }.to_json end def succesful_refund_response { - 'id' =>1145, - 'order_id' =>'310f59c57a', - 'accepted' =>true, - 'test_mode' =>true, - 'branding_id' =>nil, - 'variables' =>{}, - 'acquirer' =>'clearhaus', - 'operations' =>[], - 'metadata'=>{ - 'type' =>'card', - 'brand' =>'quickpay-test-card', - 'last4' =>'0008', - 'exp_month' =>9, - 'exp_year' =>2016, - 'country' =>'DK', - 'is_3d_secure' =>false, - 'customer_ip' =>nil, - 'customer_country' =>nil - }, - 'created_at' =>'2015-03-30T16:56:17Z', - 'balance' =>100, - 'currency' =>'DKK' - }.to_json + 'id' => 1145, + 'order_id' => '310f59c57a', + 'accepted' => true, + 'test_mode' => true, + 'branding_id' => nil, + 'variables' => {}, + 'acquirer' => 'clearhaus', + 'operations' => [], + 'metadata' => { + 'type' => 'card', + 'brand' => 'quickpay-test-card', + 'last4' => '0008', + 'exp_month' => 9, + 'exp_year' => 2016, + 'country' => 'DK', + 'is_3d_secure' => false, + 'customer_ip' => nil, + 'customer_country' => nil + }, + 'created_at' => '2015-03-30T16:56:17Z', + 'balance' => 100, + 'currency' => 'DKK' + }.to_json end def failed_authorization_response diff --git a/test/unit/gateways/quickpay_v4to7_test.rb b/test/unit/gateways/quickpay_v4to7_test.rb index 74e395980ca..e4beffd6571 100644 --- a/test/unit/gateways/quickpay_v4to7_test.rb +++ b/test/unit/gateways/quickpay_v4to7_test.rb @@ -9,14 +9,14 @@ def merchant_id def setup @gateway = QuickpayGateway.new( - :login => merchant_id, - :password => 'PASSWORD', - :version => 7 + login: merchant_id, + password: 'PASSWORD', + version: 7 ) @credit_card = credit_card('4242424242424242') @amount = 100 - @options = { :order_id => '1', :billing_address => address } + @options = { order_id: '1', billing_address: address } end def test_successful_purchase @@ -39,15 +39,15 @@ def test_successful_authorization def test_successful_store_for_v6 @gateway = QuickpayGateway.new( - :login => merchant_id, - :password => 'PASSWORD', - :version => 6 + login: merchant_id, + password: 'PASSWORD', + version: 6 ) @gateway.expects(:generate_check_hash).returns(mock_md5_hash) response = stub_comms do - @gateway.store(@credit_card, {:order_id => 'fa73664073e23597bbdd', :description => 'Storing Card'}) - end.check_request do |endpoint, data, headers| + @gateway.store(@credit_card, { order_id: 'fa73664073e23597bbdd', description: 'Storing Card' }) + end.check_request do |_endpoint, data, _headers| assert_equal(expected_store_parameters_v6, CGI::parse(data)) end.respond_with(successful_store_response_v6) @@ -61,8 +61,8 @@ def test_successful_store_for_v7 @gateway.expects(:generate_check_hash).returns(mock_md5_hash) response = stub_comms do - @gateway.store(@credit_card, {:order_id => 'ed7546cb4ceb8f017ea4', :description => 'Storing Card'}) - end.check_request do |endpoint, data, headers| + @gateway.store(@credit_card, { order_id: 'ed7546cb4ceb8f017ea4', description: 'Storing Card' }) + end.check_request do |_endpoint, data, _headers| assert_equal(expected_store_parameters_v7, CGI::parse(data)) end.respond_with(successful_store_response_v7) @@ -124,16 +124,16 @@ def test_parsing_successful_response def test_supported_countries klass = @gateway.class - assert_equal ['DE', 'DK', 'ES', 'FI', 'FR', 'FO', 'GB', 'IS', 'NO', 'SE'], klass.supported_countries + assert_equal %w[DE DK ES FI FR FO GB IS NO SE], klass.supported_countries end def test_supported_card_types klass = @gateway.class - assert_equal [ :dankort, :forbrugsforeningen, :visa, :master, :american_express, :diners_club, :jcb, :maestro ], klass.supported_cardtypes + assert_equal %i[dankort forbrugsforeningen visa master american_express diners_club jcb maestro], klass.supported_cardtypes end def test_add_testmode_does_not_add_testmode_if_transaction_id_present - post_hash = {:transaction => '12345'} + post_hash = { transaction: '12345' } @gateway.send(:add_testmode, post_hash) assert_equal nil, post_hash[:testmode] end @@ -147,7 +147,7 @@ def test_add_testmode_adds_a_testmode_param_if_transaction_id_not_present def test_finalize_is_disabled_by_default stub_comms(@gateway, :ssl_request) do @gateway.capture(@amount, '12345') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert data =~ /finalize=0/ end.respond_with(successful_capture_response) end @@ -155,7 +155,7 @@ def test_finalize_is_disabled_by_default def test_finalize_is_enabled stub_comms(@gateway, :ssl_request) do @gateway.capture(@amount, '12345', finalize: true) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert data =~ /finalize=1/ end.respond_with(successful_capture_response) end @@ -192,33 +192,33 @@ def failed_authorization_response def expected_store_parameters_v6 { - 'cardnumber'=>['4242424242424242'], - 'cvd'=>['123'], - 'expirationdate'=>[expected_expiration_date], - 'ordernumber'=>['fa73664073e23597bbdd'], - 'description'=>['Storing Card'], - 'testmode'=>['1'], - 'protocol'=>['6'], - 'msgtype'=>['subscribe'], - 'merchant'=>[merchant_id], - 'md5check'=>[mock_md5_hash] + 'cardnumber' => ['4242424242424242'], + 'cvd' => ['123'], + 'expirationdate' => [expected_expiration_date], + 'ordernumber' => ['fa73664073e23597bbdd'], + 'description' => ['Storing Card'], + 'testmode' => ['1'], + 'protocol' => ['6'], + 'msgtype' => ['subscribe'], + 'merchant' => [merchant_id], + 'md5check' => [mock_md5_hash] } end def expected_store_parameters_v7 { - 'amount'=>['0'], - 'currency'=>['DKK'], - 'cardnumber'=>['4242424242424242'], - 'cvd'=>['123'], - 'expirationdate'=>[expected_expiration_date], - 'ordernumber'=>['ed7546cb4ceb8f017ea4'], - 'description'=>['Storing Card'], - 'testmode'=>['1'], - 'protocol'=>['7'], - 'msgtype'=>['subscribe'], - 'merchant'=>[merchant_id], - 'md5check'=>[mock_md5_hash] + 'amount' => ['0'], + 'currency' => ['DKK'], + 'cardnumber' => ['4242424242424242'], + 'cvd' => ['123'], + 'expirationdate' => [expected_expiration_date], + 'ordernumber' => ['ed7546cb4ceb8f017ea4'], + 'description' => ['Storing Card'], + 'testmode' => ['1'], + 'protocol' => ['7'], + 'msgtype' => ['subscribe'], + 'merchant' => [merchant_id], + 'md5check' => [mock_md5_hash] } end diff --git a/test/unit/gateways/qvalent_test.rb b/test/unit/gateways/qvalent_test.rb index 6bff79ebb82..26e553c48d1 100644 --- a/test/unit/gateways/qvalent_test.rb +++ b/test/unit/gateways/qvalent_test.rb @@ -91,7 +91,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 %r{5d53a33d960c46d00f5dc061947d998c}, data end.respond_with(successful_refund_response) @@ -177,8 +177,8 @@ def test_empty_response_fails def test_3d_secure_fields response = stub_comms(@gateway, :ssl_request) do - @gateway.purchase(@amount, @credit_card, {xid: '123', cavv: '456', eci: '5'}) - end.check_request do |method, endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, { xid: '123', cavv: '456', eci: '5' }) + end.check_request do |_method, _endpoint, data, _headers| assert_match(/xid=123/, data) assert_match(/cavv=456/, data) assert_match(/ECI=5/, data) @@ -189,8 +189,8 @@ def test_3d_secure_fields def test_stored_credential_fields_initial response = stub_comms(@gateway, :ssl_request) do - @gateway.purchase(@amount, @credit_card, {stored_credential: {initial_transaction: true, reason_type: 'unscheduled', initiator: 'merchant'}}) - end.check_request do |method, endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, { stored_credential: { initial_transaction: true, reason_type: 'unscheduled', initiator: 'merchant' } }) + end.check_request do |_method, _endpoint, data, _headers| assert_match(/posEntryMode=MANUAL/, data) assert_match(/storedCredentialUsage=INITIAL_STORAGE/, data) assert_match(/ECI=SSL/, data) @@ -201,8 +201,8 @@ def test_stored_credential_fields_initial def test_stored_credential_fields_recurring response = stub_comms(@gateway, :ssl_request) do - @gateway.purchase(@amount, @credit_card, {stored_credential: {reason_type: 'recurring', initiator: 'merchant', network_transaction_id: '7890'}}) - end.check_request do |method, endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, { stored_credential: { reason_type: 'recurring', initiator: 'merchant', network_transaction_id: '7890' } }) + end.check_request do |_method, _endpoint, data, _headers| assert_match(/posEntryMode=STORED_CREDENTIAL/, data) assert_match(/storedCredentialUsage=RECURRING/, data) assert_match(/ECI=REC/, data) @@ -214,8 +214,8 @@ def test_stored_credential_fields_recurring def test_stored_credential_fields_unscheduled response = stub_comms(@gateway, :ssl_request) do - @gateway.purchase(@amount, @credit_card, {stored_credential: {reason_type: 'unscheduled', initiator: 'merchant', network_transaction_id: '7890'}}) - end.check_request do |method, endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, { stored_credential: { reason_type: 'unscheduled', initiator: 'merchant', network_transaction_id: '7890' } }) + end.check_request do |_method, _endpoint, data, _headers| assert_match(/posEntryMode=STORED_CREDENTIAL/, data) assert_match(/storedCredentialUsage=UNSCHEDULED/, data) assert_match(/ECI=MTO/, data) @@ -227,8 +227,8 @@ def test_stored_credential_fields_unscheduled def test_stored_credential_fields_cardholder_initiated response = stub_comms(@gateway, :ssl_request) do - @gateway.purchase(@amount, @credit_card, {stored_credential: {reason_type: 'unscheduled', initiator: 'cardholder', network_transaction_id: '7890'}}) - end.check_request do |method, endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, { stored_credential: { reason_type: 'unscheduled', initiator: 'cardholder', network_transaction_id: '7890' } }) + end.check_request do |_method, _endpoint, data, _headers| assert_match(/posEntryMode=STORED_CREDENTIAL/, data) refute_match(/storedCredentialUsage/, data) assert_match(/ECI=MTO/, data) @@ -241,8 +241,8 @@ def test_stored_credential_fields_cardholder_initiated def test_stored_credential_fields_mastercard @credit_card.brand = 'master' response = stub_comms(@gateway, :ssl_request) do - @gateway.purchase(@amount, @credit_card, {stored_credential: {reason_type: 'recurring', initiator: 'merchant', network_transaction_id: '7890'}}) - end.check_request do |method, endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, { stored_credential: { reason_type: 'recurring', initiator: 'merchant', network_transaction_id: '7890' } }) + end.check_request do |_method, _endpoint, data, _headers| assert_match(/posEntryMode=STORED_CREDENTIAL/, data) refute_match(/storedCredentialUsage/, data) assert_match(/ECI=REC/, data) diff --git a/test/unit/gateways/realex_test.rb b/test/unit/gateways/realex_test.rb index d3cf4c4dd32..1f1057a8829 100644 --- a/test/unit/gateways/realex_test.rb +++ b/test/unit/gateways/realex_test.rb @@ -15,37 +15,37 @@ def setup @refund_secret = 'your_refund_secret' @gateway = RealexGateway.new( - :login => @login, - :password => @password, - :account => @account + login: @login, + password: @password, + account: @account ) @gateway_with_account = RealexGateway.new( - :login => @login, - :password => @password, - :account => 'bill_web_cengal' + login: @login, + password: @password, + account: 'bill_web_cengal' ) @credit_card = CreditCard.new( - :number => '4263971921001307', - :month => 8, - :year => 2008, - :first_name => 'Longbob', - :last_name => 'Longsen', - :brand => 'visa' + number: '4263971921001307', + month: 8, + year: 2008, + first_name: 'Longbob', + last_name: 'Longsen', + brand: 'visa' ) @options = { - :order_id => '1' + order_id: '1' } @address = { - :name => 'Longbob Longsen', - :address1 => '123 Fake Street', - :city => 'Belfast', - :state => 'Antrim', - :country => 'Northern Ireland', - :zip => 'BT2 8XX' + name: 'Longbob Longsen', + address1: '123 Fake Street', + city: 'Belfast', + state: 'Antrim', + country: 'Northern Ireland', + zip: 'BT2 8XX' } @amount = 100 @@ -90,12 +90,12 @@ def test_initialize_without_refund_and_rebate_secrets def test_hash gateway = RealexGateway.new( - :login => 'thestore', - :password => 'mysecret' + login: 'thestore', + password: 'mysecret' ) Time.stubs(:now).returns(Time.new(2001, 4, 3, 12, 32, 45)) gateway.expects(:ssl_post).with(anything, regexp_matches(/9af7064afd307c9f988e8dfc271f9257f1fc02f6/)).returns(successful_purchase_response) - gateway.purchase(29900, credit_card('5105105105105100'), :order_id => 'ORD453-11') + gateway.purchase(29900, credit_card('5105105105105100'), order_id: 'ORD453-11') end def test_successful_purchase @@ -137,11 +137,11 @@ def test_unsuccessful_credit end def test_supported_countries - assert_equal ['IE', 'GB', 'FR', 'BE', 'NL', 'LU', 'IT', 'US', 'CA', 'ES'], RealexGateway.supported_countries + assert_equal %w[IE GB FR BE NL LU IT US CA ES], RealexGateway.supported_countries end def test_supported_card_types - assert_equal [ :visa, :master, :american_express, :diners_club ], RealexGateway.supported_cardtypes + assert_equal %i[visa master american_express diners_club], RealexGateway.supported_cardtypes end def test_avs_result_not_supported @@ -171,16 +171,16 @@ def test_malformed_xml def test_capture_xml @gateway.expects(:new_timestamp).returns('20090824160201') - valid_capture_xml = <<-SRC - - your_merchant_id - your_account - 100 - 1 - 4321 - 1234 - ef0a6c485452f3f94aff336fa90c6c62993056ca - + valid_capture_xml = <<~SRC + + your_merchant_id + your_account + 100 + 1 + 4321 + 1234 + ef0a6c485452f3f94aff336fa90c6c62993056ca + SRC assert_xml_equal valid_capture_xml, @gateway.build_capture_request(@amount, '1;4321;1234', {}) @@ -188,31 +188,68 @@ def test_capture_xml def test_purchase_xml options = { - :order_id => '1' + order_id: '1', + ip: '123.456.789.0' + } + + @gateway.expects(:new_timestamp).returns('20090824160201') + + valid_purchase_request_xml = <<~SRC + + your_merchant_id + your_account + 1 + 100 + + 4263971921001307 + 0808 + Longbob Longsen + VISA + + + + + + + + 3499d7bc8dbacdcfba2286bd74916d026bae630f + + 123.456.789.0 + + + SRC + + assert_xml_equal valid_purchase_request_xml, @gateway.build_purchase_or_authorization_request(:purchase, @amount, @credit_card, options) + end + + def test_purchase_xml_with_ipv6 + options = { + order_id: '1', + ip: '2a02:c7d:da18:ac00:6d10:4f13:1795:4890' } @gateway.expects(:new_timestamp).returns('20090824160201') - valid_purchase_request_xml = <<-SRC - - your_merchant_id - your_account - 1 - 100 - - 4263971921001307 - 0808 - Longbob Longsen - VISA - - - - - - - - 3499d7bc8dbacdcfba2286bd74916d026bae630f - + valid_purchase_request_xml = <<~SRC + + your_merchant_id + your_account + 1 + 100 + + 4263971921001307 + 0808 + Longbob Longsen + VISA + + + + + + + + 3499d7bc8dbacdcfba2286bd74916d026bae630f + SRC assert_xml_equal valid_purchase_request_xml, @gateway.build_purchase_or_authorization_request(:purchase, @amount, @credit_card, options) @@ -221,15 +258,15 @@ def test_purchase_xml def test_void_xml @gateway.expects(:new_timestamp).returns('20090824160201') - valid_void_request_xml = <<-SRC - - your_merchant_id - your_account - 1 - 4321 - 1234 - 4132600f1dc70333b943fc292bd0ca7d8e722f6e - + valid_void_request_xml = <<~SRC + + your_merchant_id + your_account + 1 + 4321 + 1234 + 4132600f1dc70333b943fc292bd0ca7d8e722f6e + SRC assert_xml_equal valid_void_request_xml, @gateway.build_void_request('1;4321;1234', {}) @@ -237,28 +274,28 @@ def test_void_xml def test_verify_xml options = { - :order_id => '1' + order_id: '1' } @gateway.expects(:new_timestamp).returns('20181026114304') - valid_verify_request_xml = <<-SRC - - your_merchant_id - your_account - 1 - - 4263971921001307 - 0808 - Longbob Longsen - VISA - - - - - - - d53aebf1eaee4c3ff4c30f83f27b80ce99ba5644 - + valid_verify_request_xml = <<~SRC + + your_merchant_id + your_account + 1 + + 4263971921001307 + 0808 + Longbob Longsen + VISA + + + + + + + d53aebf1eaee4c3ff4c30f83f27b80ce99ba5644 + SRC assert_xml_equal valid_verify_request_xml, @gateway.build_verify_request(@credit_card, options) @@ -266,31 +303,31 @@ def test_verify_xml def test_auth_xml options = { - :order_id => '1' + order_id: '1' } @gateway.expects(:new_timestamp).returns('20090824160201') - valid_auth_request_xml = <<-SRC - - your_merchant_id - your_account - 1 - 100 - - 4263971921001307 - 0808 - Longbob Longsen - VISA - - - - - - - - 3499d7bc8dbacdcfba2286bd74916d026bae630f - + valid_auth_request_xml = <<~SRC + + your_merchant_id + your_account + 1 + 100 + + 4263971921001307 + 0808 + Longbob Longsen + VISA + + + + + + + + 3499d7bc8dbacdcfba2286bd74916d026bae630f + SRC assert_xml_equal valid_auth_request_xml, @gateway.build_purchase_or_authorization_request(:authorization, @amount, @credit_card, options) @@ -299,39 +336,39 @@ def test_auth_xml def test_refund_xml @gateway.expects(:new_timestamp).returns('20090824160201') - valid_refund_request_xml = <<-SRC - - your_merchant_id - your_account - 1 - 4321 - 1234 - 100 - - ef0a6c485452f3f94aff336fa90c6c62993056ca - + valid_refund_request_xml = <<~SRC + + your_merchant_id + your_account + 1 + 4321 + 1234 + 100 + + ef0a6c485452f3f94aff336fa90c6c62993056ca + SRC assert_xml_equal valid_refund_request_xml, @gateway.build_refund_request(@amount, '1;4321;1234', {}) end def test_refund_with_rebate_secret_xml - gateway = RealexGateway.new(:login => @login, :password => @password, :account => @account, :rebate_secret => @rebate_secret) + gateway = RealexGateway.new(login: @login, password: @password, account: @account, rebate_secret: @rebate_secret) gateway.expects(:new_timestamp).returns('20090824160201') - valid_refund_request_xml = <<-SRC - - your_merchant_id - your_account - 1 - 4321 - 1234 - 100 - f94ff2a7c125a8ad87e5683114ba1e384889240e - - ef0a6c485452f3f94aff336fa90c6c62993056ca - + valid_refund_request_xml = <<~SRC + + your_merchant_id + your_account + 1 + 4321 + 1234 + 100 + f94ff2a7c125a8ad87e5683114ba1e384889240e + + ef0a6c485452f3f94aff336fa90c6c62993056ca + SRC assert_xml_equal valid_refund_request_xml, gateway.build_refund_request(@amount, '1;4321;1234', {}) @@ -339,62 +376,62 @@ def test_refund_with_rebate_secret_xml def test_credit_xml options = { - :order_id => '1' + order_id: '1' } @gateway.expects(:new_timestamp).returns('20190717161006') - valid_credit_request_xml = <<-SRC - - your_merchant_id - your_account - 1 - 100 - - 4263971921001307 - 0808 - Longbob Longsen - VISA - - - - - - - - 73ff566dcfc3a73bebf1a2d387316162111f030e - + valid_credit_request_xml = <<~SRC + + your_merchant_id + your_account + 1 + 100 + + 4263971921001307 + 0808 + Longbob Longsen + VISA + + + + + + + + 73ff566dcfc3a73bebf1a2d387316162111f030e + SRC assert_xml_equal valid_credit_request_xml, @gateway.build_credit_request(@amount, @credit_card, options) end def test_credit_with_refund_secret_xml - gateway = RealexGateway.new(:login => @login, :password => @password, :account => @account, :refund_secret => @refund_secret) + gateway = RealexGateway.new(login: @login, password: @password, account: @account, refund_secret: @refund_secret) gateway.expects(:new_timestamp).returns('20190717161006') - valid_credit_request_xml = <<-SRC - - your_merchant_id - your_account - 1 - 100 - - 4263971921001307 - 0808 - Longbob Longsen - VISA - - - - - - - bbc192c6eac0132a039c23eae8550a22907c6796 - - 73ff566dcfc3a73bebf1a2d387316162111f030e - + valid_credit_request_xml = <<~SRC + + your_merchant_id + your_account + 1 + 100 + + 4263971921001307 + 0808 + Longbob Longsen + VISA + + + + + + + bbc192c6eac0132a039c23eae8550a22907c6796 + + 73ff566dcfc3a73bebf1a2d387316162111f030e + SRC assert_xml_equal valid_credit_request_xml, gateway.build_credit_request(@amount, @credit_card, @options) @@ -404,9 +441,9 @@ def test_auth_with_address @gateway.expects(:ssl_post).returns(successful_purchase_response) options = { - :order_id => '1', - :billing_address => @address, - :shipping_address => @address + order_id: '1', + billing_address: @address, + shipping_address: @address } @gateway.expects(:new_timestamp).returns('20090824160201') @@ -421,8 +458,8 @@ def test_zip_in_shipping_address @gateway.expects(:ssl_post).with(anything, regexp_matches(/28\|123<\/code>/)).returns(successful_purchase_response) options = { - :order_id => '1', - :shipping_address => @address + order_id: '1', + shipping_address: @address } @gateway.authorize(@amount, @credit_card, options) @@ -432,8 +469,8 @@ def test_zip_in_billing_address @gateway.expects(:ssl_post).with(anything, regexp_matches(/28\|123<\/code>/)).returns(successful_purchase_response) options = { - :order_id => '1', - :billing_address => @address + order_id: '1', + billing_address: @address } @gateway.authorize(@amount, @credit_card, options) @@ -452,7 +489,7 @@ def test_three_d_secure_1 cavv: '1234', eci: '1234', xid: '1234', - version: '1.0.2', + version: '1.0.2' } } @@ -467,38 +504,38 @@ def test_auth_xml_with_three_d_secure_1 cavv: '1234', eci: '1234', xid: '1234', - version: '1.0.2', + version: '1.0.2' } } @gateway.expects(:new_timestamp).returns('20090824160201') - valid_auth_request_xml = <<-SRC - - your_merchant_id - your_account - 1 - 100 - - 4263971921001307 - 0808 - Longbob Longsen - VISA - - - - - - - - 3499d7bc8dbacdcfba2286bd74916d026bae630f - - 1234 - 1234 - 1234 - 1.0.2 - - + valid_auth_request_xml = <<~SRC + + your_merchant_id + your_account + 1 + 100 + + 4263971921001307 + 0808 + Longbob Longsen + VISA + + + + + + + + 3499d7bc8dbacdcfba2286bd74916d026bae630f + + 1234 + 1234 + 1234 + 1 + + SRC assert_xml_equal valid_auth_request_xml, @gateway.build_purchase_or_authorization_request(:authorization, @amount, @credit_card, options) @@ -511,38 +548,38 @@ def test_auth_xml_with_three_d_secure_2 cavv: '1234', eci: '1234', ds_transaction_id: '1234', - version: '2.1.0', + version: '2.1.0' } } @gateway.expects(:new_timestamp).returns('20090824160201') - valid_auth_request_xml = <<-SRC - - your_merchant_id - your_account - 1 - 100 - - 4263971921001307 - 0808 - Longbob Longsen - VISA - - - - - - - - 3499d7bc8dbacdcfba2286bd74916d026bae630f - - 1234 - 1234 - 1234 - 2.1.0 - - + valid_auth_request_xml = <<~SRC + + your_merchant_id + your_account + 1 + 100 + + 4263971921001307 + 0808 + Longbob Longsen + VISA + + + + + + + + 3499d7bc8dbacdcfba2286bd74916d026bae630f + + 1234 + 1234 + 1234 + 2.1.0 + + SRC assert_xml_equal valid_auth_request_xml, @gateway.build_purchase_or_authorization_request(:authorization, @amount, @credit_card, options) @@ -551,125 +588,125 @@ def test_auth_xml_with_three_d_secure_2 private def successful_purchase_response - <<-RESPONSE - - your merchant id - account to use - order id from request - authcode received - 00 - [ test system ] message returned from system - realex payments reference - M - batch id for this transaction (if any) - - Issuing Bank Name - Issuing Bank Country - Issuing Bank Country Code - Issuing Bank Region - - - 89 - 9 - 9 - - 7384ae67....ac7d7d - 34e7....a77d -" + <<~RESPONSE + + your merchant id + account to use + order id from request + authcode received + 00 + [ test system ] message returned from system + realex payments reference + M + batch id for this transaction (if any) + + Issuing Bank Name + Issuing Bank Country + Issuing Bank Country Code + Issuing Bank Region + + + 89 + 9 + 9 + + 7384ae67....ac7d7d + 34e7....a77d + " RESPONSE end def unsuccessful_purchase_response - <<-RESPONSE - - your merchant id - account to use - order id from request - authcode received - 01 - [ test system ] message returned from system - realex payments reference - M - batch id for this transaction (if any) - - Issuing Bank Name - Issuing Bank Country - Issuing Bank Country Code - Issuing Bank Region - - - 89 - 9 - 9 - - 7384ae67....ac7d7d - 34e7....a77d -" + <<~RESPONSE + + your merchant id + account to use + order id from request + authcode received + 01 + [ test system ] message returned from system + realex payments reference + M + batch id for this transaction (if any) + + Issuing Bank Name + Issuing Bank Country + Issuing Bank Country Code + Issuing Bank Region + + + 89 + 9 + 9 + + 7384ae67....ac7d7d + 34e7....a77d + " RESPONSE end def malformed_unsuccessful_purchase_response - <<-RESPONSE - - your merchant id - account to use - order id from request - authcode received - 01 - [ test system ] This is & not awesome - realex payments reference - M - batch id for this transaction (if any) - - Issuing Bank Name - Issuing Bank Country - Issuing Bank Country Code - Issuing Bank Region - - - 89 - 9 - 9 - - 7384ae67....ac7d7d - 34e7....a77d -" + <<~RESPONSE + + your merchant id + account to use + order id from request + authcode received + 01 + [ test system ] This is & not awesome + realex payments reference + M + batch id for this transaction (if any) + + Issuing Bank Name + Issuing Bank Country + Issuing Bank Country Code + Issuing Bank Region + + + 89 + 9 + 9 + + 7384ae67....ac7d7d + 34e7....a77d + " RESPONSE end def successful_refund_response - <<-RESPONSE - - your merchant id - account to use - order id from request - authcode received - 00 - [ test system ] message returned from system - realex payments reference - M - batch id for this transaction (if any) - 7384ae67....ac7d7d - 34e7....a77d -" + <<~RESPONSE + + your merchant id + account to use + order id from request + authcode received + 00 + [ test system ] message returned from system + realex payments reference + M + batch id for this transaction (if any) + 7384ae67....ac7d7d + 34e7....a77d + " RESPONSE end def unsuccessful_refund_response - <<-RESPONSE - - your merchant id - account to use - order id from request - authcode received - 508 - [ test system ] You may only rebate up to 115% of the original amount. - realex payments reference - M - batch id for this transaction (if any) - 7384ae67....ac7d7d - 34e7....a77d -" + <<~RESPONSE + + your merchant id + account to use + order id from request + authcode received + 508 + [ test system ] You may only rebate up to 115% of the original amount. + realex payments reference + M + batch id for this transaction (if any) + 7384ae67....ac7d7d + 34e7....a77d + " RESPONSE end diff --git a/test/unit/gateways/redsys_sha256_test.rb b/test/unit/gateways/redsys_sha256_test.rb index 083e0791cda..9f7155f2cf4 100644 --- a/test/unit/gateways/redsys_sha256_test.rb +++ b/test/unit/gateways/redsys_sha256_test.rb @@ -6,9 +6,9 @@ class RedsysSHA256Test < Test::Unit::TestCase def setup Base.mode = :test @credentials = { - :login => '091952713', - :secret_key => 'QIK77hYl6UFcoCYFKcj+ZjJg8Q6I93Dx', - :signature_algorithm => 'sha256' + login: '091952713', + secret_key: 'QIK77hYl6UFcoCYFKcj+ZjJg8Q6I93Dx', + signature_algorithm: 'sha256' } @gateway = RedsysGateway.new(@credentials) @credit_card = credit_card('4548812049400004') @@ -22,17 +22,17 @@ def test_purchase_payload @credit_card.month = 9 @credit_card.year = 2017 @gateway.expects(:ssl_post).with(RedsysGateway.test_url, purchase_request, @headers).returns(successful_purchase_response) - @gateway.purchase(100, @credit_card, :order_id => '144742736014') + @gateway.purchase(100, @credit_card, order_id: '144742736014') end def test_purchase_payload_with_credit_card_token @gateway.expects(:ssl_post).with(RedsysGateway.test_url, purchase_request_with_credit_card_token, @headers).returns(successful_purchase_response) - @gateway.purchase(100, '3126bb8b80a79e66eb1ecc39e305288b60075f86', :order_id => '144742884282') + @gateway.purchase(100, '3126bb8b80a79e66eb1ecc39e305288b60075f86', order_id: '144742884282') end def test_successful_purchase @gateway.expects(:ssl_post).returns(successful_purchase_response) - res = @gateway.purchase(100, credit_card, :order_id => '144742736014') + res = @gateway.purchase(100, credit_card, order_id: '144742736014') assert_success res assert_equal 'Transaction Approved', res.message assert_equal '144742736014|100|978', res.authorization @@ -42,7 +42,7 @@ def test_successful_purchase # This one is being werid... def test_successful_purchase_requesting_credit_card_token @gateway.expects(:ssl_post).returns(successful_purchase_response_with_credit_card_token) - res = @gateway.purchase(100, 'e55e1d0ef338e281baf1d0b5b68be433260ddea0', :order_id => '144742955848') + res = @gateway.purchase(100, 'e55e1d0ef338e281baf1d0b5b68be433260ddea0', order_id: '144742955848') assert_success res assert_equal 'Transaction Approved', res.message assert_equal '144742955848|100|978', res.authorization @@ -52,7 +52,7 @@ def test_successful_purchase_requesting_credit_card_token def test_failed_purchase @gateway.expects(:ssl_post).returns(failed_purchase_response) - res = @gateway.purchase(100, credit_card, :order_id => '144743314659') + res = @gateway.purchase(100, credit_card, order_id: '144743314659') assert_failure res assert_equal 'SIS0093 ERROR', res.message end @@ -65,7 +65,7 @@ def test_purchase_without_order_id def test_error_purchase @gateway.expects(:ssl_post).returns(error_purchase_response) - res = @gateway.purchase(100, credit_card, :order_id => '123') + res = @gateway.purchase(100, credit_card, order_id: '123') assert_failure res assert_equal 'SIS0051 ERROR', res.message end @@ -104,7 +104,7 @@ def test_authorize ), anything ).returns(successful_authorize_response) - response = @gateway.authorize(100, credit_card, :order_id => '144743367273') + response = @gateway.authorize(100, credit_card, order_id: '144743367273') assert_success response end @@ -126,7 +126,7 @@ def test_successful_authorize_with_3ds def test_3ds_data_passed stub_comms(@gateway, :ssl_request) do @gateway.authorize(100, credit_card, { execute_threed: true, order_id: '156270437866', terminal: 12, sca_exemption: 'LWV' }) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/iniciaPeticion/, data) assert_match(/12<\/DS_MERCHANT_TERMINAL>/, data) assert_match(/\"threeDSInfo\":\"CardData\"/, data) @@ -134,10 +134,96 @@ def test_3ds_data_passed end.respond_with(successful_authorize_with_3ds_response) end + def test_3ds_data_with_special_characters_properly_escaped + @credit_card.first_name = 'Julián' + stub_comms(@gateway, :ssl_request) do + @gateway.authorize(100, @credit_card, { execute_threed: true, order_id: '156270437866', terminal: 12, sca_exemption: 'LWV', description: 'esta es la descripción' }) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(/iniciaPeticion/, data) + assert_match(/12<\/DS_MERCHANT_TERMINAL>/, data) + assert_match(/\"threeDSInfo\":\"CardData\"/, data) + assert_match(/LWV<\/DS_MERCHANT_EXCEP_SCA>/, data) + assert_match(/Juli%C3%A1n/, data) + assert_match(/descripci%C3%B3n/, data) + end.respond_with(successful_authorize_with_3ds_response) + end + + def test_3ds1_data_passed_as_mpi + stub_comms(@gateway, :ssl_request) do + @gateway.authorize(100, credit_card, { order_id: '156270437866', description: 'esta es la descripción', three_d_secure: { version: '1.0.2', xid: 'xid', ds_transaction_id: 'ds_transaction_id', cavv: 'cavv', eci: '02' } }) + end.check_request do |_method, _endpoint, encdata, _headers| + data = CGI.unescape(encdata) + assert_match(//, data) + assert_match(%r("TXID":"xid"), data) + assert_match(%r("CAVV":"cavv"), data) + assert_match(%r("ECI":"02"), data) + + assert_not_match(%r("authenticacionMethod"), data) + assert_not_match(%r("authenticacionType"), data) + assert_not_match(%r("authenticacionFlow"), data) + + assert_not_match(%r("protocolVersion":"2.1.0"), data) + assert_match(/descripción/, data) + end.respond_with(successful_authorize_with_3ds_response) + end + + def test_3ds2_data_passed_as_mpi + stub_comms(@gateway, :ssl_request) do + @gateway.authorize(100, credit_card, { order_id: '156270437866', description: 'esta es la descripción', three_d_secure: { version: '2.1.0', three_ds_server_trans_id: 'three_ds_server_trans_id', ds_transaction_id: 'ds_transaction_id', cavv: 'cavv', eci: '02' } }) + end.check_request do |_method, _endpoint, encdata, _headers| + data = CGI.unescape(encdata) + assert_match(//, data) + assert_match(%r("threeDSServerTransID":"three_ds_server_trans_id"), data) + assert_match(%r("dsTransID":"ds_transaction_id"), data) + assert_match(%r("authenticacionValue":"cavv"), data) + assert_match(%r("Eci":"02"), data) + + assert_not_match(%r("authenticacionMethod"), data) + assert_not_match(%r("authenticacionType"), data) + assert_not_match(%r("authenticacionFlow"), data) + + assert_match(%r("protocolVersion":"2.1.0"), data) + assert_match(/descripción/, data) + end.respond_with(successful_authorize_with_3ds_response) + end + + def test_3ds2_data_passed_as_mpi_with_optional_values + stub_comms(@gateway, :ssl_request) do + @gateway.authorize(100, credit_card, { order_id: '156270437866', description: 'esta es la descripción', three_d_secure: { version: '2.1.0', three_ds_server_trans_id: 'three_ds_server_trans_id', ds_transaction_id: 'ds_transaction_id', cavv: 'cavv', eci: '02' }, + authentication_method: '01', + authentication_type: 'anything', + authentication_flow: 'F' }) + end.check_request do |_method, _endpoint, encdata, _headers| + data = CGI.unescape(encdata) + assert_match(//, data) + assert_match(%r("threeDSServerTransID":"three_ds_server_trans_id"), data) + assert_match(%r("dsTransID":"ds_transaction_id"), data) + assert_match(%r("authenticacionValue":"cavv"), data) + assert_match(%r("Eci":"02"), data) + + assert_match(%r("authenticacionMethod":"01"), data) + assert_match(%r("authenticacionType":"anything"), data) + assert_match(%r("authenticacionFlow":"F"), data) + + assert_match(%r("protocolVersion":"2.1.0"), data) + assert_match(/descripción/, data) + end.respond_with(successful_authorize_with_3ds_response) + end + + def test_3ds2_data_as_mpi_with_special_characters_properly_escaped + @credit_card.first_name = 'Julián' + stub_comms(@gateway, :ssl_request) do + @gateway.authorize(100, @credit_card, { order_id: '156270437866', terminal: 12, description: 'esta es la descripción', three_d_secure: { version: '2.1.0', xid: 'xid', ds_transaction_id: 'ds_transaction_id', cavv: 'cavv' } }) + end.check_request do |_method, _endpoint, encdata, _headers| + assert_match(/Juli%C3%A1n/, encdata) + assert_match(%r(descripci%C3%B3n), encdata) + end.respond_with(successful_authorize_with_3ds_response) + end + def test_moto_flag_passed stub_comms(@gateway, :ssl_request) do @gateway.authorize(100, credit_card, { order_id: '156270437866', moto: true, metadata: { manual_entry: true } }) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/DS_MERCHANT_DIRECTPAYMENT%3Emoto%3C%2FDS_MERCHANT_DIRECTPAYMENT/, data) end.respond_with(successful_authorize_with_3ds_response) end @@ -145,7 +231,7 @@ def test_moto_flag_passed def test_moto_flag_not_passed_if_not_explicitly_requested stub_comms(@gateway, :ssl_request) do @gateway.authorize(100, credit_card, { order_id: '156270437866', metadata: { manual_entry: true } }) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| refute_match(/DS_MERCHANT_DIRECTPAYMENT%3Emoto%3C%2FDS_MERCHANT_DIRECTPAYMENT/, data) end.respond_with(successful_authorize_with_3ds_response) end @@ -153,7 +239,7 @@ def test_moto_flag_not_passed_if_not_explicitly_requested def test_bad_order_id_format stub_comms(@gateway, :ssl_request) do @gateway.authorize(100, credit_card, order_id: 'Una#cce-ptable44Format') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/MERCHANT_ORDER%3E\d\d\d\dUnaccept%3C/, data) end.respond_with(successful_authorize_response) end @@ -161,7 +247,7 @@ def test_bad_order_id_format def test_order_id_numeric_start_but_too_long stub_comms(@gateway, :ssl_request) do @gateway.authorize(100, credit_card, order_id: '1234ThisIs]FineButTooLong') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/MERCHANT_ORDER%3E1234ThisIsFi%3C/, data) end.respond_with(successful_authorize_response) end @@ -199,25 +285,25 @@ def test_override_currency includes(CGI.escape('840')), anything ).returns(successful_purchase_response) - @gateway.authorize(100, credit_card, :order_id => '1001', :currency => 'USD') + @gateway.authorize(100, credit_card, order_id: '1001', currency: 'USD') end def test_successful_verify @gateway.expects(:ssl_post).times(2).returns(successful_authorize_response).then.returns(successful_void_response) - response = @gateway.verify(credit_card, :order_id => '144743367273') + response = @gateway.verify(credit_card, order_id: '144743367273') assert_success response end def test_successful_verify_with_failed_void @gateway.expects(:ssl_post).times(2).returns(successful_authorize_response).then.returns(failed_void_response) - response = @gateway.verify(credit_card, :order_id => '144743367273') + response = @gateway.verify(credit_card, order_id: '144743367273') assert_success response assert_equal 'Transaction Approved', response.message end def test_unsuccessful_verify @gateway.expects(:ssl_post).returns(failed_authorize_response) - response = @gateway.verify(credit_card, :order_id => '141278225678') + response = @gateway.verify(credit_card, order_id: '141278225678') assert_failure response assert_equal 'SIS0093 ERROR', response.message end @@ -237,7 +323,7 @@ def test_supported_countries end def test_supported_cardtypes - assert_equal [:visa, :master, :american_express, :jcb, :diners_club], RedsysGateway.supported_cardtypes + assert_equal %i[visa master american_express jcb diners_club unionpay], RedsysGateway.supported_cardtypes end def test_using_test_mode @@ -248,10 +334,10 @@ def test_using_test_mode def test_overriding_options Base.mode = :production gw = RedsysGateway.new( - :terminal => 1, - :login => '1234', - :secret_key => '12345', - :test => true + terminal: 1, + login: '1234', + secret_key: '12345', + test: true ) assert gw.test? assert_equal RedsysGateway.test_url, gw.send(:url) @@ -260,9 +346,9 @@ def test_overriding_options def test_production_mode Base.mode = :production gw = RedsysGateway.new( - :terminal => 1, - :login => '1234', - :secret_key => '12345' + terminal: 1, + login: '1234', + secret_key: '12345' ) assert !gw.test? assert_equal RedsysGateway.live_url, gw.send(:url) @@ -276,6 +362,10 @@ def test_failed_transaction_transcript_scrubbing assert_equal failed_transaction_post_scrubbed, @gateway.scrub(failed_transaction_pre_scrubbed) end + def test_failed_3ds_transaction_transcript_scrubbing + assert_equal failed_3ds_transaction_post_scrubbed, @gateway.scrub(failed_3ds_transaction_pre_scrubbed) + end + def test_nil_cvv_transcript_scrubbing assert_equal nil_cvv_post_scrubbed, @gateway.scrub(nil_cvv_pre_scrubbed) end @@ -385,6 +475,18 @@ def failed_transaction_post_scrubbed ) end + def failed_3ds_transaction_pre_scrubbed + %q( +<RETORNOXML><CODIGO>SIS0571</CODIGO><RECIBIDO>\n <REQUEST><DATOSENTRADA><DS_Version>0.1</DS_Version><DS_MERCHANT_CURRENCY>978</DS_MERCHANT_CURRENCY><DS_MERCHANT_AMOUNT>100</DS_MERCHANT_AMOUNT><DS_MERCHANT_ORDER>82973d604ba1</DS_MERCHANT_ORDER><DS_MERCHANT_TRANSACTIONTYPE>1</DS_MERCHANT_TRANSACTIONTYPE><DS_MERCHANT_PRODUCTDESCRIPTION/><DS_MERCHANT_TERMINAL>12</DS_MERCHANT_TERMINAL><DS_MERCHANT_MERCHANTCODE>091952713</DS_MERCHANT_MERCHANTCODE><DS_MERCHANT_TITULAR>Jane Doe</DS_MERCHANT_TITULAR><DS_MERCHANT_PAN>4548812049400004</DS_MERCHANT_PAN><DS_MERCHANT_EXPIRYDATE>2012</DS_MERCHANT_EXPIRYDATE><DS_MERCHANT_CVV2>123</DS_MERCHANT_CVV2><DS_MERCHANT_EMV3DS>{"threeDSInfo":"AuthenticationData","browserAcceptHeader":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3","browserUserAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"}</DS_MERCHANT_EMV3DS></DATOSENTRADA><DS_SIGNATUREVERSION>HMAC_SHA256_V1</DS_SIGNATUREVERSION><DS_SIGNATURE>ips3TqR6upMAEbC0D6vmzV9tldU5224MSR63dpWPBT0=</DS_SIGNATURE></REQUEST>\n </RECIBIDO></RETORNOXML> + ) + end + + def failed_3ds_transaction_post_scrubbed + %q( +<RETORNOXML><CODIGO>SIS0571</CODIGO><RECIBIDO>\n <REQUEST><DATOSENTRADA><DS_Version>0.1</DS_Version><DS_MERCHANT_CURRENCY>978</DS_MERCHANT_CURRENCY><DS_MERCHANT_AMOUNT>100</DS_MERCHANT_AMOUNT><DS_MERCHANT_ORDER>82973d604ba1</DS_MERCHANT_ORDER><DS_MERCHANT_TRANSACTIONTYPE>1</DS_MERCHANT_TRANSACTIONTYPE><DS_MERCHANT_PRODUCTDESCRIPTION/><DS_MERCHANT_TERMINAL>12</DS_MERCHANT_TERMINAL><DS_MERCHANT_MERCHANTCODE>091952713</DS_MERCHANT_MERCHANTCODE><DS_MERCHANT_TITULAR>Jane Doe</DS_MERCHANT_TITULAR><DS_MERCHANT_PAN>[FILTERED]</DS_MERCHANT_PAN><DS_MERCHANT_EXPIRYDATE>2012</DS_MERCHANT_EXPIRYDATE><DS_MERCHANT_CVV2>[FILTERED]</DS_MERCHANT_CVV2><DS_MERCHANT_EMV3DS>{"threeDSInfo":"AuthenticationData","browserAcceptHeader":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3","browserUserAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"}</DS_MERCHANT_EMV3DS></DATOSENTRADA><DS_SIGNATUREVERSION>HMAC_SHA256_V1</DS_SIGNATUREVERSION><DS_SIGNATURE>ips3TqR6upMAEbC0D6vmzV9tldU5224MSR63dpWPBT0=</DS_SIGNATURE></REQUEST>\n </RECIBIDO></RETORNOXML> + ) + end + def nil_cvv_pre_scrubbed <<-PRE_SCRUBBED entrada=%3CDATOSENTRADA%3E%0A++%3CDS_Version%3E0.1%3C%2FDS_Version%3E%0A++%3CDS_MERCHANT_CURRENCY%3E978%3C%2FDS_MERCHANT_CURRENCY%3E%0A++%3CDS_MERCHANT_AMOUNT%3E100%3C%2FDS_MERCHANT_AMOUNT%3E%0A++%3CDS_MERCHANT_ORDER%3E135214014098%3C%2FDS_MERCHANT_ORDER%3E%0A++%3CDS_MERCHANT_TRANSACTIONTYPE%3EA%3C%2FDS_MERCHANT_TRANSACTIONTYPE%3E%0A++%3CDS_MERCHANT_TERMINAL%3E1%3C%2FDS_MERCHANT_TERMINAL%3E%0A++%3CDS_MERCHANT_MERCHANTCODE%3E91952713%3C%2FDS_MERCHANT_MERCHANTCODE%3E%0A++%3CDS_MERCHANT_MERCHANTSIGNATURE%3E39589b03cdd3c525885cdb3b3761e2fb7a8be9ee%3C%2FDS_MERCHANT_MERCHANTSIGNATURE%3E%0A++%3CDS_MERCHANT_TITULAR%3ELongbob+Longsen%3C%2FDS_MERCHANT_TITULAR%3E%0A++%3CDS_MERCHANT_PAN%3E4548812049400004%3C%2FDS_MERCHANT_PAN%3E%0A++%3CDS_MERCHANT_EXPIRYDATE%3E1309%3C%2FDS_MERCHANT_EXPIRYDATE%3E%0A++%3CDS_MERCHANT_CVV2%2F%3E%0A%3C%2FDATOSENTRADA%3E%0A diff --git a/test/unit/gateways/redsys_test.rb b/test/unit/gateways/redsys_test.rb index 878c01a9753..3cbdce4c2e2 100644 --- a/test/unit/gateways/redsys_test.rb +++ b/test/unit/gateways/redsys_test.rb @@ -6,9 +6,9 @@ class RedsysTest < Test::Unit::TestCase def setup Base.mode = :test @credentials = { - :login => '091952713', - :secret_key => 'qwertyasdf0123456789', - :terminal => '1', + login: '091952713', + secret_key: 'qwertyasdf0123456789', + terminal: '1' } @gateway = RedsysGateway.new(@credentials) @headers = { @@ -20,12 +20,12 @@ def setup def test_purchase_payload @gateway.expects(:ssl_post).with(RedsysGateway.test_url, purchase_request, @headers).returns(successful_purchase_response) - @gateway.purchase(123, credit_card, :order_id => '1001') + @gateway.purchase(123, credit_card, order_id: '1001') end def test_purchase_payload_with_credit_card_token @gateway.expects(:ssl_post).with(RedsysGateway.test_url, purchase_request_with_credit_card_token, @headers).returns(successful_purchase_response) - @gateway.purchase(123, '77bff3a969d6f97b2ec815448cdcff453971f573', :order_id => '1001') + @gateway.purchase(123, '77bff3a969d6f97b2ec815448cdcff453971f573', order_id: '1001') end def test_successful_purchase @@ -47,6 +47,35 @@ def test_successful_purchase_requesting_credit_card_token assert_equal '77bff3a969d6f97b2ec815448cdcff453971f573', res.params['ds_merchant_identifier'] end + def test_successful_purchase_with_stored_credentials + @gateway.expects(:ssl_post).returns(successful_purchase_initial_stored_credential_response) + initial_options = @options.merge( + stored_credential: { + initial_transaction: true, + reason_type: 'recurring' + } + ) + initial_res = @gateway.purchase(123, credit_card, initial_options) + assert_success initial_res + assert_equal 'Transaction Approved', initial_res.message + assert_equal '2012102122020', initial_res.params['ds_merchant_cof_txnid'] + network_transaction_id = initial_res.params['Ds_Merchant_Cof_Txnid'] + + @gateway.expects(:ssl_post).returns(successful_purchase_used_stored_credential_response) + used_options = { + order_id: '1002', + stored_credential: { + initial_transaction: false, + reason_type: 'unscheduled', + network_transaction_id: network_transaction_id + } + } + res = @gateway.purchase(123, credit_card, used_options) + assert_success res + assert_equal 'Transaction Approved', res.message + assert_equal '561350', res.params['ds_authorisationcode'] + end + def test_failed_purchase @gateway.expects(:ssl_post).returns(failed_purchase_response) res = @gateway.purchase(123, credit_card, @options) @@ -115,7 +144,7 @@ def test_authorize_without_order_id def test_bad_order_id_format stub_comms(@gateway, :ssl_request) do @gateway.authorize(123, credit_card, order_id: 'Una#cce-ptable44Format') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/MERCHANT_ORDER%3E\d\d\d\dUnaccept%3C/, data) end.respond_with(successful_authorize_response) end @@ -123,7 +152,7 @@ def test_bad_order_id_format def test_order_id_numeric_start_but_too_long stub_comms(@gateway, :ssl_request) do @gateway.authorize(123, credit_card, order_id: '1234ThisIs]FineButTooLong') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/MERCHANT_ORDER%3E1234ThisIsFi%3C/, data) end.respond_with(successful_authorize_response) end @@ -161,7 +190,7 @@ def test_override_currency includes(CGI.escape('840')), anything ).returns(successful_purchase_response) - @gateway.authorize(123, credit_card, :order_id => '1001', :currency => 'USD') + @gateway.authorize(123, credit_card, order_id: '1001', currency: 'USD') end def test_successful_verify @@ -199,7 +228,7 @@ def test_supported_countries end def test_supported_cardtypes - assert_equal [:visa, :master, :american_express, :jcb, :diners_club], RedsysGateway.supported_cardtypes + assert_equal %i[visa master american_express jcb diners_club unionpay], RedsysGateway.supported_cardtypes end def test_using_test_mode @@ -210,10 +239,10 @@ def test_using_test_mode def test_overriding_options Base.mode = :production gw = RedsysGateway.new( - :terminal => 1, - :login => '1234', - :secret_key => '12345', - :test => true + terminal: 1, + login: '1234', + secret_key: '12345', + test: true ) assert gw.test? assert_equal RedsysGateway.test_url, gw.send(:url) @@ -222,9 +251,9 @@ def test_overriding_options def test_production_mode Base.mode = :production gw = RedsysGateway.new( - :terminal => 1, - :login => '1234', - :secret_key => '12345' + terminal: 1, + login: '1234', + secret_key: '12345' ) assert !gw.test? assert_equal RedsysGateway.live_url, gw.send(:url) @@ -271,6 +300,14 @@ def successful_purchase_response_with_credit_card_token "00.1100978141661632759C65E11D80534B432042ABAA47DCA54F5AFEC23ED32723468820000341129A0177bff3a969d6f97b2ec815448cdcff453971f573724" end + def successful_purchase_initial_stored_credential_response + "00.11239781001989D357BCC9EF0962A456C51422C4FAF4BF4399F9195271310000561350A01724201210212202013" + end + + def successful_purchase_used_stored_credential_response + "00.11239781001989D357BCC9EF0962A456C51422C4FAF4BF4399F9195271310000561350A0172413" + end + def failed_purchase_response "00.1123978100280D5D1BE64777946519C4E633EE5498C6187747B919527131190561350A01724" end diff --git a/test/unit/gateways/s5_test.rb b/test/unit/gateways/s5_test.rb index 5a858c1edf9..aebbd977634 100644 --- a/test/unit/gateways/s5_test.rb +++ b/test/unit/gateways/s5_test.rb @@ -34,7 +34,7 @@ def test_successful_purchase def test_successful_purchase_with_recurring_flag response = stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(recurring: true)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/Recurrence.*REPEATED/, data) end.respond_with(successful_purchase_response) diff --git a/test/unit/gateways/safe_charge_test.rb b/test/unit/gateways/safe_charge_test.rb index 94d310907c6..cc0cd65add2 100644 --- a/test/unit/gateways/safe_charge_test.rb +++ b/test/unit/gateways/safe_charge_test.rb @@ -8,18 +8,46 @@ def setup @credit_card = credit_card @three_ds_enrolled_card = credit_card('4012 0010 3749 0014') @amount = 100 + @network_token_credit_card = ActiveMerchant::Billing::NetworkTokenizationCreditCard.new({ + brand: 'Visa', + payment_cryptogram: 'AgAAAAAAAIR8CQrXcIhbQAAAAAA', + number: '4012001037490014', + source: :network_token, + month: '12', + year: 2020 + }) @options = { order_id: '1', billing_address: address, description: 'Store Purchase' } + @merchant_options = @options.merge( merchant_descriptor: 'Test Descriptor', merchant_phone_number: '(555)555-5555', merchant_name: 'Test Merchant' ) + @three_ds_options = @options.merge(three_d_secure: true) + + @mpi_options_3ds1 = @options.merge({ + three_d_secure: { + eci: '05', + cavv: 'Vk83Y2t0cHRzRFZzRlZlR0JIQXo=', + xid: '00000000000000000501' + } + }) + + @mpi_options_3ds2 = @options.merge({ + three_d_secure: { + version: '2.1.0', + eci: '05', + cavv: 'Vk83Y2t0cHRzRFZzRlZlR0JIQXo=', + xid: '00000000000000000501', + ds_transaction_id: 'c5b808e7-1de1-4069-a17b-f70d3b3b1645' + } + }) end def test_successful_purchase @@ -37,7 +65,7 @@ def test_successful_purchase def test_successful_purchase_with_merchant_options purchase = stub_comms do @gateway.purchase(@amount, @credit_card, @merchant_options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/sg_Descriptor/, data) assert_match(/sg_MerchantPhoneNumber/, data) assert_match(/sg_MerchantName/, data) @@ -53,7 +81,7 @@ def test_successful_purchase_with_merchant_options def test_successful_purchase_with_truthy_stored_credential_mode purchase = stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(stored_credential_mode: true)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/sg_StoredCredentialMode=1/, data) end.respond_with(successful_purchase_response) @@ -67,7 +95,7 @@ def test_successful_purchase_with_truthy_stored_credential_mode def test_successful_purchase_with_falsey_stored_credential_mode purchase = stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(stored_credential_mode: false)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/sg_StoredCredentialMode=0/, data) end.respond_with(successful_purchase_response) @@ -214,7 +242,7 @@ def test_scrub def test_3ds_response purchase = stub_comms do @gateway.purchase(@amount, @three_ds_enrolled_card, @three_ds_options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/Sale3D/, data) assert_match(/sg_APIType/, data) end.respond_with(successful_3ds_purchase_response) @@ -225,6 +253,64 @@ def test_3ds_response assert_equal 'https://pit.3dsecure.net/VbVTestSuiteService/pit1/acsService/paReq?summary=MjRlZGYwY2EtZTk5Zi00NDJjLTljOTAtNWUxZmRhMjEwODg3', purchase.params['acsurl'] end + def test_mpi_response_fail + purchase = stub_comms do + @gateway.purchase(@amount, @three_ds_enrolled_card, @mpi_options_3ds1) + end.check_request do |_, data, _| + assert_match(/sg_ECI/, data) + assert_match(/sg_CAVV/, data) + assert_match(/sg_IsExternalMPI/, data) + end.respond_with(failed_mpi_response) + + assert_failure purchase + assert_equal 'DECLINED', purchase.params['status'] + end + + def test_mpi_response_success_3ds1 + purchase = stub_comms do + @gateway.purchase(@amount, @three_ds_enrolled_card, @mpi_options_3ds1) + end.check_request do |_, data, _| + assert_match(/sg_ECI/, data) + assert_match(/sg_CAVV/, data) + assert_match(/sg_IsExternalMPI/, data) + assert_match(/sg_threeDSProtocolVersion=1/, data) + assert_match(/sg_Xid/, data) + end.respond_with(successful_mpi_response) + + assert_success purchase + assert_equal 'APPROVED', purchase.params['status'] + end + + def test_mpi_response_success_3ds2 + purchase = stub_comms do + @gateway.purchase(@amount, @three_ds_enrolled_card, @mpi_options_3ds2) + end.check_request do |_, data, _| + assert_match(/sg_ECI/, data) + assert_match(/sg_CAVV/, data) + assert_match(/sg_IsExternalMPI/, data) + assert_match(/sg_dsTransID/, data) + assert_match(/sg_threeDSProtocolVersion=2/, data) + refute_match(/sg_xid/, data) + end.respond_with(successful_mpi_response) + + assert_success purchase + assert_equal 'APPROVED', purchase.params['status'] + end + + def test_network_tokenization_success + purchase = stub_comms do + @gateway.purchase(@amount, @network_token_credit_card, @mpi_options_3ds2) + end.check_request do |_, data, _| + assert_match(/sg_CAVV/, data) + assert_match(/sg_ECI/, data) + assert_match(/sg_IsExternalMPI/, data) + assert_match(/sg_CardNumber/, data) + end.respond_with(successful_network_token_response) + + assert_success purchase + assert_equal 'APPROVED', purchase.params['status'] + end + private def pre_scrubbed @@ -360,4 +446,76 @@ def successful_3ds_purchase_response 4.1.0SpreedlyManTestTRX98bd80c8c9534088311153ad6a67d108101510108310APPROVED00ZQBpAFAAMwBTAEcAMQBZAHcASQA4ADoAPQBlACQAZAB3ACMAWwAyAFoAWQBLAFUAPwBTAHYAKQAnAHQAUAA2AHYAYwAoAG0ARgBNAEEAcAAlAGEAMwA=YeJxVUdtuwjAM/ZWK95GYgijIjVTWaUNTGdqQ4DUKFq2gF9J0A75+SVcuixTF59g+sY5xlWqi+ItUo0lgQnUtd+Rl27BXyScYAQce+MB7ApfRJx0FfpOus7IQ0Of9AbIrtK1apbIwAqU6zuYLMQSY8ABZBzEnPY8FfzhjGCH7o7GQOYlIq9J4K6qNd5VD1mZQlU1h9FkEQ47sCrDRB5EaU00ZO5RKHtKyth2ORXYfaNm4qLYqp2wrkjj6ud8XSFbRKYl3F/uGyFwFbqUhMeAwBvC5B6Opz6c+IGt5lLn73hlgR+kAVu6PqMu4xCOB1l1NhTqLydg6ckNIp6osyFZYJ28xsvvAz2/OT2WsRa+bdf2+X6cXtd9oHxZNPks+ojB0DrcFTi2zrkDAJ62cA8icBOuWx7oF2+jf4n8B000000000000715https://pit.3dsecure.net/VbVTestSuiteService/pit1/acsService/paReq?summary=MjRlZGYwY2EtZTk5Zi00NDJjLTljOTAtNWUxZmRhMjEwODg3MDAwMDAwMDAwMDE1MTAxMDgzMTA=19Visa Production Support Client Bid 1usrDNDlh6XR8R6CVdGQyqDkZzdqE0=10Debit01EUR1EUR ) end + + def successful_mpi_response + %( + 4.1.0SpreedlyTestTRX27822c1132eba4c731ebe24b6190646f1110000000009330260APPROVED11144700UQBzAFEAdABvAG0ATgA5AEwAagBHAGwAPwA7AF0ANgA1AD4AfABOADUAdAA/AD4AZQA3AEcAXQBnAGgAQQA4AG4APABNACUARABFADgAMQBrAFIAMwA=5Vk83Y2t0cHRzRFZzRlZlR0JIQXo=00000000000000000501c5b808e7-1de1-4069-a17b-f70d3b3b164519Visa Production Support Client Bid 1gbrDNDlh6XR8R6CVdGQyqDkZzdqE0=0Debit01EUR1EURAccept + ) + end + + def successful_network_token_response + %( + + 4.1.0 + SpreedlyTestTRX + 27822c1132eba4c731ebe24b6190646f + 1110000000009330260 + APPROVED + + + + + + + 0 + 0 + UQBzAFEAdABvAG0ATgA5AEwAagBHAGwAPwA7AF0ANgA1AD4AfABOADUAdAA/AD4AZQA3AEcAXQBnAGgAQQA4AG4APABNACUARABFADgAMQBrAFIAMwA= + + + + + 5 + Vk83Y2t0cHRzRFZzRlZlR0JIQXo= + + 00000000000000000501 + + + + + c5b808e7-1de1-4069-a17b-f70d3b3b1645 + + + 19 + Visa Production Support Client Bid 1 + gb + + + + rDNDlh6XR8R6CVdGQyqDkZzdqE0= + + + 0 + Debit + + + + 0 + + 1 + EUR + 1 + EUR + + + + + + ) + end + + def failed_mpi_response + %( + 4.1.0SpreedlyTestTRX040b37ca7af949daeb38a8cff0a16f1b1110000000009330310DECLINEDDecline-10UQBLAEcAdABRAE8AWABPADUANgBCADAAcABGAEUANwArADgAewBTACcAcwAlAF8APABQAEEAXgBVACUAYQBLACMALwBWAEUANQApAD4ARQBqADsAMwA=5Vk83Y2t0cHRzRFZzRlZlR0JIQXo=00000000000000000501c5b808e7-1de1-4069-a17b-f70d3b3b164519GyueFkuQqW+UL38d57fuA5/RqfQ=001EUR1EURAccept + ) + end end diff --git a/test/unit/gateways/sage_pay_test.rb b/test/unit/gateways/sage_pay_test.rb index 4341cafff4f..2a258e4c043 100644 --- a/test/unit/gateways/sage_pay_test.rb +++ b/test/unit/gateways/sage_pay_test.rb @@ -6,23 +6,23 @@ class SagePayTest < Test::Unit::TestCase def setup @gateway = SagePayGateway.new(login: 'X') - @credit_card = credit_card('4242424242424242', :brand => 'visa') - @electron_credit_card = credit_card('4245190000000000', :brand => 'visa') + @credit_card = credit_card('4242424242424242', brand: 'visa') + @electron_credit_card = credit_card('4245190000000000', brand: 'visa') @options = { - :billing_address => { - :name => 'Tekin Suleyman', - :address1 => 'Flat 10 Lapwing Court', - :address2 => 'West Didsbury', - :city => 'Manchester', - :county => 'Greater Manchester', - :country => 'GB', - :zip => 'M20 2PS' + billing_address: { + name: 'Tekin Suleyman', + address1: 'Flat 10 Lapwing Court', + address2: 'West Didsbury', + city: 'Manchester', + county: 'Greater Manchester', + country: 'GB', + zip: 'M20 2PS' }, - :order_id => '1', - :description => 'Store purchase', - :ip => '86.150.65.37', - :email => 'tekin@tekin.co.uk', - :phone => '0161 123 4567' + order_id: '1', + description: 'Store purchase', + ip: '86.150.65.37', + email: 'tekin@tekin.co.uk', + phone: '0161 123 4567' } @amount = 100 end @@ -92,18 +92,18 @@ def test_not_matched_cvv_result end def test_dont_send_fractional_amount_for_chinese_yen - @amount = 100_00 # 100 YEN + @amount = 100_00 # 100 YEN @options[:currency] = 'JPY' - @gateway.expects(:add_pair).with({}, :Amount, '100', :required => true) - @gateway.expects(:add_pair).with({}, :Currency, 'JPY', :required => true) + @gateway.expects(:add_pair).with({}, :Amount, '100', required: true) + @gateway.expects(:add_pair).with({}, :Currency, 'JPY', required: true) @gateway.send(:add_amount, {}, @amount, @options) end def test_send_fractional_amount_for_british_pounds - @gateway.expects(:add_pair).with({}, :Amount, '1.00', :required => true) - @gateway.expects(:add_pair).with({}, :Currency, 'GBP', :required => true) + @gateway.expects(:add_pair).with({}, :Amount, '1.00', required: true) + @gateway.expects(:add_pair).with({}, :Currency, 'GBP', required: true) @gateway.send(:add_amount, {}, @amount, @options) end @@ -111,7 +111,7 @@ def test_send_fractional_amount_for_british_pounds def test_paypal_callback_url_is_submitted stub_comms(@gateway, :ssl_request) do purchase_with_options(paypal_callback_url: 'callback.com') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/PayPalCallbackURL=callback\.com/, data) end.respond_with(successful_purchase_response) end @@ -119,7 +119,7 @@ def test_paypal_callback_url_is_submitted def test_basket_is_submitted stub_comms(@gateway, :ssl_request) do purchase_with_options(basket: 'A1.2 Basket section') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/Basket=A1\.2\+Basket\+section/, data) end.respond_with(successful_purchase_response) end @@ -127,7 +127,7 @@ def test_basket_is_submitted def test_gift_aid_payment_is_submitted stub_comms(@gateway, :ssl_request) do purchase_with_options(gift_aid_payment: 1) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/GiftAidPayment=1/, data) end.respond_with(successful_purchase_response) end @@ -135,7 +135,7 @@ def test_gift_aid_payment_is_submitted def test_apply_avscv2_is_submitted stub_comms(@gateway, :ssl_request) do purchase_with_options(apply_avscv2: 1) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/ApplyAVSCV2=1/, data) end.respond_with(successful_purchase_response) end @@ -143,7 +143,7 @@ def test_apply_avscv2_is_submitted def test_disable_3d_security_flag_is_submitted stub_comms(@gateway, :ssl_request) do purchase_with_options(apply_3d_secure: 1) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/Apply3DSecure=1/, data) end.respond_with(successful_purchase_response) end @@ -151,7 +151,7 @@ def test_disable_3d_security_flag_is_submitted def test_account_type_is_submitted stub_comms(@gateway, :ssl_request) do purchase_with_options(account_type: 'M') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/AccountType=M/, data) end.respond_with(successful_purchase_response) end @@ -159,7 +159,7 @@ def test_account_type_is_submitted def test_billing_agreement_is_submitted stub_comms(@gateway, :ssl_request) do purchase_with_options(billing_agreement: 1) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/BillingAgreement=1/, data) end.respond_with(successful_purchase_response) end @@ -167,7 +167,7 @@ def test_billing_agreement_is_submitted def test_store_token_is_submitted stub_comms(@gateway, :ssl_request) do purchase_with_options(store: true) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/CreateToken=1/, data) end.respond_with(successful_purchase_response) end @@ -175,7 +175,7 @@ def test_store_token_is_submitted def test_basket_xml_is_submitted stub_comms(@gateway, :ssl_request) do purchase_with_options(basket_xml: 'A1.3 BasketXML section') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/BasketXML=A1\.3\+BasketXML\+section/, data) end.respond_with(successful_purchase_response) end @@ -183,7 +183,7 @@ def test_basket_xml_is_submitted def test_customer_xml_is_submitted stub_comms(@gateway, :ssl_request) do purchase_with_options(customer_xml: 'A1.4 CustomerXML section') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/CustomerXML=A1\.4\+CustomerXML\+section/, data) end.respond_with(successful_purchase_response) end @@ -191,7 +191,7 @@ def test_customer_xml_is_submitted def test_surcharge_xml_is_submitted stub_comms(@gateway, :ssl_request) do purchase_with_options(surcharge_xml: 'A1.1 SurchargeXML section') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/SurchargeXML=A1\.1\+SurchargeXML\+section/, data) end.respond_with(successful_purchase_response) end @@ -199,7 +199,7 @@ def test_surcharge_xml_is_submitted def test_vendor_data_is_submitted stub_comms(@gateway, :ssl_request) do purchase_with_options(vendor_data: 'any data') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/VendorData=any\+data/, data) end.respond_with(successful_purchase_response) end @@ -207,7 +207,7 @@ def test_vendor_data_is_submitted def test_language_is_submitted stub_comms(@gateway, :ssl_request) do purchase_with_options(language: 'FR') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/Language=FR/, data) end.respond_with(successful_purchase_response) end @@ -215,7 +215,7 @@ def test_language_is_submitted def test_website_is_submitted stub_comms(@gateway, :ssl_request) do purchase_with_options(website: 'transaction-origin.com') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/Website=transaction-origin\.com/, data) end.respond_with(successful_purchase_response) end @@ -225,7 +225,7 @@ def test_FIxxxx_optional_fields_are_submitted purchase_with_options(recipient_account_number: '1234567890', recipient_surname: 'Withnail', recipient_postcode: 'AB11AB', recipient_dob: '19701223') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/FIRecipientAcctNumber=1234567890/, data) assert_match(/FIRecipientSurname=Withnail/, data) assert_match(/FIRecipientPostcode=AB11AB/, data) @@ -237,7 +237,7 @@ def test_description_is_truncated huge_description = 'SagePay transactions fail if the déscription is more than 100 characters. Therefore, we truncate it to 100 characters.' + ' Lots more text ' * 1000 stub_comms(@gateway, :ssl_request) do purchase_with_options(description: huge_description) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/&Description=SagePay\+transactions\+fail\+if\+the\+d%C3%A9scription\+is\+more\+than\+100\+characters.\+Therefore%2C\+we\+trunc&/, data) end.respond_with(successful_purchase_response) end @@ -247,7 +247,7 @@ def test_protocol_version_is_honoured stub_comms(gateway, :ssl_request) do gateway.purchase(@amount, @credit_card, @options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/VPSProtocol=2.23/, data) end.respond_with(successful_purchase_response) end @@ -256,7 +256,7 @@ def test_referrer_id_is_added_to_post_data_parameters ActiveMerchant::Billing::SagePayGateway.application_id = '00000000-0000-0000-0000-000000000001' stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert data.include?('ReferrerID=00000000-0000-0000-0000-000000000001') end.respond_with(successful_purchase_response) ensure @@ -266,7 +266,7 @@ def test_referrer_id_is_added_to_post_data_parameters def test_successful_store response = stub_comms(@gateway, :ssl_request) do @gateway.store(@credit_card) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/TxType=TOKEN/, data) end.respond_with(successful_purchase_response) @@ -318,8 +318,7 @@ def test_successful_authorization_and_capture_and_refund refund = stub_comms do @gateway.refund(@amount, capture.authorization, order_id: generate_unique_id, - description: 'Refund txn' - ) + description: 'Refund txn') end.respond_with(successful_refund_response) assert_success refund end @@ -327,7 +326,7 @@ def test_successful_authorization_and_capture_and_refund def test_repeat_purchase_with_reference_token stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, '1455548a8d178beecd88fe6a285f50ff;{0D2ACAF0-FA64-6DFF-3869-7ADDDC1E0474};15353766;BS231FNE14;purchase', @options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/RelatedVPSTxId=%7B0D2ACAF0-FA64-6DFF-3869-7ADDDC1E0474%/, data) assert_match(/TxType=REPEAT/, data) end.respond_with(successful_purchase_response) @@ -340,156 +339,156 @@ def purchase_with_options(optional) end def successful_purchase_response - <<-RESP -VPSProtocol=2.23 -Status=OK -StatusDetail=0000 : The Authorisation was Successful. -VPSTxId=B8AE1CF6-9DEF-C876-1BB4-9B382E6CE520 -SecurityKey=OHMETD7DFK -TxAuthNo=4193753 -AVSCV2=NO DATA MATCHES -AddressResult=NOTMATCHED -PostCodeResult=MATCHED -CV2Result=NOTMATCHED -3DSecureStatus=NOTCHECKED -Token=1 + <<~RESP + VPSProtocol=2.23 + Status=OK + StatusDetail=0000 : The Authorisation was Successful. + VPSTxId=B8AE1CF6-9DEF-C876-1BB4-9B382E6CE520 + SecurityKey=OHMETD7DFK + TxAuthNo=4193753 + AVSCV2=NO DATA MATCHES + AddressResult=NOTMATCHED + PostCodeResult=MATCHED + CV2Result=NOTMATCHED + 3DSecureStatus=NOTCHECKED + Token=1 RESP end def unsuccessful_purchase_response - <<-RESP -VPSProtocol=2.23 -Status=NOTAUTHED -StatusDetail=VSP Direct transaction from VSP Simulator. -VPSTxId=7BBA9078-8489-48CD-BF0D-10B0E6B0EF30 -SecurityKey=DKDYLDYLXV -AVSCV2=ALL MATCH -AddressResult=MATCHED -PostCodeResult=MATCHED -CV2Result=MATCHED + <<~RESP + VPSProtocol=2.23 + Status=NOTAUTHED + StatusDetail=VSP Direct transaction from VSP Simulator. + VPSTxId=7BBA9078-8489-48CD-BF0D-10B0E6B0EF30 + SecurityKey=DKDYLDYLXV + AVSCV2=ALL MATCH + AddressResult=MATCHED + PostCodeResult=MATCHED + CV2Result=MATCHED RESP end def successful_authorize_response - <<-RESP -VPSProtocol=2.23 -Status=OK -StatusDetail=0000 : The Authorisation was Successful. -VPSTxId=B8AE1CF6-9DEF-C876-1BB4-9B382E6CE520 -SecurityKey=OHMETD7DFK -TxAuthNo=4193753 -AVSCV2=NO DATA MATCHES -AddressResult=NOTMATCHED -PostCodeResult=MATCHED -CV2Result=NOTMATCHED -3DSecureStatus=NOTCHECKED -Token=1 + <<~RESP + VPSProtocol=2.23 + Status=OK + StatusDetail=0000 : The Authorisation was Successful. + VPSTxId=B8AE1CF6-9DEF-C876-1BB4-9B382E6CE520 + SecurityKey=OHMETD7DFK + TxAuthNo=4193753 + AVSCV2=NO DATA MATCHES + AddressResult=NOTMATCHED + PostCodeResult=MATCHED + CV2Result=NOTMATCHED + 3DSecureStatus=NOTCHECKED + Token=1 RESP end def successful_refund_response - <<-RESP -VPSProtocol=3.00 -Status=OK -StatusDetail=0000 : The Authorisation was Successful. -SecurityKey=KUMJBP02HM -TxAuthNo=15282432 -VPSTxId={08C870A9-1E53-3852-BA44-CBC91612CBCA} + <<~RESP + VPSProtocol=3.00 + Status=OK + StatusDetail=0000 : The Authorisation was Successful. + SecurityKey=KUMJBP02HM + TxAuthNo=15282432 + VPSTxId={08C870A9-1E53-3852-BA44-CBC91612CBCA} RESP end def successful_capture_response - <<-RESP -VPSProtocol=3.00 -Status=OK -StatusDetail=2004 : The Release was Successful. + <<~RESP + VPSProtocol=3.00 + Status=OK + StatusDetail=2004 : The Release was Successful. RESP end def unsuccessful_authorize_response - <<-RESP -VPSProtocol=2.23 -Status=NOTAUTHED -StatusDetail=VSP Direct transaction from VSP Simulator. -VPSTxId=7BBA9078-8489-48CD-BF0D-10B0E6B0EF30 -SecurityKey=DKDYLDYLXV -AVSCV2=ALL MATCH -AddressResult=MATCHED -PostCodeResult=MATCHED -CV2Result=MATCHED + <<~RESP + VPSProtocol=2.23 + Status=NOTAUTHED + StatusDetail=VSP Direct transaction from VSP Simulator. + VPSTxId=7BBA9078-8489-48CD-BF0D-10B0E6B0EF30 + SecurityKey=DKDYLDYLXV + AVSCV2=ALL MATCH + AddressResult=MATCHED + PostCodeResult=MATCHED + CV2Result=MATCHED RESP end def successful_void_response - <<-RESP -VPSProtocol=2.23 -Status=OK -StatusDetail=2006 : The Abort was Successful. -VPSTxId=B8AE1CF6-9DEF-C876-1BB4-9B382E6CE520 -SecurityKey=OHMETD7DFK -TxAuthNo=4193753 -AVSCV2=NO DATA MATCHES -AddressResult=NOTMATCHED -PostCodeResult=MATCHED -CV2Result=NOTMATCHED -3DSecureStatus=NOTCHECKED -Token=1 + <<~RESP + VPSProtocol=2.23 + Status=OK + StatusDetail=2006 : The Abort was Successful. + VPSTxId=B8AE1CF6-9DEF-C876-1BB4-9B382E6CE520 + SecurityKey=OHMETD7DFK + TxAuthNo=4193753 + AVSCV2=NO DATA MATCHES + AddressResult=NOTMATCHED + PostCodeResult=MATCHED + CV2Result=NOTMATCHED + 3DSecureStatus=NOTCHECKED + Token=1 RESP end def unsuccessful_void_response - <<-RESP -VPSProtocol=2.23 -Status=MALFORMED -StatusDetail=3046 : The VPSTxId field is missing. -VPSTxId=7BBA9078-8489-48CD-BF0D-10B0E6B0EF30 -SecurityKey=DKDYLDYLXV -AVSCV2=ALL MATCH -AddressResult=MATCHED -PostCodeResult=MATCHED -CV2Result=MATCHED + <<~RESP + VPSProtocol=2.23 + Status=MALFORMED + StatusDetail=3046 : The VPSTxId field is missing. + VPSTxId=7BBA9078-8489-48CD-BF0D-10B0E6B0EF30 + SecurityKey=DKDYLDYLXV + AVSCV2=ALL MATCH + AddressResult=MATCHED + PostCodeResult=MATCHED + CV2Result=MATCHED RESP end def transcript - <<-TRANSCRIPT - Amount=1.00&Currency=GBP&VendorTxCode=9094108b21f7b917e68d3e84b49ce9c4&Description=Store+purchase&CardHolder=Tekin+Suleyman&CardNumber=4929000000006&ExpiryDate=0616&CardType=VISA&CV2=123&BillingSurname=Suleyman&BillingFirstnames=Tekin&BillingAddress1=Flat+10+Lapwing+Court&BillingAddress2=West+Didsbury&BillingCity=Manchester&BillingCountry=GB&BillingPostCode=M20+2PS&DeliverySurname=Suleyman&DeliveryFirstnames=Tekin&DeliveryAddress1=120+Grosvenor+St&DeliveryCity=Manchester&DeliveryCountry=GB&DeliveryPostCode=M1+7QW&CustomerEMail=tekin%40tekin.co.uk&ClientIPAddress=86.150.65.37&Vendor=spreedly&TxType=PAYMENT&VPSProtocol=3.00 -I, [2015-07-22T17:16:49.292774 #97998] INFO -- : [ActiveMerchant::Billing::SagePayGateway] --> 200 OK (356 1.8635s) -D, [2015-07-22T17:16:49.292836 #97998] DEBUG -- : VPSProtocol=3.00 -Status=OK -StatusDetail=0000 : The Authorisation was Successful. -VPSTxId={D5B43220-E93C-ED13-6643-D22224BD1CDB} -SecurityKey=7OYK4OHM7Y -TxAuthNo=8769237 -AVSCV2=DATA NOT CHECKED -AddressResult=NOTPROVIDED -PostCodeResult=NOTPROVIDED -CV2Result=NOTPROVIDED -3DSecureStatus=NOTCHECKED -DeclineCode=00 -ExpiryDate=0616 -BankAuthCode=999777 + <<~TRANSCRIPT + Amount=1.00&Currency=GBP&VendorTxCode=9094108b21f7b917e68d3e84b49ce9c4&Description=Store+purchase&CardHolder=Tekin+Suleyman&CardNumber=4929000000006&ExpiryDate=0616&CardType=VISA&CV2=123&BillingSurname=Suleyman&BillingFirstnames=Tekin&BillingAddress1=Flat+10+Lapwing+Court&BillingAddress2=West+Didsbury&BillingCity=Manchester&BillingCountry=GB&BillingPostCode=M20+2PS&DeliverySurname=Suleyman&DeliveryFirstnames=Tekin&DeliveryAddress1=120+Grosvenor+St&DeliveryCity=Manchester&DeliveryCountry=GB&DeliveryPostCode=M1+7QW&CustomerEMail=tekin%40tekin.co.uk&ClientIPAddress=86.150.65.37&Vendor=spreedly&TxType=PAYMENT&VPSProtocol=3.00 + I, [2015-07-22T17:16:49.292774 #97998] INFO -- : [ActiveMerchant::Billing::SagePayGateway] --> 200 OK (356 1.8635s) + D, [2015-07-22T17:16:49.292836 #97998] DEBUG -- : VPSProtocol=3.00 + Status=OK + StatusDetail=0000 : The Authorisation was Successful. + VPSTxId={D5B43220-E93C-ED13-6643-D22224BD1CDB} + SecurityKey=7OYK4OHM7Y + TxAuthNo=8769237 + AVSCV2=DATA NOT CHECKED + AddressResult=NOTPROVIDED + PostCodeResult=NOTPROVIDED + CV2Result=NOTPROVIDED + 3DSecureStatus=NOTCHECKED + DeclineCode=00 + ExpiryDate=0616 + BankAuthCode=999777 TRANSCRIPT end def scrubbed_transcript - <<-TRANSCRIPT - Amount=1.00&Currency=GBP&VendorTxCode=9094108b21f7b917e68d3e84b49ce9c4&Description=Store+purchase&CardHolder=Tekin+Suleyman&CardNumber=[FILTERED]&ExpiryDate=0616&CardType=VISA&CV2=[FILTERED]&BillingSurname=Suleyman&BillingFirstnames=Tekin&BillingAddress1=Flat+10+Lapwing+Court&BillingAddress2=West+Didsbury&BillingCity=Manchester&BillingCountry=GB&BillingPostCode=M20+2PS&DeliverySurname=Suleyman&DeliveryFirstnames=Tekin&DeliveryAddress1=120+Grosvenor+St&DeliveryCity=Manchester&DeliveryCountry=GB&DeliveryPostCode=M1+7QW&CustomerEMail=tekin%40tekin.co.uk&ClientIPAddress=86.150.65.37&Vendor=spreedly&TxType=PAYMENT&VPSProtocol=3.00 -I, [2015-07-22T17:16:49.292774 #97998] INFO -- : [ActiveMerchant::Billing::SagePayGateway] --> 200 OK (356 1.8635s) -D, [2015-07-22T17:16:49.292836 #97998] DEBUG -- : VPSProtocol=3.00 -Status=OK -StatusDetail=0000 : The Authorisation was Successful. -VPSTxId={D5B43220-E93C-ED13-6643-D22224BD1CDB} -SecurityKey=7OYK4OHM7Y -TxAuthNo=8769237 -AVSCV2=DATA NOT CHECKED -AddressResult=NOTPROVIDED -PostCodeResult=NOTPROVIDED -CV2Result=NOTPROVIDED -3DSecureStatus=NOTCHECKED -DeclineCode=00 -ExpiryDate=0616 -BankAuthCode=999777 + <<~TRANSCRIPT + Amount=1.00&Currency=GBP&VendorTxCode=9094108b21f7b917e68d3e84b49ce9c4&Description=Store+purchase&CardHolder=Tekin+Suleyman&CardNumber=[FILTERED]&ExpiryDate=0616&CardType=VISA&CV2=[FILTERED]&BillingSurname=Suleyman&BillingFirstnames=Tekin&BillingAddress1=Flat+10+Lapwing+Court&BillingAddress2=West+Didsbury&BillingCity=Manchester&BillingCountry=GB&BillingPostCode=M20+2PS&DeliverySurname=Suleyman&DeliveryFirstnames=Tekin&DeliveryAddress1=120+Grosvenor+St&DeliveryCity=Manchester&DeliveryCountry=GB&DeliveryPostCode=M1+7QW&CustomerEMail=tekin%40tekin.co.uk&ClientIPAddress=86.150.65.37&Vendor=spreedly&TxType=PAYMENT&VPSProtocol=3.00 + I, [2015-07-22T17:16:49.292774 #97998] INFO -- : [ActiveMerchant::Billing::SagePayGateway] --> 200 OK (356 1.8635s) + D, [2015-07-22T17:16:49.292836 #97998] DEBUG -- : VPSProtocol=3.00 + Status=OK + StatusDetail=0000 : The Authorisation was Successful. + VPSTxId={D5B43220-E93C-ED13-6643-D22224BD1CDB} + SecurityKey=7OYK4OHM7Y + TxAuthNo=8769237 + AVSCV2=DATA NOT CHECKED + AddressResult=NOTPROVIDED + PostCodeResult=NOTPROVIDED + CV2Result=NOTPROVIDED + 3DSecureStatus=NOTCHECKED + DeclineCode=00 + ExpiryDate=0616 + BankAuthCode=999777 TRANSCRIPT end end diff --git a/test/unit/gateways/sage_test.rb b/test/unit/gateways/sage_test.rb index b6faa1761c6..69d3e98d876 100644 --- a/test/unit/gateways/sage_test.rb +++ b/test/unit/gateways/sage_test.rb @@ -5,29 +5,29 @@ class SageGatewayTest < Test::Unit::TestCase def setup @gateway = SageGateway.new( - :login => 'login', - :password => 'password' - ) + login: 'login', + password: 'password' + ) @credit_card = credit_card @check = check @amount = 100 @options = { - :order_id => '1', - :billing_address => address, - :description => 'Store Purchase' + order_id: '1', + billing_address: address, + description: 'Store Purchase' } @check_options = { - :order_id => generate_unique_id, - :billing_address => address, - :shipping_address => address, - :email => 'longbob@example.com', - :drivers_license_state => 'CA', - :drivers_license_number => '12345689', - :date_of_birth => Date.new(1978, 8, 11), - :ssn => '078051120' + order_id: generate_unique_id, + billing_address: address, + shipping_address: address, + email: 'longbob@example.com', + drivers_license_state: 'CA', + drivers_license_number: '12345689', + date_of_birth: Date.new(1978, 8, 11), + ssn: '078051120' } end @@ -157,16 +157,16 @@ def test_invalid_login def test_include_customer_number_for_numeric_values stub_comms do - @gateway.purchase(@amount, @credit_card, @options.merge({:customer => '123'})) - end.check_request do |method, data| + @gateway.purchase(@amount, @credit_card, @options.merge({ customer: '123' })) + end.check_request do |_method, data| assert data =~ /T_customer_number=123/ end.respond_with(successful_authorization_response) end def test_dont_include_customer_number_for_numeric_values stub_comms do - @gateway.purchase(@amount, @credit_card, @options.merge({:customer => 'bob@test.com'})) - end.check_request do |method, data| + @gateway.purchase(@amount, @credit_card, @options.merge({ customer: 'bob@test.com' })) + end.check_request do |_method, data| assert data !~ /T_customer_number/ end.respond_with(successful_authorization_response) end @@ -188,7 +188,7 @@ def test_cvv_result def test_address_with_state post = {} options = { - :billing_address => { :country => 'US', :state => 'CA'} + billing_address: { country: 'US', state: 'CA' } } @gateway.send(:add_addresses, post, options) @@ -199,7 +199,7 @@ def test_address_with_state def test_address_without_state post = {} options = { - :billing_address => { :country => 'NZ', :state => ''} + billing_address: { country: 'NZ', state: '' } } @gateway.send(:add_addresses, post, options) @@ -249,7 +249,7 @@ def test_declined_check_purchase def test_successful_store response = stub_comms do @gateway.store(@credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, headers| assert_match(/login<\/ns1:M_ID>/, data) assert_match(/password<\/ns1:M_KEY>/, data) assert_match(/#{credit_card.number}<\/ns1:CARDNUMBER>/, data) @@ -267,7 +267,7 @@ def test_successful_store def test_failed_store response = stub_comms do @gateway.store(@credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, headers| assert_match(/login<\/ns1:M_ID>/, data) assert_match(/password<\/ns1:M_KEY>/, data) assert_match(/#{credit_card.number}<\/ns1:CARDNUMBER>/, data) @@ -285,7 +285,7 @@ def test_failed_store def test_successful_unstore response = stub_comms do @gateway.unstore('1234', @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, headers| assert_match(/login<\/ns1:M_ID>/, data) assert_match(/password<\/ns1:M_KEY>/, data) assert_match(/1234<\/ns1:GUID>/, data) @@ -301,7 +301,7 @@ def test_successful_unstore def test_failed_unstore response = stub_comms do @gateway.unstore('1234', @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, headers| assert_match(/login<\/ns1:M_ID>/, data) assert_match(/password<\/ns1:M_KEY>/, data) assert_match(/1234<\/ns1:GUID>/, data) @@ -366,175 +366,175 @@ def expected_expiration_date end def successful_store_response - <<-XML - - - - - - - - - - true - 66234d2dfec24efe9fdcd4b751578c11 - SUCCESS - - - - - - - + <<~XML + + + + + + + + + + true + 66234d2dfec24efe9fdcd4b751578c11 + SUCCESS + + + + + + + XML end def failed_store_response - <<-XML - - - - - - - - - - false - - UNABLE TO VERIFY VAULT SERVICE - - - - - - - + <<~XML + + + + + + + + + + false + + UNABLE TO VERIFY VAULT SERVICE + + + + + + + XML end def successful_unstore_response - <<-XML - - - - - true - - - + <<~XML + + + + + true + + + XML end def failed_unstore_response - <<-XML - - - - - false - - - + <<~XML + + + + + false + + + XML end def pre_scrubbed - <<-PRE_SCRUBBED -opening connection to www.sagepayments.net:443... -opened -starting SSL for www.sagepayments.net:443... -SSL established -<- "POST /cgi-bin/eftBankcard.dll?transaction 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: www.sagepayments.net\r\nContent-Length: 444\r\n\r\n" -<- "C_name=Longbob+Longsen&C_cardnumber=4111111111111111&C_exp=0917&C_cvv=123&T_amt=1.00&T_ordernum=1741a24e00a5a5f11653&C_address=456+My+Street&C_city=Ottawa&C_state=ON&C_zip=K1C2N6&C_country=CA&C_telephone=%28555%29555-5555&C_fax=%28555%29555-6666&C_email=longbob%40example.com&C_ship_name=Jim+Smith&C_ship_address=456+My+Street&C_ship_city=Ottawa&C_ship_state=ON&C_ship_zip=K1C2N6&C_ship_country=CA&M_id=214282982451&M_key=Z5W2S8J7X8T5&T_code=01" --> "HTTP/1.1 200 OK\r\n" --> "Content-Type: text/html\r\n" --> "Content-Encoding: gzip\r\n" --> "Vary: Accept-Encoding\r\n" --> "Server: \r\n" --> "X-AspNet-Version: \r\n" --> "X-Powered-By: ASP.NET\r\n" --> "Date: Thu, 30 Jun 2016 02:58:40 GMT\r\n" --> "Connection: close\r\n" --> "Content-Length: 185\r\n" --> "\r\n" -reading 185 bytes... --> "\x1F\x8B\b\x00\x00\x00\x00\x00\x04\x00\xED\xBD\a`\x1CI\x96%&/m\xCA{\x7FJ\xF5J\xD7\xE0t\xA1\b\x80`\x13$\xD8\x90@\x10\xEC\xC1\x88\xCD\xE6\x92\xEC\x1DiG#)\xAB*\x81\xCAeVe]f\x16@\xCC\xED\x9D\xBC\xF7\xDE{\xEF\xBD\xF7\xDE{\xEF\xBD\xF7\xBA;\x9DN'\xF7\xDF\xFF?\\fd\x01l\xF6\xCEJ\xDA\xC9\x9E!\x80\xAA\xC8\x1F?~|\x1F?\"~\xAD\xE3\x1D<\xBB\xC7/_\xBE\xFA\xF2'O\x9F\xA6\xF4\a\xFD\x99v\x9F\xDD\x9D/\xE8\xAB\xCF?}\xF3\xF9\x17\xEF\xCE\xBF;\xDF\xF9\x9Dv\x1F\xEC\xEFf{\xFB\xF9\xCENv?\xBB\x7F\xBE\xBB\xFB\xE9\xFD{\xBF\xD3\xCE\xEF\xF4k\xFF?XI\x04rQ\x00\x00\x00" -read 185 bytes -Conn close + <<~PRE_SCRUBBED + opening connection to www.sagepayments.net:443... + opened + starting SSL for www.sagepayments.net:443... + SSL established + <- "POST /cgi-bin/eftBankcard.dll?transaction 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: www.sagepayments.net\r\nContent-Length: 444\r\n\r\n" + <- "C_name=Longbob+Longsen&C_cardnumber=4111111111111111&C_exp=0917&C_cvv=123&T_amt=1.00&T_ordernum=1741a24e00a5a5f11653&C_address=456+My+Street&C_city=Ottawa&C_state=ON&C_zip=K1C2N6&C_country=CA&C_telephone=%28555%29555-5555&C_fax=%28555%29555-6666&C_email=longbob%40example.com&C_ship_name=Jim+Smith&C_ship_address=456+My+Street&C_ship_city=Ottawa&C_ship_state=ON&C_ship_zip=K1C2N6&C_ship_country=CA&M_id=214282982451&M_key=Z5W2S8J7X8T5&T_code=01" + -> "HTTP/1.1 200 OK\r\n" + -> "Content-Type: text/html\r\n" + -> "Content-Encoding: gzip\r\n" + -> "Vary: Accept-Encoding\r\n" + -> "Server: \r\n" + -> "X-AspNet-Version: \r\n" + -> "X-Powered-By: ASP.NET\r\n" + -> "Date: Thu, 30 Jun 2016 02:58:40 GMT\r\n" + -> "Connection: close\r\n" + -> "Content-Length: 185\r\n" + -> "\r\n" + reading 185 bytes... + -> "\x1F\x8B\b\x00\x00\x00\x00\x00\x04\x00\xED\xBD\a`\x1CI\x96%&/m\xCA{\x7FJ\xF5J\xD7\xE0t\xA1\b\x80`\x13$\xD8\x90@\x10\xEC\xC1\x88\xCD\xE6\x92\xEC\x1DiG#)\xAB*\x81\xCAeVe]f\x16@\xCC\xED\x9D\xBC\xF7\xDE{\xEF\xBD\xF7\xDE{\xEF\xBD\xF7\xBA;\x9DN'\xF7\xDF\xFF?\\fd\x01l\xF6\xCEJ\xDA\xC9\x9E!\x80\xAA\xC8\x1F?~|\x1F?\"~\xAD\xE3\x1D<\xBB\xC7/_\xBE\xFA\xF2'O\x9F\xA6\xF4\a\xFD\x99v\x9F\xDD\x9D/\xE8\xAB\xCF?}\xF3\xF9\x17\xEF\xCE\xBF;\xDF\xF9\x9Dv\x1F\xEC\xEFf{\xFB\xF9\xCENv?\xBB\x7F\xBE\xBB\xFB\xE9\xFD{\xBF\xD3\xCE\xEF\xF4k\xFF?XI\x04rQ\x00\x00\x00" + read 185 bytes + Conn close PRE_SCRUBBED end def post_scrubbed - <<-POST_SCRUBBED -opening connection to www.sagepayments.net:443... -opened -starting SSL for www.sagepayments.net:443... -SSL established -<- "POST /cgi-bin/eftBankcard.dll?transaction 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: www.sagepayments.net\r\nContent-Length: 444\r\n\r\n" -<- "C_name=Longbob+Longsen&C_cardnumber=[FILTERED]&C_exp=0917&C_cvv=[FILTERED]&T_amt=1.00&T_ordernum=1741a24e00a5a5f11653&C_address=456+My+Street&C_city=Ottawa&C_state=ON&C_zip=K1C2N6&C_country=CA&C_telephone=%28555%29555-5555&C_fax=%28555%29555-6666&C_email=longbob%40example.com&C_ship_name=Jim+Smith&C_ship_address=456+My+Street&C_ship_city=Ottawa&C_ship_state=ON&C_ship_zip=K1C2N6&C_ship_country=CA&M_id=[FILTERED]&M_key=[FILTERED]&T_code=01" --> "HTTP/1.1 200 OK\r\n" --> "Content-Type: text/html\r\n" --> "Content-Encoding: gzip\r\n" --> "Vary: Accept-Encoding\r\n" --> "Server: \r\n" --> "X-AspNet-Version: \r\n" --> "X-Powered-By: ASP.NET\r\n" --> "Date: Thu, 30 Jun 2016 02:58:40 GMT\r\n" --> "Connection: close\r\n" --> "Content-Length: 185\r\n" --> "\r\n" -reading 185 bytes... --> \"\u001F?\b\u0000\u0000\u0000\u0000\u0000\u0004\u0000??\a`\u001CI?%&/m?{\u007FJ?J??t?\b?`\u0013$?@\u0010??????\u001DiG#)?*??eVe]f\u0016@????{???{???;?N'????\\fd\u0001l??J??!???\u001F?~|\u001F?\"~??\u001D "HTTP/1.1 200 OK\r\n" + -> "Content-Type: text/html\r\n" + -> "Content-Encoding: gzip\r\n" + -> "Vary: Accept-Encoding\r\n" + -> "Server: \r\n" + -> "X-AspNet-Version: \r\n" + -> "X-Powered-By: ASP.NET\r\n" + -> "Date: Thu, 30 Jun 2016 02:58:40 GMT\r\n" + -> "Connection: close\r\n" + -> "Content-Length: 185\r\n" + -> "\r\n" + reading 185 bytes... + -> \"\u001F?\b\u0000\u0000\u0000\u0000\u0000\u0004\u0000??\a`\u001CI?%&/m?{\u007FJ?J??t?\b?`\u0013$?@\u0010??????\u001DiG#)?*??eVe]f\u0016@????{???{???;?N'????\\fd\u0001l??J??!???\u001F?~|\u001F?\"~??\u001D "HTTP/1.1 200 OK\r\n" --> "Cache-Control: no-cache\r\n" --> "Pragma: no-cache\r\n" --> "Transfer-Encoding: chunked\r\n" --> "Content-Type: text/html; charset=us-ascii\r\n" --> "Content-Encoding: gzip\r\n" --> "Expires: -1\r\n" --> "Vary: Accept-Encoding\r\n" --> "Server: Microsoft-IIS/7.5\r\n" --> "X-Powered-By: ASP.NET\r\n" --> "Date: Thu, 02 Nov 2017 13:26:30 GMT\r\n" --> "Connection: close\r\n" --> "\r\n" --> "ac\r\n" -reading 172 bytes... --> "\x1F\x8B\b\x00\x00\x00\x00\x00\x04\x00\xED\xBD\a`\x1CI\x96%&/m\xCA{\x7FJ\xF5J\xD7\xE0t\xA1\b\x80`\x13$\xD8\x90@\x10\xEC\xC1\x88\xCD\xE6\x92\xEC\x1DiG#)\xAB*\x81\xCAeVe]f\x16@\xCC\xED\x9D\xBC\xF7\xDE{\xEF\xBD\xF7\xDE{\xEF\xBD\xF7\xBA;\x9DN'\xF7\xDF\xFF?\\fd\x01l\xF6\xCEJ\xDA\xC9\x9E!\x80\xAA\xC8\x1F?~|\x1F?\"~\xAD\xE3\x94\x9F\xE3\x93\x93\xD3\x97oN\x9F\xD2\xAF\xD1gg\xE7\xD9\x93\xBDo?\xFC\x89\xAF\x16\xF7v~\xA7\x9Dl\xFA\xE9\xF9l\xF7\xFC\xC1~\xF6\xF0`\x96?\xDC\x9F\x9C?\xFC\x9Dv~\xA7\x17_\xBE8\xA5\x1F\xBF" -read 172 bytes -reading 2 bytes... --> "\r\n" -read 2 bytes --> "b\r\n" -reading 11 bytes... --> "\xF6\xFF\x03\x90\xEB\x1E T\x00\x00\x00" -read 11 bytes -reading 2 bytes... --> "\r\n" -read 2 bytes --> "0\r\n" --> "\r\n" -Conn close + <<~PRE_SCRUBBED + opening connection to www.sagepayments.net:443... + opened + starting SSL for www.sagepayments.net:443... + SSL established + <- "POST /cgi-bin/eftVirtualCheck.dll?transaction 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: www.sagepayments.net\r\nContent-Length: 562\r\n\r\n" + <- "C_first_name=Jim&C_last_name=Smith&C_rte=244183602&C_acct=15378535&C_check_number=1&C_acct_type=DDA&C_customer_type=WEB&C_originator_id=&T_addenda=&C_ssn=&C_dl_state_code=&C_dl_number=&C_dob=&T_amt=1.00&T_ordernum=0ac6fd1f74a98de94bf9&C_address=456+My+Street&C_city=Ottawa&C_state=ON&C_zip=K1C2N6&C_country=CA&C_telephone=%28555%29555-5555&C_fax=%28555%29555-6666&C_email=longbob%40example.com&C_ship_name=Jim+Smith&C_ship_address=456+My+Street&C_ship_city=Ottawa&C_ship_state=ON&C_ship_zip=K1C2N6&C_ship_country=CA&M_id=562313162894&M_key=J6U9B3G2F6L3&T_code=01" + -> "HTTP/1.1 200 OK\r\n" + -> "Cache-Control: no-cache\r\n" + -> "Pragma: no-cache\r\n" + -> "Transfer-Encoding: chunked\r\n" + -> "Content-Type: text/html; charset=us-ascii\r\n" + -> "Content-Encoding: gzip\r\n" + -> "Expires: -1\r\n" + -> "Vary: Accept-Encoding\r\n" + -> "Server: Microsoft-IIS/7.5\r\n" + -> "X-Powered-By: ASP.NET\r\n" + -> "Date: Thu, 02 Nov 2017 13:26:30 GMT\r\n" + -> "Connection: close\r\n" + -> "\r\n" + -> "ac\r\n" + reading 172 bytes... + -> "\x1F\x8B\b\x00\x00\x00\x00\x00\x04\x00\xED\xBD\a`\x1CI\x96%&/m\xCA{\x7FJ\xF5J\xD7\xE0t\xA1\b\x80`\x13$\xD8\x90@\x10\xEC\xC1\x88\xCD\xE6\x92\xEC\x1DiG#)\xAB*\x81\xCAeVe]f\x16@\xCC\xED\x9D\xBC\xF7\xDE{\xEF\xBD\xF7\xDE{\xEF\xBD\xF7\xBA;\x9DN'\xF7\xDF\xFF?\\fd\x01l\xF6\xCEJ\xDA\xC9\x9E!\x80\xAA\xC8\x1F?~|\x1F?\"~\xAD\xE3\x94\x9F\xE3\x93\x93\xD3\x97oN\x9F\xD2\xAF\xD1gg\xE7\xD9\x93\xBDo?\xFC\x89\xAF\x16\xF7v~\xA7\x9Dl\xFA\xE9\xF9l\xF7\xFC\xC1~\xF6\xF0`\x96?\xDC\x9F\x9C?\xFC\x9Dv~\xA7\x17_\xBE8\xA5\x1F\xBF" + read 172 bytes + reading 2 bytes... + -> "\r\n" + read 2 bytes + -> "b\r\n" + reading 11 bytes... + -> "\xF6\xFF\x03\x90\xEB\x1E T\x00\x00\x00" + read 11 bytes + reading 2 bytes... + -> "\r\n" + read 2 bytes + -> "0\r\n" + -> "\r\n" + Conn close PRE_SCRUBBED end def post_scrubbed_echeck - <<-POST_SCRUBBED -opening connection to www.sagepayments.net:443...\nopened\nstarting SSL for www.sagepayments.net:443...\nSSL established\n<- \"POST /cgi-bin/eftVirtualCheck.dll?transaction 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: www.sagepayments.net\r\nContent-Length: 562\r\n\r\n\"\n<- \"C_first_name=Jim&C_last_name=Smith&C_rte=[FILTERED]&C_acct=[FILTERED]&C_check_number=1&C_acct_type=DDA&C_customer_type=WEB&C_originator_id=&T_addenda=&C_ssn=[FILTERED]&C_dl_state_code=&C_dl_number=&C_dob=&T_amt=1.00&T_ordernum=0ac6fd1f74a98de94bf9&C_address=456+My+Street&C_city=Ottawa&C_state=ON&C_zip=K1C2N6&C_country=CA&C_telephone=%28555%29555-5555&C_fax=%28555%29555-6666&C_email=longbob%40example.com&C_ship_name=Jim+Smith&C_ship_address=456+My+Street&C_ship_city=Ottawa&C_ship_state=ON&C_ship_zip=K1C2N6&C_ship_country=CA&M_id=[FILTERED]&M_key=[FILTERED]&T_code=01\"\n-> \"HTTP/1.1 200 OK\r\n\"\n-> \"Cache-Control: no-cache\r\n\"\n-> \"Pragma: no-cache\r\n\"\n-> \"Transfer-Encoding: chunked\r\n\"\n-> \"Content-Type: text/html; charset=us-ascii\r\n\"\n-> \"Content-Encoding: gzip\r\n\"\n-> \"Expires: -1\r\n\"\n-> \"Vary: Accept-Encoding\r\n\"\n-> \"Server: Microsoft-IIS/7.5\r\n\"\n-> \"X-Powered-By: ASP.NET\r\n\"\n-> \"Date: Thu, 02 Nov 2017 13:26:30 GMT\r\n\"\n-> \"Connection: close\r\n\"\n-> \"\r\n\"\n-> \"ac\r\n\"\nreading 172 bytes...\n-> \"\u001F?\b\u0000\u0000\u0000\u0000\u0000\u0004\u0000??\a`\u001CI?%&/m?{\u007FJ?J??t?\b?`\u0013$?@\u0010??????\u001DiG#)?*??eVe]f\u0016@????{???{???;?N'????\\fd\u0001l??J??!???\u001F?~|\u001F?\"~????oN???gg???o????\u0016?v~??l???l???~??`???????v~?\u0017_?8?\u001F?\"\nread 172 bytes\nreading 2 bytes...\n-> \"\r\n\"\nread 2 bytes\n-> \"b\r\n\"\nreading 11 bytes...\n-> \"??\u0003??\u001E T\u0000\u0000\u0000\"\nread 11 bytes\nreading 2 bytes...\n-> \"\r\n\"\nread 2 bytes\n-> \"0\r\n\"\n-> \"\r\n\"\nConn close + <<~POST_SCRUBBED + opening connection to www.sagepayments.net:443...\nopened\nstarting SSL for www.sagepayments.net:443...\nSSL established\n<- \"POST /cgi-bin/eftVirtualCheck.dll?transaction 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: www.sagepayments.net\r\nContent-Length: 562\r\n\r\n\"\n<- \"C_first_name=Jim&C_last_name=Smith&C_rte=[FILTERED]&C_acct=[FILTERED]&C_check_number=1&C_acct_type=DDA&C_customer_type=WEB&C_originator_id=&T_addenda=&C_ssn=[FILTERED]&C_dl_state_code=&C_dl_number=&C_dob=&T_amt=1.00&T_ordernum=0ac6fd1f74a98de94bf9&C_address=456+My+Street&C_city=Ottawa&C_state=ON&C_zip=K1C2N6&C_country=CA&C_telephone=%28555%29555-5555&C_fax=%28555%29555-6666&C_email=longbob%40example.com&C_ship_name=Jim+Smith&C_ship_address=456+My+Street&C_ship_city=Ottawa&C_ship_state=ON&C_ship_zip=K1C2N6&C_ship_country=CA&M_id=[FILTERED]&M_key=[FILTERED]&T_code=01\"\n-> \"HTTP/1.1 200 OK\r\n\"\n-> \"Cache-Control: no-cache\r\n\"\n-> \"Pragma: no-cache\r\n\"\n-> \"Transfer-Encoding: chunked\r\n\"\n-> \"Content-Type: text/html; charset=us-ascii\r\n\"\n-> \"Content-Encoding: gzip\r\n\"\n-> \"Expires: -1\r\n\"\n-> \"Vary: Accept-Encoding\r\n\"\n-> \"Server: Microsoft-IIS/7.5\r\n\"\n-> \"X-Powered-By: ASP.NET\r\n\"\n-> \"Date: Thu, 02 Nov 2017 13:26:30 GMT\r\n\"\n-> \"Connection: close\r\n\"\n-> \"\r\n\"\n-> \"ac\r\n\"\nreading 172 bytes...\n-> \"\u001F?\b\u0000\u0000\u0000\u0000\u0000\u0004\u0000??\a`\u001CI?%&/m?{\u007FJ?J??t?\b?`\u0013$?@\u0010??????\u001DiG#)?*??eVe]f\u0016@????{???{???;?N'????\\fd\u0001l??J??!???\u001F?~|\u001F?\"~????oN???gg???o????\u0016?v~??l???l???~??`???????v~?\u0017_?8?\u001F?\"\nread 172 bytes\nreading 2 bytes...\n-> \"\r\n\"\nread 2 bytes\n-> \"b\r\n\"\nreading 11 bytes...\n-> \"??\u0003??\u001E T\u0000\u0000\u0000\"\nread 11 bytes\nreading 2 bytes...\n-> \"\r\n\"\nread 2 bytes\n-> \"0\r\n\"\n-> \"\r\n\"\nConn close POST_SCRUBBED end end diff --git a/test/unit/gateways/sallie_mae_test.rb b/test/unit/gateways/sallie_mae_test.rb index 40194a47164..b47bb928923 100644 --- a/test/unit/gateways/sallie_mae_test.rb +++ b/test/unit/gateways/sallie_mae_test.rb @@ -3,16 +3,16 @@ class SallieMaeTest < Test::Unit::TestCase def setup @gateway = SallieMaeGateway.new( - :login => 'FAKEACCOUNT' - ) + login: 'FAKEACCOUNT' + ) @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 @@ -35,7 +35,7 @@ def test_non_test_account end def test_test_account - gateway = SallieMaeGateway.new(:login => 'TEST0') + gateway = SallieMaeGateway.new(login: 'TEST0') assert gateway.test? end diff --git a/test/unit/gateways/secure_net_test.rb b/test/unit/gateways/secure_net_test.rb index 01c9b55c70d..76baf7edfac 100644 --- a/test/unit/gateways/secure_net_test.rb +++ b/test/unit/gateways/secure_net_test.rb @@ -5,17 +5,17 @@ class SecureNetTest < Test::Unit::TestCase def setup @gateway = SecureNetGateway.new( - :login => 'X', - :password => 'Y' - ) + login: 'X', + password: 'Y' + ) @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 @@ -118,7 +118,7 @@ def test_order_id_is_truncated order_id = "SecureNet doesn't like order_ids greater than 25 characters." stub_comms do @gateway.purchase(@amount, @credit_card, order_id: order_id) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/ORDERID>SecureNet doesn't like orGood Stuff<}, data) assert_match(%r{INVOICEDESC>Sweet Invoice<}, data) assert_match(%r{INVOICENUM>48<}, data) @@ -143,7 +143,7 @@ def test_passes_optional_fields def test_only_passes_optional_fields_if_specified 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(%r{NOTE}, data) assert_no_match(%r{INVOICEDESC}, data) assert_no_match(%r{INVOICENUM}, data) @@ -153,7 +153,7 @@ def test_only_passes_optional_fields_if_specified def test_passes_with_no_developer_id 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(%r{DEVELOPERID}, data) end.respond_with(successful_purchase_response) end @@ -161,7 +161,7 @@ def test_passes_with_no_developer_id def test_passes_with_developer_id stub_comms do @gateway.purchase(@amount, @credit_card, developer_id: '1234') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{DEVELOPERID}, data) end.respond_with(successful_purchase_response) end @@ -169,7 +169,7 @@ def test_passes_with_developer_id def test_passes_with_test_mode stub_comms do @gateway.purchase(@amount, @credit_card, test_mode: false) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{FALSE}, data) end.respond_with(successful_purchase_response) end @@ -177,7 +177,7 @@ def test_passes_with_test_mode def test_passes_without_test_mode stub_comms do @gateway.purchase(@amount, @credit_card) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{TRUE}, data) end.respond_with(successful_purchase_response) end @@ -231,48 +231,48 @@ def failed_refund_response end def pre_scrubbed - <<-EOS -opening connection to certify.securenet.com:443... -opened -starting SSL for certify.securenet.com:443... -SSL established -<- "POST /API/gateway.svc/webHttp/ProcessTransaction HTTP/1.1\r\nContent-Type: text/xml\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: certify.securenet.com\r\nContent-Length: 1044\r\n\r\n" -<- "1.00123400010001111222409190100
456 My Street
OttawaWidgets IncCALongbobLongsen(555)555-5555ONK1C2N6
010BI8gL8HO1dKP7001218CCStore Purchase151992186896260900TRUE00
" --> "HTTP/1.1 200 OK\r\n" --> "Content-Length: 2547\r\n" --> "Content-Type: application/xml; charset=utf-8\r\n" --> "X-Powered-By: ASP.NET\r\n" --> "Date: Thu, 01 Mar 2018 16:31:01 GMT\r\n" --> "Connection: close\r\n" --> "Set-Cookie: TS01e56b0e=010bfb2c76b6671aabf6f176a4e5aefd8e7a6ce7f697d82dfcfd424edede4ae7d4dba7557a4a7a13a539cfc1c5c061e08d5040811a; Path=/\r\n" --> "\r\n" -reading 2547 bytes... --> "10000Approved0JUJQLQ1.00Y0LongbobLongsenVIM000100
456 My Street
OttawaWidgets IncCAFALSELongbobLongsen(555)555-5555ONK1C2N6
09190P2224FALSEFALSECCStore Purchase151992186896260970012181.000301201811310101.0003012018113101116186071
" -read 2547 bytes -Conn close - EOS + <<~REQUEST + opening connection to certify.securenet.com:443... + opened + starting SSL for certify.securenet.com:443... + SSL established + <- "POST /API/gateway.svc/webHttp/ProcessTransaction HTTP/1.1\r\nContent-Type: text/xml\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: certify.securenet.com\r\nContent-Length: 1044\r\n\r\n" + <- "1.00123400010001111222409190100
456 My Street
OttawaWidgets IncCALongbobLongsen(555)555-5555ONK1C2N6
010BI8gL8HO1dKP7001218CCStore Purchase151992186896260900TRUE00
" + -> "HTTP/1.1 200 OK\r\n" + -> "Content-Length: 2547\r\n" + -> "Content-Type: application/xml; charset=utf-8\r\n" + -> "X-Powered-By: ASP.NET\r\n" + -> "Date: Thu, 01 Mar 2018 16:31:01 GMT\r\n" + -> "Connection: close\r\n" + -> "Set-Cookie: TS01e56b0e=010bfb2c76b6671aabf6f176a4e5aefd8e7a6ce7f697d82dfcfd424edede4ae7d4dba7557a4a7a13a539cfc1c5c061e08d5040811a; Path=/\r\n" + -> "\r\n" + reading 2547 bytes... + -> "10000Approved0JUJQLQ1.00Y0LongbobLongsenVIM000100
456 My Street
OttawaWidgets IncCAFALSELongbobLongsen(555)555-5555ONK1C2N6
09190P2224FALSEFALSECCStore Purchase151992186896260970012181.000301201811310101.0003012018113101116186071
" + read 2547 bytes + Conn close + REQUEST end def post_scrubbed - <<-EOS -opening connection to certify.securenet.com:443... -opened -starting SSL for certify.securenet.com:443... -SSL established -<- "POST /API/gateway.svc/webHttp/ProcessTransaction HTTP/1.1\r\nContent-Type: text/xml\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: certify.securenet.com\r\nContent-Length: 1044\r\n\r\n" -<- "1.00[FILTERED][FILTERED]09190100
456 My Street
OttawaWidgets IncCALongbobLongsen(555)555-5555ONK1C2N6
010[FILTERED]7001218CCStore Purchase151992186896260900TRUE00
" --> "HTTP/1.1 200 OK\r\n" --> "Content-Length: 2547\r\n" --> "Content-Type: application/xml; charset=utf-8\r\n" --> "X-Powered-By: ASP.NET\r\n" --> "Date: Thu, 01 Mar 2018 16:31:01 GMT\r\n" --> "Connection: close\r\n" --> "Set-Cookie: TS01e56b0e=010bfb2c76b6671aabf6f176a4e5aefd8e7a6ce7f697d82dfcfd424edede4ae7d4dba7557a4a7a13a539cfc1c5c061e08d5040811a; Path=/\r\n" --> "\r\n" -reading 2547 bytes... --> "10000Approved0JUJQLQ1.00Y0LongbobLongsenVIM000100
456 My Street
OttawaWidgets IncCAFALSELongbobLongsen(555)555-5555ONK1C2N6
09190P2224FALSEFALSECCStore Purchase151992186896260970012181.000301201811310101.0003012018113101116186071
" -read 2547 bytes -Conn close - EOS + <<~REQUEST + opening connection to certify.securenet.com:443... + opened + starting SSL for certify.securenet.com:443... + SSL established + <- "POST /API/gateway.svc/webHttp/ProcessTransaction HTTP/1.1\r\nContent-Type: text/xml\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: certify.securenet.com\r\nContent-Length: 1044\r\n\r\n" + <- "1.00[FILTERED][FILTERED]09190100
456 My Street
OttawaWidgets IncCALongbobLongsen(555)555-5555ONK1C2N6
010[FILTERED]7001218CCStore Purchase151992186896260900TRUE00
" + -> "HTTP/1.1 200 OK\r\n" + -> "Content-Length: 2547\r\n" + -> "Content-Type: application/xml; charset=utf-8\r\n" + -> "X-Powered-By: ASP.NET\r\n" + -> "Date: Thu, 01 Mar 2018 16:31:01 GMT\r\n" + -> "Connection: close\r\n" + -> "Set-Cookie: TS01e56b0e=010bfb2c76b6671aabf6f176a4e5aefd8e7a6ce7f697d82dfcfd424edede4ae7d4dba7557a4a7a13a539cfc1c5c061e08d5040811a; Path=/\r\n" + -> "\r\n" + reading 2547 bytes... + -> "10000Approved0JUJQLQ1.00Y0LongbobLongsenVIM000100
456 My Street
OttawaWidgets IncCAFALSELongbobLongsen(555)555-5555ONK1C2N6
09190P2224FALSEFALSECCStore Purchase151992186896260970012181.000301201811310101.0003012018113101116186071
" + read 2547 bytes + Conn close + REQUEST end end diff --git a/test/unit/gateways/secure_pay_au_test.rb b/test/unit/gateways/secure_pay_au_test.rb index 5d995aab6f8..4bbd0213712 100644 --- a/test/unit/gateways/secure_pay_au_test.rb +++ b/test/unit/gateways/secure_pay_au_test.rb @@ -5,17 +5,17 @@ class SecurePayAuTest < Test::Unit::TestCase def setup @gateway = SecurePayAuGateway.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 @@ -24,7 +24,7 @@ def test_supported_countries end def test_supported_card_types - assert_equal [:visa, :master, :american_express, :diners_club, :jcb], SecurePayAuGateway.supported_cardtypes + assert_equal %i[visa master american_express diners_club jcb], SecurePayAuGateway.supported_cardtypes end def test_successful_purchase_with_live_data @@ -51,14 +51,14 @@ def test_successful_purchase def test_localized_currency stub_comms do - @gateway.purchase(100, @credit_card, @options.merge(:currency => 'CAD')) - end.check_request do |endpoint, data, headers| + @gateway.purchase(100, @credit_card, @options.merge(currency: 'CAD')) + end.check_request do |_endpoint, data, _headers| assert_match %r{100<\/amount>}, data end.respond_with(successful_purchase_response) stub_comms do - @gateway.purchase(100, @credit_card, @options.merge(:currency => 'JPY')) - end.check_request do |endpoint, data, headers| + @gateway.purchase(100, @credit_card, @options.merge(currency: 'JPY')) + end.check_request do |_endpoint, data, _headers| assert_match %r{1<\/amount>}, data end.respond_with(successful_purchase_response) end @@ -166,7 +166,7 @@ def test_failed_login def test_successful_store @gateway.expects(:ssl_post).returns(successful_store_response) - assert response = @gateway.store(@credit_card, {:billing_id => 'test3', :amount => 123}) + assert response = @gateway.store(@credit_card, { billing_id: 'test3', amount: 123 }) assert_instance_of Response, response assert_equal 'Successful', response.message assert_equal 'test3', response.params['client_id'] diff --git a/test/unit/gateways/secure_pay_tech_test.rb b/test/unit/gateways/secure_pay_tech_test.rb index 87293a7f817..6ebe85049ff 100644 --- a/test/unit/gateways/secure_pay_tech_test.rb +++ b/test/unit/gateways/secure_pay_tech_test.rb @@ -3,14 +3,14 @@ class SecurePayTechTest < Test::Unit::TestCase def setup @gateway = SecurePayTechGateway.new( - :login => 'x', - :password => 'y' - ) + login: 'x', + password: 'y' + ) @amount = 100 @credit_card = credit_card('4987654321098769') @options = { - :billing_address => address + billing_address: address } end diff --git a/test/unit/gateways/secure_pay_test.rb b/test/unit/gateways/secure_pay_test.rb index 0fdc3b08493..71cd4e7fa00 100644 --- a/test/unit/gateways/secure_pay_test.rb +++ b/test/unit/gateways/secure_pay_test.rb @@ -3,16 +3,16 @@ class SecurePayTest < Test::Unit::TestCase def setup @gateway = SecurePayGateway.new( - :login => 'X', - :password => 'Y' + login: 'X', + password: 'Y' ) @credit_card = credit_card @options = { - :order_id => generate_unique_id, - :description => 'Store purchase', - :billing_address => address + order_id: generate_unique_id, + description: 'Store purchase', + billing_address: address } @amount = 100 diff --git a/test/unit/gateways/securion_pay_test.rb b/test/unit/gateways/securion_pay_test.rb index e98a1146e18..e90222e0ab2 100644 --- a/test/unit/gateways/securion_pay_test.rb +++ b/test/unit/gateways/securion_pay_test.rb @@ -66,7 +66,7 @@ def test_successful_purchase def test_successful_purchase_with_token response = stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, 'tok_xxx') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/card=tok_xxx/, data) refute_match(/card\[number\]/, data) end.respond_with(successful_purchase_response) @@ -99,7 +99,7 @@ def test_client_data_submitted_with_purchase } }) @gateway.purchase(@amount, @credit_card, updated_options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/description=test\+charge/, data) assert_match(/ip=127\.127\.127\.127/, data) assert_match(/user_agent=browser\+XXX/, data) @@ -115,7 +115,7 @@ def test_client_data_submitted_with_purchase_without_email_or_order stub_comms(@gateway, :ssl_request) do updated_options = @options.merge({ description: 'test charge', ip: '127.127.127.127', user_agent: 'browser XXX', referrer: 'http://www.foobar.com' }) @gateway.purchase(@amount, @credit_card, updated_options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/description=test\+charge/, data) assert_match(/ip=127\.127\.127\.127/, data) assert_match(/user_agent=browser\+XXX/, data) @@ -136,7 +136,7 @@ def test_successful_authorization end def test_add_address - post = { card: { } } + post = { card: {} } @gateway.send(:add_address, post, @options) assert_equal @options[:billing_address][:zip], post[:card][:addressZip] assert_equal @options[:billing_address][:state], post[:card][:addressState] @@ -153,7 +153,7 @@ def test_ensure_does_not_respond_to_credit def test_address_is_included_with_card_data stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert data =~ /card\[addressLine1\]/ end.respond_with(successful_purchase_response) end diff --git a/test/unit/gateways/skip_jack_test.rb b/test/unit/gateways/skip_jack_test.rb index 6df67c6a94e..362efffb520 100644 --- a/test/unit/gateways/skip_jack_test.rb +++ b/test/unit/gateways/skip_jack_test.rb @@ -1,38 +1,37 @@ require 'test_helper' class SkipJackTest < Test::Unit::TestCase - def setup Base.mode = :test - @gateway = SkipJackGateway.new(:login => 'X', :password => 'Y') + @gateway = SkipJackGateway.new(login: 'X', password: 'Y') @credit_card = credit_card('4242424242424242') @billing_address = { - :address1 => '123 Any St.', - :address2 => 'Apt. B', - :city => 'Anytown', - :state => 'ST', - :country => 'US', - :zip => '51511-1234', - :phone => '616-555-1212', - :fax => '616-555-2121' + address1: '123 Any St.', + address2: 'Apt. B', + city: 'Anytown', + state: 'ST', + country: 'US', + zip: '51511-1234', + phone: '616-555-1212', + fax: '616-555-2121' } @shipping_address = { - :name => 'Stew Packman', - :address1 => 'Company', - :address2 => '321 No RD', - :city => 'Nowhereton', - :state => 'ZC', - :country => 'MX', - :phone => '0123231212' + name: 'Stew Packman', + address1: 'Company', + address2: '321 No RD', + city: 'Nowhereton', + state: 'ZC', + country: 'MX', + phone: '0123231212' } @options = { - :order_id => 1, - :email => 'cody@example.com' + order_id: 1, + email: 'cody@example.com' } @amount = 100 @@ -103,10 +102,10 @@ def test_split_line end def test_turn_authorizeapi_response_into_hash - body = <<-EOS -"AUTHCODE","szSerialNumber","szTransactionAmount","szAuthorizationDeclinedMessage","szAVSResponseCode","szAVSResponseMessage","szOrderNumber","szAuthorizationResponseCode","szIsApproved","szCVV2ResponseCode","szCVV2ResponseMessage","szReturnCode","szTransactionFileName","szCAVVResponseCode" -"000067","999888777666","1900","","N","Card authorized, exact address match with 5 digit zipcode.","1","000067","1","","","1","10138083786558.009","" - EOS + body = <<~RESPONSE + "AUTHCODE","szSerialNumber","szTransactionAmount","szAuthorizationDeclinedMessage","szAVSResponseCode","szAVSResponseMessage","szOrderNumber","szAuthorizationResponseCode","szIsApproved","szCVV2ResponseCode","szCVV2ResponseMessage","szReturnCode","szTransactionFileName","szCAVVResponseCode" + "000067","999888777666","1900","","N","Card authorized, exact address match with 5 digit zipcode.","1","000067","1","","","1","10138083786558.009","" + RESPONSE map = @gateway.send(:authorize_response_map, body) @@ -194,7 +193,7 @@ def test_paymentech_authorization_failure end def test_serial_number_is_added_before_developer_serial_number_for_authorization - expected ="Year=#{Time.now.year + 1}&TransactionAmount=1.00&ShipToPhone=&SerialNumber=X&SJName=Longbob+Longsen&OrderString=1~None~0.00~0~N~%7C%7C&OrderNumber=1&OrderDescription=&Month=9&InvoiceNumber=&Email=cody%40example.com&DeveloperSerialNumber=Y&CustomerCode=&CVV2=123&AccountNumber=4242424242424242" + expected = "Year=#{Time.now.year + 1}&TransactionAmount=1.00&ShipToPhone=&SerialNumber=X&SJName=Longbob+Longsen&OrderString=1~None~0.00~0~N~%7C%7C&OrderNumber=1&OrderDescription=&Month=9&InvoiceNumber=&Email=cody%40example.com&DeveloperSerialNumber=Y&CustomerCode=&CVV2=123&AccountNumber=4242424242424242" expected = expected.gsub('~', '%7E') if RUBY_VERSION < '2.5.0' @gateway.expects(:ssl_post).with('https://developer.skipjackic.com/scripts/evolvcc.dll?AuthorizeAPI', expected).returns(successful_authorization_response) @@ -215,7 +214,7 @@ def test_successful_partial_capture response = @gateway.authorize(@amount, @credit_card, @options) @gateway.expects(:ssl_post).with('https://developer.skipjackic.com/scripts/evolvcc.dll?SJAPI_TransactionChangeStatusRequest', "szTransactionId=#{response.authorization}&szSerialNumber=X&szForceSettlement=0&szDeveloperSerialNumber=Y&szDesiredStatus=SETTLE&szAmount=1.00").returns(successful_capture_response) - response = @gateway.capture(@amount/2, response.authorization) + response = @gateway.capture(@amount / 2, response.authorization) assert_equal '1.0000', response.params['TransactionAmount'] end @@ -226,8 +225,8 @@ def test_dont_send_blank_state @options[:shipping_address] = @shipping_address @gateway.expects(:ssl_post).with do |url, params| url == 'https://developer.skipjackic.com/scripts/evolvcc.dll?AuthorizeAPI' && - CGI.parse(params)['State'].first == 'XX' && - CGI.parse(params)['ShipToState'].first == 'XX' + CGI.parse(params)['State'].first == 'XX' && + CGI.parse(params)['ShipToState'].first == 'XX' end.returns(successful_authorization_response) @gateway.authorize(@amount, @credit_card, @options) @@ -236,43 +235,43 @@ def test_dont_send_blank_state private def successful_authorization_response - <<-CSV -"AUTHCODE","szSerialNumber","szTransactionAmount","szAuthorizationDeclinedMessage","szAVSResponseCode","szAVSResponseMessage","szOrderNumber","szAuthorizationResponseCode","szIsApproved","szCVV2ResponseCode","szCVV2ResponseMessage","szReturnCode","szTransactionFileName","szCAVVResponseCode" -"TAS204","000386891209","100","","Y","Card authorized, exact address match with 5 digit zip code.","107a0fdb21ba42cf04f60274908085ea","TAS204","1","M","Match","1","9802853155172.022","" + <<~CSV + "AUTHCODE","szSerialNumber","szTransactionAmount","szAuthorizationDeclinedMessage","szAVSResponseCode","szAVSResponseMessage","szOrderNumber","szAuthorizationResponseCode","szIsApproved","szCVV2ResponseCode","szCVV2ResponseMessage","szReturnCode","szTransactionFileName","szCAVVResponseCode" + "TAS204","000386891209","100","","Y","Card authorized, exact address match with 5 digit zip code.","107a0fdb21ba42cf04f60274908085ea","TAS204","1","M","Match","1","9802853155172.022","" CSV end def successful_capture_response - <<-CSV -"000386891209","0","1","","","","","","","","","" -"000386891209","1.0000","SETTLE","SUCCESSFUL","Valid","618844630c5fad658e95abfd5e1d4e22","9802853156029.022" + <<~CSV + "000386891209","0","1","","","","","","","","","" + "000386891209","1.0000","SETTLE","SUCCESSFUL","Valid","618844630c5fad658e95abfd5e1d4e22","9802853156029.022" CSV end def successful_refund_response - <<-CSV -"AUTHCODE","szSerialNumber","szTransactionAmount","szAuthorizationDeclinedMessage","szAVSResponseCode","szAVSResponseMessage","szOrderNumber","szAuthorizationResponseCode","szIsApproved","szCVV2ResponseCode","szCVV2ResponseMessage","szReturnCode","szTransactionFileName","szCAVVResponseCode" -"TAS204","000386891209","100","","Y","Card authorized, exact address match with 5 digit zip code.","107a0fdb21ba42cf04f60274908085ea","TAS204","1","M","Match","1","9802853155172.022","" + <<~CSV + "AUTHCODE","szSerialNumber","szTransactionAmount","szAuthorizationDeclinedMessage","szAVSResponseCode","szAVSResponseMessage","szOrderNumber","szAuthorizationResponseCode","szIsApproved","szCVV2ResponseCode","szCVV2ResponseMessage","szReturnCode","szTransactionFileName","szCAVVResponseCode" + "TAS204","000386891209","100","","Y","Card authorized, exact address match with 5 digit zip code.","107a0fdb21ba42cf04f60274908085ea","TAS204","1","M","Match","1","9802853155172.022","" CSV end def unsuccessful_authorization_response - <<-CSV -"AUTHCODE","szSerialNumber","szTransactionAmount","szAuthorizationDeclinedMessage","szAVSResponseCode","szAVSResponseMessage","szOrderNumber","szAuthorizationResponseCode","szIsApproved","szCVV2ResponseCode","szCVV2ResponseMessage","szReturnCode","szTransactionFileName","szCAVVResponseCode"\r\n"EMPTY","000386891209","100","","","","b1eec256d0182f29375e0cbae685092d","","0","","","-35","","" + <<~CSV + "AUTHCODE","szSerialNumber","szTransactionAmount","szAuthorizationDeclinedMessage","szAVSResponseCode","szAVSResponseMessage","szOrderNumber","szAuthorizationResponseCode","szIsApproved","szCVV2ResponseCode","szCVV2ResponseMessage","szReturnCode","szTransactionFileName","szCAVVResponseCode"\r\n"EMPTY","000386891209","100","","","","b1eec256d0182f29375e0cbae685092d","","0","","","-35","","" CSV end def unsuccessful_paymentech_authorization_response - <<-CSV -"AUTHCODE","szSerialNumber","szTransactionAmount","szAuthorizationDeclinedMessage","szAVSResponseCode","szAVSResponseMessage","szOrderNumber","szAuthorizationResponseCode","szIsApproved","szCVV2ResponseCode","szCVV2ResponseMessage","szReturnCode","szTransactionFileName","szCAVVResponseCode", -"EMPTY","000000000000","1.00","","","","43985b7953199d1f02c3017f948e9f13","","0","","","-83","","", + <<~CSV + "AUTHCODE","szSerialNumber","szTransactionAmount","szAuthorizationDeclinedMessage","szAVSResponseCode","szAVSResponseMessage","szOrderNumber","szAuthorizationResponseCode","szIsApproved","szCVV2ResponseCode","szCVV2ResponseMessage","szReturnCode","szTransactionFileName","szCAVVResponseCode", + "EMPTY","000000000000","1.00","","","","43985b7953199d1f02c3017f948e9f13","","0","","","-83","","", CSV end def successful_paymentech_authorization_response - <<-CSV -"AUTHCODE","szSerialNumber","szTransactionAmount","szAuthorizationDeclinedMessage","szAVSResponseCode","szAVSResponseMessage","szOrderNumber","szAuthorizationResponseCode","szIsApproved","szCVV2ResponseCode","szCVV2ResponseMessage","szReturnCode","szTransactionFileName","szCAVVResponseCode", -"093223","000000000000","1.00","","Y","Card authorized, exact address match with 5 digit zip code.","5ac0f04e737baea5a5370037afe827f6","093223","1","M","Match","1","40000024585892.109","", + <<~CSV + "AUTHCODE","szSerialNumber","szTransactionAmount","szAuthorizationDeclinedMessage","szAVSResponseCode","szAVSResponseMessage","szOrderNumber","szAuthorizationResponseCode","szIsApproved","szCVV2ResponseCode","szCVV2ResponseMessage","szReturnCode","szTransactionFileName","szCAVVResponseCode", + "093223","000000000000","1.00","","Y","Card authorized, exact address match with 5 digit zip code.","5ac0f04e737baea5a5370037afe827f6","093223","1","M","Match","1","40000024585892.109","", CSV end end diff --git a/test/unit/gateways/so_easy_pay_test.rb b/test/unit/gateways/so_easy_pay_test.rb index 94a7f913a80..ae4c9579feb 100644 --- a/test/unit/gateways/so_easy_pay_test.rb +++ b/test/unit/gateways/so_easy_pay_test.rb @@ -3,17 +3,17 @@ class SoEasyPayTest < Test::Unit::TestCase def setup @gateway = SoEasyPayGateway.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 @@ -87,7 +87,7 @@ def test_do_not_depend_on_expiry_date_class def test_use_ducktyping_for_credit_card @gateway.expects(:ssl_post).returns(successful_purchase_response) - credit_card = stub(:number => '4242424242424242', :verification_value => '123', :name => 'Hans Tester', :year => 2012, :month => 1) + credit_card = stub(number: '4242424242424242', verification_value: '123', name: 'Hans Tester', year: 2012, month: 1) assert_nothing_raised do assert_success @gateway.purchase(@amount, credit_card, @options) @@ -220,5 +220,4 @@ def failed_credit_response ) end - end diff --git a/test/unit/gateways/spreedly_core_test.rb b/test/unit/gateways/spreedly_core_test.rb index 89e86fb2e28..6a819353a93 100644 --- a/test/unit/gateways/spreedly_core_test.rb +++ b/test/unit/gateways/spreedly_core_test.rb @@ -1,9 +1,8 @@ require 'test_helper' class SpreedlyCoreTest < Test::Unit::TestCase - def setup - @gateway = SpreedlyCoreGateway.new(:login => 'api_login', :password => 'api_secret', :gateway_token => 'token') + @gateway = SpreedlyCoreGateway.new(login: 'api_login', password: 'api_secret', gateway_token: 'token') @payment_method_token = 'E3eQGR3E0xiosj7FOJRtIKbF8Ch' @credit_card = credit_card @@ -950,7 +949,7 @@ def successful_unstore_response end def pre_scrubbed - <<-EOS + <<-REQUEST opening connection to core.spreedly.com:443... opened starting SSL for core.spreedly.com:443... @@ -975,11 +974,11 @@ def pre_scrubbed -> "\n NRBpydUCWn658GHV8h2kVlUzB0i\n 2018-03-10T22:04:06Z\n 2018-03-10T22:04:06Z\n true\n AddPaymentMethod\n false\n succeeded\n Succeeded!\n \n Wd25UIrH1uopTkZZ4UDdb5XmSDd\n 2018-03-10T22:04:06Z\n 2018-03-10T22:04:06Z\n \n \n cached\n true\n 4444\n 555555\n master\n Longbob\n Longsen\n 9\n 2019\n \n \n \n \n \n \n \n \n Longbob Longsen\n true\n \n \n \n \n \n \n \n credit_card\n \n \n XXX\n XXXX-XXXX-XXXX-4444\n 125370bb396dff6fed4f581f85a91a9e5317\n \n\n" read 1875 bytes Conn close - EOS + REQUEST end def post_scrubbed - <<-EOS + <<-REQUEST opening connection to core.spreedly.com:443... opened starting SSL for core.spreedly.com:443... @@ -1004,7 +1003,7 @@ def post_scrubbed -> "\n NRBpydUCWn658GHV8h2kVlUzB0i\n 2018-03-10T22:04:06Z\n 2018-03-10T22:04:06Z\n true\n AddPaymentMethod\n false\n succeeded\n Succeeded!\n \n Wd25UIrH1uopTkZZ4UDdb5XmSDd\n 2018-03-10T22:04:06Z\n 2018-03-10T22:04:06Z\n \n \n cached\n true\n 4444\n 555555\n master\n Longbob\n Longsen\n 9\n 2019\n \n \n \n \n \n \n \n \n Longbob Longsen\n true\n \n \n \n \n \n \n \n credit_card\n \n \n [FILTERED]\n [FILTERED]\n 125370bb396dff6fed4f581f85a91a9e5317\n \n\n" read 1875 bytes Conn close - EOS + REQUEST end def successful_verify_response diff --git a/test/unit/gateways/stripe_payment_intents_test.rb b/test/unit/gateways/stripe_payment_intents_test.rb index 6245e7b494a..c84634e1ab3 100644 --- a/test/unit/gateways/stripe_payment_intents_test.rb +++ b/test/unit/gateways/stripe_payment_intents_test.rb @@ -4,17 +4,24 @@ class StripePaymentIntentsTest < Test::Unit::TestCase include CommStub def setup - @gateway = StripePaymentIntentsGateway.new(:login => 'login') + @gateway = StripePaymentIntentsGateway.new(login: 'login') @credit_card = credit_card() @threeds_2_card = credit_card('4000000000003220') @visa_token = 'pm_card_visa' + + @three_ds_authentication_required_setup_for_off_session = 'pm_card_authenticationRequiredSetupForOffSession' + @three_ds_off_session_credit_card = credit_card('4000002500003155', + verification_value: '737', + month: 10, + year: 2022) + @amount = 2020 @update_amount = 2050 @options = { currency: 'GBP', - confirmation_method: 'manual', + confirmation_method: 'manual' } end @@ -55,6 +62,16 @@ def test_successful_create_and_update_intent assert_equal 'requires_confirmation', update.params['status'] end + def test_contains_statement_descriptor_suffix + options = @options.merge(capture_method: 'manual', statement_descriptor_suffix: 'suffix') + + stub_comms(@gateway, :ssl_request) do + @gateway.create_intent(@amount, @visa_token, options) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(/statement_descriptor_suffix=suffix/, data) + end.respond_with(successful_create_intent_response) + end + def test_successful_create_and_void_intent @gateway.expects(:ssl_request).twice.returns(successful_create_intent_response, successful_void_response) assert create = @gateway.create_intent(@amount, @visa_token, @options.merge(capture_method: 'manual', confirm: true)) @@ -64,6 +81,85 @@ def test_successful_create_and_void_intent assert_equal 'canceled', cancel.params['status'] end + def test_create_intent_with_optional_idempotency_key_header + idempotency_key = 'test123' + options = @options.merge(idempotency_key: idempotency_key) + + stub_comms(@gateway, :ssl_request) do + @gateway.create_intent(@amount, @visa_token, options) + end.check_request do |_method, _endpoint, _data, headers| + assert_equal idempotency_key, headers['Idempotency-Key'] + end.respond_with(successful_create_intent_response) + end + + def test_request_three_d_secure + request_three_d_secure = 'any' + options = @options.merge(request_three_d_secure: request_three_d_secure) + + stub_comms(@gateway, :ssl_request) do + @gateway.create_intent(@amount, @visa_token, options) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(/\[request_three_d_secure\]=any/, data) + end.respond_with(successful_request_three_d_secure_response) + + request_three_d_secure = 'automatic' + options = @options.merge(request_three_d_secure: request_three_d_secure) + + stub_comms(@gateway, :ssl_request) do + @gateway.create_intent(@amount, @visa_token, options) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(/\[request_three_d_secure\]=automatic/, data) + end.respond_with(successful_request_three_d_secure_response) + + request_three_d_secure = true + options = @options.merge(request_three_d_secure: request_three_d_secure) + + stub_comms(@gateway, :ssl_request) do + @gateway.create_intent(@amount, @visa_token, options) + end.check_request do |_method, _endpoint, data, _headers| + refute_match(/\[request_three_d_secure\]/, data) + end.respond_with(successful_request_three_d_secure_response) + end + + def test_external_three_d_secure_auth_data + options = @options.merge( + three_d_secure: { + eci: '05', + cavv: '4BQwsg4yuKt0S1LI1nDZTcO9vUM=', + xid: 'd+NEBKSpEMauwleRhdrDY06qj4A=' + } + ) + + stub_comms(@gateway, :ssl_request) do + @gateway.purchase(@amount, @visa_token, options) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(/payment_method_options\[card\]\[three_d_secure\]/, data) + assert_match(/three_d_secure\]\[version\]=1.0.2/, data) + assert_match(/three_d_secure\]\[electronic_commerce_indicator\]=05/, data) + assert_match(/three_d_secure\]\[cryptogram\]=4BQwsg4yuKt0S1LI1nDZTcO9vUM%3D/, data) + assert_match(/three_d_secure\]\[transaction_id\]=d%2BNEBKSpEMauwleRhdrDY06qj4A%3D/, data) + end.respond_with(successful_request_three_d_secure_response) + + options = @options.merge( + three_d_secure: { + version: '2.1.0', + eci: '02', + cavv: 'jJ81HADVRtXfCBATEp01CJUAAAA=', + ds_transaction_id: 'f879ea1c-aa2c-4441-806d-e30406466d79' + } + ) + + stub_comms(@gateway, :ssl_request) do + @gateway.purchase(@amount, @visa_token, options) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(/payment_method_options\[card\]\[three_d_secure\]/, data) + assert_match(/three_d_secure\]\[version\]=2.1.0/, data) + assert_match(/three_d_secure\]\[electronic_commerce_indicator\]=02/, data) + assert_match(/three_d_secure\]\[cryptogram\]=jJ81HADVRtXfCBATEp01CJUAAAA%3D/, data) + assert_match(/three_d_secure\]\[transaction_id\]=f879ea1c-aa2c-4441-806d-e30406466d79/, data) + end.respond_with(successful_request_three_d_secure_response) + end + def test_failed_capture_after_creation @gateway.expects(:ssl_request).returns(failed_capture_response) @@ -85,6 +181,177 @@ def test_failed_void_after_capture 'requires_payment_method, requires_capture, requires_confirmation, requires_action.', cancel.message end + def test_connected_account + destination = 'account_27701' + amount = 8000 + on_behalf_of = 'account_27704' + transfer_group = 'TG1000' + application_fee_amount = 100 + + options = @options.merge( + transfer_destination: destination, + transfer_amount: amount, + on_behalf_of: on_behalf_of, + transfer_group: transfer_group, + application_fee: application_fee_amount + ) + + stub_comms(@gateway, :ssl_request) do + @gateway.create_intent(@amount, @visa_token, options) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(/transfer_data\[destination\]=#{destination}/, data) + assert_match(/transfer_data\[amount\]=#{amount}/, data) + assert_match(/on_behalf_of=#{on_behalf_of}/, data) + assert_match(/transfer_group=#{transfer_group}/, data) + assert_match(/application_fee_amount=#{application_fee_amount}/, data) + end.respond_with(successful_create_intent_response) + end + + def test_on_behalf_of + on_behalf_of = 'account_27704' + + options = @options.merge( + on_behalf_of: on_behalf_of + ) + + stub_comms(@gateway, :ssl_request) do + @gateway.create_intent(@amount, @visa_token, options) + end.check_request do |_method, _endpoint, data, _headers| + assert_no_match(/transfer_data\[destination\]/, data) + assert_no_match(/transfer_data\[amount\]/, data) + assert_match(/on_behalf_of=#{on_behalf_of}/, data) + assert_no_match(/transfer_group/, data) + assert_no_match(/application_fee_amount/, data) + end.respond_with(successful_create_intent_response) + end + + def test_failed_payment_methods_post + @gateway.expects(:ssl_request).returns(failed_payment_method_response) + + assert create = @gateway.create_intent(@amount, 'pm_failed', @options) + assert_equal 'validation_error', create.params.dig('error', 'code') + assert_equal 'You must verify a phone number on your Stripe account before you can send raw credit card numbers to the Stripe API. You can avoid this requirement by using Stripe.js, the Stripe mobile bindings, or Stripe Checkout. For more information, see https://dashboard.stripe.com/phone-verification.', create.params.dig('error', 'message') + assert_equal 'invalid_request_error', create.params.dig('error', 'type') + end + + def test_failed_error_on_requires_action + @gateway.expects(:ssl_request).returns(failed_with_set_error_on_requires_action_response) + + assert create = @gateway.create_intent(@amount, 'pm_failed', @options) + assert_equal 'This payment required an authentication action to complete, but `error_on_requires_action` was set. When you\'re ready, you can upgrade your integration to handle actions at https://stripe.com/docs/payments/payment-intents/upgrade-to-handle-actions.', create.params.dig('error', 'message') + assert_equal 'card_error', create.params.dig('error', 'type') + end + + def test_failed_refund_due_to_service_unavailability + @gateway.expects(:ssl_request).returns(failed_service_response) + + assert refund = @gateway.refund(@amount, 'pi_123') + assert_failure refund + assert_match(/Error while communicating with one of our backends/, refund.params.dig('error', 'message')) + end + + def test_failed_refund_due_to_pending_3ds_auth + @gateway.expects(:ssl_request).returns(successful_confirm_3ds2_intent_response) + + assert refund = @gateway.refund(@amount, 'pi_123') + assert_failure refund + assert_equal 'requires_action', refund.params['status'] + assert_match(/payment_intent has a status of requires_action/, refund.message) + end + + def test_successful_verify + @gateway.expects(:ssl_request).returns(successful_verify_response) + assert verify = @gateway.verify(@visa_token) + assert_success verify + assert_equal 'succeeded', verify.params['status'] + end + + def test_succesful_purchase_with_stored_credentials + [@three_ds_off_session_credit_card, @three_ds_authentication_required_setup_for_off_session].each do |card_to_use| + network_transaction_id = '1098510912210968' + stub_comms(@gateway, :ssl_request) do + @gateway.purchase(@amount, card_to_use, { + currency: 'USD', + execute_threed: true, + confirm: true, + off_session: true, + stored_credential: { + network_transaction_id: network_transaction_id, # TEST env seems happy with any value :/ + ds_transaction_id: 'null' # this is optional and can be null if not available. + } + }) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(%r{payment_method_options\[card\]\[mit_exemption\]\[network_transaction_id\]=#{network_transaction_id}}, data) + assert_match(%r{payment_method_options\[card\]\[mit_exemption\]\[ds_transaction_id\]=null}, data) + end.respond_with(successful_create_intent_response) + end + end + + def test_succesful_purchase_with_stored_credentials_without_optional_ds_transaction_id + [@three_ds_off_session_credit_card, @three_ds_authentication_required_setup_for_off_session].each do |card_to_use| + network_transaction_id = '1098510912210968' + stub_comms(@gateway, :ssl_request) do + @gateway.purchase(@amount, card_to_use, { + currency: 'USD', + execute_threed: true, + confirm: true, + off_session: true, + stored_credential: { + network_transaction_id: network_transaction_id, # TEST env seems happy with any value :/ + } + }) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(%r{payment_method_options\[card\]\[mit_exemption\]\[network_transaction_id\]=#{network_transaction_id}}, data) + assert_no_match(%r{payment_method_options\[card\]\[mit_exemption\]\[ds_transaction_id\]=null}, data) + end.respond_with(successful_create_intent_response) + end + end + + def test_succesful_purchase_without_stored_credentials_introduces_no_exemption_fields + [@three_ds_off_session_credit_card, @three_ds_authentication_required_setup_for_off_session].each do |card_to_use| + stub_comms(@gateway, :ssl_request) do + @gateway.purchase(@amount, card_to_use, { + currency: 'USD' + }) + end.check_request do |_method, _endpoint, data, _headers| + assert_no_match(%r{payment_method_options\[card\]\[mit_exemption\]\[network_transaction_id\]=}, data) + assert_no_match(%r{payment_method_options\[card\]\[mit_exemption\]\[ds_transaction_id\]=null}, data) + end.respond_with(successful_create_intent_response) + end + end + + def test_store_does_not_pass_validation_to_attach_by_default + stub_comms(@gateway, :ssl_request) do + @gateway.store(@credit_card) + end.check_request do |_method, endpoint, data, _headers| + assert_no_match(/validate=/, data) if /attach/.match?(endpoint) + end.respond_with(successful_payment_method_response, successful_create_customer_response, successful_payment_method_attach_response) + end + + def test_store_sets_validation_on_attach_to_false_when_false_in_options + options = @options.merge( + validate: false + ) + + stub_comms(@gateway, :ssl_request) do + @gateway.store(@credit_card, options) + end.check_request do |_method, endpoint, data, _headers| + assert_match(/validate=false/, data) if /attach/.match?(endpoint) + end.respond_with(successful_payment_method_response, successful_create_customer_response, successful_payment_method_attach_response) + end + + def test_store_sets_validationon_attach_to_true_when_true_in_options + options = @options.merge( + validate: true + ) + + stub_comms(@gateway, :ssl_request) do + @gateway.store(@credit_card, options) + end.check_request do |_method, endpoint, data, _headers| + assert_match(/validate=true/, data) if /attach/.match?(endpoint) + end.respond_with(successful_payment_method_response, successful_create_customer_response, successful_payment_method_attach_response) + end + private def successful_create_intent_response @@ -252,6 +519,131 @@ def successful_confirm_3ds2_intent_response RESPONSE end + def successful_request_three_d_secure_response + <<-RESPONSE + {"id"=>"pi_1HZJGPAWOtgoysogrKURP11Q", + "object"=>"payment_intent", + "amount"=>2000, + "amount_capturable"=>0, + "amount_received"=>2000, + "application"=>nil, + "application_fee_amount"=>nil, + "canceled_at"=>nil, + "cancellation_reason"=>nil, + "capture_method"=>"automatic", + "charges"=> + {"object"=>"list", + "data"=> + [{"id"=>"ch_1HZJGQAWOtgoysogEpbZTGIl", + "object"=>"charge", + "amount"=>2000, + "amount_captured"=>2000, + "amount_refunded"=>0, + "application"=>nil, + "application_fee"=>nil, + "application_fee_amount"=>nil, + "balance_transaction"=>"txn_1HZJGQAWOtgoysogEKwV2r5N", + "billing_details"=> + {"address"=>{"city"=>nil, "country"=>nil, "line1"=>nil, "line2"=>nil, "postal_code"=>nil, "state"=>nil}, "email"=>nil, "name"=>nil, "phone"=>nil}, + "calculated_statement_descriptor"=>"SPREEDLY", + "captured"=>true, + "created"=>1602002626, + "currency"=>"gbp", + "customer"=>nil, + "description"=>nil, + "destination"=>nil, + "dispute"=>nil, + "disputed"=>false, + "failure_code"=>nil, + "failure_message"=>nil, + "fraud_details"=>{}, + "invoice"=>nil, + "livemode"=>false, + "metadata"=>{}, + "on_behalf_of"=>nil, + "order"=>nil, + "outcome"=> + {"network_status"=>"approved_by_network", + "reason"=>nil, + "risk_level"=>"normal", + "risk_score"=>16, + "seller_message"=>"Payment complete.", + "type"=>"authorized"}, + "paid"=>true, + "payment_intent"=>"pi_1HZJGPAWOtgoysogrKURP11Q", + "payment_method"=>"pm_1HZJGOAWOtgoysogvnMsnnG1", + "payment_method_details"=> + {"card"=> + {"brand"=>"visa", + "checks"=>{"address_line1_check"=>nil, "address_postal_code_check"=>nil, "cvc_check"=>"pass"}, + "country"=>"US", + "ds_transaction_id"=>nil, + "exp_month"=>10, + "exp_year"=>2020, + "fingerprint"=>"hfaVNMiXc0dYSiC5", + "funding"=>"credit", + "installments"=>nil, + "last4"=>"4242", + "moto"=>nil, + "network"=>"visa", + "network_transaction_id"=>"1041029786787710", + "three_d_secure"=> + {"authenticated"=>false, + "authentication_flow"=>nil, + "electronic_commerce_indicator"=>"06", + "result"=>"attempt_acknowledged", + "result_reason"=>nil, + "succeeded"=>true, + "transaction_id"=>"d1VlRVF6a1BVNXN1cjMzZVl0RU0=", + "version"=>"1.0.2"}, + "wallet"=>nil}, + "type"=>"card"}, + "receipt_email"=>nil, + "receipt_number"=>nil, + "receipt_url"=>"https://pay.stripe.com/receipts/acct_160DX6AWOtgoysog/ch_1HZJGQAWOtgoysogEpbZTGIl/rcpt_I9cVpN9xAeS39FhMqTS33Fj8gHsjjuX", + "refunded"=>false, + "refunds"=>{"object"=>"list", "data"=>[], "has_more"=>false, "total_count"=>0, "url"=>"/v1/charges/ch_1HZJGQAWOtgoysogEpbZTGIl/refunds"}, + "review"=>nil, + "shipping"=>nil, + "source"=>nil, + "source_transfer"=>nil, + "statement_descriptor"=>nil, + "statement_descriptor_suffix"=>nil, + "status"=>"succeeded", + "transfer_data"=>nil, + "transfer_group"=>nil}], + "has_more"=>false, + "total_count"=>1, + "url"=>"/v1/charges?payment_intent=pi_1HZJGPAWOtgoysogrKURP11Q"}, + "client_secret"=>"pi_1HZJGPAWOtgoysogrKURP11Q_secret_dJNY00dYXC22Fc9nPscAmhFMt", + "confirmation_method"=>"automatic", + "created"=>1602002625, + "currency"=>"gbp", + "customer"=>nil, + "description"=>nil, + "invoice"=>nil, + "last_payment_error"=>nil, + "livemode"=>false, + "metadata"=>{}, + "next_action"=>nil, + "on_behalf_of"=>nil, + "payment_method"=>"pm_1HZJGOAWOtgoysogvnMsnnG1", + "payment_method_options"=>{"card"=>{"installments"=>nil, "network"=>nil, "request_three_d_secure"=>"any"}}, + "payment_method_types"=>["card"], + "receipt_email"=>nil, + "review"=>nil, + "setup_future_usage"=>nil, + "shipping"=>nil, + "source"=>nil, + "statement_descriptor"=>nil, + "statement_descriptor_suffix"=>nil, + "status"=>"succeeded", + "transfer_data"=>nil, + "transfer_group"=>nil + } + RESPONSE + end + def failed_capture_response <<-RESPONSE {"error":{"charge":"ch_1F2MB6AWOtgoysogAIvNV32Z","code":"card_declined","decline_code":"generic_decline","doc_url":"https://stripe.com/docs/error-codes/card-declined","message":"Your card was declined.","payment_intent":{"id":"pi_1F2MB5AWOtgoysogCMt8BaxR","object":"payment_intent","amount":2020,"amount_capturable":0,"amount_received":0,"application":null,"application_fee_amount":null,"canceled_at":null,"cancellation_reason":null,"capture_method":"automatic","charges":{"object":"list","data":[{"id":"ch_1F2MB6AWOtgoysogAIvNV32Z","object":"charge","amount":2020,"amount_refunded":0,"application":null,"application_fee":null,"application_fee_amount":null,"balance_transaction":null,"billing_details":{"address":{"city":null,"country":null,"line1":null,"line2":null,"postal_code":null,"state":null},"email":null,"name":null,"phone":null},"captured":false,"created":1564596332,"currency":"gbp","customer":"cus_7s22nNueP2Hjj6","description":null,"destination":null,"dispute":null,"failure_code":"card_declined","failure_message":"Your card was declined.","fraud_details":{},"invoice":null,"livemode":false,"metadata":{},"on_behalf_of":null,"order":null,"outcome":{"network_status":"declined_by_network","reason":"generic_decline","risk_level":"normal","risk_score":41,"seller_message":"The bank did not return any further details with this decline.","type":"issuer_declined"},"paid":false,"payment_intent":"pi_1F2MB5AWOtgoysogCMt8BaxR","payment_method":"pm_1F2MB5AWOtgoysogq3yXZ98h","payment_method_details":{"card":{"brand":"visa","checks":{"address_line1_check":null,"address_postal_code_check":null,"cvc_check":null},"country":"US","exp_month":7,"exp_year":2020,"fingerprint":"1VUoWMvHnqtngyrD","funding":"credit","last4":"0002","three_d_secure":null,"wallet":null},"type":"card"},"receipt_email":null,"receipt_number":null,"receipt_url":"https://pay.stripe.com/receipts/acct_160DX6AWOtgoysog/ch_1F2MB6AWOtgoysogAIvNV32Z/rcpt_FXR3PjBGluHmHsnLmp0S2KQiHl3yg6W","refunded":false,"refunds":{"object":"list","data":[],"has_more":false,"total_count":0,"url":"/v1/charges/ch_1F2MB6AWOtgoysogAIvNV32Z/refunds"},"review":null,"shipping":null,"source":null,"source_transfer":null,"statement_descriptor":null,"status":"failed","transfer_data":null,"transfer_group":null}],"has_more":false,"total_count":1,"url":"/v1/charges?payment_intent=pi_1F2MB5AWOtgoysogCMt8BaxR"},"client_secret":"pi_1F2MB5AWOtgoysogCMt8BaxR_secret_fOHryjtjBE4gACiHTcREraXSQ","confirmation_method":"manual","created":1564596331,"currency":"gbp","customer":"cus_7s22nNueP2Hjj6","description":null,"invoice":null,"last_payment_error":{"charge":"ch_1F2MB6AWOtgoysogAIvNV32Z","code":"card_declined","decline_code":"generic_decline","doc_url":"https://stripe.com/docs/error-codes/card-declined","message":"Your card was declined.","payment_method":{"id":"pm_1F2MB5AWOtgoysogq3yXZ98h","object":"payment_method","billing_details":{"address":{"city":null,"country":null,"line1":null,"line2":null,"postal_code":null,"state":null},"email":null,"name":null,"phone":null},"card":{"brand":"visa","checks":{"address_line1_check":null,"address_postal_code_check":null,"cvc_check":null},"country":"US","exp_month":7,"exp_year":2020,"fingerprint":"1VUoWMvHnqtngyrD","funding":"credit","generated_from":null,"last4":"0002","three_d_secure_usage":{"supported":true},"wallet":null},"created":1564596331,"customer":null,"livemode":false,"metadata":{},"type":"card"},"type":"card_error"},"livemode":false,"metadata":{},"next_action":null,"on_behalf_of":null,"payment_method":null,"payment_method_options":{"card":{"request_three_d_secure":"automatic"}},"payment_method_types":["card"],"receipt_email":null,"review":null,"setup_future_usage":null,"shipping":null,"source":null,"statement_descriptor":null,"status":"requires_payment_method","transfer_data":null,"transfer_group":null},"payment_method":{"id":"pm_1F2MB5AWOtgoysogq3yXZ98h","object":"payment_method","billing_details":{"address":{"city":null,"country":null,"line1":null,"line2":null,"postal_code":null,"state":null},"email":null,"name":null,"phone":null},"card":{"brand":"visa","checks":{"address_line1_check":null,"address_postal_code_check":null,"cvc_check":null},"country":"US","exp_month":7,"exp_year":2020,"fingerprint":"1VUoWMvHnqtngyrD","funding":"credit","generated_from":null,"last4":"0002","three_d_secure_usage":{"supported":true},"wallet":null},"created":1564596331,"customer":null,"livemode":false,"metadata":{},"type":"card"},"type":"card_error"}} @@ -263,4 +655,219 @@ def failed_cancel_response {"error":{"code":"payment_intent_unexpected_state","doc_url":"https://stripe.com/docs/error-codes/payment-intent-unexpected-state","message":"You cannot cancel this PaymentIntent because it has a status of succeeded. Only a PaymentIntent with one of the following statuses may be canceled: requires_payment_method, requires_capture, requires_confirmation, requires_action.","payment_intent":{"id":"pi_1F2McmAWOtgoysoglFLDRWab","object":"payment_intent","amount":2020,"amount_capturable":0,"amount_received":2020,"application":null,"application_fee_amount":null,"canceled_at":null,"cancellation_reason":null,"capture_method":"automatic","charges":{"object":"list","data":[{"id":"ch_1F2McmAWOtgoysogQgUS1YtH","object":"charge","amount":2020,"amount_refunded":0,"application":null,"application_fee":null,"application_fee_amount":null,"balance_transaction":"txn_1F2McmAWOtgoysog8uxBEJ30","billing_details":{"address":{"city":null,"country":null,"line1":null,"line2":null,"postal_code":null,"state":null},"email":null,"name":null,"phone":null},"captured":true,"created":1564598048,"currency":"gbp","customer":"cus_7s22nNueP2Hjj6","description":null,"destination":null,"dispute":null,"failure_code":null,"failure_message":null,"fraud_details":{},"invoice":null,"livemode":false,"metadata":{},"on_behalf_of":null,"order":null,"outcome":{"network_status":"approved_by_network","reason":null,"risk_level":"normal","risk_score":53,"seller_message":"Payment complete.","type":"authorized"},"paid":true,"payment_intent":"pi_1F2McmAWOtgoysoglFLDRWab","payment_method":"pm_1F2MclAWOtgoysogq80GBBMO","payment_method_details":{"card":{"brand":"visa","checks":{"address_line1_check":null,"address_postal_code_check":null,"cvc_check":null},"country":"US","exp_month":7,"exp_year":2020,"fingerprint":"hfaVNMiXc0dYSiC5","funding":"credit","last4":"4242","three_d_secure":null,"wallet":null},"type":"card"},"receipt_email":null,"receipt_number":null,"receipt_url":"https://pay.stripe.com/receipts/acct_160DX6AWOtgoysog/ch_1F2McmAWOtgoysogQgUS1YtH/rcpt_FXRVzyFnf7aCS1r13N3uym1u8AaboOJ","refunded":false,"refunds":{"object":"list","data":[],"has_more":false,"total_count":0,"url":"/v1/charges/ch_1F2McmAWOtgoysogQgUS1YtH/refunds"},"review":null,"shipping":null,"source":null,"source_transfer":null,"statement_descriptor":null,"status":"succeeded","transfer_data":null,"transfer_group":null}],"has_more":false,"total_count":1,"url":"/v1/charges?payment_intent=pi_1F2McmAWOtgoysoglFLDRWab"},"client_secret":"pi_1F2McmAWOtgoysoglFLDRWab_secret_z4faDF0Cv0JZJ6pxK3bdIodkD","confirmation_method":"manual","created":1564598048,"currency":"gbp","customer":"cus_7s22nNueP2Hjj6","description":null,"invoice":null,"last_payment_error":null,"livemode":false,"metadata":{},"next_action":null,"on_behalf_of":null,"payment_method":"pm_1F2MclAWOtgoysogq80GBBMO","payment_method_options":{"card":{"request_three_d_secure":"automatic"}},"payment_method_types":["card"],"receipt_email":null,"review":null,"setup_future_usage":null,"shipping":null,"source":null,"statement_descriptor":null,"status":"succeeded","transfer_data":null,"transfer_group":null},"type":"invalid_request_error"}} RESPONSE end + + def failed_payment_method_response + <<-RESPONSE + {"error": {"code": "validation_error", "message": "You must verify a phone number on your Stripe account before you can send raw credit card numbers to the Stripe API. You can avoid this requirement by using Stripe.js, the Stripe mobile bindings, or Stripe Checkout. For more information, see https://dashboard.stripe.com/phone-verification.", "type": "invalid_request_error"}} + RESPONSE + end + + def failed_service_response + <<-RESPONSE + {"error": {"message": "Error while communicating with one of our backends. Sorry about that! We have been notified of the problem. If you have any questions, we can help at https://support.stripe.com/.", "type": "api_error" }} + RESPONSE + end + + def failed_with_set_error_on_requires_action_response + <<-RESPONSE + {"error": {"message": "This payment required an authentication action to complete, but `error_on_requires_action` was set. When you're ready, you can upgrade your integration to handle actions at https://stripe.com/docs/payments/payment-intents/upgrade-to-handle-actions.", "type": "card_error" }} + RESPONSE + end + + def successful_verify_response + <<-RESPONSE + { + "id": "seti_1Gsw0aAWOtgoysog0XjSBPVX", + "object": "setup_intent", + "application": null, + "cancellation_reason": null, + "client_secret": "seti_1Gsw0aAWOtgoysog0XjSBPVX_secret_HRpfHkvewAdYQJgee27ihJfm4E4zWmW", + "created": 1591903456, + "customer": "cus_GkjsDZC58SgUcY", + "description": null, + "last_setup_error": null, + "livemode": false, + "mandate": null, + "metadata": { + }, + "next_action": null, + "on_behalf_of": null, + "payment_method": "pm_1Gsw0aAWOtgoysog304wX4J9", + "payment_method_options": { + "card": { + "request_three_d_secure": "automatic" + } + }, + "payment_method_types": [ + "card" + ], + "single_use_mandate": null, + "status": "succeeded", + "usage": "off_session" + } + RESPONSE + end + + def successful_payment_method_response + <<-RESPONSE + { + "id": "pm_1IQ3OhAWOtgoysogUkVwJ5MT", + "object": "payment_method", + "billing_details": { + "address": { + "city": null, + "country": null, + "line1": null, + "line2": null, + "postal_code": null, + "state": null + }, + "email": null, + "name": null, + "phone": null + }, + "card": { + "brand": "visa", + "checks": { + "address_line1_check": null, + "address_postal_code_check": null, + "cvc_check": "unchecked" + }, + "country": "US", + "exp_month": 10, + "exp_year": 2021, + "fingerprint": "hfaVNMiXc0dYSiC5", + "funding": "credit", + "generated_from": null, + "last4": "4242", + "networks": { + "available": [ + "visa" + ], + "preferred": null + }, + "three_d_secure_usage": { + "supported": true + }, + "wallet": null + }, + "created": 1614573020, + "customer": null, + "livemode": false, + "metadata": { + }, + "type": "card" + } + RESPONSE + end + + def successful_create_customer_response + <<-RESPONSE + { + "id": "cus_J27e2tthifSmpm", + "object": "customer", + "account_balance": 0, + "address": null, + "balance": 0, + "created": 1614573020, + "currency": null, + "default_source": null, + "delinquent": false, + "description": null, + "discount": null, + "email": null, + "invoice_prefix": "B0C3D1B5", + "invoice_settings": { + "custom_fields": null, + "default_payment_method": null, + "footer": null + }, + "livemode": false, + "metadata": { + }, + "name": null, + "next_invoice_sequence": 1, + "phone": null, + "preferred_locales": [], + "shipping": null, + "sources": { + "object": "list", + "data": [], + "has_more": false, + "total_count": 0, + "url": "/v1/customers/cus_J27e2tthifSmpm/sources" + }, + "subscriptions": { + "object": "list", + "data": [], + "has_more": false, + "total_count": 0, + "url": "/v1/customers/cus_J27e2tthifSmpm/subscriptions" + }, + "tax_exempt": "none", + "tax_ids": { + "object": "list", + "data": [], + "has_more": false, + "total_count": 0, + "url": "/v1/customers/cus_J27e2tthifSmpm/tax_ids" + }, + "tax_info": null, + "tax_info_verification": null + } + RESPONSE + end + + def successful_payment_method_attach_response + <<-RESPONSE + { + "id": "pm_1IQ3AYAWOtgoysogcvbllgNa", + "object": "payment_method", + "billing_details": { + "address": { + "city": null, + "country": null, + "line1": null, + "line2": null, + "postal_code": null, + "state": null + }, + "email": null, + "name": null, + "phone": null + }, + "card": { + "brand": "visa", + "checks": { + "address_line1_check": null, + "address_postal_code_check": null, + "cvc_check": "unchecked" + }, + "country": "US", + "exp_month": 10, + "exp_year": 2021, + "fingerprint": "hfaVNMiXc0dYSiC5", + "funding": "credit", + "generated_from": null, + "last4": "4242", + "networks": { + "available": [ + "visa" + ], + "preferred": null + }, + "three_d_secure_usage": { + "supported": true + }, + "wallet": null + }, + "created": 1614572142, + "customer": "cus_J27PL9krZlnw82", + "livemode": false, + "metadata": { + }, + "type": "card" + } + RESPONSE + end end diff --git a/test/unit/gateways/stripe_test.rb b/test/unit/gateways/stripe_test.rb index 0fb2d96ff1b..069c4067bae 100644 --- a/test/unit/gateways/stripe_test.rb +++ b/test/unit/gateways/stripe_test.rb @@ -4,7 +4,7 @@ class StripeTest < Test::Unit::TestCase include CommStub def setup - @gateway = StripeGateway.new(:login => 'login') + @gateway = StripeGateway.new(login: 'login') @credit_card = credit_card() @threeds_card = credit_card('4000000000003063') @@ -13,14 +13,14 @@ def setup @refund_amount = 200 @options = { - :billing_address => address(), - :statement_address => statement_address(), - :description => 'Test Purchase' + billing_address: address(), + statement_address: statement_address(), + description: 'Test Purchase' } @threeds_options = { - :execute_threed => true, - :callback_url => 'http://www.example.com/callback' + execute_threed: true, + callback_url: 'http://www.example.com/callback' } @apple_pay_payment_token = apple_pay_payment_token @@ -31,7 +31,7 @@ def setup @check = check({ bank_name: 'STRIPE TEST BANK', account_number: '000123456789', - routing_number: '110000000', + routing_number: '110000000' }) end @@ -82,7 +82,7 @@ def test_successful_new_card @gateway.expects(:ssl_request).returns(successful_new_card_response) @gateway.expects(:add_creditcard) - assert response = @gateway.store(@credit_card, :customer => 'cus_3sgheFxeBgTQ3M') + assert response = @gateway.store(@credit_card, customer: 'cus_3sgheFxeBgTQ3M') assert_instance_of MultiResponse, response assert_success response @@ -94,7 +94,7 @@ def test_successful_new_card_via_apple_pay_payment_token @gateway.expects(:ssl_request).returns(successful_new_card_response) @gateway.expects(:tokenize_apple_pay_token).returns(Response.new(true, nil, token: successful_apple_pay_token_exchange)) - assert response = @gateway.store(@apple_pay_payment_token, :customer => 'cus_3sgheFxeBgTQ3M') + assert response = @gateway.store(@apple_pay_payment_token, customer: 'cus_3sgheFxeBgTQ3M') assert_instance_of MultiResponse, response assert_success response @@ -106,7 +106,7 @@ def test_successful_new_card_with_emv_credit_card @gateway.expects(:ssl_request).returns(successful_new_card_response) @gateway.expects(:add_creditcard) - assert response = @gateway.store(@emv_credit_card, :customer => 'cus_3sgheFxeBgTQ3M') + assert response = @gateway.store(@emv_credit_card, customer: 'cus_3sgheFxeBgTQ3M') assert_instance_of MultiResponse, response assert_success response @@ -118,7 +118,7 @@ def test_successful_new_card_with_token_string @gateway.expects(:ssl_request).returns(successful_new_card_response) @gateway.expects(:add_creditcard) - assert response = @gateway.store(@token_string, :customer => 'cus_3sgheFxeBgTQ3M') + assert response = @gateway.store(@token_string, customer: 'cus_3sgheFxeBgTQ3M') assert_instance_of MultiResponse, response assert_success response @@ -130,7 +130,7 @@ def test_successful_new_card_with_payment_token @gateway.expects(:ssl_request).returns(successful_new_card_response) @gateway.expects(:add_payment_token) - assert response = @gateway.store(@payment_token, :customer => 'cus_3sgheFxeBgTQ3M') + assert response = @gateway.store(@payment_token, customer: 'cus_3sgheFxeBgTQ3M') assert_instance_of MultiResponse, response assert_success response @@ -142,7 +142,7 @@ def test_successful_new_card_and_customer_update @gateway.expects(:ssl_request).twice.returns(successful_new_card_response, successful_new_customer_response) @gateway.expects(:add_creditcard) - assert response = @gateway.store(@credit_card, :customer => 'cus_3sgheFxeBgTQ3M', :email => 'test@test.com') + assert response = @gateway.store(@credit_card, customer: 'cus_3sgheFxeBgTQ3M', email: 'test@test.com') assert_instance_of MultiResponse, response assert_success response @@ -157,7 +157,7 @@ def test_successful_new_card_and_customer_update_via_apple_pay_payment_token @gateway.expects(:ssl_request).twice.returns(successful_new_card_response, successful_new_customer_response) @gateway.expects(:tokenize_apple_pay_token).returns(Response.new(true, nil, token: successful_apple_pay_token_exchange)) - assert response = @gateway.store(@apple_pay_payment_token, :customer => 'cus_3sgheFxeBgTQ3M', :email => 'test@test.com') + assert response = @gateway.store(@apple_pay_payment_token, customer: 'cus_3sgheFxeBgTQ3M', email: 'test@test.com') assert_instance_of MultiResponse, response assert_success response @@ -171,7 +171,7 @@ def test_successful_new_card_and_customer_update_via_apple_pay_payment_token def test_successful_new_card_and_customer_update_with_emv_credit_card @gateway.expects(:ssl_request).twice.returns(successful_new_card_response, successful_new_customer_response) - assert response = @gateway.store(@emv_credit_card, :customer => 'cus_3sgheFxeBgTQ3M', :email => 'test@test.com') + assert response = @gateway.store(@emv_credit_card, customer: 'cus_3sgheFxeBgTQ3M', email: 'test@test.com') assert_instance_of MultiResponse, response assert_success response @@ -185,7 +185,7 @@ def test_successful_new_card_and_customer_update_with_emv_credit_card def test_successful_new_card_and_customer_update_with_token_string @gateway.expects(:ssl_request).twice.returns(successful_new_card_response, successful_new_customer_response) - assert response = @gateway.store(@token_string, :customer => 'cus_3sgheFxeBgTQ3M', :email => 'test@test.com') + assert response = @gateway.store(@token_string, customer: 'cus_3sgheFxeBgTQ3M', email: 'test@test.com') assert_instance_of MultiResponse, response assert_success response @@ -199,7 +199,7 @@ def test_successful_new_card_and_customer_update_with_token_string def test_successful_new_card_and_customer_update_with_payment_token @gateway.expects(:ssl_request).twice.returns(successful_new_card_response, successful_new_customer_response) - assert response = @gateway.store(@payment_token, :customer => 'cus_3sgheFxeBgTQ3M', :email => 'test@test.com') + assert response = @gateway.store(@payment_token, customer: 'cus_3sgheFxeBgTQ3M', email: 'test@test.com') assert_instance_of MultiResponse, response assert_success response @@ -214,7 +214,7 @@ def test_successful_new_default_card @gateway.expects(:ssl_request).twice.returns(successful_new_card_response, successful_new_customer_response) @gateway.expects(:add_creditcard) - assert response = @gateway.store(@credit_card, @options.merge(:customer => 'cus_3sgheFxeBgTQ3M', :set_default => true)) + assert response = @gateway.store(@credit_card, @options.merge(customer: 'cus_3sgheFxeBgTQ3M', set_default: true)) assert_instance_of MultiResponse, response assert_success response @@ -229,7 +229,7 @@ def test_successful_new_default_card_via_apple_pay_payment_token @gateway.expects(:ssl_request).twice.returns(successful_new_card_response, successful_new_customer_response) @gateway.expects(:tokenize_apple_pay_token).returns(Response.new(true, nil, token: successful_apple_pay_token_exchange)) - assert response = @gateway.store(@apple_pay_payment_token, @options.merge(:customer => 'cus_3sgheFxeBgTQ3M', :set_default => true)) + assert response = @gateway.store(@apple_pay_payment_token, @options.merge(customer: 'cus_3sgheFxeBgTQ3M', set_default: true)) assert_instance_of MultiResponse, response assert_success response @@ -243,7 +243,7 @@ def test_successful_new_default_card_via_apple_pay_payment_token def test_successful_new_default_card_with_emv_credit_card @gateway.expects(:ssl_request).twice.returns(successful_new_card_response, successful_new_customer_response) - assert response = @gateway.store(@emv_credit_card, @options.merge(:customer => 'cus_3sgheFxeBgTQ3M', :set_default => true)) + assert response = @gateway.store(@emv_credit_card, @options.merge(customer: 'cus_3sgheFxeBgTQ3M', set_default: true)) assert_instance_of MultiResponse, response assert_success response @@ -258,7 +258,7 @@ def test_successful_new_default_card_with_token_string @gateway.expects(:ssl_request).twice.returns(successful_new_card_response, successful_new_customer_response) @gateway.expects(:add_creditcard) - assert response = @gateway.store(@token_string, @options.merge(:customer => 'cus_3sgheFxeBgTQ3M', :set_default => true)) + assert response = @gateway.store(@token_string, @options.merge(customer: 'cus_3sgheFxeBgTQ3M', set_default: true)) assert_instance_of MultiResponse, response assert_success response @@ -273,7 +273,7 @@ def test_successful_new_default_card_with_payment_token @gateway.expects(:ssl_request).twice.returns(successful_new_card_response, successful_new_customer_response) @gateway.expects(:add_payment_token) - assert response = @gateway.store(@payment_token, @options.merge(:customer => 'cus_3sgheFxeBgTQ3M', :set_default => true)) + assert response = @gateway.store(@payment_token, @options.merge(customer: 'cus_3sgheFxeBgTQ3M', set_default: true)) assert_instance_of MultiResponse, response assert_success response @@ -287,7 +287,7 @@ def test_successful_new_default_card_with_payment_token def test_passing_validate_false_on_store response = stub_comms(@gateway, :ssl_request) do @gateway.store(@credit_card, validate: false) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/validate=false/, data) end.respond_with(successful_new_customer_response) @@ -297,7 +297,7 @@ def test_passing_validate_false_on_store def test_empty_values_not_sent response = stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, @credit_card, referrer: '') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| refute_match(/referrer/, data) end.respond_with(successful_purchase_response) @@ -363,6 +363,42 @@ def test_successful_authorization_with_emv_credit_card assert response.emv_authorization, 'Response should include emv_authorization containing the EMV ARPC' end + def test_contains_statement_descriptor_suffix + options = @options.merge(statement_descriptor_suffix: 'suffix') + + stub_comms(@gateway, :ssl_request) do + @gateway.purchase(@amount, @credit_card, options) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(/statement_descriptor_suffix=suffix/, data) + end.respond_with(successful_purchase_response) + end + + def test_connected_account + destination = 'account_27701' + amount = 8000 + on_behalf_of = 'account_27704' + transfer_group = 'TG1000' + application_fee_amount = 100 + + options = @options.merge( + transfer_destination: destination, + transfer_amount: amount, + on_behalf_of: on_behalf_of, + transfer_group: transfer_group, + application_fee_amount: application_fee_amount + ) + + stub_comms(@gateway, :ssl_request) do + @gateway.purchase(@amount, @credit_card, options) + end.check_request do |_method, _endpoint, data, _headers| + assert_match(/transfer_data\[destination\]=#{destination}/, data) + assert_match(/transfer_data\[amount\]=#{amount}/, data) + assert_match(/on_behalf_of=#{on_behalf_of}/, data) + assert_match(/transfer_group=#{transfer_group}/, data) + assert_match(/application_fee_amount=#{application_fee_amount}/, data) + end.respond_with(successful_purchase_response) + end + def test_declined_authorization_with_emv_credit_card @gateway.expects(:ssl_request).returns(declined_authorization_response_with_emv_auth_data) @@ -383,9 +419,23 @@ def test_successful_capture end def test_successful_capture_with_emv_credit_card_tc - @gateway.expects(:ssl_request).returns(successful_capture_response_with_icc_data) - - assert response = @gateway.capture(@amount, 'ch_test_emv_charge') + stripe_charge_id = 'ch_test_emv_charge' + tc_emv_response = 'mock_icc_data' + @gateway. + expects(:ssl_request). + with( + :post, + "https://api.stripe.com/v1/charges/#{stripe_charge_id}", + "card[emv_approval_data]=#{tc_emv_response}", + anything + ).returns(successful_capture_response_with_icc_data) + + @gateway. + expects(:ssl_request). + with(:post, 'https://api.stripe.com/v1/charges/ch_test_emv_charge/capture', '', anything). + returns(successful_capture_response_without_icc_data) + + assert response = @gateway.capture(@amount, stripe_charge_id, icc_data: tc_emv_response) assert_success response assert response.emv_authorization, 'Response should include emv_authorization containing the EMV TC' end @@ -461,7 +511,7 @@ def test_successful_purchase_with_level3_data response = stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, @credit_card, @options) end.check_request do |_method, endpoint, data, _headers| - if %r{/charges} =~ endpoint + if %r{/charges}.match?(endpoint) assert_match('level3[merchant_reference]=123', data) assert_match('level3[customer_reference]=456', data) assert_match('level3[shipping_address_zip]=98765', data) @@ -495,8 +545,8 @@ def test_adds_application_to_x_stripe_client_user_agent_header } response = stub_comms(@gateway, :ssl_request) do - @gateway.purchase(@amount, 'cus_xxx|card_xxx', @options.merge({application: application})) - end.check_request do |method, endpoint, data, headers| + @gateway.purchase(@amount, 'cus_xxx|card_xxx', @options.merge({ application: application })) + end.check_request do |_method, _endpoint, _data, headers| assert_match(/\"application\"/, headers['X-Stripe-Client-User-Agent']) assert_match(/\"name\":\"app\"/, headers['X-Stripe-Client-User-Agent']) assert_match(/\"version\":\"1.0\"/, headers['X-Stripe-Client-User-Agent']) @@ -509,7 +559,7 @@ def test_adds_application_to_x_stripe_client_user_agent_header def test_successful_purchase_with_token_including_customer response = stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, 'cus_xxx|card_xxx') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/customer=cus_xxx/, data) assert_match(/card=card_xxx/, data) end.respond_with(successful_purchase_response) @@ -520,7 +570,7 @@ def test_successful_purchase_with_token_including_customer def test_successful_purchase_with_token response = stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, 'card_xxx') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/card=card_xxx/, data) end.respond_with(successful_purchase_response) @@ -530,7 +580,7 @@ def test_successful_purchase_with_token def test_successful_purchase_with_statement_description stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, @credit_card, statement_description: '5K RACE TICKET') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/statement_descriptor=5K\+RACE\+TICKET/, data) end.respond_with(successful_purchase_response) end @@ -581,7 +631,7 @@ def test_successful_void_with_metadata post.include?('metadata[first_value]=true') end.returns(successful_purchase_response(true)) - assert response = @gateway.void('ch_test_charge', {metadata: {first_value: true}}) + assert response = @gateway.void('ch_test_charge', { metadata: { first_value: true } }) assert_success response end @@ -590,7 +640,7 @@ def test_successful_void_with_reason post.include?('reason=fraudulent') end.returns(successful_purchase_response(true)) - assert response = @gateway.void('ch_test_charge', {reason: 'fraudulent'}) + assert response = @gateway.void('ch_test_charge', { reason: 'fraudulent' }) assert_success response end @@ -620,11 +670,11 @@ def test_unsuccessful_refund end def test_successful_refund_with_refund_application_fee - @gateway.expects(:ssl_request).with do |method, url, post, headers| + @gateway.expects(:ssl_request).with do |_method, _url, post, _headers| post.include?('refund_application_fee=true') end.returns(successful_partially_refunded_response) - assert response = @gateway.refund(@refund_amount, 'ch_test_charge', :refund_application_fee => true) + assert response = @gateway.refund(@refund_amount, 'ch_test_charge', refund_application_fee: true) assert_success response end @@ -659,18 +709,18 @@ def test_refund_with_expand_charge_only_sends_one_charge_expand end def test_successful_refund_with_metadata - @gateway.expects(:ssl_request).with do |method, url, post, headers| + @gateway.expects(:ssl_request).with do |_method, _url, post, _headers| post.include?('metadata[first_value]=true') end.returns(successful_partially_refunded_response) - assert response = @gateway.refund(@refund_amount, 'ch_test_charge', {metadata: {first_value: true}}) + assert response = @gateway.refund(@refund_amount, 'ch_test_charge', { metadata: { first_value: true } }) assert_success response end def test_successful_refund_with_reverse_transfer stub_comms(@gateway, :ssl_request) do @gateway.refund(@amount, 'auth', reverse_transfer: true) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/reverse_transfer=true/, data) end.respond_with(successful_partially_refunded_response) end @@ -681,7 +731,7 @@ def test_successful_refund_with_refund_fee_amount @gateway.expects(:ssl_request).returns(successful_fetch_application_fee_response).in_sequence(s) @gateway.expects(:ssl_request).returns(successful_partially_refunded_application_fee_response).in_sequence(s) - assert response = @gateway.refund(@refund_amount, 'ch_test_charge', :refund_fee_amount => 100) + assert response = @gateway.refund(@refund_amount, 'ch_test_charge', refund_fee_amount: 100) assert_success response end @@ -691,7 +741,7 @@ def test_refund_with_fee_response_responds_with_the_refund_authorization @gateway.expects(:ssl_request).returns(successful_fetch_application_fee_response).in_sequence(s) @gateway.expects(:ssl_request).returns(successful_partially_refunded_application_fee_response).in_sequence(s) - assert response = @gateway.refund(@refund_amount, 'ch_test_charge', :refund_fee_amount => 100) + assert response = @gateway.refund(@refund_amount, 'ch_test_charge', refund_fee_amount: 100) assert_success response assert_equal 're_test_refund', response.authorization end @@ -701,7 +751,7 @@ def test_successful_refund_with_failed_fee_refund_fetch @gateway.expects(:ssl_request).returns(successful_partially_refunded_response).in_sequence(s) @gateway.expects(:ssl_request).returns(unsuccessful_fetch_application_fee_response).in_sequence(s) - assert response = @gateway.refund(@refund_amount, 'ch_test_charge', :refund_fee_amount => 100) + assert response = @gateway.refund(@refund_amount, 'ch_test_charge', refund_fee_amount: 100) assert_success response end @@ -711,7 +761,7 @@ def test_successful_refund_with_failed_fee_refund @gateway.expects(:ssl_request).returns(successful_fetch_application_fee_response).in_sequence(s) @gateway.expects(:ssl_request).returns(generic_error_response).in_sequence(s) - assert response = @gateway.refund(@refund_amount, 'ch_test_charge', :refund_fee_amount => 100) + assert response = @gateway.refund(@refund_amount, 'ch_test_charge', refund_fee_amount: 100) assert_success response end @@ -719,7 +769,7 @@ def test_unsuccessful_refund_does_not_refund_fee s = sequence('request') @gateway.expects(:ssl_request).returns(generic_error_response).in_sequence(s) - assert response = @gateway.refund(@refund_amount, 'ch_test_charge', :refund_fee_amount => 100) + assert response = @gateway.refund(@refund_amount, 'ch_test_charge', refund_fee_amount: 100) assert_failure response end @@ -886,7 +936,7 @@ def test_add_creditcard_with_card_token_and_customer def test_add_creditcard_with_card_token_and_track_data post = {} credit_card_token = 'card_2iD4AezYnNNzkW' - @gateway.send(:add_creditcard, post, credit_card_token, :track_data => 'Tracking data') + @gateway.send(:add_creditcard, post, credit_card_token, track_data: 'Tracking data') assert_equal 'Tracking data', post[:card][:swipe_data] end @@ -902,8 +952,7 @@ def test_add_creditcard_pads_eci_value credit_card = network_tokenization_credit_card('4242424242424242', payment_cryptogram: '111111111100cryptogram', verification_value: nil, - eci: '7' - ) + eci: '7') @gateway.send(:add_creditcard, post, credit_card, {}) @@ -912,57 +961,57 @@ def test_add_creditcard_pads_eci_value def test_application_fee_is_submitted_for_purchase stub_comms(@gateway, :ssl_request) do - @gateway.purchase(@amount, @credit_card, @options.merge({:application_fee => 144})) - end.check_request do |method, endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, @options.merge({ application_fee: 144 })) + end.check_request do |_method, _endpoint, data, _headers| assert_match(/application_fee=144/, data) end.respond_with(successful_purchase_response) end def test_application_fee_is_submitted_for_capture stub_comms(@gateway, :ssl_request) do - @gateway.capture(@amount, 'ch_test_charge', @options.merge({:application_fee => 144})) - end.check_request do |method, endpoint, data, headers| + @gateway.capture(@amount, 'ch_test_charge', @options.merge({ application_fee: 144 })) + end.check_request do |_method, _endpoint, data, _headers| assert_match(/application_fee=144/, data) end.respond_with(successful_capture_response) end def test_exchange_rate_is_submitted_for_purchase stub_comms(@gateway, :ssl_request) do - @gateway.purchase(@amount, @credit_card, @options.merge({:exchange_rate => 0.96251})) - end.check_request do |method, endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, @options.merge({ exchange_rate: 0.96251 })) + end.check_request do |_method, _endpoint, data, _headers| assert_match(/exchange_rate=0.96251/, data) end.respond_with(successful_purchase_response) end def test_exchange_rate_is_submitted_for_capture stub_comms(@gateway, :ssl_request) do - @gateway.capture(@amount, 'ch_test_charge', @options.merge({:exchange_rate => 0.96251})) - end.check_request do |method, endpoint, data, headers| + @gateway.capture(@amount, 'ch_test_charge', @options.merge({ exchange_rate: 0.96251 })) + end.check_request do |_method, _endpoint, data, _headers| assert_match(/exchange_rate=0.96251/, data) end.respond_with(successful_capture_response) end def test_destination_is_submitted_for_purchase stub_comms(@gateway, :ssl_request) do - @gateway.purchase(@amount, @credit_card, @options.merge({:destination => 'subaccountid'})) - end.check_request do |method, endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, @options.merge({ destination: 'subaccountid' })) + end.check_request do |_method, _endpoint, data, _headers| assert_match(/destination\[account\]=subaccountid/, data) end.respond_with(successful_purchase_response) end def test_destination_amount_is_submitted_for_purchase stub_comms(@gateway, :ssl_request) do - @gateway.purchase(@amount, @credit_card, @options.merge({:destination => 'subaccountid', :destination_amount => @amount - 20})) - end.check_request do |method, endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, @options.merge({ destination: 'subaccountid', destination_amount: @amount - 20 })) + end.check_request do |_method, _endpoint, data, _headers| assert_match(/destination\[amount\]=#{@amount - 20}/, data) end.respond_with(successful_purchase_response) end def test_client_data_submitted_with_purchase stub_comms(@gateway, :ssl_request) do - updated_options = @options.merge({:description => 'a test customer', :ip => '127.127.127.127', :user_agent => 'some browser', :order_id => '42', :email => 'foo@wonderfullyfakedomain.com', :receipt_email => 'receipt-receiver@wonderfullyfakedomain.com', :referrer =>'http://www.shopify.com'}) + updated_options = @options.merge({ description: 'a test customer', ip: '127.127.127.127', user_agent: 'some browser', order_id: '42', email: 'foo@wonderfullyfakedomain.com', receipt_email: 'receipt-receiver@wonderfullyfakedomain.com', referrer: 'http://www.shopify.com' }) @gateway.purchase(@amount, @credit_card, updated_options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/description=a\+test\+customer/, data) assert_match(/ip=127\.127\.127\.127/, data) assert_match(/user_agent=some\+browser/, data) @@ -977,9 +1026,9 @@ def test_client_data_submitted_with_purchase def test_client_data_submitted_with_purchase_without_email_or_order stub_comms(@gateway, :ssl_request) do - updated_options = @options.merge({:description => 'a test customer', :ip => '127.127.127.127', :user_agent => 'some browser', :referrer =>'http://www.shopify.com'}) + updated_options = @options.merge({ description: 'a test customer', ip: '127.127.127.127', user_agent: 'some browser', referrer: 'http://www.shopify.com' }) @gateway.purchase(@amount, @credit_card, updated_options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/description=a\+test\+customer/, data) assert_match(/ip=127\.127\.127\.127/, data) assert_match(/user_agent=some\+browser/, data) @@ -991,9 +1040,9 @@ def test_client_data_submitted_with_purchase_without_email_or_order def test_client_data_submitted_with_metadata_in_options stub_comms(@gateway, :ssl_request) do - updated_options = @options.merge({:metadata => {:this_is_a_random_key_name => 'with a random value', :i_made_up_this_key_too => 'canyoutell'}, :order_id => '42', :email => 'foo@wonderfullyfakedomain.com'}) + updated_options = @options.merge({ metadata: { this_is_a_random_key_name: 'with a random value', i_made_up_this_key_too: 'canyoutell' }, order_id: '42', email: 'foo@wonderfullyfakedomain.com' }) @gateway.purchase(@amount, @credit_card, updated_options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/metadata\[this_is_a_random_key_name\]=with\+a\+random\+value/, data) assert_match(/metadata\[i_made_up_this_key_too\]=canyoutell/, data) assert_match(/metadata\[email\]=foo\%40wonderfullyfakedomain\.com/, data) @@ -1003,9 +1052,9 @@ def test_client_data_submitted_with_metadata_in_options def test_client_data_submitted_with_metadata_in_options_with_emv_credit_card_purchase stub_comms(@gateway, :ssl_request) do - updated_options = @options.merge({:metadata => {:this_is_a_random_key_name => 'with a random value', :i_made_up_this_key_too => 'canyoutell'}, :order_id => '42', :email => 'foo@wonderfullyfakedomain.com'}) + updated_options = @options.merge({ metadata: { this_is_a_random_key_name: 'with a random value', i_made_up_this_key_too: 'canyoutell' }, order_id: '42', email: 'foo@wonderfullyfakedomain.com' }) @gateway.purchase(@amount, @emv_credit_card, updated_options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/metadata\[this_is_a_random_key_name\]=with\+a\+random\+value/, data) assert_match(/metadata\[i_made_up_this_key_too\]=canyoutell/, data) assert_match(/metadata\[email\]=foo\%40wonderfullyfakedomain\.com/, data) @@ -1016,9 +1065,9 @@ def test_client_data_submitted_with_metadata_in_options_with_emv_credit_card_pur def test_client_data_submitted_with_metadata_in_options_with_emv_credit_card_authorize stub_comms(@gateway, :ssl_request) do - updated_options = @options.merge({:metadata => {:this_is_a_random_key_name => 'with a random value', :i_made_up_this_key_too => 'canyoutell'}, :order_id => '42', :email => 'foo@wonderfullyfakedomain.com'}) + updated_options = @options.merge({ metadata: { this_is_a_random_key_name: 'with a random value', i_made_up_this_key_too: 'canyoutell' }, order_id: '42', email: 'foo@wonderfullyfakedomain.com' }) @gateway.authorize(@amount, @emv_credit_card, updated_options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/metadata\[this_is_a_random_key_name\]=with\+a\+random\+value/, data) assert_match(/metadata\[i_made_up_this_key_too\]=canyoutell/, data) assert_match(/metadata\[email\]=foo\%40wonderfullyfakedomain\.com/, data) @@ -1031,7 +1080,7 @@ def test_quickchip_is_set_on_purchase stub_comms(@gateway, :ssl_request) do @emv_credit_card.read_method = 'contact_quickchip' @gateway.purchase(@amount, @emv_credit_card, @options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/card\[processing_method\]=quick_chip/, data) end.respond_with(successful_purchase_response) end @@ -1040,13 +1089,13 @@ def test_quickchip_is_not_set_on_authorize stub_comms(@gateway, :ssl_request) do @emv_credit_card.read_method = 'contact_quickchip' @gateway.authorize(@amount, @emv_credit_card, @options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| refute_match(/card\[processing_method\]=quick_chip/, data) end.respond_with(successful_purchase_response) end def test_add_address - post = {:card => {}} + post = { card: {} } @gateway.send(:add_address, post, @options) assert_equal @options[:billing_address][:zip], post[:card][:address_zip] assert_equal @options[:billing_address][:state], post[:card][:address_state] @@ -1071,7 +1120,7 @@ def test_add_statement_address def test_add_statement_address_returns_nil_if_required_fields_missing post = {} - [:address1, :city, :zip, :state].each do |required_key| + %i[address1 city zip state].each do |required_key| missing_required = @options.tap do |options| options[:statement_address].delete_if { |k| k == required_key } end @@ -1093,55 +1142,55 @@ def test_gateway_without_credentials end def test_metadata_header - @gateway.expects(:ssl_request).once.with { |method, url, post, headers| - headers && headers['X-Stripe-Client-User-Metadata'] == {:ip => '1.1.1.1'}.to_json + @gateway.expects(:ssl_request).once.with { |_method, _url, _post, headers| + headers && headers['X-Stripe-Client-User-Metadata'] == { ip: '1.1.1.1' }.to_json }.returns(successful_purchase_response) - @gateway.purchase(@amount, @credit_card, @options.merge(:ip => '1.1.1.1')) + @gateway.purchase(@amount, @credit_card, @options.merge(ip: '1.1.1.1')) end def test_optional_version_header - @gateway.expects(:ssl_request).once.with { |method, url, post, headers| + @gateway.expects(:ssl_request).once.with { |_method, _url, _post, headers| headers && headers['Stripe-Version'] == '2013-10-29' }.returns(successful_purchase_response) - @gateway.purchase(@amount, @credit_card, @options.merge(:version => '2013-10-29')) + @gateway.purchase(@amount, @credit_card, @options.merge(version: '2013-10-29')) end def test_optional_idempotency_key_header - @gateway.expects(:ssl_request).once.with { |method, url, post, headers| + @gateway.expects(:ssl_request).once.with { |_method, _url, _post, headers| headers && headers['Idempotency-Key'] == 'test123' }.returns(successful_purchase_response) - response = @gateway.purchase(@amount, @credit_card, @options.merge(:idempotency_key => 'test123')) + response = @gateway.purchase(@amount, @credit_card, @options.merge(idempotency_key: 'test123')) assert_success response end def test_optional_idempotency_on_void - @gateway.expects(:ssl_request).once.with { |method, url, post, headers| + @gateway.expects(:ssl_request).once.with { |_method, _url, _post, headers| headers && headers['Idempotency-Key'] == 'test123' }.returns(successful_purchase_response(true)) - response = @gateway.void('ch_test_charge', @options.merge(:idempotency_key => 'test123')) + response = @gateway.void('ch_test_charge', @options.merge(idempotency_key: 'test123')) assert_success response end def test_optional_idempotency_on_verify - @gateway.expects(:ssl_request).with do |method, url, post, headers| + @gateway.expects(:ssl_request).with do |_method, _url, _post, headers| headers && headers['Idempotency-Key'] == nil end.returns(successful_void_response) - @gateway.expects(:ssl_request).with do |method, url, post, headers| + @gateway.expects(:ssl_request).with do |_method, _url, _post, headers| headers && headers['Idempotency-Key'] == 'test123' end.returns(successful_authorization_response) - response = @gateway.verify(@credit_card, @options.merge(:idempotency_key => 'test123')) + response = @gateway.verify(@credit_card, @options.merge(idempotency_key: 'test123')) assert_success response end def test_initialize_gateway_with_version - @gateway = StripeGateway.new(:login => 'login', :version => '2013-12-03') - @gateway.expects(:ssl_request).once.with { |method, url, post, headers| + @gateway = StripeGateway.new(login: 'login', version: '2013-12-03') + @gateway.expects(:ssl_request).once.with { |_method, _url, _post, headers| headers && headers['Stripe-Version'] == '2013-12-03' }.returns(successful_purchase_response) @@ -1151,7 +1200,7 @@ def test_initialize_gateway_with_version def test_track_data_and_traditional_should_be_mutually_exclusive stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert data =~ /card\[name\]/ assert data !~ /card\[swipe_data\]/ end.respond_with(successful_purchase_response) @@ -1159,7 +1208,7 @@ def test_track_data_and_traditional_should_be_mutually_exclusive stub_comms(@gateway, :ssl_request) do @credit_card.track_data = '%B378282246310005^LONGSON/LONGBOB^1705101130504392?' @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert data !~ /card\[name\]/ assert data =~ /card\[swipe_data\]/ end.respond_with(successful_purchase_response) @@ -1168,7 +1217,7 @@ def test_track_data_and_traditional_should_be_mutually_exclusive def test_address_is_included_with_card_data stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert data =~ /card\[address_line1\]/ end.respond_with(successful_purchase_response) end @@ -1177,7 +1226,7 @@ def test_contactless_flag_is_included_with_emv_card_data stub_comms(@gateway, :ssl_request) do @emv_credit_card.read_method = 'contactless' @gateway.purchase(@amount, @emv_credit_card, @options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert data =~ /card\[read_method\]=contactless/ end.respond_with(successful_purchase_response) end @@ -1186,7 +1235,7 @@ def test_contactless_magstripe_flag_is_included_with_emv_card_data stub_comms(@gateway, :ssl_request) do @emv_credit_card.read_method = 'contactless_magstripe' @gateway.purchase(@amount, @emv_credit_card, @options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert data =~ /card\[read_method\]=contactless_magstripe_mode/ end.respond_with(successful_purchase_response) end @@ -1194,7 +1243,7 @@ def test_contactless_magstripe_flag_is_included_with_emv_card_data def test_contactless_flag_is_not_included_with_emv_card_data_by_default stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, @emv_credit_card, @options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert data !~ /card\[read_method\]=contactless/ && data !~ /card\[read_method\]=contactless_magstripe_mode/ end.respond_with(successful_purchase_response) end @@ -1204,18 +1253,18 @@ def test_encrypted_pin_is_included_with_emv_card_data @emv_credit_card.encrypted_pin_cryptogram = '8b68af72199529b8' @emv_credit_card.encrypted_pin_ksn = 'ffff0102628d12000001' @gateway.purchase(@amount, @emv_credit_card, @options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert data =~ /card\[encrypted_pin\]=8b68af72199529b8/ assert data =~ /card\[encrypted_pin_key_id\]=ffff0102628d12000001/ end.respond_with(successful_purchase_response) end def generate_options_should_allow_key - assert_equal({:key => '12345'}, generate_options({:key => '12345'})) + assert_equal({ key: '12345' }, generate_options({ key: '12345' })) end def test_passing_expand_parameters - @gateway.expects(:ssl_request).with do |method, url, post, headers| + @gateway.expects(:ssl_request).with do |_method, _url, post, _headers| post.include?('expand[0]=balance_transaction') end.returns(successful_authorization_response) @@ -1225,17 +1274,17 @@ def test_passing_expand_parameters end def test_passing_expand_parameters_as_array - @gateway.expects(:ssl_request).with do |method, url, post, headers| + @gateway.expects(:ssl_request).with do |_method, _url, post, _headers| post.include?('expand[0]=balance_transaction&expand[1]=customer') end.returns(successful_authorization_response) - @options[:expand] = [:balance_transaction, :customer] + @options[:expand] = %i[balance_transaction customer] @gateway.authorize(@amount, @credit_card, @options) end def test_recurring_flag_not_set_by_default - @gateway.expects(:ssl_request).with do |method, url, post, headers| + @gateway.expects(:ssl_request).with do |_method, _url, post, _headers| !post.include?('recurring') end.returns(successful_authorization_response) @@ -1243,7 +1292,7 @@ def test_recurring_flag_not_set_by_default end def test_passing_recurring_eci_sets_recurring_flag - @gateway.expects(:ssl_request).with do |method, url, post, headers| + @gateway.expects(:ssl_request).with do |_method, _url, post, _headers| post.include?('recurring=true') end.returns(successful_authorization_response) @@ -1253,7 +1302,7 @@ def test_passing_recurring_eci_sets_recurring_flag end def test_passing_unknown_eci_does_not_set_recurring_flag - @gateway.expects(:ssl_request).with do |method, url, post, headers| + @gateway.expects(:ssl_request).with do |_method, _url, post, _headers| !post.include?('recurring') end.returns(successful_authorization_response) @@ -1263,7 +1312,7 @@ def test_passing_unknown_eci_does_not_set_recurring_flag end def test_passing_recurring_true_option_sets_recurring_flag - @gateway.expects(:ssl_request).with do |method, url, post, headers| + @gateway.expects(:ssl_request).with do |_method, _url, post, _headers| post.include?('recurring=true') end.returns(successful_authorization_response) @@ -1273,7 +1322,7 @@ def test_passing_recurring_true_option_sets_recurring_flag end def test_passing_recurring_false_option_does_not_set_recurring_flag - @gateway.expects(:ssl_request).with do |method, url, post, headers| + @gateway.expects(:ssl_request).with do |_method, _url, post, _headers| !post.include?('recurring') end.returns(successful_authorization_response) @@ -1284,8 +1333,8 @@ def test_passing_recurring_false_option_does_not_set_recurring_flag def test_new_attributes_are_included_in_update stub_comms(@gateway, :ssl_request) do - @gateway.send(:update, 'cus_3sgheFxeBgTQ3M', 'card_483etw4er9fg4vF3sQdrt3FG', { :name => 'John Smith', :exp_year => 2021, :exp_month => 6 }) - end.check_request do |method, endpoint, data, headers| + @gateway.send(:update, 'cus_3sgheFxeBgTQ3M', 'card_483etw4er9fg4vF3sQdrt3FG', { name: 'John Smith', exp_year: 2021, exp_month: 6 }) + end.check_request do |_method, endpoint, data, _headers| assert data == 'name=John+Smith&exp_year=2021&exp_month=6' assert endpoint.include? '/customers/cus_3sgheFxeBgTQ3M/cards/card_483etw4er9fg4vF3sQdrt3FG' end.respond_with(successful_update_credit_card_response) @@ -1293,6 +1342,7 @@ def test_new_attributes_are_included_in_update def test_scrub assert_equal @gateway.scrub(pre_scrubbed), post_scrubbed + assert_equal @gateway.scrub(pre_scrubbed_nested_payment_method_data), post_scrubbed_nested_payment_method_data end def test_scrubs_track_data @@ -1308,7 +1358,7 @@ def test_supports_scrubbing? end def test_successful_auth_with_network_tokenization_apple_pay - @gateway.expects(:ssl_request).with do |method, endpoint, data, headers| + @gateway.expects(:ssl_request).with do |method, _endpoint, data, _headers| assert_equal :post, method assert_match %r'card\[cryptogram\]=111111111100cryptogram&card\[eci\]=05&card\[tokenization_method\]=apple_pay', data true @@ -1317,8 +1367,7 @@ def test_successful_auth_with_network_tokenization_apple_pay credit_card = network_tokenization_credit_card('4242424242424242', payment_cryptogram: '111111111100cryptogram', verification_value: nil, - eci: '05' - ) + eci: '05') assert response = @gateway.authorize(@amount, credit_card, @options) assert_instance_of Response, response @@ -1329,7 +1378,7 @@ def test_successful_auth_with_network_tokenization_apple_pay end def test_successful_auth_with_network_tokenization_android_pay - @gateway.expects(:ssl_request).with do |method, endpoint, data, headers| + @gateway.expects(:ssl_request).with do |method, _endpoint, data, _headers| assert_equal :post, method assert_match %r'card\[cryptogram\]=111111111100cryptogram&card\[eci\]=05&card\[tokenization_method\]=android_pay', data true @@ -1339,8 +1388,7 @@ def test_successful_auth_with_network_tokenization_android_pay payment_cryptogram: '111111111100cryptogram', verification_value: nil, eci: '05', - source: :android_pay - ) + source: :android_pay) assert response = @gateway.authorize(@amount, credit_card, @options) assert_instance_of Response, response @@ -1351,7 +1399,7 @@ def test_successful_auth_with_network_tokenization_android_pay end def test_successful_purchase_with_network_tokenization_apple_pay - @gateway.expects(:ssl_request).with do |method, endpoint, data, headers| + @gateway.expects(:ssl_request).with do |method, _endpoint, data, _headers| assert_equal :post, method assert_match %r'card\[cryptogram\]=111111111100cryptogram&card\[eci\]=05&card\[tokenization_method\]=apple_pay', data true @@ -1360,8 +1408,7 @@ def test_successful_purchase_with_network_tokenization_apple_pay credit_card = network_tokenization_credit_card('4242424242424242', payment_cryptogram: '111111111100cryptogram', verification_value: nil, - eci: '05' - ) + eci: '05') assert response = @gateway.purchase(@amount, credit_card, @options) assert_instance_of Response, response @@ -1372,7 +1419,7 @@ def test_successful_purchase_with_network_tokenization_apple_pay end def test_successful_purchase_with_network_tokenization_android_pay - @gateway.expects(:ssl_request).with do |method, endpoint, data, headers| + @gateway.expects(:ssl_request).with do |method, _endpoint, data, _headers| assert_equal :post, method assert_match %r'card\[cryptogram\]=111111111100cryptogram&card\[eci\]=05&card\[tokenization_method\]=android_pay', data true @@ -1382,8 +1429,7 @@ def test_successful_purchase_with_network_tokenization_android_pay payment_cryptogram: '111111111100cryptogram', verification_value: nil, eci: '05', - source: :android_pay - ) + source: :android_pay) assert response = @gateway.purchase(@amount, credit_card, @options) assert_instance_of Response, response @@ -1400,7 +1446,7 @@ def test_supports_network_tokenization def test_emv_capture_application_fee_ignored response = stub_comms(@gateway, :ssl_request) do @gateway.capture(@amount, 'ch_test_charge', application_fee: 100, icc_data: @emv_credit_card.icc_data) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert data !~ /application_fee/, 'request should not include application_fee' end.respond_with(successful_capture_response_with_icc_data) @@ -1410,15 +1456,25 @@ def test_emv_capture_application_fee_ignored def test_authorization_with_emv_payment_application_fee_included response = stub_comms(@gateway, :ssl_request) do @gateway.authorize(@amount, 'ch_test_charge', application_fee: 100, icc_data: @emv_credit_card.icc_data) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert data =~ /application_fee/, 'request should include application_fee' end.respond_with(successful_capture_response_with_icc_data) assert_success response end + def test_authorization_with_emv_payment_sets_capture_to_false + response = stub_comms(@gateway, :ssl_request) do + @gateway.authorize(@amount, 'ch_test_charge', application_fee: 100, icc_data: @emv_credit_card.icc_data) + end.check_request do |_method, _endpoint, data, _headers| + assert data =~ /capture\=false/, 'request should set capture to false' + end.respond_with(successful_capture_response_with_icc_data) + + assert_success response + end + def test_passing_stripe_account_header - @gateway.expects(:ssl_request).with do |method, url, post, headers| + @gateway.expects(:ssl_request).with do |_method, _url, _post, headers| headers.include?('Stripe-Account') end.returns(successful_authorization_response) @@ -1457,7 +1513,7 @@ def test_webhook_creation def test_webhook_deletion @gateway.expects(:ssl_request).twice.returns(webhook_event_creation_response, webhook_event_deletion_response) webhook = @gateway.send(:create_webhook_endpoint, @options.merge(@threeds_options), ['source.chargeable']) - response = @gateway.send(:delete_webhook_endpoint, @options.merge(:webhook_id => webhook.params['id'])) + response = @gateway.send(:delete_webhook_endpoint, @options.merge(webhook_id: webhook.params['id'])) assert_equal response.params['id'], webhook.params['id'] assert_equal true, response.params['deleted'] end @@ -1519,6 +1575,35 @@ def pre_scrubbed PRE_SCRUBBED end + def pre_scrubbed_nested_payment_method_data + <<-PRE_SCRUBBED + opening connection to api.stripe.com:443... + opened + starting SSL for api.stripe.com:443... + SSL established + <- "POST /v1/charges HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAuthorization: Basic c2tfdGVzdF9oQkwwTXF6ZGZ6Rnk3OXU0cFloUmVhQlo6\r\nUser-Agent: Stripe/v1 ActiveMerchantBindings/1.45.0\r\nX-Stripe-Client-User-Agent: {\"bindings_version\":\"1.45.0\",\"lang\":\"ruby\",\"lang_version\":\"2.1.3 p242 (2014-09-19)\",\"platform\":\"x86_64-linux\",\"publisher\":\"active_merchant\"}\r\nX-Stripe-Client-User-Metadata: {\"ip\":null}\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nConnection: close\r\nHost: api.stripe.com\r\nContent-Length: 270\r\n\r\n" + <- "amount=100¤cy=usd&payment_method_data[card][number]=4242424242424242&payment_method_data[card][exp_month]=9&payment_method_data[card][exp_year]=2015&payment_method_data[card][cvc]=123&payment_method_data[card][name]=Longbob+Longsen&description=ActiveMerchant+Test+Purchase&payment_user_agent=Stripe%2Fv1+ActiveMerchantBindings%2F1.45.0&metadata[email]=wow%40example.com&payment_method_data[card][cryptogram]=sensitive_data&three_d_secure[cryptogram]=123456789abcdefghijklmnop&three_d_secure[apple_pay]=true" + -> "HTTP/1.1 200 OK\r\n" + -> "Server: nginx\r\n" + -> "Date: Tue, 02 Dec 2014 19:44:17 GMT\r\n" + -> "Content-Type: application/json;charset=utf-8\r\n" + -> "Content-Length: 1303\r\n" + -> "Connection: close\r\n" + -> "Access-Control-Allow-Credentials: true\r\n" + -> "Access-Control-Allow-Methods: GET, POST, HEAD, OPTIONS, DELETE\r\n" + -> "Access-Control-Max-Age: 300\r\n" + -> "Cache-Control: no-cache, no-store\r\n" + -> "Request-Id: 89de951c-f880-4c39-93b0-832b3cc6dd32\r\n" + -> "Stripe-Version: 2013-12-03\r\n" + -> "Strict-Transport-Security: max-age=31556926; includeSubDomains\r\n" + -> "\r\n" + reading 1303 bytes... + -> "{\n \"id\": \"ch_155MZJ2gKyKnHxtY1dGqFhSb\",\n \"object\": \"charge\",\n \"created\": 1417549457,\n \"livemode\": false,\n \"paid\": true,\n \"amount\": 100,\n \"currency\": \"usd\",\n \"refunded\": false,\n \"captured\": true,\n \"refunds\": [],\n \"card\": {\n \"id\": \"card_155MZJ2gKyKnHxtYihrJ8z94\",\n \"object\": \"card\",\n \"last4\": \"4242\",\n \"brand\": \"Visa\",\n \"funding\": \"credit\",\n \"exp_month\": 9,\n \"exp_year\": 2015,\n \"fingerprint\": \"944LvWcY01HVTbVc\",\n \"country\": \"US\",\n \"name\": \"Longbob Longsen\",\n \"address_line1\": null,\n \"address_line2\": null,\n \"address_city\": null,\n \"address_state\": null,\n \"address_zip\": null,\n \"address_country\": null,\n \"cvc_check\": \"pass\",\n \"address_line1_check\": null,\n \"address_zip_check\": null,\n \"dynamic_last4\": null,\n \"customer\": null,\n \"type\": \"Visa\"\n },\n \"balance_transaction\": \"txn_155MZJ2gKyKnHxtYxpYDI5OW\",\n \"failure_message\": null,\n \"failure_code\": null,\n \"amount_refunded\": 0,\n \"customer\": null,\n \"invoice\": null,\n \"description\": \"ActiveMerchant Test Purchase\",\n \"dispute\": null,\n \"metadata\": {\n \"email\": \"wow@example.com\"\n },\n \"statement_description\": null,\n \"fraud_details\": {\n \"stripe_report\": \"unavailable\",\n \"user_report\": null\n },\n \"receipt_email\": null,\n \"receipt_number\": null,\n \"shipping\": null\n}\n" + read 1303 bytes + Conn close + PRE_SCRUBBED + end + def pre_scrubbed_with_track_data <<-PRE_SCRUBBED opening connection to api.stripe.com:443... @@ -1666,6 +1751,35 @@ def post_scrubbed POST_SCRUBBED end + def post_scrubbed_nested_payment_method_data + <<-POST_SCRUBBED + opening connection to api.stripe.com:443... + opened + starting SSL for api.stripe.com:443... + SSL established + <- "POST /v1/charges HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAuthorization: Basic [FILTERED]\r\nUser-Agent: Stripe/v1 ActiveMerchantBindings/1.45.0\r\nX-Stripe-Client-User-Agent: {\"bindings_version\":\"1.45.0\",\"lang\":\"ruby\",\"lang_version\":\"2.1.3 p242 (2014-09-19)\",\"platform\":\"x86_64-linux\",\"publisher\":\"active_merchant\"}\r\nX-Stripe-Client-User-Metadata: {\"ip\":null}\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nConnection: close\r\nHost: api.stripe.com\r\nContent-Length: 270\r\n\r\n" + <- "amount=100¤cy=usd&payment_method_data[card][number]=[FILTERED]&payment_method_data[card][exp_month]=9&payment_method_data[card][exp_year]=2015&payment_method_data[card][cvc]=[FILTERED]&payment_method_data[card][name]=Longbob+Longsen&description=ActiveMerchant+Test+Purchase&payment_user_agent=Stripe%2Fv1+ActiveMerchantBindings%2F1.45.0&metadata[email]=wow%40example.com&payment_method_data[card][cryptogram]=[FILTERED]&three_d_secure[cryptogram]=[FILTERED]&three_d_secure[apple_pay]=true" + -> "HTTP/1.1 200 OK\r\n" + -> "Server: nginx\r\n" + -> "Date: Tue, 02 Dec 2014 19:44:17 GMT\r\n" + -> "Content-Type: application/json;charset=utf-8\r\n" + -> "Content-Length: 1303\r\n" + -> "Connection: close\r\n" + -> "Access-Control-Allow-Credentials: true\r\n" + -> "Access-Control-Allow-Methods: GET, POST, HEAD, OPTIONS, DELETE\r\n" + -> "Access-Control-Max-Age: 300\r\n" + -> "Cache-Control: no-cache, no-store\r\n" + -> "Request-Id: 89de951c-f880-4c39-93b0-832b3cc6dd32\r\n" + -> "Stripe-Version: 2013-12-03\r\n" + -> "Strict-Transport-Security: max-age=31556926; includeSubDomains\r\n" + -> "\r\n" + reading 1303 bytes... + -> "{\n \"id\": \"ch_155MZJ2gKyKnHxtY1dGqFhSb\",\n \"object\": \"charge\",\n \"created\": 1417549457,\n \"livemode\": false,\n \"paid\": true,\n \"amount\": 100,\n \"currency\": \"usd\",\n \"refunded\": false,\n \"captured\": true,\n \"refunds\": [],\n \"card\": {\n \"id\": \"card_155MZJ2gKyKnHxtYihrJ8z94\",\n \"object\": \"card\",\n \"last4\": \"4242\",\n \"brand\": \"Visa\",\n \"funding\": \"credit\",\n \"exp_month\": 9,\n \"exp_year\": 2015,\n \"fingerprint\": \"944LvWcY01HVTbVc\",\n \"country\": \"US\",\n \"name\": \"Longbob Longsen\",\n \"address_line1\": null,\n \"address_line2\": null,\n \"address_city\": null,\n \"address_state\": null,\n \"address_zip\": null,\n \"address_country\": null,\n \"cvc_check\": \"pass\",\n \"address_line1_check\": null,\n \"address_zip_check\": null,\n \"dynamic_last4\": null,\n \"customer\": null,\n \"type\": \"Visa\"\n },\n \"balance_transaction\": \"txn_155MZJ2gKyKnHxtYxpYDI5OW\",\n \"failure_message\": null,\n \"failure_code\": null,\n \"amount_refunded\": 0,\n \"customer\": null,\n \"invoice\": null,\n \"description\": \"ActiveMerchant Test Purchase\",\n \"dispute\": null,\n \"metadata\": {\n \"email\": \"wow@example.com\"\n },\n \"statement_description\": null,\n \"fraud_details\": {\n \"stripe_report\": \"unavailable\",\n \"user_report\": null\n },\n \"receipt_email\": null,\n \"receipt_number\": null,\n \"shipping\": null\n}\n" + read 1303 bytes + Conn close + POST_SCRUBBED + end + def successful_new_customer_response <<-RESPONSE { @@ -1944,6 +2058,173 @@ def successful_capture_response RESPONSE end + def successful_capture_response_without_icc_data + <<-RESPONSE + { + "id": "ch_test_emv_charge", + "object": "charge", + "amount": 1000, + "amount_refunded": 0, + "application": "ca_37BT8jOfv0Cu42Vfd", + "application_fee": "fee_test_fee", + "application_fee_amount": 55, + "authorization_code": "123456", + "balance_transaction": { + "id": "txn_1FSQUtFwNjfzuchLeWPB9X8K", + "object": "balance_transaction", + "amount": 1000, + "available_on": 1571184000, + "created": 1570809463, + "currency": "usd", + "description": null, + "exchange_rate": null, + "fee": 55, + "fee_details": [ + { + "amount": 55, + "application": "ca_37BT8jOfv0Cu42Vfd", + "currency": "usd", + "description": "application fee", + "type": "application_fee" + } + ], + "net": 945, + "source": "ch_test_emv_charge", + "sourced_transfers": { + "object": "list", + "data": [ + ], + "has_more": false, + "total_count": 0, + "url": "/v1/transfers?source_transaction=ch_test_emv_charge" + }, + "status": "pending", + "type": "charge" + }, + "billing_details": { + "address": { + "city": null, + "country": null, + "line1": null, + "line2": null, + "postal_code": null, + "state": null + }, + "email": null, + "name": null, + "phone": null + }, + "captured": true, + "created": 1570809458, + "currency": "usd", + "customer": null, + "description": null, + "destination": null, + "dispute": null, + "failure_code": null, + "failure_message": null, + "fraud_details": { + }, + "invoice": null, + "livemode": false, + "metadata": { + "card_read_method": "contact", + "shop_id": "1", + "shop_name": "Shop 1", + "transaction_fee_total_amount": "55", + "transaction_fee_tax_amount": "0", + "payments_charge_id": "86", + "order_transaction_id": "149", + "order_id": "c62.1" + }, + "on_behalf_of": null, + "order": null, + "outcome": { + "network_status": "approved_by_network", + "reason": null, + "risk_level": "normal", + "risk_score": 2, + "seller_message": "Payment complete.", + "type": "authorized" + }, + "paid": true, + "payment_intent": null, + "payment_method": "card_1FSQUo", + "payment_method_details": { + "card": { + "brand": "visa", + "checks": { + "address_line1_check": null, + "address_postal_code_check": null, + "cvc_check": null + }, + "country": "US", + "ds_transaction_id": null, + "exp_month": 12, + "exp_year": 2022, + "fingerprint": "PgHpMSUia1FIuXM6", + "funding": "unknown", + "installments": null, + "last4": "0119", + "moto": null, + "network": "visa", + "network_transaction_id": "ihQUSGFPfpVpg6J3", + "three_d_secure": null, + "wallet": null + }, + "type": "card" + }, + "receipt_email": null, + "receipt_number": null, + "receipt_url": "https://pay.stripe.com/receipts/acct_1FPxOBFwNjfzuchL/ch_test_emv_charge/rcpt_FyNFASxNs66DXe7zTe9jW9hpYZkQda9", + "refunded": false, + "refunds": { + "object": "list", + "data": [ + ], + "has_more": false, + "total_count": 0, + "url": "/v1/charges/ch_test_emv_charge/refunds" + }, + "review": null, + "shipping": null, + "source": { + "id": "card_1FSQUo", + "object": "card", + "address_city": null, + "address_country": null, + "address_line1": null, + "address_line1_check": null, + "address_line2": null, + "address_state": null, + "address_zip": null, + "address_zip_check": null, + "brand": "Visa", + "country": "US", + "customer": null, + "cvc_check": null, + "dynamic_last4": null, + "emv_auth_data": "8A023030", + "exp_month": 12, + "exp_year": 2022, + "fingerprint": "ihQUSGFPfpVpg6J3", + "funding": "unknown", + "last4": "0119", + "metadata": { + }, + "name": null, + "tokenization_method": null + }, + "source_transfer": null, + "statement_descriptor": null, + "statement_descriptor_suffix": null, + "status": "succeeded", + "transfer_data": null, + "transfer_group": null + } + RESPONSE + end + def successful_capture_response_with_icc_data <<-RESPONSE { @@ -2022,7 +2303,7 @@ def successful_capture_response_with_icc_data RESPONSE end - def successful_purchase_response(refunded=false) + def successful_purchase_response(refunded = false) <<-RESPONSE { "amount": 400, diff --git a/test/unit/gateways/swipe_checkout_test.rb b/test/unit/gateways/swipe_checkout_test.rb index e6c4e0da63a..0536f400685 100644 --- a/test/unit/gateways/swipe_checkout_test.rb +++ b/test/unit/gateways/swipe_checkout_test.rb @@ -19,7 +19,7 @@ def setup end def test_supported_countries - assert @gateway.supported_countries == ['NZ', 'CA'] + assert @gateway.supported_countries == %w[NZ CA] end def test_successful_purchase diff --git a/test/unit/gateways/telr_test.rb b/test/unit/gateways/telr_test.rb index 8e3ac5766bd..e34399b6faf 100644 --- a/test/unit/gateways/telr_test.rb +++ b/test/unit/gateways/telr_test.rb @@ -43,7 +43,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(/029894296182/, data) end.respond_with(successful_capture_response) @@ -77,7 +77,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(/029894296182/, data) end.respond_with(successful_void_response) @@ -87,7 +87,7 @@ def test_successful_void 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) @@ -104,7 +104,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(/029724176180/, data) end.respond_with(successful_refund_response) @@ -145,7 +145,7 @@ def test_successful_reference_purchase ref_purchase = stub_comms do @gateway.purchase(@amount, response.authorization) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/029724176180/, data) end.respond_with(successful_reference_purchase_response) diff --git a/test/unit/gateways/tns_test.rb b/test/unit/gateways/tns_test.rb index 926b921bca3..df59c9a62af 100644 --- a/test/unit/gateways/tns_test.rb +++ b/test/unit/gateways/tns_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']) @@ -166,7 +166,7 @@ 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| + end.check_request do |_method, endpoint, _data, _headers| assert_match(/secure.na.tnspayments.com/, endpoint) end.respond_with(successful_capture_response) @@ -182,7 +182,7 @@ def test_asia_pacific_region_url response = stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, endpoint, _data, _headers| assert_match(/secure.ap.tnspayments.com/, endpoint) end.respond_with(successful_capture_response) @@ -198,7 +198,7 @@ def test_europe_region_url response = stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, endpoint, _data, _headers| assert_match(/secure.eu.tnspayments.com/, endpoint) end.respond_with(successful_capture_response) diff --git a/test/unit/gateways/trans_first_test.rb b/test/unit/gateways/trans_first_test.rb index 02920e50d13..d8a2ca93ed2 100644 --- a/test/unit/gateways/trans_first_test.rb +++ b/test/unit/gateways/trans_first_test.rb @@ -1,17 +1,16 @@ require 'test_helper' class TransFirstTest < Test::Unit::TestCase - def setup @gateway = TransFirstGateway.new( - :login => 'LOGIN', - :password => 'PASSWORD' + login: 'LOGIN', + password: 'PASSWORD' ) @credit_card = credit_card('4242424242424242') @check = check @options = { - :billing_address => address + billing_address: address } @amount = 100 end @@ -68,7 +67,7 @@ def test_successful_refund response = @gateway.refund(@amount, 'TransID') assert_success response assert_equal '207686608|creditcard', response.authorization - assert_equal @amount, response.params['amount'].to_i*100 + assert_equal @amount, response.params['amount'].to_i * 100 end def test_failed_refund diff --git a/test/unit/gateways/trans_first_transaction_express_test.rb b/test/unit/gateways/trans_first_transaction_express_test.rb index 1bbfdf81f88..f3bbd4b42e2 100644 --- a/test/unit/gateways/trans_first_transaction_express_test.rb +++ b/test/unit/gateways/trans_first_transaction_express_test.rb @@ -26,6 +26,25 @@ def test_successful_purchase assert response.test? end + def test_strip_hyphens_from_zip + options = { + billing_address: { + name: 'John & Mary Smith', + address1: '1 Main St.', + city: 'Burlington', + state: 'MA', + zip: '01803-3747', + country: 'US' + } + } + + stub_comms do + @gateway.purchase(@amount, @credit_card, options) + end.check_request do |_endpoint, data, _headers| + assert_match(/018033747/, data) + end.respond_with(successful_purchase_response) + end + def test_failed_purchase response = stub_comms do @gateway.purchase(@declined_amount, @credit_card) @@ -63,7 +82,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(/000015377801/, data) end.respond_with(successful_capture_response) @@ -99,7 +118,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(/000015212561/, data) end.respond_with(successful_void_response) @@ -109,7 +128,7 @@ def test_successful_void def test_failed_void response = stub_comms do @gateway.void('purchase|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) @@ -127,7 +146,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(/000015212561/, data) end.respond_with(successful_refund_response) @@ -153,7 +172,7 @@ def test_successful_refund_with_echeck 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(/000028705491/, data) end.respond_with(successful_refund_echeck_response) @@ -321,62 +340,62 @@ def empty_purchase_response end def transcript - <<-PRE_SCRUBBED -opening connection to ws.cert.transactionexpress.com:443... -opened -starting SSL for ws.cert.transactionexpress.com:443... -SSL established -<- "POST /portal/merchantframework/MerchantWebServices-v1?wsdl HTTP/1.1\r\nContent-Type: text/xml\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: ws.cert.transactionexpress.com\r\nContent-Length: 1186\r\n\r\n" -<- "7777778764M84PKPDMD5BY86HN1144858962610177081709Longbob LongsenAcmeQA Manager43334445555450 MainSuite 100BroomfieldCO85284USexample@example.comLongbob Longsen450 MainSuite 100BroomfieldCO8528433344455551007a0f975b6e86aff44364360cbc6d0f00" --> "HTTP/1.1 200 OK\r\n" --> "Content-Type: text/xml;charset=utf-8\r\n" --> "Date: Thu, 21 Jan 2016 20:09:44 GMT\r\n" --> "Server: WebServer\r\n" --> "Set-Cookie: NSC_UMT12_DFSU-xt.dfsu.UYQ.dpn=ffffffff0918172545525d5f4f58455e445a4a42378b;expires=Thu, 21-Jan-2016 20:17:43 GMT;path=/;secure;httponly\r\n" --> "Cache-Control: private\r\n" --> "Content-Encoding: gzip\r\n" --> "Transfer-Encoding: chunked\r\n" --> "\r\n" --> "1AA \r\n" -reading 426 bytes... --> "" -read 426 bytes -reading 2 bytes... --> "\r\n" -read 2 bytes --> "0\r\n" --> "\r\n" -Conn close + <<~PRE_SCRUBBED + opening connection to ws.cert.transactionexpress.com:443... + opened + starting SSL for ws.cert.transactionexpress.com:443... + SSL established + <- "POST /portal/merchantframework/MerchantWebServices-v1?wsdl HTTP/1.1\r\nContent-Type: text/xml\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: ws.cert.transactionexpress.com\r\nContent-Length: 1186\r\n\r\n" + <- "7777778764M84PKPDMD5BY86HN1144858962610177081709Longbob LongsenAcmeQA Manager43334445555450 MainSuite 100BroomfieldCO85284USexample@example.comLongbob Longsen450 MainSuite 100BroomfieldCO8528433344455551007a0f975b6e86aff44364360cbc6d0f00" + -> "HTTP/1.1 200 OK\r\n" + -> "Content-Type: text/xml;charset=utf-8\r\n" + -> "Date: Thu, 21 Jan 2016 20:09:44 GMT\r\n" + -> "Server: WebServer\r\n" + -> "Set-Cookie: NSC_UMT12_DFSU-xt.dfsu.UYQ.dpn=ffffffff0918172545525d5f4f58455e445a4a42378b;expires=Thu, 21-Jan-2016 20:17:43 GMT;path=/;secure;httponly\r\n" + -> "Cache-Control: private\r\n" + -> "Content-Encoding: gzip\r\n" + -> "Transfer-Encoding: chunked\r\n" + -> "\r\n" + -> "1AA \r\n" + reading 426 bytes... + -> "" + read 426 bytes + reading 2 bytes... + -> "\r\n" + read 2 bytes + -> "0\r\n" + -> "\r\n" + Conn close PRE_SCRUBBED end def scrubbed_transcript - <<-POST_SCRUBBED -opening connection to ws.cert.transactionexpress.com:443... -opened -starting SSL for ws.cert.transactionexpress.com:443... -SSL established -<- "POST /portal/merchantframework/MerchantWebServices-v1?wsdl HTTP/1.1\r\nContent-Type: text/xml\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: ws.cert.transactionexpress.com\r\nContent-Length: 1186\r\n\r\n" -<- "[FILTERED][FILTERED]11[FILTERED]1709Longbob LongsenAcmeQA Manager43334445555450 MainSuite 100BroomfieldCO85284USexample@example.comLongbob Longsen450 MainSuite 100BroomfieldCO8528433344455551007a0f975b6e86aff44364360cbc6d0f00" --> "HTTP/1.1 200 OK\r\n" --> "Content-Type: text/xml;charset=utf-8\r\n" --> "Date: Thu, 21 Jan 2016 20:09:44 GMT\r\n" --> "Server: WebServer\r\n" --> "Set-Cookie: NSC_UMT12_DFSU-xt.dfsu.UYQ.dpn=ffffffff0918172545525d5f4f58455e445a4a42378b;expires=Thu, 21-Jan-2016 20:17:43 GMT;path=/;secure;httponly\r\n" --> "Cache-Control: private\r\n" --> "Content-Encoding: gzip\r\n" --> "Transfer-Encoding: chunked\r\n" --> "\r\n" --> "1AA \r\n" -reading 426 bytes... --> "" -read 426 bytes -reading 2 bytes... --> "\r\n" -read 2 bytes --> "0\r\n" --> "\r\n" -Conn close + <<~POST_SCRUBBED + opening connection to ws.cert.transactionexpress.com:443... + opened + starting SSL for ws.cert.transactionexpress.com:443... + SSL established + <- "POST /portal/merchantframework/MerchantWebServices-v1?wsdl HTTP/1.1\r\nContent-Type: text/xml\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: ws.cert.transactionexpress.com\r\nContent-Length: 1186\r\n\r\n" + <- "[FILTERED][FILTERED]11[FILTERED]1709Longbob LongsenAcmeQA Manager43334445555450 MainSuite 100BroomfieldCO85284USexample@example.comLongbob Longsen450 MainSuite 100BroomfieldCO8528433344455551007a0f975b6e86aff44364360cbc6d0f00" + -> "HTTP/1.1 200 OK\r\n" + -> "Content-Type: text/xml;charset=utf-8\r\n" + -> "Date: Thu, 21 Jan 2016 20:09:44 GMT\r\n" + -> "Server: WebServer\r\n" + -> "Set-Cookie: NSC_UMT12_DFSU-xt.dfsu.UYQ.dpn=ffffffff0918172545525d5f4f58455e445a4a42378b;expires=Thu, 21-Jan-2016 20:17:43 GMT;path=/;secure;httponly\r\n" + -> "Cache-Control: private\r\n" + -> "Content-Encoding: gzip\r\n" + -> "Transfer-Encoding: chunked\r\n" + -> "\r\n" + -> "1AA \r\n" + reading 426 bytes... + -> "" + read 426 bytes + reading 2 bytes... + -> "\r\n" + read 2 bytes + -> "0\r\n" + -> "\r\n" + Conn close POST_SCRUBBED end end diff --git a/test/unit/gateways/transact_pro_test.rb b/test/unit/gateways/transact_pro_test.rb index 6323dc78536..642fc6f4ed6 100644 --- a/test/unit/gateways/transact_pro_test.rb +++ b/test/unit/gateways/transact_pro_test.rb @@ -75,7 +75,7 @@ def test_partial_capture @gateway.expects(:ssl_post).never assert_raise(ArgumentError) do - @gateway.capture(@amount-1, '3d25ab044075924479d3836f549b015481d15d74|100') + @gateway.capture(@amount - 1, '3d25ab044075924479d3836f549b015481d15d74|100') end end @@ -100,7 +100,7 @@ def test_successful_refund def test_partial_refund @gateway.expects(:ssl_post).returns(successful_refund_response) - assert refund = @gateway.refund(@amount-1, '3d25ab044075924479d3836f549b015481d15d74|100') + assert refund = @gateway.refund(@amount - 1, '3d25ab044075924479d3836f549b015481d15d74|100') assert_success refund assert_equal 'Refund Success', refund.message assert_equal '3d25ab044075924479d3836f549b015481d15d74', refund.authorization @@ -109,7 +109,7 @@ def test_partial_refund def test_failed_refund @gateway.expects(:ssl_post).returns(failed_refund_response) - assert refund = @gateway.refund(@amount+1, '3d25ab044075924479d3836f549b015481d15d74|100') + assert refund = @gateway.refund(@amount + 1, '3d25ab044075924479d3836f549b015481d15d74|100') assert_failure refund end diff --git a/test/unit/gateways/trexle_test.rb b/test/unit/gateways/trexle_test.rb index a1ee4295ccc..b1bb3625ec2 100644 --- a/test/unit/gateways/trexle_test.rb +++ b/test/unit/gateways/trexle_test.rb @@ -46,7 +46,7 @@ def test_supported_countries end def test_supported_cardtypes - assert_equal [:visa, :master, :american_express], TrexleGateway.supported_cardtypes + assert_equal %i[visa master american_express], TrexleGateway.supported_cardtypes end def test_display_name @@ -123,7 +123,7 @@ def test_successful_update def test_successful_refund token = 'charge_0cfad7ee5ffe75f58222bff214bfa5cc7ad7c367' - @gateway.expects(:ssl_request).with(:post, "https://core.trexle.com/api/v1/charges/#{token}/refunds", {amount: '100'}.to_json, instance_of(Hash)).returns(successful_refund_response) + @gateway.expects(:ssl_request).with(:post, "https://core.trexle.com/api/v1/charges/#{token}/refunds", { amount: '100' }.to_json, instance_of(Hash)).returns(successful_refund_response) assert response = @gateway.refund(100, token) assert_equal 'refund_7f696a86f9cb136520c51ea90c17f687b8df40b0', response.authorization @@ -133,7 +133,7 @@ def test_successful_refund def test_unsuccessful_refund token = 'charge_0cfad7ee5ffe75f58222bff214bfa5cc7ad7c367' - @gateway.expects(:ssl_request).with(:post, "https://core.trexle.com/api/v1/charges/#{token}/refunds", {amount: '100'}.to_json, instance_of(Hash)).returns(failed_refund_response) + @gateway.expects(:ssl_request).with(:post, "https://core.trexle.com/api/v1/charges/#{token}/refunds", { amount: '100' }.to_json, instance_of(Hash)).returns(failed_refund_response) assert response = @gateway.refund(100, token) assert_failure response @@ -440,5 +440,4 @@ def scrubbed_transcript } }' end - end diff --git a/test/unit/gateways/trust_commerce_test.rb b/test/unit/gateways/trust_commerce_test.rb index 84d14090b66..cbca3c48762 100644 --- a/test/unit/gateways/trust_commerce_test.rb +++ b/test/unit/gateways/trust_commerce_test.rb @@ -4,9 +4,9 @@ class TrustCommerceTest < Test::Unit::TestCase include CommStub def setup @gateway = TrustCommerceGateway.new( - :login => 'TestMerchant', - :password => 'password', - :aggregator_id => 'abc123' + login: 'TestMerchant', + password: 'password', + aggregator_id: 'abc123' ) # Force SSL post @gateway.stubs(:tclink?).returns(false) @@ -41,7 +41,7 @@ def test_succesful_purchase_with_check ActiveMerchant::Billing::TrustCommerceGateway.application_id = 'abc123' stub_comms do @gateway.purchase(@amount, @check) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{aggregator1}, data) assert_match(%r{name=Jim\+Smith}, data) end.respond_with(successful_purchase_response) @@ -50,7 +50,7 @@ def test_succesful_purchase_with_check def test_succesful_purchase_with_custom_fields stub_comms do @gateway.purchase(@amount, @credit_card, @options_with_custom_fields) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{customfield1=test1}, data) end.respond_with(successful_purchase_response) end @@ -58,7 +58,7 @@ def test_succesful_purchase_with_custom_fields def test_succesful_authorize_with_custom_fields stub_comms do @gateway.authorize(@amount, @check, @options_with_custom_fields) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{customfield1=test1}, data) end.respond_with(successful_authorize_response) end @@ -66,7 +66,7 @@ def test_succesful_authorize_with_custom_fields def test_successful_void_from_purchase stub_comms do @gateway.void('1235|sale') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{action=void}, data) end.respond_with(successful_void_response) end @@ -74,7 +74,7 @@ def test_successful_void_from_purchase def test_successful_void_from_authorize stub_comms do @gateway.void('1235|preauth') - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{action=reversal}, data) end.respond_with(successful_void_response) end @@ -82,7 +82,7 @@ def test_successful_void_from_authorize def test_succesful_capture_with_custom_fields stub_comms do @gateway.capture(@amount, 'auth', @options_with_custom_fields) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{customfield1=test1}, data) end.respond_with(successful_capture_response) end @@ -90,7 +90,7 @@ def test_succesful_capture_with_custom_fields def test_succesful_refund_with_custom_fields stub_comms do @gateway.refund(@amount, 'auth|100', @options_with_custom_fields) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{customfield1=test1}, data) end.respond_with(successful_refund_response) end @@ -98,7 +98,7 @@ def test_succesful_refund_with_custom_fields def test_succesful_void_with_custom_fields stub_comms do @gateway.void('1235|sale', @options_with_custom_fields) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{customfield1=test1}, data) end.respond_with(successful_void_response) end @@ -106,7 +106,7 @@ def test_succesful_void_with_custom_fields def test_succesful_store_with_custom_fields stub_comms do @gateway.store(@credit_card, @options_with_custom_fields) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{customfield1=test1}, data) end.respond_with(successful_store_response) end @@ -114,7 +114,7 @@ def test_succesful_store_with_custom_fields def test_succesful_unstore_with_custom_fields stub_comms do @gateway.unstore('test', @options_with_custom_fields) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(%r{customfield1=test1}, data) end.respond_with(successful_unstore_response) end @@ -146,7 +146,7 @@ def test_supported_countries end def test_supported_card_types - assert_equal [:visa, :master, :discover, :american_express, :diners_club, :jcb], TrustCommerceGateway.supported_cardtypes + assert_equal %i[visa master discover american_express diners_club jcb], TrustCommerceGateway.supported_cardtypes end def test_test_flag_should_be_set_when_using_test_login_in_production @@ -166,80 +166,80 @@ def test_transcript_scrubbing private def successful_authorize_response - <<-RESPONSE -authcode=123456 -transid=026-0193338367, -status=approved -avs=Y -cvv=M + <<~RESPONSE + authcode=123456 + transid=026-0193338367, + status=approved + avs=Y + cvv=M RESPONSE end def successful_purchase_response - <<-RESPONSE -transid=025-0007423614 -status=approved -avs=Y -cvv=P + <<~RESPONSE + transid=025-0007423614 + status=approved + avs=Y + cvv=P RESPONSE end def successful_capture_response - <<-RESPONSE -transid=026-0193338993 -status=accepted + <<~RESPONSE + transid=026-0193338993 + status=accepted RESPONSE end def unsuccessful_purchase_response - <<-RESPONSE -transid=025-0007423827 -declinetype=cvv -status=decline -cvv=N + <<~RESPONSE + transid=025-0007423827 + declinetype=cvv + status=decline + cvv=N RESPONSE end def successful_void_response - <<-RESPONSE -transid=025-0007423828 -status=accpeted + <<~RESPONSE + transid=025-0007423828 + status=accpeted RESPONSE end def successful_refund_response - <<-RESPONSE -transid=026-0193345407 -status=accepted + <<~RESPONSE + transid=026-0193345407 + status=accepted RESPONSE end def successful_store_response - <<-RESPONSE -transid=026-0193346109 -status=approved, -cvv=M, -avs=0 -billingid=Q5T7PT + <<~RESPONSE + transid=026-0193346109 + status=approved, + cvv=M, + avs=0 + billingid=Q5T7PT RESPONSE end def successful_unstore_response - <<-RESPONSE -transid=026-0193346231 -status=rejected + <<~RESPONSE + transid=026-0193346231 + status=rejected RESPONSE end def transcript - <<-TRANSCRIPT -action=sale&demo=y&password=password&custid=TestMerchant&shipto_zip=90001&shipto_state=CA&shipto_city=Somewhere&shipto_address1=123+Test+St.&avs=n&zip=90001&state=CA&city=Somewhere&address1=123+Test+St.&cvv=1234&exp=0916&cc=4111111111111111&name=Longbob+Longsen&media=cc&ip=10.10.10.10&email=cody%40example.com&ticket=%231000.1&amount=100 + <<~TRANSCRIPT + action=sale&demo=y&password=password&custid=TestMerchant&shipto_zip=90001&shipto_state=CA&shipto_city=Somewhere&shipto_address1=123+Test+St.&avs=n&zip=90001&state=CA&city=Somewhere&address1=123+Test+St.&cvv=1234&exp=0916&cc=4111111111111111&name=Longbob+Longsen&media=cc&ip=10.10.10.10&email=cody%40example.com&ticket=%231000.1&amount=100 TRANSCRIPT end def scrubbed_transcript - <<-TRANSCRIPT -action=sale&demo=y&password=[FILTERED]&custid=TestMerchant&shipto_zip=90001&shipto_state=CA&shipto_city=Somewhere&shipto_address1=123+Test+St.&avs=n&zip=90001&state=CA&city=Somewhere&address1=123+Test+St.&cvv=[FILTERED]&exp=0916&cc=[FILTERED]&name=Longbob+Longsen&media=cc&ip=10.10.10.10&email=cody%40example.com&ticket=%231000.1&amount=100 + <<~TRANSCRIPT + action=sale&demo=y&password=[FILTERED]&custid=TestMerchant&shipto_zip=90001&shipto_state=CA&shipto_city=Somewhere&shipto_address1=123+Test+St.&avs=n&zip=90001&state=CA&city=Somewhere&address1=123+Test+St.&cvv=[FILTERED]&exp=0916&cc=[FILTERED]&name=Longbob+Longsen&media=cc&ip=10.10.10.10&email=cody%40example.com&ticket=%231000.1&amount=100 TRANSCRIPT end end diff --git a/test/unit/gateways/usa_epay_advanced_test.rb b/test/unit/gateways/usa_epay_advanced_test.rb index 7c22b87d841..7edd03a6728 100644 --- a/test/unit/gateways/usa_epay_advanced_test.rb +++ b/test/unit/gateways/usa_epay_advanced_test.rb @@ -16,90 +16,90 @@ def setup # UsaEpayAdvancedGateway.wiredump_device.sync = true @gateway = UsaEpayAdvancedGateway.new( - :login => 'X', - :password => 'Y', - :software_id => 'Z' - ) + login: 'X', + password: 'Y', + software_id: 'Z' + ) @credit_card = ActiveMerchant::Billing::CreditCard.new( - :number => '4000100011112224', - :month => 12, - :year => 12, - :brand => 'visa', - :verification_value => '123', - :first_name => 'Fred', - :last_name => 'Flintstone' + number: '4000100011112224', + month: 12, + year: 12, + brand: 'visa', + verification_value: '123', + first_name: 'Fred', + last_name: 'Flintstone' ) @check = ActiveMerchant::Billing::Check.new( - :account_number => '123456789012', - :routing_number => '123456789', - :account_type => 'checking', - :first_name => 'Fred', - :last_name => 'Flintstone' + account_number: '123456789012', + routing_number: '123456789', + account_type: 'checking', + first_name: 'Fred', + last_name: 'Flintstone' ) payment_methods = [ { - :name => 'My Visa', # optional - :sort => 2, # optional - :method => @credit_card + name: 'My Visa', # optional + sort: 2, # optional + method: @credit_card }, { - :name => 'My Checking', - :method => @check + name: 'My Checking', + method: @check } ] payment_method = { - :name => 'My new Visa', # optional - :method => @credit_card + name: 'My new Visa', # optional + method: @credit_card } @customer_options = { - :id => 1, # optional: merchant assigned id, usually db id - :notes => 'Note about customer', # optional - :data => 'Some Data', # optional - :url => 'awesomesite.com', # optional - :payment_methods => payment_methods # optional + id: 1, # optional: merchant assigned id, usually db id + notes: 'Note about customer', # optional + data: 'Some Data', # optional + url: 'awesomesite.com', # optional + payment_methods: payment_methods # optional } @payment_options = { - :payment_method => payment_method + payment_method: payment_method } @transaction_options = { - :payment_method => @credit_card, - :recurring => { - :schedule => 'monthly', - :amount => 4000 + payment_method: @credit_card, + recurring: { + schedule: 'monthly', + amount: 4000 } } @standard_transaction_options = { - :method_id => 0, - :command => 'Sale', - :amount => 2000 # 20.00 + method_id: 0, + command: 'Sale', + amount: 2000 # 20.00 } @get_payment_options = { - :method_id => 0 + method_id: 0 } @delete_customer_options = { - :customer_number => 299461 + customer_number: 299461 } @custom_options = { - :fields => ['Response.StatusCode', 'Response.Status'] + fields: ['Response.StatusCode', 'Response.Status'] } @options = { - :client_ip => '127.0.0.1', - :billing_address => address, + client_ip: '127.0.0.1', + billing_address: address, - :customer_number => 298741, - :reference_number => 9999 + customer_number: 298741, + reference_number: 9999 } end @@ -203,7 +203,7 @@ def test_successful_update_customer def test_successful_quick_update_customer @gateway.expects(:ssl_post).returns(successful_customer_response('quickUpdateCustomer')) - assert response = @gateway.quick_update_customer({customer_number: @options[:customer_number], update_data: @customer_options}) + assert response = @gateway.quick_update_customer({ customer_number: @options[:customer_number], update_data: @customer_options }) assert_instance_of Response, response assert response.test? assert_success response @@ -279,7 +279,7 @@ def test_successful_get_customer_payment_method def test_successful_get_customer_payment_methods @gateway.expects(:ssl_post).returns(successful_get_customer_payment_methods_response) - assert response = @gateway.get_customer_payment_methods(@options.merge!(:customer_number => 298741)) + assert response = @gateway.get_customer_payment_methods(@options.merge!(customer_number: 298741)) assert_instance_of Response, response assert_success response assert response.test? @@ -305,7 +305,7 @@ def test_successful_update_customer_payment_method def test_successful_delete_customer_payment_method @gateway.expects(:ssl_post).returns(successful_delete_customer_payment_method_response) - assert response = @gateway.delete_customer_payment_method(@options.merge!(:customer_number => 298741, :method_id => 15)) + assert response = @gateway.delete_customer_payment_method(@options.merge!(customer_number: 298741, method_id: 15)) assert_instance_of Response, response assert_success response assert_equal 'true', response.message @@ -396,8 +396,8 @@ def test_successful_run_check_sale @options.merge!(@transaction_options) response = stub_comms do - @gateway.run_check_sale(@options.merge(:payment_method => @check)) - end.check_request do |endpoint, data, headers| + @gateway.run_check_sale(@options.merge(payment_method: @check)) + end.check_request do |_endpoint, data, _headers| assert_match(/123456789012/, data) end.respond_with(successful_transaction_response('runCheckSale')) @@ -580,125 +580,125 @@ def test_mismatch_response # Standard Gateway ================================================== def successful_purchase_response - <<-XML - -0017523Address: Match & 5 Digit Zip: MatchYYY114004MatchMVisa TraditionalA008400Approved0false47602591ApprovedAPendingP + <<~XML + + 0017523Address: Match & 5 Digit Zip: MatchYYY114004MatchMVisa TraditionalA008400Approved0false47602591ApprovedAPendingP XML end def successful_authorize_response - <<-XML - -0017524Address: Match & 5 Digit Zip: MatchYYY114004MatchMVisa TraditionalA008400Approved0false47602592ApprovedAPendingP + <<~XML + + 0017524Address: Match & 5 Digit Zip: MatchYYY114004MatchMVisa TraditionalA008400Approved0false47602592ApprovedAPendingP XML end def successful_capture_response - <<-XML - -0017525No AVS response (Typically no AVS data sent or swiped transaction)00No CVV2/CVC data available for transaction.Unknown Code 008400Approved0false47602593ApprovedAPendingP + <<~XML + + 0017525No AVS response (Typically no AVS data sent or swiped transaction)00No CVV2/CVC data available for transaction.Unknown Code 008400Approved0false47602593ApprovedAPendingP XML end def successful_void_response - <<-XML - -true + <<~XML + + true XML end def successful_credit_response - <<-XML - -047612622Unmapped AVS response ( )No CVV2/CVC data available for transaction.Unknown Code 000false47602599ApprovedAPendingP + <<~XML + + 047612622Unmapped AVS response ( )No CVV2/CVC data available for transaction.Unknown Code 000false47602599ApprovedAPendingP XML end # Customer ========================================================== def successful_add_customer_response - <<-XML - -274141 + <<~XML + + 274141 XML end def invalid_checking_add_customer_response - <<-XML -SOAP-ENV:Server39: Invalid Checking Account Number. + <<~XML + SOAP-ENV:Server39: Invalid Checking Account Number. XML end def successful_customer_response(method) - <<-XML -<#{method}Return xsi:type="xsd:boolean">true + <<~XML + <#{method}Return xsi:type="xsd:boolean">true XML end def successful_run_customer_transaction_response - <<-XML -038460Address: Match & 5 Digit Zip: MatchYYY114004Not ProcessedP000Approved0false47555081ApprovedAPendingP + <<~XML + 038460Address: Match & 5 Digit Zip: MatchYYY114004Not ProcessedP000Approved0false47555081ApprovedAPendingP XML end def successful_add_customer_payment_method_response - <<-XML -77 + <<~XML + 77 XML end def failed_add_customer_payment_method_response - <<-XML -SOAP-ENV:Server40459: Payment method not added because verification returned a Declined:10127:Card Declined (00) + <<~XML + SOAP-ENV:Server40459: Payment method not added because verification returned a Declined:10127:Card Declined (00) XML end def successful_get_customer_payment_method_response - <<-XML -cc103My CC52011-06-09T13:48:57+08:002011-06-09T13:48:57+08:00456 My StreetK1C2N62012-12XXXXXXXXXXXX2224V + <<~XML + cc103My CC52011-06-09T13:48:57+08:002011-06-09T13:48:57+08:00456 My StreetK1C2N62012-12XXXXXXXXXXXX2224V XML end def failed_get_customer_payment_method_response - <<-XML -SOAP-ENV:Server40453: Unable to locate requested payment method. + <<~XML + SOAP-ENV:Server40453: Unable to locate requested payment method. XML end def successful_get_customer_payment_methods_response - <<-XML -cc93My CC52011-06-09T08:10:44+08:002011-06-09T08:10:44+08:00456 My StreetK1C2N62012-12XXXXXXXXXXXX2224Vcc94Other CC122011-06-09T08:10:44+08:002011-06-09T08:10:44+08:00456 My StreetK1C2N62012-12XXXXXXXXXXXX2224V + <<~XML + cc93My CC52011-06-09T08:10:44+08:002011-06-09T08:10:44+08:00456 My StreetK1C2N62012-12XXXXXXXXXXXX2224Vcc94Other CC122011-06-09T08:10:44+08:002011-06-09T08:10:44+08:00456 My StreetK1C2N62012-12XXXXXXXXXXXX2224V XML end def successful_single_get_customer_payment_methods_response - <<-XML -cc15My Visa22011-06-05T19:44:09+08:002011-06-05T19:44:09+08:00456 My StreetK1C2N62012-09XXXXXXXXXXXX4242V + <<~XML + cc15My Visa22011-06-05T19:44:09+08:002011-06-05T19:44:09+08:00456 My StreetK1C2N62012-09XXXXXXXXXXXX4242V XML end def successful_update_customer_payment_method_response - <<-XML - -true + <<~XML + + true XML end def successful_delete_customer_payment_method_response - <<-XML -true + <<~XML + true XML end def failed_delete_customer_payment_method_response - <<-XML -SOAP-ENV:Server40453: Unable to locate requested payment method. + <<~XML + SOAP-ENV:Server40453: Unable to locate requested payment method. XML end def failed_delete_customer_response - <<-XML -SOAP-ENV:Server40030: Customer Not Found + <<~XML + SOAP-ENV:Server40030: Customer Not Found XML end @@ -710,20 +710,20 @@ def successful_avs_cvv_transaction_response(method) end def successful_transaction_response(method) - <<-XML -<#{method}Return xsi:type="ns1:TransactionResponse">047578712Unmapped AVS response ( )00No CVV2/CVC data available for transaction.Unknown Code 0084000false47568689ApprovedAPendingP + <<~XML + <#{method}Return xsi:type="ns1:TransactionResponse">047578712Unmapped AVS response ( )00No CVV2/CVC data available for transaction.Unknown Code 0084000false47568689ApprovedAPendingP XML end def failed_run_check_sale_response - <<-XML -0000000No AVS response (Typically no AVS data sent or swiped transaction)00No CVV2/CVC data available for transaction.Unknown Code 000Invalid Routing Number.38false0ErrorEPendingP + <<~XML + 0000000No AVS response (Typically no AVS data sent or swiped transaction)00No CVV2/CVC data available for transaction.Unknown Code 000Invalid Routing Number.38false0ErrorEPendingP XML end def failed_run_check_credit_response - <<-XML -0000000No AVS response (Typically no AVS data sent or swiped transaction)00No CVV2/CVC data available for transaction.Unknown Code 000Invalid Routing Number.38false0ErrorEPendingP + <<~XML + 0000000No AVS response (Typically no AVS data sent or swiped transaction)00No CVV2/CVC data available for transaction.Unknown Code 000Invalid Routing Number.38false0ErrorEPendingP XML end @@ -733,15 +733,15 @@ def successful_post_auth_response end def failed_post_auth_response - <<-XML -0000000No AVS response (Typically no AVS data sent or swiped transaction)00No CVV2/CVC data available for transaction.Unknown Code 000Valid AuthCode required for PostAuth108false0ErrorEPendingP + <<~XML + 0000000No AVS response (Typically no AVS data sent or swiped transaction)00No CVV2/CVC data available for transaction.Unknown Code 000Valid AuthCode required for PostAuth108false0ErrorEPendingP XML end def successful_capture_transaction_response - <<-XML - -0004043No AVS response (Typically no AVS data sent or swiped transaction)00No CVV2/CVC data available for transaction.Unknown Code 008400Approved0false47587252ApprovedAPendingP + <<~XML + + 0004043No AVS response (Typically no AVS data sent or swiped transaction)00No CVV2/CVC data available for transaction.Unknown Code 008400Approved0false47587252ApprovedAPendingP XML end @@ -751,61 +751,61 @@ def successful_override_transaction_response end def failed_override_transaction_response - <<-XML -SOAP-ENV:Server105: Override not available for requested transaction. + <<~XML + SOAP-ENV:Server105: Override not available for requested transaction. XML end def successful_void_transaction_response - <<-XML - -true + <<~XML + + true XML end def successful_refund_transaction_response - <<-XML - -047597281Unmapped AVS response ( )No CVV2/CVC data available for transaction.Unknown Code 000false47587258ApprovedAPendingP + <<~XML + + 047597281Unmapped AVS response ( )No CVV2/CVC data available for transaction.Unknown Code 000false47587258ApprovedAPendingP XML end # Transaction Response ============================================== def successful_get_transaction_status_response - <<-XML - -50050162Address: Match & 5 Digit Zip: MatchYYY114004MatchM000Approved0false47569011ApprovedAPendingP + <<~XML + + 50050162Address: Match & 5 Digit Zip: MatchYYY114004MatchM000Approved0false47569011ApprovedAPendingP XML end def successful_get_transaction_custom_response - <<-XML - -Response.StatusCodePResponse.StatusPending + <<~XML + + Response.StatusCodePResponse.StatusPending XML end def successful_get_check_trace_response - <<-XML - -PendingP2011-06-2111061908516155 + <<~XML + + PendingP2011-06-2111061908516155 XML end def successful_get_transaction_response - <<-XML - -OttawaWidgets IncCAJimSmith(555)555-5555ON456 My StreetApt 1K1C2N6127.0.0.1456 My StreetK1C2N6XXXXXXXXXXXXXXXXXXX2224falseVfalse2011-06-11 19:23:37
500false00
00
50050129Address: Match & 5 Digit Zip: MatchYYY114004MatchM000Approved0false47568950ApprovedAPendingP67.168.21.42OttawaWidgets IncCAJimSmith(555)555-5555ON456 My StreetApt 1K1C2N6testAuthorized (Pending Settlement)Saleauto
+ <<~XML + + OttawaWidgets IncCAJimSmith(555)555-5555ON456 My StreetApt 1K1C2N6127.0.0.1456 My StreetK1C2N6XXXXXXXXXXXXXXXXXXX2224falseVfalse2011-06-11 19:23:37
500false00
00
50050129Address: Match & 5 Digit Zip: MatchYYY114004MatchM000Approved0false47568950ApprovedAPendingP67.168.21.42OttawaWidgets IncCAJimSmith(555)555-5555ON456 My StreetApt 1K1C2N6testAuthorized (Pending Settlement)Saleauto
XML end # Account =========================================================== def successful_get_account_details - <<-XML -Disabled -TestBedTest BedfalseDisabledeCommerce + <<~XML + Disabled + TestBedTest BedfalseDisabledeCommerce XML end diff --git a/test/unit/gateways/usa_epay_test.rb b/test/unit/gateways/usa_epay_test.rb index 4aa91905676..e7647eb15c8 100644 --- a/test/unit/gateways/usa_epay_test.rb +++ b/test/unit/gateways/usa_epay_test.rb @@ -2,29 +2,28 @@ require 'logger' class UsaEpayTest < Test::Unit::TestCase - def test_transaction_gateway_created gateway = UsaEpayGateway.new( - :login => 'X' + login: 'X' ) assert_kind_of UsaEpayTransactionGateway, gateway end def test_advanced_gateway_created_with_software_id gateway = UsaEpayGateway.new( - :login => 'X', - :password => 'Y', - :software_id => 'Z' + login: 'X', + password: 'Y', + software_id: 'Z' ) assert_kind_of UsaEpayAdvancedGateway, gateway end def test_advanced_gateway_created_with_urls gateway = UsaEpayGateway.new( - :login => 'X', - :password => 'Y', - :test_url => 'Z', - :live_url => 'Z' + login: 'X', + password: 'Y', + test_url: 'Z', + live_url: 'Z' ) assert_kind_of UsaEpayAdvancedGateway, gateway end diff --git a/test/unit/gateways/usa_epay_transaction_test.rb b/test/unit/gateways/usa_epay_transaction_test.rb index b75959ee308..d3803502e2b 100644 --- a/test/unit/gateways/usa_epay_transaction_test.rb +++ b/test/unit/gateways/usa_epay_transaction_test.rb @@ -4,13 +4,13 @@ class UsaEpayTransactionTest < Test::Unit::TestCase include CommStub def setup - @gateway = UsaEpayTransactionGateway.new(:login => 'LOGIN') + @gateway = UsaEpayTransactionGateway.new(login: 'LOGIN') @credit_card = credit_card('4242424242424242') @check = check @options = { - :billing_address => address, - :shipping_address => address + billing_address: address, + shipping_address: address } @amount = 100 end @@ -21,7 +21,7 @@ def test_urls end def test_request_url_live - gateway = UsaEpayTransactionGateway.new(:login => 'LOGIN', :test => false) + gateway = UsaEpayTransactionGateway.new(login: 'LOGIN', test: false) gateway.expects(:ssl_post). with('https://www.usaepay.com/gate', regexp_matches(Regexp.new('^' + Regexp.escape(purchase_request)))). returns(successful_purchase_response) @@ -56,7 +56,7 @@ def test_successful_request_with_echeck def test_successful_purchase_with_echeck_and_extra_options response = stub_comms do @gateway.purchase(@amount, check(account_type: 'savings'), @options.merge(check_format: 'ARC')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/UMcheckformat=ARC/, data) assert_match(/UMaccounttype=Savings/, data) end.respond_with(successful_purchase_response_echeck) @@ -78,8 +78,8 @@ def test_unsuccessful_request def test_successful_purchase_passing_extra_info response = stub_comms do - @gateway.purchase(@amount, @credit_card, @options.merge(:invoice => '1337', :description => 'socool')) - end.check_request do |endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, @options.merge(invoice: '1337', description: 'socool')) + end.check_request do |_endpoint, data, _headers| assert_match(/UMinvoice=1337/, data) assert_match(/UMdescription=socool/, data) assert_match(/UMtestmode=0/, data) @@ -89,8 +89,8 @@ def test_successful_purchase_passing_extra_info def test_successful_purchase_passing_extra_test_mode response = stub_comms do - @gateway.purchase(@amount, @credit_card, @options.merge(:test_mode => true)) - end.check_request do |endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, @options.merge(test_mode: true)) + end.check_request do |_endpoint, data, _headers| assert_match(/UMtestmode=1/, data) end.respond_with(successful_purchase_response) assert_success response @@ -98,8 +98,8 @@ def test_successful_purchase_passing_extra_test_mode def test_successful_purchase_email_receipt response = stub_comms do - @gateway.purchase(@amount, @credit_card, @options.merge(:email => 'bobby@hill.com', :cust_receipt => 'Yes', :cust_receipt_name => 'socool')) - end.check_request do |endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, @options.merge(email: 'bobby@hill.com', cust_receipt: 'Yes', cust_receipt_name: 'socool')) + end.check_request do |_endpoint, data, _headers| assert_match(/UMcustreceipt=Yes/, data) assert_match(/UMcustreceiptname=socool/, data) assert_match(/UMtestmode=0/, data) @@ -108,14 +108,15 @@ def test_successful_purchase_email_receipt end def test_successful_purchase_split_payment + options = @options.merge( + split_payments: [ + { key: 'abc123', amount: 199, description: 'Second payee' }, + { key: 'def456', amount: 911, description: 'Third payee' }, + ] + ) response = stub_comms do - @gateway.purchase(@amount, @credit_card, @options.merge( - :split_payments => [ - { :key => 'abc123', :amount => 199, :description => 'Second payee' }, - { :key => 'def456', :amount => 911, :description => 'Third payee' }, - ] - )) - end.check_request do |endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, options) + end.check_request do |_endpoint, data, _headers| assert_match %r{UM02key=abc123}, data assert_match %r{UM02amount=1.99}, data assert_match %r{UM02description=Second\+payee}, data @@ -130,33 +131,35 @@ def test_successful_purchase_split_payment end def test_successful_purchase_split_payment_with_custom_on_error + options = @options.merge( + split_payments: [ + { key: 'abc123', amount: 199, description: 'Second payee' } + ], + on_error: 'Continue' + ) response = stub_comms do - @gateway.purchase(@amount, @credit_card, @options.merge( - :split_payments => [ - { :key => 'abc123', :amount => 199, :description => 'Second payee' } - ], - :on_error => 'Continue' - )) - end.check_request do |endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, options) + end.check_request do |_endpoint, data, _headers| assert_match %r{UMonError=Continue}, data end.respond_with(successful_purchase_response) assert_success response end def test_successful_purchase_recurring_fields + options = @options.merge( + recurring_fields: { + add_customer: true, + schedule: 'quarterly', + bill_source_key: 'bill source key', + bill_amount: 123, + num_left: 5, + start: '20501212', + recurring_receipt: true + } + ) response = stub_comms do - @gateway.purchase(@amount, @credit_card, @options.merge( - :recurring_fields => { - add_customer: true, - schedule: 'quarterly', - bill_source_key: 'bill source key', - bill_amount: 123, - num_left: 5, - start: '20501212', - recurring_receipt: true - } - )) - end.check_request do |endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, options) + end.check_request do |_endpoint, data, _headers| assert_match %r{UMaddcustomer=yes}, data assert_match %r{UMschedule=quarterly}, data assert_match %r{UMbillsourcekey=bill\+source\+key}, data @@ -169,15 +172,16 @@ def test_successful_purchase_recurring_fields end def test_successful_purchase_custom_fields + options = @options.merge( + custom_fields: { + 1 => 'diablo', + 2 => 'mephisto', + 3 => 'baal' + } + ) response = stub_comms do - @gateway.purchase(@amount, @credit_card, @options.merge( - :custom_fields => { - 1 => 'diablo', - 2 => 'mephisto', - 3 => 'baal' - } - )) - end.check_request do |endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, options) + end.check_request do |_endpoint, data, _headers| assert_match %r{UMcustom1=diablo}, data assert_match %r{UMcustom2=mephisto}, data assert_match %r{UMcustom3=baal}, data @@ -186,39 +190,42 @@ def test_successful_purchase_custom_fields end def test_first_index_guard_on_custom_fields + num_options = @options.merge( + custom_fields: { + 0 => 'butcher', + 1 => 'diablo', + 2 => 'mephisto', + 3 => 'baal' + } + ) assert_raise(ArgumentError) do - @gateway.purchase(@amount, @credit_card, @options.merge( - :custom_fields => { - 0 => 'butcher', - 1 => 'diablo', - 2 => 'mephisto', - 3 => 'baal' - } - )) + @gateway.purchase(@amount, @credit_card, num_options) end + str_options = @options.merge( + custom_fields: { + '0' => 'butcher', + '1' => 'diablo', + '2' => 'mephisto', + '3' => 'baal' + } + ) assert_raise(ArgumentError) do - @gateway.purchase(@amount, @credit_card, @options.merge( - :custom_fields => { - '0' => 'butcher', - '1' => 'diablo', - '2' => 'mephisto', - '3' => 'baal' - } - )) + @gateway.purchase(@amount, @credit_card, str_options) end end def test_successful_purchase_line_items + options = @options.merge( + line_items: [ + { sku: 'abc123', cost: 119, quantity: 1 }, + { sku: 'def456', cost: 200, quantity: 2, name: 'an item' }, + { cost: 300, qty: 4 } + ] + ) response = stub_comms do - @gateway.purchase(@amount, @credit_card, @options.merge( - :line_items => [ - { :sku=> 'abc123', :cost => 119, :quantity => 1 }, - { :sku => 'def456', :cost => 200, :quantity => 2, :name => 'an item' }, - { :cost => 300, :qty => 4 } - ] - )) - end.check_request do |endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, options) + end.check_request do |_endpoint, data, _headers| assert_match %r{UMline0sku=abc123}, data assert_match %r{UMline0cost=1.19}, data assert_match %r{UMline0qty=1}, data @@ -245,8 +252,8 @@ def test_successful_authorize_request def test_successful_authorize_passing_extra_info response = stub_comms do - @gateway.authorize(@amount, @credit_card, @options.merge(:invoice => '1337', order_id: 'w00t', :description => 'socool')) - end.check_request do |endpoint, data, headers| + @gateway.authorize(@amount, @credit_card, @options.merge(invoice: '1337', order_id: 'w00t', description: 'socool')) + end.check_request do |_endpoint, data, _headers| assert_match(/UMinvoice=1337/, data) assert_match(/UMorderid=w00t/, data) assert_match(/UMdescription=socool/, data) @@ -257,8 +264,8 @@ def test_successful_authorize_passing_extra_info def test_successful_authorize_passing_extra_test_mode response = stub_comms do - @gateway.authorize(@amount, @credit_card, @options.merge(:test_mode => true)) - end.check_request do |endpoint, data, headers| + @gateway.authorize(@amount, @credit_card, @options.merge(test_mode: true)) + end.check_request do |_endpoint, data, _headers| assert_match(/UMtestmode=1/, data) end.respond_with(successful_authorize_response) assert_success response @@ -276,7 +283,7 @@ def test_successful_capture_request def test_successful_capture_passing_extra_info response = stub_comms do @gateway.capture(@amount, '65074409', @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/UMamount=1.00/, data) assert_match(/UMtestmode=0/, data) end.respond_with(successful_capture_response) @@ -285,8 +292,8 @@ def test_successful_capture_passing_extra_info def test_successful_capture_passing_extra_test_mode response = stub_comms do - @gateway.capture(@amount, '65074409', @options.merge(:test_mode => true)) - end.check_request do |endpoint, data, headers| + @gateway.capture(@amount, '65074409', @options.merge(test_mode: true)) + end.check_request do |_endpoint, data, _headers| assert_match(/UMtestmode=1/, data) end.respond_with(successful_capture_response) assert_success response @@ -313,7 +320,7 @@ def test_successful_refund_request_with_echeck def test_successful_refund_passing_extra_info response = stub_comms do @gateway.refund(@amount, '65074409', @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/UMamount=1.00/, data) assert_match(/UMtestmode=0/, data) end.respond_with(successful_refund_response) @@ -322,8 +329,8 @@ def test_successful_refund_passing_extra_info def test_successful_refund_passing_extra_test_mode response = stub_comms do - @gateway.refund(@amount, '65074409', @options.merge(:test_mode => true)) - end.check_request do |endpoint, data, headers| + @gateway.refund(@amount, '65074409', @options.merge(test_mode: true)) + end.check_request do |_endpoint, data, _headers| assert_match(/UMtestmode=1/, data) end.respond_with(successful_refund_response) assert_success response @@ -349,8 +356,8 @@ def test_successful_void_request_with_echeck def test_successful_void_passing_extra_info response = stub_comms do - @gateway.void('65074409', @options.merge(:no_release => true)) - end.check_request do |endpoint, data, headers| + @gateway.void('65074409', @options.merge(no_release: true)) + end.check_request do |_endpoint, data, _headers| assert_match(/UMcommand=cc%3Avoid/, data) assert_match(/UMtestmode=0/, data) end.respond_with(successful_void_response) @@ -359,8 +366,8 @@ def test_successful_void_passing_extra_info def test_successful_void_passing_extra_test_mode response = stub_comms do - @gateway.refund(@amount, '65074409', @options.merge(:test_mode => true)) - end.check_request do |endpoint, data, headers| + @gateway.refund(@amount, '65074409', @options.merge(test_mode: true)) + end.check_request do |_endpoint, data, _headers| assert_match(/UMtestmode=1/, data) end.respond_with(successful_void_response) assert_success response @@ -412,8 +419,8 @@ def test_add_address_with_empty_billing_and_shipping_names def test_add_address_with_single_billing_and_shipping_names post = {} options = { - :billing_address => address(:name => 'Smith'), - :shipping_address => address(:name => 'Longsen') + billing_address: address(name: 'Smith'), + shipping_address: address(name: 'Longsen') } @gateway.send(:add_address, post, @credit_card, options) @@ -430,13 +437,13 @@ def test_add_test_mode_without_test_mode_option def test_add_test_mode_with_true_test_mode_option post = {} - @gateway.send(:add_test_mode, post, :test_mode => true) + @gateway.send(:add_test_mode, post, test_mode: true) assert_equal 1, post[:testmode] end def test_add_test_mode_with_false_test_mode_option post = {} - @gateway.send(:add_test_mode, post, :test_mode => false) + @gateway.send(:add_test_mode, post, test_mode: false) assert_equal 0, post[:testmode] end @@ -453,7 +460,7 @@ def test_supported_countries end def test_supported_card_types - assert_equal [:visa, :master, :american_express], UsaEpayTransactionGateway.supported_cardtypes + assert_equal %i[visa master american_express], UsaEpayTransactionGateway.supported_cardtypes end def test_avs_result @@ -501,7 +508,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{UMcard=4242424242424242}, data assert_match %r{UMcardpresent=true}, data end.respond_with(successful_purchase_response) @@ -600,146 +607,146 @@ def successful_void_response_echeck end def pre_scrubbed - <<-EOS -opening connection to sandbox.usaepay.com:443... -opened -starting SSL for sandbox.usaepay.com:443... -SSL established -<- "POST /gate 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: sandbox.usaepay.com\r\nContent-Length: 774\r\n\r\n" -<- "UMamount=1.00&UMinvoice=&UMdescription=&UMcard=4000100011112224&UMcvv2=123&UMexpir=0919&UMname=Longbob+Longsen&UMbillfname=Jim&UMbilllname=Smith&UMbillcompany=Widgets+Inc&UMbillstreet=456+My+Street&UMbillstreet2=Apt+1&UMbillcity=Ottawa&UMbillstate=NC&UMbillzip=27614&UMbillcountry=CA&UMbillphone=%28555%29555-5555&UMshipfname=Jim&UMshiplname=Smith&UMshipcompany=Widgets+Inc&UMshipstreet=456+My+Street&UMshipstreet2=Apt+1&UMshipcity=Ottawa&UMshipstate=ON&UMshipzip=K1C2N6&UMshipcountry=CA&UMshipphone=%28555%29555-5555&UMstreet=456+My+Street&UMzip=27614&UMcommand=cc%3Asale&UMkey=4EoZ5U2Q55j976W7eplC71i6b7kn4pcV&UMsoftware=Active+Merchant&UMtestmode=0&UMhash=s%2F5268F91058BC9F9FA944693D799F324B2497B7247850A51E53226309FB2540F0%2F7b4c4f6a4e775141cc0e4e10c0388d9adeb47fd1%2Fn" --> "HTTP/1.1 200 OK\r\n" --> "Server: http\r\n" --> "Date: Tue, 13 Feb 2018 18:17:20 GMT\r\n" --> "Content-Type: text/html\r\n" --> "Content-Length: 485\r\n" --> "Connection: close\r\n" --> "P3P: policyref=\"http://www.usaepay.com/w3c/p3p.xml\", CP=\"NON TAIa IVAa IVDa OUR NOR PHY ONL UNI FIN INT DEM\"\r\n" --> "Strict-Transport-Security: max-age=15768000\r\n" --> "\r\n" -reading 485 bytes... --> "UMversion=2.9&UMstatus=Approved&UMauthCode=042366&UMrefNum=132020588&UMavsResult=Address%3A%20Match%20%26%205%20Digit%20Zip%3A%20Match&UMavsResultCode=YYY&UMcvv2Result=Match&UMcvv2ResultCode=M&UMresult=A&UMvpasResultCode=&UMerror=Approved&UMerrorcode=00000&UMcustnum=&UMbatch=120&UMbatchRefNum=848&UMisDuplicate=N&UMconvertedAmount=&UMconvertedAmountCurrency=840&UMconversionRate=&UMcustReceiptResult=No%20Receipt%20Sent&UMprocRefNum=&UMcardLevelResult=A&UMauthAmount=1&UMfiller=filled" -read 485 bytes -Conn close - EOS + <<~REQUEST + opening connection to sandbox.usaepay.com:443... + opened + starting SSL for sandbox.usaepay.com:443... + SSL established + <- "POST /gate 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: sandbox.usaepay.com\r\nContent-Length: 774\r\n\r\n" + <- "UMamount=1.00&UMinvoice=&UMdescription=&UMcard=4000100011112224&UMcvv2=123&UMexpir=0919&UMname=Longbob+Longsen&UMbillfname=Jim&UMbilllname=Smith&UMbillcompany=Widgets+Inc&UMbillstreet=456+My+Street&UMbillstreet2=Apt+1&UMbillcity=Ottawa&UMbillstate=NC&UMbillzip=27614&UMbillcountry=CA&UMbillphone=%28555%29555-5555&UMshipfname=Jim&UMshiplname=Smith&UMshipcompany=Widgets+Inc&UMshipstreet=456+My+Street&UMshipstreet2=Apt+1&UMshipcity=Ottawa&UMshipstate=ON&UMshipzip=K1C2N6&UMshipcountry=CA&UMshipphone=%28555%29555-5555&UMstreet=456+My+Street&UMzip=27614&UMcommand=cc%3Asale&UMkey=4EoZ5U2Q55j976W7eplC71i6b7kn4pcV&UMsoftware=Active+Merchant&UMtestmode=0&UMhash=s%2F5268F91058BC9F9FA944693D799F324B2497B7247850A51E53226309FB2540F0%2F7b4c4f6a4e775141cc0e4e10c0388d9adeb47fd1%2Fn" + -> "HTTP/1.1 200 OK\r\n" + -> "Server: http\r\n" + -> "Date: Tue, 13 Feb 2018 18:17:20 GMT\r\n" + -> "Content-Type: text/html\r\n" + -> "Content-Length: 485\r\n" + -> "Connection: close\r\n" + -> "P3P: policyref=\"http://www.usaepay.com/w3c/p3p.xml\", CP=\"NON TAIa IVAa IVDa OUR NOR PHY ONL UNI FIN INT DEM\"\r\n" + -> "Strict-Transport-Security: max-age=15768000\r\n" + -> "\r\n" + reading 485 bytes... + -> "UMversion=2.9&UMstatus=Approved&UMauthCode=042366&UMrefNum=132020588&UMavsResult=Address%3A%20Match%20%26%205%20Digit%20Zip%3A%20Match&UMavsResultCode=YYY&UMcvv2Result=Match&UMcvv2ResultCode=M&UMresult=A&UMvpasResultCode=&UMerror=Approved&UMerrorcode=00000&UMcustnum=&UMbatch=120&UMbatchRefNum=848&UMisDuplicate=N&UMconvertedAmount=&UMconvertedAmountCurrency=840&UMconversionRate=&UMcustReceiptResult=No%20Receipt%20Sent&UMprocRefNum=&UMcardLevelResult=A&UMauthAmount=1&UMfiller=filled" + read 485 bytes + Conn close + REQUEST end def post_scrubbed - <<-EOS -opening connection to sandbox.usaepay.com:443... -opened -starting SSL for sandbox.usaepay.com:443... -SSL established -<- "POST /gate 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: sandbox.usaepay.com\r\nContent-Length: 774\r\n\r\n" -<- "UMamount=1.00&UMinvoice=&UMdescription=&UMcard=[FILTERED]&UMcvv2=[FILTERED]&UMexpir=0919&UMname=Longbob+Longsen&UMbillfname=Jim&UMbilllname=Smith&UMbillcompany=Widgets+Inc&UMbillstreet=456+My+Street&UMbillstreet2=Apt+1&UMbillcity=Ottawa&UMbillstate=NC&UMbillzip=27614&UMbillcountry=CA&UMbillphone=%28555%29555-5555&UMshipfname=Jim&UMshiplname=Smith&UMshipcompany=Widgets+Inc&UMshipstreet=456+My+Street&UMshipstreet2=Apt+1&UMshipcity=Ottawa&UMshipstate=ON&UMshipzip=K1C2N6&UMshipcountry=CA&UMshipphone=%28555%29555-5555&UMstreet=456+My+Street&UMzip=27614&UMcommand=cc%3Asale&UMkey=[FILTERED]&UMsoftware=Active+Merchant&UMtestmode=0&UMhash=s%2F5268F91058BC9F9FA944693D799F324B2497B7247850A51E53226309FB2540F0%2F7b4c4f6a4e775141cc0e4e10c0388d9adeb47fd1%2Fn" --> "HTTP/1.1 200 OK\r\n" --> "Server: http\r\n" --> "Date: Tue, 13 Feb 2018 18:17:20 GMT\r\n" --> "Content-Type: text/html\r\n" --> "Content-Length: 485\r\n" --> "Connection: close\r\n" --> "P3P: policyref=\"http://www.usaepay.com/w3c/p3p.xml\", CP=\"NON TAIa IVAa IVDa OUR NOR PHY ONL UNI FIN INT DEM\"\r\n" --> "Strict-Transport-Security: max-age=15768000\r\n" --> "\r\n" -reading 485 bytes... --> "UMversion=2.9&UMstatus=Approved&UMauthCode=042366&UMrefNum=132020588&UMavsResult=Address%3A%20Match%20%26%205%20Digit%20Zip%3A%20Match&UMavsResultCode=YYY&UMcvv2Result=Match&UMcvv2ResultCode=M&UMresult=A&UMvpasResultCode=&UMerror=Approved&UMerrorcode=00000&UMcustnum=&UMbatch=120&UMbatchRefNum=848&UMisDuplicate=N&UMconvertedAmount=&UMconvertedAmountCurrency=840&UMconversionRate=&UMcustReceiptResult=No%20Receipt%20Sent&UMprocRefNum=&UMcardLevelResult=A&UMauthAmount=1&UMfiller=filled" -read 485 bytes -Conn close - EOS + <<~REQUEST + opening connection to sandbox.usaepay.com:443... + opened + starting SSL for sandbox.usaepay.com:443... + SSL established + <- "POST /gate 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: sandbox.usaepay.com\r\nContent-Length: 774\r\n\r\n" + <- "UMamount=1.00&UMinvoice=&UMdescription=&UMcard=[FILTERED]&UMcvv2=[FILTERED]&UMexpir=0919&UMname=Longbob+Longsen&UMbillfname=Jim&UMbilllname=Smith&UMbillcompany=Widgets+Inc&UMbillstreet=456+My+Street&UMbillstreet2=Apt+1&UMbillcity=Ottawa&UMbillstate=NC&UMbillzip=27614&UMbillcountry=CA&UMbillphone=%28555%29555-5555&UMshipfname=Jim&UMshiplname=Smith&UMshipcompany=Widgets+Inc&UMshipstreet=456+My+Street&UMshipstreet2=Apt+1&UMshipcity=Ottawa&UMshipstate=ON&UMshipzip=K1C2N6&UMshipcountry=CA&UMshipphone=%28555%29555-5555&UMstreet=456+My+Street&UMzip=27614&UMcommand=cc%3Asale&UMkey=[FILTERED]&UMsoftware=Active+Merchant&UMtestmode=0&UMhash=s%2F5268F91058BC9F9FA944693D799F324B2497B7247850A51E53226309FB2540F0%2F7b4c4f6a4e775141cc0e4e10c0388d9adeb47fd1%2Fn" + -> "HTTP/1.1 200 OK\r\n" + -> "Server: http\r\n" + -> "Date: Tue, 13 Feb 2018 18:17:20 GMT\r\n" + -> "Content-Type: text/html\r\n" + -> "Content-Length: 485\r\n" + -> "Connection: close\r\n" + -> "P3P: policyref=\"http://www.usaepay.com/w3c/p3p.xml\", CP=\"NON TAIa IVAa IVDa OUR NOR PHY ONL UNI FIN INT DEM\"\r\n" + -> "Strict-Transport-Security: max-age=15768000\r\n" + -> "\r\n" + reading 485 bytes... + -> "UMversion=2.9&UMstatus=Approved&UMauthCode=042366&UMrefNum=132020588&UMavsResult=Address%3A%20Match%20%26%205%20Digit%20Zip%3A%20Match&UMavsResultCode=YYY&UMcvv2Result=Match&UMcvv2ResultCode=M&UMresult=A&UMvpasResultCode=&UMerror=Approved&UMerrorcode=00000&UMcustnum=&UMbatch=120&UMbatchRefNum=848&UMisDuplicate=N&UMconvertedAmount=&UMconvertedAmountCurrency=840&UMconversionRate=&UMcustReceiptResult=No%20Receipt%20Sent&UMprocRefNum=&UMcardLevelResult=A&UMauthAmount=1&UMfiller=filled" + read 485 bytes + Conn close + REQUEST end def pre_scrubbed_track_data - <<-EOS -opening connection to sandbox.usaepay.com:443... -opened -starting SSL for sandbox.usaepay.com:443... -SSL established -<- "POST /gate 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: sandbox.usaepay.com\r\nContent-Length: 382\r\n\r\n" -<- "UMamount=1.00&UMinvoice=&UMdescription=&UMmagstripe=%25B4000100011112224%5ELONGSEN%2FL.+%5E19091200000000000000%2A%2A123%2A%2A%2A%2A%2A%2A%3F&UMcardpresent=true&UMcommand=cc%3Asale&UMkey=4EoZ5U2Q55j976W7eplC71i6b7kn4pcV&UMsoftware=Active+Merchant&UMtestmode=0&UMhash=s%2FE27734F076643B23131E5432C1E225EFF982A73D350179EFC2F191CA499B59A4%2F13391bd14ab6e61058cc9a1b78f259a4c26aa8e1%2Fn" --> "HTTP/1.1 200 OK\r\n" --> "Server: http\r\n" --> "Date: Tue, 13 Feb 2018 18:13:11 GMT\r\n" --> "Content-Type: text/html\r\n" --> "Content-Length: 485\r\n" --> "Connection: close\r\n" --> "P3P: policyref=\"http://www.usaepay.com/w3c/p3p.xml\", CP=\"NON TAIa IVAa IVDa OUR NOR PHY ONL UNI FIN INT DEM\"\r\n" --> "Strict-Transport-Security: max-age=15768000\r\n" --> "\r\n" -reading 485 bytes... --> "UMversion=2.9&UMstatus=Approved&UMauthCode=042087&UMrefNum=132020522&UMavsResult=Address%3A%20Match%20%26%205%20Digit%20Zip%3A%20Match&UMavsResultCode=YYY&UMcvv2Result=Match&UMcvv2ResultCode=M&UMresult=A&UMvpasResultCode=&UMerror=Approved&UMerrorcode=00000&UMcustnum=&UMbatch=120&UMbatchRefNum=848&UMisDuplicate=N&UMconvertedAmount=&UMconvertedAmountCurrency=840&UMconversionRate=&UMcustReceiptResult=No%20Receipt%20Sent&UMprocRefNum=&UMcardLevelResult=A&UMauthAmount=1&UMfiller=filled" -read 485 bytes -Conn close - EOS + <<~REQUEST + opening connection to sandbox.usaepay.com:443... + opened + starting SSL for sandbox.usaepay.com:443... + SSL established + <- "POST /gate 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: sandbox.usaepay.com\r\nContent-Length: 382\r\n\r\n" + <- "UMamount=1.00&UMinvoice=&UMdescription=&UMmagstripe=%25B4000100011112224%5ELONGSEN%2FL.+%5E19091200000000000000%2A%2A123%2A%2A%2A%2A%2A%2A%3F&UMcardpresent=true&UMcommand=cc%3Asale&UMkey=4EoZ5U2Q55j976W7eplC71i6b7kn4pcV&UMsoftware=Active+Merchant&UMtestmode=0&UMhash=s%2FE27734F076643B23131E5432C1E225EFF982A73D350179EFC2F191CA499B59A4%2F13391bd14ab6e61058cc9a1b78f259a4c26aa8e1%2Fn" + -> "HTTP/1.1 200 OK\r\n" + -> "Server: http\r\n" + -> "Date: Tue, 13 Feb 2018 18:13:11 GMT\r\n" + -> "Content-Type: text/html\r\n" + -> "Content-Length: 485\r\n" + -> "Connection: close\r\n" + -> "P3P: policyref=\"http://www.usaepay.com/w3c/p3p.xml\", CP=\"NON TAIa IVAa IVDa OUR NOR PHY ONL UNI FIN INT DEM\"\r\n" + -> "Strict-Transport-Security: max-age=15768000\r\n" + -> "\r\n" + reading 485 bytes... + -> "UMversion=2.9&UMstatus=Approved&UMauthCode=042087&UMrefNum=132020522&UMavsResult=Address%3A%20Match%20%26%205%20Digit%20Zip%3A%20Match&UMavsResultCode=YYY&UMcvv2Result=Match&UMcvv2ResultCode=M&UMresult=A&UMvpasResultCode=&UMerror=Approved&UMerrorcode=00000&UMcustnum=&UMbatch=120&UMbatchRefNum=848&UMisDuplicate=N&UMconvertedAmount=&UMconvertedAmountCurrency=840&UMconversionRate=&UMcustReceiptResult=No%20Receipt%20Sent&UMprocRefNum=&UMcardLevelResult=A&UMauthAmount=1&UMfiller=filled" + read 485 bytes + Conn close + REQUEST end def post_scrubbed_track_data - <<-EOS -opening connection to sandbox.usaepay.com:443... -opened -starting SSL for sandbox.usaepay.com:443... -SSL established -<- "POST /gate 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: sandbox.usaepay.com\r\nContent-Length: 382\r\n\r\n" -<- "UMamount=1.00&UMinvoice=&UMdescription=&UMmagstripe=[FILTERED]&UMcardpresent=true&UMcommand=cc%3Asale&UMkey=[FILTERED]&UMsoftware=Active+Merchant&UMtestmode=0&UMhash=s%2FE27734F076643B23131E5432C1E225EFF982A73D350179EFC2F191CA499B59A4%2F13391bd14ab6e61058cc9a1b78f259a4c26aa8e1%2Fn" --> "HTTP/1.1 200 OK\r\n" --> "Server: http\r\n" --> "Date: Tue, 13 Feb 2018 18:13:11 GMT\r\n" --> "Content-Type: text/html\r\n" --> "Content-Length: 485\r\n" --> "Connection: close\r\n" --> "P3P: policyref=\"http://www.usaepay.com/w3c/p3p.xml\", CP=\"NON TAIa IVAa IVDa OUR NOR PHY ONL UNI FIN INT DEM\"\r\n" --> "Strict-Transport-Security: max-age=15768000\r\n" --> "\r\n" -reading 485 bytes... --> "UMversion=2.9&UMstatus=Approved&UMauthCode=042087&UMrefNum=132020522&UMavsResult=Address%3A%20Match%20%26%205%20Digit%20Zip%3A%20Match&UMavsResultCode=YYY&UMcvv2Result=Match&UMcvv2ResultCode=M&UMresult=A&UMvpasResultCode=&UMerror=Approved&UMerrorcode=00000&UMcustnum=&UMbatch=120&UMbatchRefNum=848&UMisDuplicate=N&UMconvertedAmount=&UMconvertedAmountCurrency=840&UMconversionRate=&UMcustReceiptResult=No%20Receipt%20Sent&UMprocRefNum=&UMcardLevelResult=A&UMauthAmount=1&UMfiller=filled" -read 485 bytes -Conn close - EOS + <<~REQUEST + opening connection to sandbox.usaepay.com:443... + opened + starting SSL for sandbox.usaepay.com:443... + SSL established + <- "POST /gate 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: sandbox.usaepay.com\r\nContent-Length: 382\r\n\r\n" + <- "UMamount=1.00&UMinvoice=&UMdescription=&UMmagstripe=[FILTERED]&UMcardpresent=true&UMcommand=cc%3Asale&UMkey=[FILTERED]&UMsoftware=Active+Merchant&UMtestmode=0&UMhash=s%2FE27734F076643B23131E5432C1E225EFF982A73D350179EFC2F191CA499B59A4%2F13391bd14ab6e61058cc9a1b78f259a4c26aa8e1%2Fn" + -> "HTTP/1.1 200 OK\r\n" + -> "Server: http\r\n" + -> "Date: Tue, 13 Feb 2018 18:13:11 GMT\r\n" + -> "Content-Type: text/html\r\n" + -> "Content-Length: 485\r\n" + -> "Connection: close\r\n" + -> "P3P: policyref=\"http://www.usaepay.com/w3c/p3p.xml\", CP=\"NON TAIa IVAa IVDa OUR NOR PHY ONL UNI FIN INT DEM\"\r\n" + -> "Strict-Transport-Security: max-age=15768000\r\n" + -> "\r\n" + reading 485 bytes... + -> "UMversion=2.9&UMstatus=Approved&UMauthCode=042087&UMrefNum=132020522&UMavsResult=Address%3A%20Match%20%26%205%20Digit%20Zip%3A%20Match&UMavsResultCode=YYY&UMcvv2Result=Match&UMcvv2ResultCode=M&UMresult=A&UMvpasResultCode=&UMerror=Approved&UMerrorcode=00000&UMcustnum=&UMbatch=120&UMbatchRefNum=848&UMisDuplicate=N&UMconvertedAmount=&UMconvertedAmountCurrency=840&UMconversionRate=&UMcustReceiptResult=No%20Receipt%20Sent&UMprocRefNum=&UMcardLevelResult=A&UMauthAmount=1&UMfiller=filled" + read 485 bytes + Conn close + REQUEST end def pre_scrubbed_echeck - <<-EOS -opening connection to sandbox.usaepay.com:443... -opened -starting SSL for sandbox.usaepay.com:443... -SSL established -<- "POST /gate 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: sandbox.usaepay.com\r\nContent-Length: 762\r\n\r\n" -<- "UMamount=1.00&UMinvoice=&UMdescription=&UMaccount=15378535&UMrouting=244183602&UMname=Jim+Smith&UMbillfname=Jim&UMbilllname=Smith&UMbillcompany=Widgets+Inc&UMbillstreet=456+My+Street&UMbillstreet2=Apt+1&UMbillcity=Ottawa&UMbillstate=NC&UMbillzip=27614&UMbillcountry=CA&UMbillphone=%28555%29555-5555&UMshipfname=Jim&UMshiplname=Smith&UMshipcompany=Widgets+Inc&UMshipstreet=456+My+Street&UMshipstreet2=Apt+1&UMshipcity=Ottawa&UMshipstate=ON&UMshipzip=K1C2N6&UMshipcountry=CA&UMshipphone=%28555%29555-5555&UMstreet=456+My+Street&UMzip=27614&UMcommand=check%3Asale&UMkey=4EoZ5U2Q55j976W7eplC71i6b7kn4pcV&UMsoftware=Active+Merchant&UMtestmode=0&UMhash=s%2F7F71E7DCB851901EA1D4E2CA1C60D2A7E8BAB99FA10F6220E821BD8B8331114B%2F85f1a7ab01b725c4eed80a12c78ef65d3fa367e6%2Fn" --> "HTTP/1.1 200 OK\r\n" --> "Server: http\r\n" --> "Date: Fri, 16 Mar 2018 20:54:49 GMT\r\n" --> "Content-Type: text/html\r\n" --> "Content-Length: 572\r\n" --> "Connection: close\r\n" --> "P3P: policyref=\"http://www.usaepay.com/w3c/p3p.xml\", CP=\"NON TAIa IVAa IVDa OUR NOR PHY ONL UNI FIN INT DEM\"\r\n" --> "Strict-Transport-Security: max-age=15768000\r\n" --> "\r\n" -reading 572 bytes... --> "UMversion=2.9&UMstatus=Approved&UMauthCode=TMEAAF&UMrefNum=133135121&UMavsResult=No%20AVS%20response%20%28Typically%20no%20AVS%20data%20sent%20or%20swiped%20transaction%29&UMavsResultCode=&UMcvv2Result=No%20CVV2%2FCVC%20data%20available%20for%20transaction.&UMcvv2ResultCode=&UMresult=A&UMvpasResultCode=&UMerror=&UMerrorcode=00000&UMcustnum=&UMbatch=180316&UMbatchRefNum=&UMisDuplicate=N&UMconvertedAmount=&UMconvertedAmountCurrency=840&UMconversionRate=&UMcustReceiptResult=No%20Receipt%20Sent&UMprocRefNum=18031621233689&UMcardLevelResult=&UMauthAmount=&UMfiller=filled" -read 572 bytes -Conn close - EOS + <<~REQUEST + opening connection to sandbox.usaepay.com:443... + opened + starting SSL for sandbox.usaepay.com:443... + SSL established + <- "POST /gate 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: sandbox.usaepay.com\r\nContent-Length: 762\r\n\r\n" + <- "UMamount=1.00&UMinvoice=&UMdescription=&UMaccount=15378535&UMrouting=244183602&UMname=Jim+Smith&UMbillfname=Jim&UMbilllname=Smith&UMbillcompany=Widgets+Inc&UMbillstreet=456+My+Street&UMbillstreet2=Apt+1&UMbillcity=Ottawa&UMbillstate=NC&UMbillzip=27614&UMbillcountry=CA&UMbillphone=%28555%29555-5555&UMshipfname=Jim&UMshiplname=Smith&UMshipcompany=Widgets+Inc&UMshipstreet=456+My+Street&UMshipstreet2=Apt+1&UMshipcity=Ottawa&UMshipstate=ON&UMshipzip=K1C2N6&UMshipcountry=CA&UMshipphone=%28555%29555-5555&UMstreet=456+My+Street&UMzip=27614&UMcommand=check%3Asale&UMkey=4EoZ5U2Q55j976W7eplC71i6b7kn4pcV&UMsoftware=Active+Merchant&UMtestmode=0&UMhash=s%2F7F71E7DCB851901EA1D4E2CA1C60D2A7E8BAB99FA10F6220E821BD8B8331114B%2F85f1a7ab01b725c4eed80a12c78ef65d3fa367e6%2Fn" + -> "HTTP/1.1 200 OK\r\n" + -> "Server: http\r\n" + -> "Date: Fri, 16 Mar 2018 20:54:49 GMT\r\n" + -> "Content-Type: text/html\r\n" + -> "Content-Length: 572\r\n" + -> "Connection: close\r\n" + -> "P3P: policyref=\"http://www.usaepay.com/w3c/p3p.xml\", CP=\"NON TAIa IVAa IVDa OUR NOR PHY ONL UNI FIN INT DEM\"\r\n" + -> "Strict-Transport-Security: max-age=15768000\r\n" + -> "\r\n" + reading 572 bytes... + -> "UMversion=2.9&UMstatus=Approved&UMauthCode=TMEAAF&UMrefNum=133135121&UMavsResult=No%20AVS%20response%20%28Typically%20no%20AVS%20data%20sent%20or%20swiped%20transaction%29&UMavsResultCode=&UMcvv2Result=No%20CVV2%2FCVC%20data%20available%20for%20transaction.&UMcvv2ResultCode=&UMresult=A&UMvpasResultCode=&UMerror=&UMerrorcode=00000&UMcustnum=&UMbatch=180316&UMbatchRefNum=&UMisDuplicate=N&UMconvertedAmount=&UMconvertedAmountCurrency=840&UMconversionRate=&UMcustReceiptResult=No%20Receipt%20Sent&UMprocRefNum=18031621233689&UMcardLevelResult=&UMauthAmount=&UMfiller=filled" + read 572 bytes + Conn close + REQUEST end def post_scrubbed_echeck - <<-EOS -opening connection to sandbox.usaepay.com:443... -opened -starting SSL for sandbox.usaepay.com:443... -SSL established -<- "POST /gate 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: sandbox.usaepay.com\r\nContent-Length: 762\r\n\r\n" -<- "UMamount=1.00&UMinvoice=&UMdescription=&UMaccount=[FILTERED]&UMrouting=244183602&UMname=Jim+Smith&UMbillfname=Jim&UMbilllname=Smith&UMbillcompany=Widgets+Inc&UMbillstreet=456+My+Street&UMbillstreet2=Apt+1&UMbillcity=Ottawa&UMbillstate=NC&UMbillzip=27614&UMbillcountry=CA&UMbillphone=%28555%29555-5555&UMshipfname=Jim&UMshiplname=Smith&UMshipcompany=Widgets+Inc&UMshipstreet=456+My+Street&UMshipstreet2=Apt+1&UMshipcity=Ottawa&UMshipstate=ON&UMshipzip=K1C2N6&UMshipcountry=CA&UMshipphone=%28555%29555-5555&UMstreet=456+My+Street&UMzip=27614&UMcommand=check%3Asale&UMkey=[FILTERED]&UMsoftware=Active+Merchant&UMtestmode=0&UMhash=s%2F7F71E7DCB851901EA1D4E2CA1C60D2A7E8BAB99FA10F6220E821BD8B8331114B%2F85f1a7ab01b725c4eed80a12c78ef65d3fa367e6%2Fn" --> "HTTP/1.1 200 OK\r\n" --> "Server: http\r\n" --> "Date: Fri, 16 Mar 2018 20:54:49 GMT\r\n" --> "Content-Type: text/html\r\n" --> "Content-Length: 572\r\n" --> "Connection: close\r\n" --> "P3P: policyref=\"http://www.usaepay.com/w3c/p3p.xml\", CP=\"NON TAIa IVAa IVDa OUR NOR PHY ONL UNI FIN INT DEM\"\r\n" --> "Strict-Transport-Security: max-age=15768000\r\n" --> "\r\n" -reading 572 bytes... --> "UMversion=2.9&UMstatus=Approved&UMauthCode=TMEAAF&UMrefNum=133135121&UMavsResult=No%20AVS%20response%20%28Typically%20no%20AVS%20data%20sent%20or%20swiped%20transaction%29&UMavsResultCode=&UMcvv2Result=No%20CVV2%2FCVC%20data%20available%20for%20transaction.&UMcvv2ResultCode=&UMresult=A&UMvpasResultCode=&UMerror=&UMerrorcode=00000&UMcustnum=&UMbatch=180316&UMbatchRefNum=&UMisDuplicate=N&UMconvertedAmount=&UMconvertedAmountCurrency=840&UMconversionRate=&UMcustReceiptResult=No%20Receipt%20Sent&UMprocRefNum=18031621233689&UMcardLevelResult=&UMauthAmount=&UMfiller=filled" -read 572 bytes -Conn close - EOS + <<~REQUEST + opening connection to sandbox.usaepay.com:443... + opened + starting SSL for sandbox.usaepay.com:443... + SSL established + <- "POST /gate 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: sandbox.usaepay.com\r\nContent-Length: 762\r\n\r\n" + <- "UMamount=1.00&UMinvoice=&UMdescription=&UMaccount=[FILTERED]&UMrouting=244183602&UMname=Jim+Smith&UMbillfname=Jim&UMbilllname=Smith&UMbillcompany=Widgets+Inc&UMbillstreet=456+My+Street&UMbillstreet2=Apt+1&UMbillcity=Ottawa&UMbillstate=NC&UMbillzip=27614&UMbillcountry=CA&UMbillphone=%28555%29555-5555&UMshipfname=Jim&UMshiplname=Smith&UMshipcompany=Widgets+Inc&UMshipstreet=456+My+Street&UMshipstreet2=Apt+1&UMshipcity=Ottawa&UMshipstate=ON&UMshipzip=K1C2N6&UMshipcountry=CA&UMshipphone=%28555%29555-5555&UMstreet=456+My+Street&UMzip=27614&UMcommand=check%3Asale&UMkey=[FILTERED]&UMsoftware=Active+Merchant&UMtestmode=0&UMhash=s%2F7F71E7DCB851901EA1D4E2CA1C60D2A7E8BAB99FA10F6220E821BD8B8331114B%2F85f1a7ab01b725c4eed80a12c78ef65d3fa367e6%2Fn" + -> "HTTP/1.1 200 OK\r\n" + -> "Server: http\r\n" + -> "Date: Fri, 16 Mar 2018 20:54:49 GMT\r\n" + -> "Content-Type: text/html\r\n" + -> "Content-Length: 572\r\n" + -> "Connection: close\r\n" + -> "P3P: policyref=\"http://www.usaepay.com/w3c/p3p.xml\", CP=\"NON TAIa IVAa IVDa OUR NOR PHY ONL UNI FIN INT DEM\"\r\n" + -> "Strict-Transport-Security: max-age=15768000\r\n" + -> "\r\n" + reading 572 bytes... + -> "UMversion=2.9&UMstatus=Approved&UMauthCode=TMEAAF&UMrefNum=133135121&UMavsResult=No%20AVS%20response%20%28Typically%20no%20AVS%20data%20sent%20or%20swiped%20transaction%29&UMavsResultCode=&UMcvv2Result=No%20CVV2%2FCVC%20data%20available%20for%20transaction.&UMcvv2ResultCode=&UMresult=A&UMvpasResultCode=&UMerror=&UMerrorcode=00000&UMcustnum=&UMbatch=180316&UMbatchRefNum=&UMisDuplicate=N&UMconvertedAmount=&UMconvertedAmountCurrency=840&UMconversionRate=&UMcustReceiptResult=No%20Receipt%20Sent&UMprocRefNum=18031621233689&UMcardLevelResult=&UMauthAmount=&UMfiller=filled" + read 572 bytes + Conn close + REQUEST end end diff --git a/test/unit/gateways/vanco_test.rb b/test/unit/gateways/vanco_test.rb index 449cd696448..fed06cb0bd8 100644 --- a/test/unit/gateways/vanco_test.rb +++ b/test/unit/gateways/vanco_test.rb @@ -29,10 +29,8 @@ def test_successful_purchase def test_successful_purchase_with_fund_id response = stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(fund_id: 'MyEggcellentFund')) - end.check_request do |endpoint, data, headers| - if data =~ /EFTAdd/ - assert_match(%r(MyEggcellentFund<\/FundID>), data) - end + end.check_request do |_endpoint, data, _headers| + assert_match(%r(MyEggcellentFund<\/FundID>), data) if data =~ /EFTAdd/ end.respond_with(successful_login_response, successful_purchase_with_fund_id_response) assert_success response @@ -43,10 +41,8 @@ def test_successful_purchase_with_fund_id def test_successful_purchase_with_ip_address response = stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(ip: '192.168.0.1')) - end.check_request do |endpoint, data, headers| - if data =~ /EFTAdd/ - assert_match(%r(192), data) - end + end.check_request do |_endpoint, data, _headers| + assert_match(%r(192), data) if data =~ /EFTAdd/ end.respond_with(successful_login_response, successful_purchase_response) assert_success response end @@ -184,5 +180,4 @@ def failed_refund_response dc9a5e2b620eee5d248e1b33cc1f332015-05-01 16:19:33 -0400EFTAddCredit67a731057f821413155033bc23551aef3ba0b2042575Amount Cannot Be Greater Than $100.05 ) end - end diff --git a/test/unit/gateways/verifi_test.rb b/test/unit/gateways/verifi_test.rb index 404556b2d6c..f32e8ee6a74 100644 --- a/test/unit/gateways/verifi_test.rb +++ b/test/unit/gateways/verifi_test.rb @@ -5,16 +5,16 @@ class VerifiTest < Test::Unit::TestCase def setup @gateway = VerifiGateway.new( - :login => 'l', - :password => 'p' + login: 'l', + password: 'p' ) @credit_card = credit_card('4111111111111111') @options = { - :order_id => '37', - :email => 'paul@example.com', - :billing_address => address + order_id: '37', + email: 'paul@example.com', + billing_address: address } @amount = 100 @@ -67,7 +67,7 @@ def test_amount_style def test_add_description result = {} - @gateway.send(:add_invoice_data, result, :description => 'My Purchase is great') + @gateway.send(:add_invoice_data, result, description: 'My Purchase is great') assert_equal 'My Purchase is great', result[:orderdescription] end diff --git a/test/unit/gateways/viaklix_test.rb b/test/unit/gateways/viaklix_test.rb index ef288b6b652..1c92a986145 100644 --- a/test/unit/gateways/viaklix_test.rb +++ b/test/unit/gateways/viaklix_test.rb @@ -1,19 +1,18 @@ require 'test_helper' class ViaklixTest < Test::Unit::TestCase - def setup @gateway = ViaklixGateway.new( - :login => 'LOGIN', - :password => 'PIN' + login: 'LOGIN', + password: 'PIN' ) @credit_card = credit_card @options = { - :order_id => '37', - :email => 'paul@domain.com', - :description => 'Test Transaction', - :billing_address => address + order_id: '37', + email: 'paul@domain.com', + description: 'Test Transaction', + billing_address: address } @amount = 100 end @@ -70,9 +69,9 @@ def unsuccessful_purchase_response end def invalid_login_response - <<-RESPONSE -ssl_result=7000\r -ssl_result_message=The viaKLIX ID and/or User ID supplied in the authorization request is invalid.\r + <<~RESPONSE + ssl_result=7000\r + ssl_result_message=The viaKLIX ID and/or User ID supplied in the authorization request is invalid.\r RESPONSE end end diff --git a/test/unit/gateways/visanet_peru_test.rb b/test/unit/gateways/visanet_peru_test.rb index c58840c78a0..a9a21fc531f 100644 --- a/test/unit/gateways/visanet_peru_test.rb +++ b/test/unit/gateways/visanet_peru_test.rb @@ -67,7 +67,7 @@ def test_successful_capture @gateway.expects(:ssl_request).with(:post, any_parameters).returns(successful_authorize_response) @gateway.expects(:ssl_request).with(:put, any_parameters).returns(successful_capture_response) response = @gateway.authorize(@amount, @credit_card, @options) - capture = @gateway.capture(response.authorization, @options) + capture = @gateway.capture(@amount, response.authorization, @options) assert_success capture assert_equal 'OK', capture.message assert_match %r(^[0-9]{9}|$), capture.authorization @@ -78,7 +78,7 @@ def test_successful_capture def test_failed_capture @gateway.expects(:ssl_request).returns(failed_capture_response) invalid_purchase_number = '900000044' - response = @gateway.capture(invalid_purchase_number) + response = @gateway.capture(@amount, invalid_purchase_number) assert_failure response assert_equal '[ "NUMORDEN 900000044 no se encuentra registrado", "No se realizo el deposito" ]', response.message assert_equal 400, response.error_code @@ -518,5 +518,4 @@ def failed_refund_with_message_and_action_code_response_2 } RESPONSE end - end diff --git a/test/unit/gateways/webpay_test.rb b/test/unit/gateways/webpay_test.rb index 25123a5623b..474479742f1 100644 --- a/test/unit/gateways/webpay_test.rb +++ b/test/unit/gateways/webpay_test.rb @@ -4,15 +4,15 @@ class WebpayTest < Test::Unit::TestCase include CommStub def setup - @gateway = WebpayGateway.new(:login => 'login') + @gateway = WebpayGateway.new(login: 'login') @credit_card = credit_card() @amount = 40000 @refund_amount = 20000 @options = { - :billing_address => address(), - :description => 'Test Purchase' + billing_address: address(), + description: 'Test Purchase' } end @@ -60,7 +60,7 @@ def test_appropriate_purchase_amount def test_successful_purchase_with_token response = stub_comms(@gateway, :ssl_request) do @gateway.purchase(@amount, 'cus_xxx|card_xxx') - end.check_request do |method, endpoint, data, headers| + end.check_request do |_method, _endpoint, data, _headers| assert_match(/customer=cus_xxx/, data) assert_match(/card=card_xxx/, data) end.respond_with(successful_purchase_response) @@ -94,7 +94,7 @@ def test_successful_refund end def test_successful_request_always_uses_live_mode_to_determine_test_request - @gateway.expects(:ssl_request).returns(successful_partially_refunded_response(:livemode => true)) + @gateway.expects(:ssl_request).returns(successful_partially_refunded_response(livemode: true)) assert response = @gateway.refund(@refund_amount, 'ch_test_charge') assert_success response @@ -121,24 +121,24 @@ def test_invalid_raw_response def test_add_customer post = {} - @gateway.send(:add_customer, post, 'card_token', {:customer => 'test_customer'}) + @gateway.send(:add_customer, post, 'card_token', { customer: 'test_customer' }) assert_equal 'test_customer', post[:customer] end def test_doesnt_add_customer_if_card post = {} - @gateway.send(:add_customer, post, @credit_card, {:customer => 'test_customer'}) + @gateway.send(:add_customer, post, @credit_card, { customer: 'test_customer' }) assert !post[:customer] end def test_add_customer_data post = {} - @gateway.send(:add_customer_data, post, {:description => 'a test customer'}) + @gateway.send(:add_customer_data, post, { description: 'a test customer' }) assert_equal 'a test customer', post[:description] end def test_add_address - post = {:card => {}} + post = { card: {} } @gateway.send(:add_address, post, @options) assert_equal @options[:billing_address][:zip], post[:card][:address_zip] assert_equal @options[:billing_address][:state], post[:card][:address_state] @@ -158,270 +158,270 @@ def test_gateway_without_credentials end def test_metadata_header - @gateway.expects(:ssl_request).once.with { |method, url, post, headers| - headers && headers['X-Webpay-Client-User-Metadata'] == {:ip => '1.1.1.1'}.to_json + @gateway.expects(:ssl_request).once.with { |_method, _url, _post, headers| + headers && headers['X-Webpay-Client-User-Metadata'] == { ip: '1.1.1.1' }.to_json }.returns(successful_purchase_response) - @gateway.purchase(@amount, @credit_card, @options.merge(:ip => '1.1.1.1')) + @gateway.purchase(@amount, @credit_card, @options.merge(ip: '1.1.1.1')) end private def successful_authorization_response - <<-RESPONSE -{ - "id": "ch_test_charge", - "object": "charge", - "livemode": false, - "currency": "jpy", - "description": "ActiveMerchant Test Purchase", - "amount": 40000, - "amount_refunded": 0, - "customer": null, - "recursion": null, - "created": 1309131571, - "paid": false, - "refunded": false, - "failure_message": null, - "card": { - "object": "card", - "exp_year": #{Time.now.year + 1}, - "exp_month": 11, - "fingerprint": "215b5b2fe460809b8bb90bae6eeac0e0e0987bd7", - "name": "LONGBOB LONGSEN", - "country": "JP", - "type": "Visa", - "cvc_check": "pass", - "last4": "4242" - }, - "captured": false, - "expire_time": 1309736371, - "fees": [ - - ] -} + <<~RESPONSE + { + "id": "ch_test_charge", + "object": "charge", + "livemode": false, + "currency": "jpy", + "description": "ActiveMerchant Test Purchase", + "amount": 40000, + "amount_refunded": 0, + "customer": null, + "recursion": null, + "created": 1309131571, + "paid": false, + "refunded": false, + "failure_message": null, + "card": { + "object": "card", + "exp_year": #{Time.now.year + 1}, + "exp_month": 11, + "fingerprint": "215b5b2fe460809b8bb90bae6eeac0e0e0987bd7", + "name": "LONGBOB LONGSEN", + "country": "JP", + "type": "Visa", + "cvc_check": "pass", + "last4": "4242" + }, + "captured": false, + "expire_time": 1309736371, + "fees": [ + + ] + } RESPONSE end def successful_capture_response - <<-RESPONSE -{ - "id": "ch_test_charge", - "object": "charge", - "livemode": false, - "currency": "jpy", - "description": "ActiveMerchant Test Purchase", - "amount": 40000, - "amount_refunded": 0, - "customer": null, - "recursion": null, - "created": 1309131571, - "paid": true, - "refunded": false, - "failure_message": null, - "card": { - "object": "card", - "exp_year": #{Time.now.year + 1}, - "exp_month": 11, - "fingerprint": "215b5b2fe460809b8bb90bae6eeac0e0e0987bd7", - "name": "LONGBOB LONGSEN", - "country": "JP", - "type": "Visa", - "cvc_check": "pass", - "last4": "4242" - }, - "captured": true, - "expire_time": 1309736371, - "fees": [ - { - "object": "fee", - "transaction_type": "payment", - "transaction_fee": 0, - "rate": 3.25, - "amount": 1300, - "created": 1408585142 - } - ] -} + <<~RESPONSE + { + "id": "ch_test_charge", + "object": "charge", + "livemode": false, + "currency": "jpy", + "description": "ActiveMerchant Test Purchase", + "amount": 40000, + "amount_refunded": 0, + "customer": null, + "recursion": null, + "created": 1309131571, + "paid": true, + "refunded": false, + "failure_message": null, + "card": { + "object": "card", + "exp_year": #{Time.now.year + 1}, + "exp_month": 11, + "fingerprint": "215b5b2fe460809b8bb90bae6eeac0e0e0987bd7", + "name": "LONGBOB LONGSEN", + "country": "JP", + "type": "Visa", + "cvc_check": "pass", + "last4": "4242" + }, + "captured": true, + "expire_time": 1309736371, + "fees": [ + { + "object": "fee", + "transaction_type": "payment", + "transaction_fee": 0, + "rate": 3.25, + "amount": 1300, + "created": 1408585142 + } + ] + } RESPONSE end # Place raw successful response from gateway here - def successful_purchase_response(refunded=false) - <<-RESPONSE -{ - "id": "ch_test_charge", - "object": "charge", - "livemode": false, - "currency": "jpy", - "description": "ActiveMerchant Test Purchase", - "amount": 400, - "amount_refunded": 0, - "customer": null, - "recursion": null, - "created": 1408585273, - "paid": true, - "refunded": false, - "failure_message": null, - "card": { - "object": "card", - "exp_year": #{Time.now.year + 1}, - "exp_month": 11, - "fingerprint": "215b5b2fe460809b8bb90bae6eeac0e0e0987bd7", - "name": "LONGBOB LONGSEN", - "country": "JP", - "type": "Visa", - "cvc_check": "pass", - "last4": "4242" - }, - "captured": true, - "expire_time": null, - "fees": [ - { - "object": "fee", - "transaction_type": "payment", - "transaction_fee": 0, - "rate": 3.25, - "amount": 1300, - "created": 1408585273 - } - ] -} + def successful_purchase_response(refunded = false) + <<~RESPONSE + { + "id": "ch_test_charge", + "object": "charge", + "livemode": false, + "currency": "jpy", + "description": "ActiveMerchant Test Purchase", + "amount": 400, + "amount_refunded": 0, + "customer": null, + "recursion": null, + "created": 1408585273, + "paid": true, + "refunded": false, + "failure_message": null, + "card": { + "object": "card", + "exp_year": #{Time.now.year + 1}, + "exp_month": 11, + "fingerprint": "215b5b2fe460809b8bb90bae6eeac0e0e0987bd7", + "name": "LONGBOB LONGSEN", + "country": "JP", + "type": "Visa", + "cvc_check": "pass", + "last4": "4242" + }, + "captured": true, + "expire_time": null, + "fees": [ + { + "object": "fee", + "transaction_type": "payment", + "transaction_fee": 0, + "rate": 3.25, + "amount": 1300, + "created": 1408585273 + } + ] + } RESPONSE end def successful_refunded_response - <<-RESPONSE -{ - "id": "ch_test_charge", - "object": "charge", - "livemode": false, - "currency": "jpy", - "description": "ActiveMerchant Test Purchase", - "amount": 400, - "amount_refunded": 400, - "customer": null, - "recursion": null, - "created": 1408585273, - "paid": true, - "refunded": true, - "failure_message": null, - "card": { - "object": "card", - "exp_year": #{Time.now.year + 1}, - "exp_month": 11, - "fingerprint": "215b5b2fe460809b8bb90bae6eeac0e0e0987bd7", - "name": "KEI KUBO", - "country": "JP", - "type": "Visa", - "cvc_check": "pass", - "last4": "4242" - }, - "captured": true, - "expire_time": null, - "fees": [ - { - "object": "fee", - "transaction_type": "payment", - "transaction_fee": 0, - "rate": 3.25, - "amount": 1300, - "created": 1408585273 - }, - { - "object": "fee", - "transaction_type": "refund", - "transaction_fee": 0, - "rate": 3.25, - "amount": -1300, - "created": 1408585461 - } - ] -} + <<~RESPONSE + { + "id": "ch_test_charge", + "object": "charge", + "livemode": false, + "currency": "jpy", + "description": "ActiveMerchant Test Purchase", + "amount": 400, + "amount_refunded": 400, + "customer": null, + "recursion": null, + "created": 1408585273, + "paid": true, + "refunded": true, + "failure_message": null, + "card": { + "object": "card", + "exp_year": #{Time.now.year + 1}, + "exp_month": 11, + "fingerprint": "215b5b2fe460809b8bb90bae6eeac0e0e0987bd7", + "name": "KEI KUBO", + "country": "JP", + "type": "Visa", + "cvc_check": "pass", + "last4": "4242" + }, + "captured": true, + "expire_time": null, + "fees": [ + { + "object": "fee", + "transaction_type": "payment", + "transaction_fee": 0, + "rate": 3.25, + "amount": 1300, + "created": 1408585273 + }, + { + "object": "fee", + "transaction_type": "refund", + "transaction_fee": 0, + "rate": 3.25, + "amount": -1300, + "created": 1408585461 + } + ] + } RESPONSE end def successful_partially_refunded_response(options = {}) - options = {:livemode=>false}.merge!(options) - <<-RESPONSE -{ - "id": "ch_test_charge", - "object": "charge", - "livemode": #{options[:livemode]}, - "currency": "jpy", - "description": "ActiveMerchant Test Purchase", - "amount": 400, - "amount_refunded": 200, - "customer": null, - "recursion": null, - "created": 1408584994, - "paid": true, - "refunded": false, - "failure_message": null, - "card": { - "object": "card", - "exp_year": #{Time.now.year + 1}, - "exp_month": 11, - "fingerprint": "215b5b2fe460809b8bb90bae6eeac0e0e0987bd7", - "name": "KEI KUBO", - "country": "JP", - "type": "Visa", - "cvc_check": "pass", - "last4": "4242" - }, - "captured": true, - "expire_time": 1409189794, - "fees": [ - { - "object": "fee", - "transaction_type": "payment", - "transaction_fee": 0, - "rate": 3.25, - "amount": 1300, - "created": 1408585142 - }, - { - "object": "fee", - "transaction_type": "refund", - "transaction_fee": 0, - "rate": 3.25, - "amount": -1300, - "created": 1408585699 - }, - { - "object": "fee", - "transaction_type": "payment", - "transaction_fee": 0, - "rate": 3.25, - "amount": 650, - "created": 1408585699 - } - ] -} + options = { livemode: false }.merge!(options) + <<~RESPONSE + { + "id": "ch_test_charge", + "object": "charge", + "livemode": #{options[:livemode]}, + "currency": "jpy", + "description": "ActiveMerchant Test Purchase", + "amount": 400, + "amount_refunded": 200, + "customer": null, + "recursion": null, + "created": 1408584994, + "paid": true, + "refunded": false, + "failure_message": null, + "card": { + "object": "card", + "exp_year": #{Time.now.year + 1}, + "exp_month": 11, + "fingerprint": "215b5b2fe460809b8bb90bae6eeac0e0e0987bd7", + "name": "KEI KUBO", + "country": "JP", + "type": "Visa", + "cvc_check": "pass", + "last4": "4242" + }, + "captured": true, + "expire_time": 1409189794, + "fees": [ + { + "object": "fee", + "transaction_type": "payment", + "transaction_fee": 0, + "rate": 3.25, + "amount": 1300, + "created": 1408585142 + }, + { + "object": "fee", + "transaction_type": "refund", + "transaction_fee": 0, + "rate": 3.25, + "amount": -1300, + "created": 1408585699 + }, + { + "object": "fee", + "transaction_type": "payment", + "transaction_fee": 0, + "rate": 3.25, + "amount": 650, + "created": 1408585699 + } + ] + } RESPONSE end # Place raw failed response from gateway here def failed_purchase_response - <<-RESPONSE -{ - "error": { - "message": "The card number is invalid. Make sure the number entered matches your credit card.", - "caused_by": "buyer", - "param": "number", - "type": "card_error", - "code": "incorrect_number" - } -} + <<~RESPONSE + { + "error": { + "message": "The card number is invalid. Make sure the number entered matches your credit card.", + "caused_by": "buyer", + "param": "number", + "type": "card_error", + "code": "incorrect_number" + } + } RESPONSE end # Place raw invalid JSON from gateway here def invalid_json_response - <<-RESPONSE - { - foo : bar - } + <<~RESPONSE + { + foo : bar + } RESPONSE end end diff --git a/test/unit/gateways/wepay_test.rb b/test/unit/gateways/wepay_test.rb index 9f749e27916..30c012b590a 100644 --- a/test/unit/gateways/wepay_test.rb +++ b/test/unit/gateways/wepay_test.rb @@ -160,7 +160,7 @@ def test_invalid_json_response def test_no_version_by_default stub_comms do @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, _data, headers| assert_no_match(/Api-Version/, headers.to_s) end.respond_with(successful_authorize_response) end @@ -168,7 +168,7 @@ def test_no_version_by_default def test_version_override stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(version: '2017-05-31')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, _data, headers| assert_match(/"Api-Version\"=>\"2017-05-31\"/, headers.to_s) end.respond_with(successful_authorize_response) end @@ -425,5 +425,4 @@ def failed_capture_response def invalid_json_response %({"checkout_id"=1852898602,"state":"captured") end - end diff --git a/test/unit/gateways/wirecard_test.rb b/test/unit/gateways/wirecard_test.rb index 6931f58bd9b..fcbd76c83d6 100644 --- a/test/unit/gateways/wirecard_test.rb +++ b/test/unit/gateways/wirecard_test.rb @@ -32,7 +32,7 @@ def setup city: 'Ottawa', zip: 'K12 P2A', country: 'CA', - state: nil, + state: nil } @address_avs = { @@ -40,7 +40,7 @@ def setup city: 'London', zip: 'W8 2TE', country: 'GB', - state: 'London', + state: 'London' } end @@ -192,7 +192,7 @@ def test_description_trucated_to_32_chars_in_authorize 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(/32chars-------------------------<\/FunctionID>/, data) end.respond_with(successful_authorization_response) end @@ -202,7 +202,7 @@ def test_description_trucated_to_32_chars_in_purchase 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(/32chars-------------------------<\/FunctionID>/, data) end.respond_with(successful_purchase_response) end @@ -212,7 +212,7 @@ def test_description_is_ascii_encoded_since_wirecard_does_not_like_utf_8 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(/\?D\?nde est\? la estaci\?n\?<\/FunctionID>/, data) end.respond_with(successful_purchase_response) end @@ -236,7 +236,7 @@ def test_commerce_type_option 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(/MOTO<\/CommerceType>/, data) end.respond_with(successful_purchase_response) end @@ -244,7 +244,7 @@ def test_commerce_type_option def test_store_sets_recurring_transaction_type_to_initial stub_comms do @gateway.store(@credit_card) - end.check_request do |endpoint, body, headers| + end.check_request do |_endpoint, body, _headers| assert_xml_element_text(body, '//RECURRING_TRANSACTION/Type', 'Initial') end.respond_with(successful_authorization_response) end @@ -252,15 +252,15 @@ def test_store_sets_recurring_transaction_type_to_initial def test_store_sets_amount_to_100_by_default stub_comms do @gateway.store(@credit_card) - end.check_request do |endpoint, body, headers| + end.check_request do |_endpoint, body, _headers| assert_xml_element_text(body, '//CC_TRANSACTION/Amount', '100') end.respond_with(successful_authorization_response) end def test_store_sets_amount_to_amount_from_options stub_comms do - @gateway.store(@credit_card, :amount => 120) - end.check_request do |endpoint, body, headers| + @gateway.store(@credit_card, amount: 120) + end.check_request do |_endpoint, body, _headers| assert_xml_element_text(body, '//CC_TRANSACTION/Amount', '120') end.respond_with(successful_authorization_response) end @@ -268,7 +268,7 @@ def test_store_sets_amount_to_amount_from_options def test_authorization_using_reference_sets_proper_elements stub_comms do @gateway.authorize(@amount, '45678', @options) - end.check_request do |endpoint, body, headers| + end.check_request do |_endpoint, body, _headers| assert_xml_element_text(body, '//GuWID', '45678') assert_no_match(//, body) end.respond_with(successful_authorization_response) @@ -277,7 +277,7 @@ def test_authorization_using_reference_sets_proper_elements def test_purchase_using_reference_sets_proper_elements stub_comms do @gateway.purchase(@amount, '87654', @options) - end.check_request do |endpoint, body, headers| + end.check_request do |_endpoint, body, _headers| assert_xml_element_text(body, '//GuWID', '87654') assert_no_match(//, body) end.respond_with(successful_authorization_response) @@ -285,16 +285,16 @@ def test_purchase_using_reference_sets_proper_elements def test_authorization_with_recurring_transaction_type_initial stub_comms do - @gateway.authorize(@amount, @credit_card, @options.merge(:recurring => 'Initial')) - end.check_request do |endpoint, body, headers| + @gateway.authorize(@amount, @credit_card, @options.merge(recurring: 'Initial')) + end.check_request do |_endpoint, body, _headers| assert_xml_element_text(body, '//RECURRING_TRANSACTION/Type', 'Initial') end.respond_with(successful_authorization_response) end def test_purchase_using_with_recurring_transaction_type_initial stub_comms do - @gateway.purchase(@amount, @credit_card, @options.merge(:recurring => 'Initial')) - end.check_request do |endpoint, body, headers| + @gateway.purchase(@amount, @credit_card, @options.merge(recurring: 'Initial')) + end.check_request do |_endpoint, body, _headers| assert_xml_element_text(body, '//RECURRING_TRANSACTION/Type', 'Initial') end.respond_with(successful_authorization_response) end @@ -329,42 +329,42 @@ def assert_xml_element_text(xml, xpath, expected_text) # Authorization success def successful_authorization_response - <<-XML - - - - - test dummy data - - Wirecard remote test purchase - - 1 - - C822580121385121429927 - 709678 - THIS IS A DEMO TRANSACTION USING CREDIT CARD NUMBER 420000****0000. NO REAL MONEY WILL BE TRANSFERED. - INFO - ACK - 2008-06-19 06:53:33 - - - - - - + <<~XML + + + + + test dummy data + + Wirecard remote test purchase + + 1 + + C822580121385121429927 + 709678 + THIS IS A DEMO TRANSACTION USING CREDIT CARD NUMBER 420000****0000. NO REAL MONEY WILL BE TRANSFERED. + INFO + ACK + 2008-06-19 06:53:33 + + + + + + XML end # Authorization failure # TODO: replace with real xml string here (current way seems to complicated) def wrong_creditcard_authorization_response - error = <<-XML - - DATA_ERROR - 24997 - Credit card number not allowed in demo mode. - Only demo card number '4200000000000000' is allowed for VISA in demo mode. - + error = <<~XML + + DATA_ERROR + 24997 + Credit card number not allowed in demo mode. + Only demo card number '4200000000000000' is allowed for VISA in demo mode. + XML result_node = '' auth = 'AuthorizationCode' @@ -377,94 +377,94 @@ def wrong_creditcard_authorization_response # Capture success def successful_capture_response - <<-XML - - - - - test dummy data - - Wirecard remote test purchase - - 1 - - C833707121385268439116 - 915025 - THIS IS A DEMO TRANSACTION USING CREDIT CARD NUMBER 420000****0000. NO REAL MONEY WILL BE TRANSFERED. - INFO - ACK - 2008-06-19 07:18:04 - - - - - - + <<~XML + + + + + test dummy data + + Wirecard remote test purchase + + 1 + + C833707121385268439116 + 915025 + THIS IS A DEMO TRANSACTION USING CREDIT CARD NUMBER 420000****0000. NO REAL MONEY WILL BE TRANSFERED. + INFO + ACK + 2008-06-19 07:18:04 + + + + + + XML end # Capture failure def unauthorized_capture_response - <<-XML - - - - - test dummy data - - Test dummy FunctionID - - a2783d471ccc98825b8c498f1a62ce8f - - C833707121385268439116 - - INFO - NOK - - DATA_ERROR - 20080 - Could not find referenced transaction for GuWID 1234567890123456789012. - - 2008-06-19 08:09:20 - - - - - - + <<~XML + + + + + test dummy data + + Test dummy FunctionID + + a2783d471ccc98825b8c498f1a62ce8f + + C833707121385268439116 + + INFO + NOK + + DATA_ERROR + 20080 + Could not find referenced transaction for GuWID 1234567890123456789012. + + 2008-06-19 08:09:20 + + + + + + XML end # Purchase success def successful_purchase_response - <<-XML - - - - - test dummy data - - Wirecard remote test purchase - - 1 - - C865402121385575982910 - 531750 - THIS IS A DEMO TRANSACTION USING CREDIT CARD NUMBER 420000****0000. NO REAL MONEY WILL BE TRANSFERED. - INFO - ACK - 2008-06-19 08:09:19 - - - - - - + <<~XML + + + + + test dummy data + + Wirecard remote test purchase + + 1 + + C865402121385575982910 + 531750 + THIS IS A DEMO TRANSACTION USING CREDIT CARD NUMBER 420000****0000. NO REAL MONEY WILL BE TRANSFERED. + INFO + ACK + 2008-06-19 08:09:19 + + + + + + XML end def successful_refund_response - <<-XML + <<~XML @@ -491,7 +491,7 @@ def successful_refund_response end def failed_refund_response - <<-XML + <<~XML @@ -522,7 +522,7 @@ def failed_refund_response end def successful_void_response - <<-XML + <<~XML @@ -549,7 +549,7 @@ def successful_void_response end def failed_void_response - <<-XML + <<~XML @@ -581,202 +581,202 @@ def failed_void_response # Purchase failure def wrong_creditcard_purchase_response - <<-XML - - - - - test dummy data - - Wirecard remote test purchase - - 1 - - C824697121385153203112 - - INFO - NOK - - DATA_ERROR 24997 - Credit card number not allowed in demo mode. - Only demo card number '4200000000000000' is allowed for VISA in demo mode. - - 2008-06-19 06:58:51 - - - - - - + <<~XML + + + + + test dummy data + + Wirecard remote test purchase + + 1 + + C824697121385153203112 + + INFO + NOK + + DATA_ERROR 24997 + Credit card number not allowed in demo mode. + Only demo card number '4200000000000000' is allowed for VISA in demo mode. + + 2008-06-19 06:58:51 + + + + + + XML end # AVS failure def failed_avs_response - <<-XML - - - - - - - - - E0BCBF30B82D0131000000000000E4CF - - C997753139988691610455 - 732129 - THIS IS A DEMO TRANSACTION USING CREDIT CARD NUMBER 420000****0000. NO REAL MONEY WILL BE TRANSFERED. - INFO - PENDING - - U - AVS Unavailable. - 5 - Response provided by issuer processor. - A - Address information is unavailable, or the Issuer does not support AVS. Acquirer has representment rights. - - 2014-05-12 11:28:36 - - - - - - + <<~XML + + + + + + + + + E0BCBF30B82D0131000000000000E4CF + + C997753139988691610455 + 732129 + THIS IS A DEMO TRANSACTION USING CREDIT CARD NUMBER 420000****0000. NO REAL MONEY WILL BE TRANSFERED. + INFO + PENDING + + U + AVS Unavailable. + 5 + Response provided by issuer processor. + A + Address information is unavailable, or the Issuer does not support AVS. Acquirer has representment rights. + + 2014-05-12 11:28:36 + + + + + + XML end def system_error_response - <<-XML - - - - - - - - - 3A368E50D50B01310000000000009153 - - C967464140265180577024 - - THIS IS A DEMO TRANSACTION USING CREDIT CARD NUMBER 420000****0000. NO REAL MONEY WILL BE TRANSFERED. - INFO - NOK - - SYSTEM_ERROR - 20205 - - - 2014-06-13 11:30:05 - - - - - - + <<~XML + + + + + + + + + 3A368E50D50B01310000000000009153 + + C967464140265180577024 + + THIS IS A DEMO TRANSACTION USING CREDIT CARD NUMBER 420000****0000. NO REAL MONEY WILL BE TRANSFERED. + INFO + NOK + + SYSTEM_ERROR + 20205 + + + 2014-06-13 11:30:05 + + + + + + XML end def system_error_response_without_job - <<-XML - - - - - SYSTEM_ERROR - 10003 - Job Refused - - - + <<~XML + + + + + SYSTEM_ERROR + 10003 + Job Refused + + + XML end def transcript - <<-XML - - - - - 00000031629CAFD5 - - Wirecard remote test purchase - - 1 - 100 - EUR - CA - - Single - - - 4200000000000000 - 123 - 2016 - 09 - Longbob Longsen - - -
- 456 My Street - Apt 1 - Ottawa - K1C2N6 - ON - CA - soleone@example.com -
-
-
-
-
-
-
+ <<~XML + + + + + 00000031629CAFD5 + + Wirecard remote test purchase + + 1 + 100 + EUR + CA + + Single + + + 4200000000000000 + 123 + 2016 + 09 + Longbob Longsen + + +
+ 456 My Street + Apt 1 + Ottawa + K1C2N6 + ON + CA + soleone@example.com +
+
+
+
+
+
+
XML end def scrubbed_transcript - <<-XML - - - - - 00000031629CAFD5 - - Wirecard remote test purchase - - 1 - 100 - EUR - CA - - Single - - - [FILTERED] - [FILTERED] - 2016 - 09 - Longbob Longsen - - -
- 456 My Street - Apt 1 - Ottawa - K1C2N6 - ON - CA - soleone@example.com -
-
-
-
-
-
-
+ <<~XML + + + + + 00000031629CAFD5 + + Wirecard remote test purchase + + 1 + 100 + EUR + CA + + Single + + + [FILTERED] + [FILTERED] + 2016 + 09 + Longbob Longsen + + +
+ 456 My Street + Apt 1 + Ottawa + K1C2N6 + ON + CA + soleone@example.com +
+
+
+
+
+
+
XML end end diff --git a/test/unit/gateways/worldpay_online_payments_test.rb b/test/unit/gateways/worldpay_online_payments_test.rb index 697ac11aba0..124f8b3e179 100644 --- a/test/unit/gateways/worldpay_online_payments_test.rb +++ b/test/unit/gateways/worldpay_online_payments_test.rb @@ -43,7 +43,7 @@ def test_successful_authorize_and_capture assert_success authorize @gateway.expects(:ssl_request).returns(successful_capture_response) - assert capture = @gateway.capture(@amount-1, authorize.authorization) + assert capture = @gateway.capture(@amount - 1, authorize.authorization) assert_success capture end @@ -71,7 +71,7 @@ def test_partial_capture assert_success authorize @gateway.expects(:ssl_request).returns(successful_capture_response) - assert capture = @gateway.capture(@amount-1, authorize.authorization) + assert capture = @gateway.capture(@amount - 1, authorize.authorization) assert_success capture end diff --git a/test/unit/gateways/worldpay_test.rb b/test/unit/gateways/worldpay_test.rb index 679af17ed49..5b74e699b85 100644 --- a/test/unit/gateways/worldpay_test.rb +++ b/test/unit/gateways/worldpay_test.rb @@ -5,23 +5,22 @@ class WorldpayTest < Test::Unit::TestCase def setup @gateway = WorldpayGateway.new( - :login => 'testlogin', - :password => 'testpassword' - ) + login: 'testlogin', + password: 'testpassword' + ) @amount = 100 @credit_card = credit_card('4242424242424242') @token = '|99411111780163871111|shopper|59424549c291397379f30c5c082dbed8' @elo_credit_card = credit_card('4514 1600 0000 0008', - :month => 10, - :year => 2020, - :first_name => 'John', - :last_name => 'Smith', - :verification_value => '737', - :brand => 'elo' - ) + month: 10, + year: 2020, + first_name: 'John', + last_name: 'Smith', + verification_value: '737', + brand: 'elo') @sodexo_voucher = credit_card('6060704495764400', brand: 'sodexo') - @options = {:order_id => 1} + @options = { order_id: 1 } @store_options = { customer: '59424549c291397379f30c5c082dbed8', email: 'wow@example.com' @@ -31,7 +30,7 @@ def setup def test_successful_authorize 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(/4242424242424242/, data) end.respond_with(successful_authorize_response) assert_success response @@ -41,7 +40,7 @@ def test_successful_authorize def test_successful_authorize_by_reference response = stub_comms do @gateway.authorize(@amount, @options[:order_id].to_s, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/payAsOrder/, data) end.respond_with(successful_authorize_response) assert_success response @@ -50,18 +49,75 @@ def test_successful_authorize_by_reference def test_exemption_in_request response = stub_comms do - @gateway.authorize(@amount, @credit_card, @options.merge({exemption_type: 'LV', exemption_placement: 'AUTHENTICATION'})) - end.check_request do |endpoint, data, headers| + @gateway.authorize(@amount, @credit_card, @options.merge({ exemption_type: 'LV', exemption_placement: 'AUTHENTICATION' })) + end.check_request do |_endpoint, data, _headers| assert_match(/exemption/, data) assert_match(/AUTHENTICATION/, data) end.respond_with(successful_authorize_response) assert_success response end + def test_risk_data_in_request + response = stub_comms do + @gateway.authorize(@amount, @credit_card, @options.merge(risk_data: risk_data)) + end.check_request do |_endpoint, data, _headers| + doc = Nokogiri::XML(data) + + authentication_risk_data = doc.at_xpath('//riskData//authenticationRiskData') + assert_equal(risk_data[:authentication_risk_data][:authentication_method], authentication_risk_data.attribute('authenticationMethod').value) + + timestamp = doc.at_xpath('//riskData//authenticationRiskData//authenticationTimestamp//date') + assert_equal(risk_data[:authentication_risk_data][:authentication_date][:day_of_month], timestamp.attribute('dayOfMonth').value) + assert_equal(risk_data[:authentication_risk_data][:authentication_date][:month], timestamp.attribute('month').value) + assert_equal(risk_data[:authentication_risk_data][:authentication_date][:year], timestamp.attribute('year').value) + assert_equal(risk_data[:authentication_risk_data][:authentication_date][:hour], timestamp.attribute('hour').value) + assert_equal(risk_data[:authentication_risk_data][:authentication_date][:minute], timestamp.attribute('minute').value) + assert_equal(risk_data[:authentication_risk_data][:authentication_date][:second], timestamp.attribute('second').value) + + shopper_account_risk_data_xml = doc.at_xpath('//riskData//shopperAccountRiskData') + shopper_account_risk_data = risk_data[:shopper_account_risk_data] + assert_equal(shopper_account_risk_data[:transactions_attempted_last_day], shopper_account_risk_data_xml.attribute('transactionsAttemptedLastDay').value) + assert_equal(shopper_account_risk_data[:transactions_attempted_last_year], shopper_account_risk_data_xml.attribute('transactionsAttemptedLastYear').value) + assert_equal(shopper_account_risk_data[:purchases_completed_last_six_months], shopper_account_risk_data_xml.attribute('purchasesCompletedLastSixMonths').value) + assert_equal(shopper_account_risk_data[:add_card_attempts_last_day], shopper_account_risk_data_xml.attribute('addCardAttemptsLastDay').value) + assert_equal(shopper_account_risk_data[:previous_suspicious_activity], shopper_account_risk_data_xml.attribute('previousSuspiciousActivity').value) + assert_equal(shopper_account_risk_data[:shipping_name_matches_account_name], shopper_account_risk_data_xml.attribute('shippingNameMatchesAccountName').value) + assert_equal(shopper_account_risk_data[:shopper_account_age_indicator], shopper_account_risk_data_xml.attribute('shopperAccountAgeIndicator').value) + assert_equal(shopper_account_risk_data[:shopper_account_change_indicator], shopper_account_risk_data_xml.attribute('shopperAccountChangeIndicator').value) + assert_equal(shopper_account_risk_data[:shopper_account_password_change_indicator], shopper_account_risk_data_xml.attribute('shopperAccountPasswordChangeIndicator').value) + assert_equal(shopper_account_risk_data[:shopper_account_shipping_address_usage_indicator], shopper_account_risk_data_xml.attribute('shopperAccountShippingAddressUsageIndicator').value) + assert_equal(shopper_account_risk_data[:shopper_account_payment_account_indicator], shopper_account_risk_data_xml.attribute('shopperAccountPaymentAccountIndicator').value) + assert_date_element(shopper_account_risk_data[:shopper_account_creation_date], shopper_account_risk_data_xml.at_xpath('//shopperAccountCreationDate//date')) + assert_date_element(shopper_account_risk_data[:shopper_account_modification_date], shopper_account_risk_data_xml.at_xpath('//shopperAccountModificationDate//date')) + assert_date_element(shopper_account_risk_data[:shopper_account_password_change_date], shopper_account_risk_data_xml.at_xpath('//shopperAccountPasswordChangeDate//date')) + assert_date_element(shopper_account_risk_data[:shopper_account_shipping_address_first_use_date], shopper_account_risk_data_xml.at_xpath('//shopperAccountShippingAddressFirstUseDate//date')) + assert_date_element(shopper_account_risk_data[:shopper_account_payment_account_first_use_date], shopper_account_risk_data_xml.at_xpath('//shopperAccountPaymentAccountFirstUseDate//date')) + + transaction_risk_data_xml = doc.at_xpath('//riskData//transactionRiskData') + transaction_risk_data = risk_data[:transaction_risk_data] + assert_equal(transaction_risk_data[:shipping_method], transaction_risk_data_xml.attribute('shippingMethod').value) + assert_equal(transaction_risk_data[:delivery_timeframe], transaction_risk_data_xml.attribute('deliveryTimeframe').value) + assert_equal(transaction_risk_data[:delivery_email_address], transaction_risk_data_xml.attribute('deliveryEmailAddress').value) + assert_equal(transaction_risk_data[:reordering_previous_purchases], transaction_risk_data_xml.attribute('reorderingPreviousPurchases').value) + assert_equal(transaction_risk_data[:pre_order_purchase], transaction_risk_data_xml.attribute('preOrderPurchase').value) + assert_equal(transaction_risk_data[:gift_card_count], transaction_risk_data_xml.attribute('giftCardCount').value) + + amount_xml = doc.at_xpath('//riskData//transactionRiskData//transactionRiskDataGiftCardAmount//amount') + amount_data = transaction_risk_data[:transaction_risk_data_gift_card_amount] + assert_equal(amount_data[:value], amount_xml.attribute('value').value) + assert_equal(amount_data[:currency], amount_xml.attribute('currencyCode').value) + assert_equal(amount_data[:exponent], amount_xml.attribute('exponent').value) + assert_equal(amount_data[:debit_credit_indicator], amount_xml.attribute('debitCreditIndicator').value) + + assert_date_element(transaction_risk_data[:transaction_risk_data_pre_order_date], transaction_risk_data_xml.at_xpath('//transactionRiskDataPreOrderDate//date')) + end.respond_with(successful_authorize_response) + assert_success response + end + def test_successful_reference_transaction_authorize_with_merchant_code response = stub_comms do - @gateway.authorize(@amount, @options[:order_id].to_s, @options.merge({ merchant_code: 'testlogin2'})) - end.check_request do |endpoint, data, headers| + @gateway.authorize(@amount, @options[:order_id].to_s, @options.merge({ merchant_code: 'testlogin2' })) + end.check_request do |_endpoint, data, _headers| assert_match(/testlogin2/, data) end.respond_with(successful_authorize_response) assert_success response @@ -71,7 +127,7 @@ def test_successful_reference_transaction_authorize_with_merchant_code def test_authorize_passes_ip_and_session_id response = stub_comms do @gateway.authorize(@amount, @credit_card, @options.merge(ip: '127.0.0.1', session_id: '0215ui8ib1')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(//, data) end.respond_with(successful_authorize_response) assert_success response @@ -85,7 +141,7 @@ def test_authorize_passes_stored_credential_options ) 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(//, data) assert_match(/000000000000020005060720116005060\<\/schemeTransactionIdentifier\>/, data) end.respond_with(successful_authorize_response) @@ -108,6 +164,14 @@ def test_successful_purchase assert_success response end + def test_successful_purchase_skipping_capture + response = stub_comms do + @gateway.purchase(@amount, @credit_card, @options.merge(skip_capture: true)) + end.respond_with(successful_authorize_response, successful_capture_response) + assert response.responses.length == 1 + assert_success response + end + def test_successful_purchase_with_elo response = stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(currency: 'BRL')) @@ -118,7 +182,7 @@ def test_successful_purchase_with_elo def test_purchase_passes_correct_currency response = stub_comms do @gateway.purchase(@amount, @credit_card, @options.merge(currency: 'CAD')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(/CAD/, data) end.respond_with(successful_authorize_response, successful_capture_response) assert_success response @@ -179,13 +243,9 @@ def test_void_using_order_id_embedded_with_token response = stub_comms do authorization = "#{@options[:order_id]}|99411111780163871111|shopper|59424549c291397379f30c5c082dbed8" @gateway.void(authorization, @options) - end.check_request do |endpoint, data, headers| - if %r() =~ data - assert_tag_with_attributes('orderInquiry', {'orderCode' => @options[:order_id].to_s}, data) - end - if %r() =~ data - assert_tag_with_attributes('orderModification', {'orderCode' => @options[:order_id].to_s}, data) - end + end.check_request do |_endpoint, data, _headers| + assert_tag_with_attributes('orderInquiry', { 'orderCode' => @options[:order_id].to_s }, data) if %r().match?(data) + assert_tag_with_attributes('orderModification', { 'orderCode' => @options[:order_id].to_s }, data) if %r().match?(data) end.respond_with(successful_void_inquiry_response, successful_void_response) assert_success response assert_equal 'SUCCESS', response.message @@ -231,17 +291,21 @@ def test_full_refund_for_unsettled_payment_forces_void assert 'cancel', response.responses.last.params['action'] end + def test_refund_failure_with_force_full_refund_if_unsettled_does_not_force_void + response = stub_comms do + @gateway.refund(@amount, @options[:order_id], @options.merge(force_full_refund_if_unsettled: true)) + end.respond_with('total garbage') + + assert_failure response + end + def test_refund_using_order_id_embedded_with_token response = stub_comms do authorization = "#{@options[:order_id]}|99411111780163871111|shopper|59424549c291397379f30c5c082dbed8" @gateway.refund(@amount, authorization, @options) - end.check_request do |endpoint, data, headers| - if %r() =~ data - assert_tag_with_attributes('orderInquiry', {'orderCode' => @options[:order_id].to_s}, data) - end - if %r() =~ data - assert_tag_with_attributes('orderModification', {'orderCode' => @options[:order_id].to_s}, data) - end + end.check_request do |_endpoint, data, _headers| + assert_tag_with_attributes('orderInquiry', { 'orderCode' => @options[:order_id].to_s }, data) if %r().match?(data) + assert_tag_with_attributes('orderModification', { 'orderCode' => @options[:order_id].to_s }, data) if %r().match?(data) end.respond_with(successful_refund_inquiry_response('CAPTURED'), successful_refund_response) assert_success response end @@ -259,10 +323,8 @@ def test_capture_using_order_id_embedded_with_token response = @gateway.authorize(@amount, @credit_card, @options) authorization = "#{response.authorization}|99411111780163871111|shopper|59424549c291397379f30c5c082dbed8" @gateway.capture(@amount, authorization, @options) - end.check_request do |endpoint, data, headers| - if %r() =~ data - assert_tag_with_attributes('orderModification', {'orderCode' => response.authorization}, data) - end + end.check_request do |_endpoint, data, _headers| + assert_tag_with_attributes('orderModification', { 'orderCode' => response.authorization }, data) if %r().match?(data) end.respond_with(successful_authorize_response, successful_capture_response) assert_success response end @@ -270,7 +332,7 @@ def test_capture_using_order_id_embedded_with_token def test_successful_visa_credit response = stub_comms do @gateway.credit(@amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(//, data) end.respond_with(successful_visa_credit_response) assert_success response @@ -280,7 +342,7 @@ def test_successful_visa_credit def test_successful_mastercard_credit response = stub_comms do @gateway.credit(@amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match(//, data) end.respond_with(successful_mastercard_credit_response) assert_success response @@ -290,13 +352,13 @@ def test_successful_mastercard_credit def test_description 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(Purchase), data end.respond_with(successful_authorize_response) stub_comms do @gateway.authorize(@amount, @credit_card, @options.merge(description: 'Something cool.')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match %r(Something cool.), data end.respond_with(successful_authorize_response) end @@ -304,13 +366,13 @@ def test_description def test_order_content 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 %r(orderContent), data end.respond_with(successful_authorize_response) stub_comms do @gateway.authorize(@amount, @credit_card, @options.merge(order_content: "Lots 'o' crazy stuff.")) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match %r(\s* stuff\.\]\]>\s*), data end.respond_with(successful_authorize_response) end @@ -318,11 +380,11 @@ def test_order_content def test_capture_time stub_comms do @gateway.capture(@amount, 'bogus', @options) - end.check_request do |endpoint, data, headers| - if data =~ /capture/ + end.check_request do |_endpoint, data, _headers| + if /capture/.match?(data) t = Time.now assert_tag_with_attributes 'date', - {'dayOfMonth' => t.day.to_s, 'month' => t.month.to_s, 'year' => t.year.to_s}, + { 'dayOfMonth' => t.day.to_s, 'month' => t.month.to_s, 'year' => t.year.to_s }, data end end.respond_with(successful_inquiry_response, successful_capture_response) @@ -331,9 +393,9 @@ def test_capture_time def test_amount_handling stub_comms do @gateway.authorize(100, @credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_tag_with_attributes 'amount', - {'value' => '100', 'exponent' => '2', 'currencyCode' => 'GBP'}, + { 'value' => '100', 'exponent' => '2', 'currencyCode' => 'GBP' }, data end.respond_with(successful_authorize_response) end @@ -341,17 +403,17 @@ def test_amount_handling def test_currency_exponent_handling stub_comms do @gateway.authorize(10000, @credit_card, @options.merge(currency: :JPY)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_tag_with_attributes 'amount', - {'value' => '100', 'exponent' => '0', 'currencyCode' => 'JPY'}, + { 'value' => '100', 'exponent' => '0', 'currencyCode' => 'JPY' }, data end.respond_with(successful_authorize_response) stub_comms do @gateway.authorize(10000, @credit_card, @options.merge(currency: :OMR)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_tag_with_attributes 'amount', - {'value' => '10000', 'exponent' => '3', 'currencyCode' => 'OMR'}, + { 'value' => '10000', 'exponent' => '3', 'currencyCode' => 'OMR' }, data end.respond_with(successful_authorize_response) end @@ -359,7 +421,7 @@ def test_currency_exponent_handling def test_address_handling stub_comms do @gateway.authorize(100, @credit_card, @options.merge(billing_address: address)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match %r(Jim), data assert_match %r(Smith), data assert_match %r(456 My Street), data @@ -373,7 +435,7 @@ def test_address_handling stub_comms do @gateway.authorize(100, @credit_card, @options.merge(billing_address: address.with_indifferent_access)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match %r(Jim), data assert_match %r(Smith), data assert_match %r(456 My Street), data @@ -387,7 +449,7 @@ def test_address_handling stub_comms do @gateway.authorize(100, @credit_card, @options.merge(address: address)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match %r(Jim), data assert_match %r(Smith), data assert_match %r(456 My Street), data @@ -401,14 +463,14 @@ def test_address_handling stub_comms do @gateway.authorize(100, @credit_card, @options.merge(billing_address: { phone: '555-3323' })) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_no_match %r(firstName), data assert_no_match %r(lastName), data assert_no_match %r(address2), data assert_match %r(N/A), data assert_match %r(N/A), data assert_match %r(0000), data - assert_match %r(N/A), data + assert_match %r(), data assert_match %r(US), data assert_match %r(555-3323), data end.respond_with(successful_authorize_response) @@ -417,7 +479,7 @@ def test_address_handling def test_no_address_specified stub_comms do @gateway.authorize(100, @credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_no_match %r(cardAddress), data assert_no_match %r(address), data assert_no_match %r(firstName), data @@ -438,38 +500,80 @@ def test_address_with_parts_unspecified stub_comms do @gateway.authorize(100, @credit_card, @options.merge(billing_address: address_with_nils)) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_no_match %r(firstName), data assert_no_match %r(lastName), data assert_no_match %r(address2), data assert_match %r(N/A), data assert_match %r(N/A), data assert_match %r(0000), data - assert_match %r(N/A), data + assert_match %r(), data assert_match %r(US), data assert_match %r(555-3323), data end.respond_with(successful_authorize_response) end + def test_state_sent_for_3ds_transactions_in_us_country + us_billing_address = address.merge(country: 'US') + stub_comms do + @gateway.authorize(100, @credit_card, @options.merge(billing_address: us_billing_address, execute_threed: true)) + end.check_request do |_endpoint, data, _headers| + assert_match %r(firstName), data + assert_match %r(lastName), data + assert_match %r(456 My Street), data + assert_match %r(Apt 1), data + assert_match %r(Ottawa), data + assert_match %r(K1C2N6), data + assert_match %r(ON), data + assert_match %r(US), data + assert_match %r(\(555\)555-5555), data + end.respond_with(successful_authorize_response) + end + + def test_state_not_sent_for_3ds_transactions_in_non_us_country + stub_comms do + @gateway.authorize(100, @credit_card, @options.merge(billing_address: address, execute_threed: true)) + end.check_request do |_endpoint, data, _headers| + assert_match %r(firstName), data + assert_match %r(lastName), data + assert_match %r(456 My Street), data + assert_match %r(Apt 1), data + assert_match %r(Ottawa), data + assert_match %r(K1C2N6), data + assert_no_match %r(ON), data + assert_match %r(CA), data + assert_match %r(\(555\)555-5555), data + end.respond_with(successful_authorize_response) + end + def test_email stub_comms do @gateway.authorize(100, @credit_card, @options.merge(email: 'eggcellent@example.com')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match %r(eggcellent@example.com), data end.respond_with(successful_authorize_response) stub_comms do @gateway.authorize(100, @credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_no_match %r(shopperEmailAddress), data end.respond_with(successful_authorize_response) end + def test_statement_narrative_and_truncation + stub_comms do + @gateway.authorize(100, @credit_card, @options.merge(statement_narrative: 'Merchant Statement Narrative The Story Of Your Purchase')) + end.check_request do |_endpoint, data, _headers| + assert_match %r(Merchant Statement Narrative The Story Of Your Pur), data + assert_no_match %r(Merchant Statement Narrative The Story Of Your Purchase), data + end.respond_with(successful_authorize_response) + end + def test_instalments stub_comms do @gateway.purchase(100, @credit_card, @options.merge(instalments: 3)) - end.check_request do |endpoint, data, headers| - unless // =~ data + end.check_request do |_endpoint, data, _headers| + unless //.match?(data) assert_match %r(3), data assert_no_match %r(cpf), data end @@ -477,8 +581,8 @@ def test_instalments stub_comms do @gateway.purchase(100, @credit_card, @options.merge(instalments: 3, cpf: 12341234)) - end.check_request do |endpoint, data, headers| - unless // =~ data + end.check_request do |_endpoint, data, _headers| + unless //.match?(data) assert_match %r(3), data assert_match %r(12341234), data end @@ -488,50 +592,50 @@ def test_instalments def test_ip stub_comms do @gateway.authorize(100, @credit_card, @options.merge(ip: '192.137.11.44')) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match %r(), data end.respond_with(successful_authorize_response) stub_comms do @gateway.authorize(100, @credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_no_match %r('authorize', - 'amount_currency_code'=>'HKD', - 'amount_debit_credit_indicator'=>'credit', - 'amount_exponent'=>'2', - 'amount_value'=>'15000', - 'avs_result_code_description'=>'UNKNOWN', - 'balance'=>true, - 'balance_account_type'=>'IN_PROCESS_AUTHORISED', - 'card_number'=>'4111********1111', - 'cvc_result_code_description'=>'UNKNOWN', - 'last_event'=>'AUTHORISED', - 'order_status'=>true, - 'order_status_order_code'=>'R50704213207145707', - 'payment'=>true, - 'payment_method'=>'VISA-SSL', - 'payment_service'=>true, - 'payment_service_merchant_code'=>'XXXXXXXXXXXXXXX', - 'payment_service_version'=>'1.4', - 'reply'=>true, - 'risk_score_value'=>'1', - }, response.params) + 'action' => 'authorize', + 'amount_currency_code' => 'HKD', + 'amount_debit_credit_indicator' => 'credit', + 'amount_exponent' => '2', + 'amount_value' => '15000', + 'avs_result_code_description' => 'UNKNOWN', + 'balance' => true, + 'balance_account_type' => 'IN_PROCESS_AUTHORISED', + 'card_number' => '4111********1111', + 'cvc_result_code_description' => 'UNKNOWN', + 'last_event' => 'AUTHORISED', + 'order_status' => true, + 'order_status_order_code' => 'R50704213207145707', + 'payment' => true, + 'payment_method' => 'VISA-SSL', + 'payment_service' => true, + 'payment_service_merchant_code' => 'XXXXXXXXXXXXXXX', + 'payment_service_version' => '1.4', + 'reply' => true, + 'risk_score_value' => '1' + }, response.params) end def test_auth stub_comms do @gateway.authorize(100, @credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, _data, headers| assert_equal 'Basic dGVzdGxvZ2luOnRlc3RwYXNzd29yZA==', headers['Authorization'] end.respond_with(successful_authorize_response) end @@ -540,14 +644,14 @@ def test_request_respects_test_mode_on_gateway_instance ActiveMerchant::Billing::Base.mode = :production @gateway = WorldpayGateway.new( - :login => 'testlogin', - :password => 'testpassword', - :test => true + login: 'testlogin', + password: 'testpassword', + test: true ) stub_comms do @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |endpoint, _data, _headers| assert_equal WorldpayGateway.test_url, endpoint end.respond_with(successful_authorize_response, successful_capture_response) ensure @@ -557,8 +661,8 @@ def test_request_respects_test_mode_on_gateway_instance def test_refund_amount_contains_debit_credit_indicator response = stub_comms do @gateway.refund(@amount, @options[:order_id], @options) - end.check_request do |endpoint, data, headers| - if data =~ // + end.check_request do |_endpoint, data, _headers| + if //.match?(data) request_hash = Hash.from_xml(data) assert_equal 'credit', request_hash['paymentService']['modify']['orderModification']['refund']['amount']['debitCreditIndicator'] end @@ -594,18 +698,69 @@ def test_failed_verify assert_failure response end + def test_empty_inst_id_is_stripped + stub_comms do + @gateway.authorize(@amount, @credit_card, @options.merge({ inst_id: '' })) + end.check_request do |_, data, _| + assert_not_match(/installationId/, data) + end.respond_with(successful_authorize_response) + end + def test_3ds_name_coersion @options[:execute_threed] = true response = stub_comms do @gateway.purchase(@amount, @credit_card, @options) - end.check_request do |endpoint, data, headers| - if // =~ data - assert_match %r{3D}, data - end + end.check_request do |_endpoint, data, _headers| + assert_match %r{3D}, data if //.match?(data) end.respond_with(successful_authorize_response, successful_capture_response) assert_success response end + def test_3ds_name_coersion_based_on_version + @options[:execute_threed] = true + @options[:three_ds_version] = '2.0' + response = stub_comms do + @gateway.purchase(@amount, @credit_card, @options) + end.check_request do |_endpoint, data, _headers| + assert_match %r{Longbob Longsen}, data if //.match?(data) + end.respond_with(successful_authorize_response, successful_capture_response) + assert_success response + + @options[:three_ds_version] = '2' + response = stub_comms do + @gateway.purchase(@amount, @credit_card, @options) + end.check_request do |_endpoint, data, _headers| + assert_match %r{Longbob Longsen}, data if //.match?(data) + end.respond_with(successful_authorize_response, successful_capture_response) + assert_success response + + @options[:three_ds_version] = '1.0.2' + response = stub_comms do + @gateway.purchase(@amount, @credit_card, @options) + end.check_request do |_endpoint, data, _headers| + assert_match %r{3D}, data if //.match?(data) + end.respond_with(successful_authorize_response, successful_capture_response) + assert_success response + end + + def test_3ds_additional_information + browser_size = '390x400' + session_id = '0215ui8ib1' + + options = @options.merge( + session_id: session_id, + browser_size: browser_size, + execute_threed: true, + three_ds_version: '2.0.1' + ) + + stub_comms do + @gateway.authorize(@amount, @credit_card, options) + end.check_request do |_endpoint, data, _headers| + assert_tag_with_attributes 'additional3DSData', { 'dfReferenceId' => session_id, 'challengeWindowSize' => browser_size }, data + end.respond_with(successful_authorize_response) + end + def test_transcript_scrubbing assert_equal scrubbed_transcript, @gateway.scrub(transcript) end @@ -613,7 +768,7 @@ def test_transcript_scrubbing def test_3ds_version_1_request stub_comms do @gateway.authorize(@amount, @credit_card, @options.merge(three_d_secure_option(version: '1.0.2', xid: 'xid'))) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match %r{}, data assert_match %r{eci}, data assert_match %r{cavv}, data @@ -625,7 +780,7 @@ def test_3ds_version_1_request def test_3ds_version_2_request stub_comms do @gateway.authorize(@amount, @credit_card, @options.merge(three_d_secure_option(version: '2.1.0', ds_transaction_id: 'ds_transaction_id'))) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match %r{}, data assert_match %r{eci}, data assert_match %r{cavv}, data @@ -661,7 +816,7 @@ def test_failed_verify_with_unknown_card def test_successful_store response = stub_comms do @gateway.store(@credit_card, @store_options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match %r(), data assert_match %r(), data assert_match %r(59424549c291397379f30c5c082dbed8), data @@ -679,10 +834,10 @@ def test_successful_store def test_successful_authorize_using_token response = stub_comms do @gateway.authorize(@amount, @token, @options) - end.check_request do |endpoint, data, headers| - assert_tag_with_attributes('order', {'orderCode' => @options[:order_id].to_s}, data) + end.check_request do |_endpoint, data, _headers| + assert_tag_with_attributes('order', { 'orderCode' => @options[:order_id].to_s }, data) assert_match %r(59424549c291397379f30c5c082dbed8), data - assert_tag_with_attributes 'TOKEN-SSL', {'tokenScope' => 'shopper'}, data + assert_tag_with_attributes 'TOKEN-SSL', { 'tokenScope' => 'shopper' }, data assert_match %r(99411111780163871111), data end.respond_with(successful_authorize_response) @@ -693,7 +848,7 @@ def test_successful_authorize_using_token def test_authorize_with_token_includes_shopper_using_minimal_options stub_comms do @gateway.authorize(@amount, @token, @options) - end.check_request do |endpoint, data, headers| + end.check_request do |_endpoint, data, _headers| assert_match %r(59424549c291397379f30c5c082dbed8), data end.respond_with(successful_authorize_response) end @@ -701,10 +856,8 @@ def test_authorize_with_token_includes_shopper_using_minimal_options def test_successful_purchase_using_token response = stub_comms do @gateway.purchase(@amount, @token, @options) - end.check_request do |endpoint, data, headers| - if %r() =~ data - assert_tag_with_attributes('order', {'orderCode' => @options[:order_id].to_s}, data) - end + end.check_request do |_endpoint, data, _headers| + assert_tag_with_attributes('order', { 'orderCode' => @options[:order_id].to_s }, data) if %r().match?(data) end.respond_with(successful_authorize_response, successful_capture_response) assert_success response @@ -714,10 +867,8 @@ def test_successful_purchase_using_token def test_successful_verify_using_token response = stub_comms do @gateway.verify(@token, @options) - end.check_request do |endpoint, data, headers| - if %r() =~ data - assert_tag_with_attributes('order', {'orderCode' => @options[:order_id].to_s}, data) - end + end.check_request do |_endpoint, data, _headers| + assert_tag_with_attributes('order', { 'orderCode' => @options[:order_id].to_s }, data) if %r().match?(data) end.respond_with(successful_authorize_response, successful_void_response) assert_success response @@ -727,11 +878,11 @@ def test_successful_verify_using_token def test_successful_credit_using_token response = stub_comms do @gateway.credit(@amount, @token, @options) - end.check_request do |endpoint, data, headers| - assert_tag_with_attributes('order', {'orderCode' => @options[:order_id].to_s}, data) + end.check_request do |_endpoint, data, _headers| + assert_tag_with_attributes('order', { 'orderCode' => @options[:order_id].to_s }, data) assert_match(//, data) assert_match %r(59424549c291397379f30c5c082dbed8), data - assert_tag_with_attributes 'TOKEN-SSL', {'tokenScope' => 'shopper'}, data + assert_tag_with_attributes 'TOKEN-SSL', { 'tokenScope' => 'shopper' }, data assert_match '99411111780163871111', data end.respond_with(successful_visa_credit_response) @@ -740,6 +891,16 @@ def test_successful_credit_using_token assert_equal '3d4187536044bd39ad6a289c4339c41c', response.authorization end + def test_optional_idempotency_key_header + response = stub_comms do + @gateway.authorize(@amount, @token, @options.merge({ idempotency_key: 'test123' })) + end.check_request do |_endpoint, _data, headers| + headers && headers['Idempotency-Key'] == 'test123' + end.respond_with(successful_authorize_response) + + assert_success response + end + def test_failed_store response = stub_comms do @gateway.store(@credit_card, @store_options.merge(customer: '_invalidId')) @@ -780,10 +941,10 @@ def test_authorize_order_id_not_overridden_by_order_id_of_token @token = 'wrong_order_id|99411111780163871111|shopper|59424549c291397379f30c5c082dbed8' response = stub_comms do @gateway.authorize(@amount, @token, @options) - end.check_request do |endpoint, data, headers| - assert_tag_with_attributes('order', {'orderCode' => @options[:order_id].to_s}, data) + end.check_request do |_endpoint, data, _headers| + assert_tag_with_attributes('order', { 'orderCode' => @options[:order_id].to_s }, data) assert_match %r(59424549c291397379f30c5c082dbed8), data - assert_tag_with_attributes 'TOKEN-SSL', {'tokenScope' => 'shopper'}, data + assert_tag_with_attributes 'TOKEN-SSL', { 'tokenScope' => 'shopper' }, data assert_match %r(99411111780163871111), data end.respond_with(successful_authorize_response) @@ -795,10 +956,8 @@ def test_purchase_order_id_not_overridden_by_order_id_of_token @token = 'wrong_order_id|99411111780163871111|shopper|59424549c291397379f30c5c082dbed8' response = stub_comms do @gateway.purchase(@amount, @token, @options) - end.check_request do |endpoint, data, headers| - if %r() =~ data - assert_tag_with_attributes('order', {'orderCode' => @options[:order_id].to_s}, data) - end + end.check_request do |_endpoint, data, _headers| + assert_tag_with_attributes('order', { 'orderCode' => @options[:order_id].to_s }, data) if %r().match?(data) end.respond_with(successful_authorize_response, successful_capture_response) assert_success response @@ -809,10 +968,8 @@ def test_verify_order_id_not_overridden_by_order_id_of_token @token = 'wrong_order_id|99411111780163871111|shopper|59424549c291397379f30c5c082dbed8' response = stub_comms do @gateway.verify(@token, @options) - end.check_request do |endpoint, data, headers| - if %r() =~ data - assert_tag_with_attributes('order', {'orderCode' => @options[:order_id].to_s}, data) - end + end.check_request do |_endpoint, data, _headers| + assert_tag_with_attributes('order', { 'orderCode' => @options[:order_id].to_s }, data) if %r().match?(data) end.respond_with(successful_authorize_response, successful_void_response) assert_success response @@ -823,11 +980,11 @@ def test_credit_order_id_not_overridden_by_order_if_of_token @token = 'wrong_order_id|99411111780163871111|shopper|59424549c291397379f30c5c082dbed8' response = stub_comms do @gateway.credit(@amount, @token, @options) - end.check_request do |endpoint, data, headers| - assert_tag_with_attributes('order', {'orderCode' => @options[:order_id].to_s}, data) + end.check_request do |_endpoint, data, _headers| + assert_tag_with_attributes('order', { 'orderCode' => @options[:order_id].to_s }, data) assert_match(//, data) assert_match %r(59424549c291397379f30c5c082dbed8), data - assert_tag_with_attributes 'TOKEN-SSL', {'tokenScope' => 'shopper'}, data + assert_tag_with_attributes 'TOKEN-SSL', { 'tokenScope' => 'shopper' }, data assert_match '99411111780163871111', data end.respond_with(successful_visa_credit_response) @@ -846,6 +1003,12 @@ def test_handles_plain_text_response private + def assert_date_element(expected_date_hash, date_element) + assert_equal(expected_date_hash[:day_of_month], date_element.attribute('dayOfMonth').value) + assert_equal(expected_date_hash[:month], date_element.attribute('month').value) + assert_equal(expected_date_hash[:year], date_element.attribute('year').value) + end + def assert_tag_with_attributes(tag, attributes, string) assert(m = %r(<#{tag}([^>]+)/?>).match(string)) attributes.each do |attribute, value| @@ -860,13 +1023,96 @@ def three_d_secure_option(version:, xid: nil, ds_transaction_id: nil) cavv: 'cavv', xid: xid, ds_transaction_id: ds_transaction_id, - version: version, + version: version + } + } + end + + def risk_data + return @risk_data if defined?(@risk_data) + + authentication_time = Time.now + shopper_account_creation_date = Date.today + shopper_account_modification_date = Date.today - 1.day + shopper_account_password_change_date = Date.today - 2.days + shopper_account_shipping_address_first_use_date = Date.today - 3.day + shopper_account_payment_account_first_use_date = Date.today - 4.day + transaction_risk_data_pre_order_date = Date.today + 1.day + + @risk_data = { + authentication_risk_data: { + authentication_method: 'localAccount', + authentication_date: { + day_of_month: authentication_time.strftime('%d'), + month: authentication_time.strftime('%m'), + year: authentication_time.strftime('%Y'), + hour: authentication_time.strftime('%H'), + minute: authentication_time.strftime('%M'), + second: authentication_time.strftime('%S') + } + }, + shopper_account_risk_data: { + transactions_attempted_last_day: '1', + transactions_attempted_last_year: '2', + purchases_completed_last_six_months: '3', + add_card_attempts_last_day: '4', + previous_suspicious_activity: 'false', # Boolean (true or false) + shipping_name_matches_account_name: 'true', # Boolean (true or false) + shopper_account_age_indicator: 'lessThanThirtyDays', # Possible Values: noAccount, createdDuringTransaction, lessThanThirtyDays, thirtyToSixtyDays, moreThanSixtyDays + shopper_account_change_indicator: 'thirtyToSixtyDays', # Possible values: changedDuringTransaction, lessThanThirtyDays, thirtyToSixtyDays, moreThanSixtyDays + shopper_account_password_change_indicator: 'noChange', # Possible Values: noChange, changedDuringTransaction, lessThanThirtyDays, thirtyToSixtyDays, moreThanSixtyDays + shopper_account_shipping_address_usage_indicator: 'moreThanSixtyDays', # Possible Values: thisTransaction, lessThanThirtyDays, thirtyToSixtyDays, moreThanSixtyDays + shopper_account_payment_account_indicator: 'thirtyToSixtyDays', # Possible Values: noAccount, duringTransaction, lessThanThirtyDays, thirtyToSixtyDays, moreThanSixtyDays + shopper_account_creation_date: { + day_of_month: shopper_account_creation_date.strftime('%d'), + month: shopper_account_creation_date.strftime('%m'), + year: shopper_account_creation_date.strftime('%Y') + }, + shopper_account_modification_date: { + day_of_month: shopper_account_modification_date.strftime('%d'), + month: shopper_account_modification_date.strftime('%m'), + year: shopper_account_modification_date.strftime('%Y') + }, + shopper_account_password_change_date: { + day_of_month: shopper_account_password_change_date.strftime('%d'), + month: shopper_account_password_change_date.strftime('%m'), + year: shopper_account_password_change_date.strftime('%Y') + }, + shopper_account_shipping_address_first_use_date: { + day_of_month: shopper_account_shipping_address_first_use_date.strftime('%d'), + month: shopper_account_shipping_address_first_use_date.strftime('%m'), + year: shopper_account_shipping_address_first_use_date.strftime('%Y') + }, + shopper_account_payment_account_first_use_date: { + day_of_month: shopper_account_payment_account_first_use_date.strftime('%d'), + month: shopper_account_payment_account_first_use_date.strftime('%m'), + year: shopper_account_payment_account_first_use_date.strftime('%Y') + } + }, + transaction_risk_data: { + shipping_method: 'digital', + delivery_timeframe: 'electronicDelivery', + delivery_email_address: 'abe@lincoln.gov', + reordering_previous_purchases: 'false', + pre_order_purchase: 'false', + gift_card_count: '0', + transaction_risk_data_gift_card_amount: { + value: '123', + currency: 'EUR', + exponent: '2', + debit_credit_indicator: 'credit' + }, + transaction_risk_data_pre_order_date: { + day_of_month: transaction_risk_data_pre_order_date.strftime('%d'), + month: transaction_risk_data_pre_order_date.strftime('%m'), + year: transaction_risk_data_pre_order_date.strftime('%Y') + } } } end def successful_authorize_response - <<-RESPONSE + <<~RESPONSE @@ -892,7 +1138,7 @@ def successful_authorize_response end def failed_authorize_response - <<-RESPONSE + <<~RESPONSE @@ -912,19 +1158,19 @@ def failed_authorize_response # more recent captured response from remote tests where the reply is # contained the error directly (no ) def failed_authorize_response_2 - <<-RESPONSE - - - - - - - + <<~RESPONSE + + + + + + + RESPONSE end def successful_capture_response - <<-RESPONSE + <<~RESPONSE @@ -941,7 +1187,7 @@ def successful_capture_response end def successful_authorize_with_elo_response - <<-RESPONSE + <<~RESPONSE @@ -966,7 +1212,7 @@ def successful_authorize_with_elo_response end def successful_capture_with_elo_response - <<-RESPONSE + <<~RESPONSE @@ -982,46 +1228,46 @@ def successful_capture_with_elo_response end def successful_void_inquiry_with_elo_response - <<-RESPONSE - - - - - - - ELO-SSL - - AUTHORISED - - - + <<~RESPONSE + + + + + + + ELO-SSL - - 4514********0008 - - - - - + AUTHORISED + + + + + + 4514********0008 + + + + + RESPONSE end def successful_void_with_elo_response - <<-RESPONSE - - - - - - - - - + <<~RESPONSE + + + + + + + + + RESPONSE end def successful_inquiry_response - <<-RESPONSE + <<~RESPONSE @@ -1048,7 +1294,7 @@ def successful_inquiry_response end def successful_void_inquiry_response - <<-RESPONSE + <<~RESPONSE @@ -1075,7 +1321,7 @@ def successful_void_inquiry_response end def successful_void_response - <<-RESPONSE + <<~RESPONSE @@ -1090,7 +1336,7 @@ def successful_void_response end def failed_void_inquiry_response - <<-RESPONSE + <<~RESPONSE @@ -1117,35 +1363,35 @@ def failed_void_inquiry_response RESPONSE end - def successful_refund_inquiry_response(last_event='CAPTURED') - <<-RESPONSE - - - - - - - VISA-SSL - - #{last_event} - - - - - - 4111********1111 - - - - - - + def successful_refund_inquiry_response(last_event = 'CAPTURED') + <<~RESPONSE + + + + + + + VISA-SSL + + #{last_event} + + + + + + 4111********1111 + + + + + + RESPONSE end def successful_refund_response - <<-RESPONSE + <<~RESPONSE @@ -1162,7 +1408,7 @@ def successful_refund_response end def failed_refund_inquiry_response - <<-RESPONSE + <<~RESPONSE @@ -1191,7 +1437,7 @@ def failed_refund_inquiry_response end def failed_void_response - <<-REQUEST + <<~REQUEST @@ -1207,7 +1453,7 @@ def failed_void_response end def successful_visa_credit_response - <<-RESPONSE + <<~RESPONSE @@ -1225,29 +1471,29 @@ def successful_visa_credit_response def successful_mastercard_credit_response <<~RESPONSE - - - - - - - ECMC_DEBIT-SSL - - SENT_FOR_REFUND - - - - - - - - + + + + + + + ECMC_DEBIT-SSL + + SENT_FOR_REFUND + + + + + + + + RESPONSE end def sample_authorization_request - <<-REQUEST + <<~REQUEST @@ -1293,134 +1539,134 @@ def sample_authorization_request end def transcript - <<-TRANSCRIPT - - - - Purchase - - - - 4111111111111111 - - - - Longbob Longsen - 123 - -
- N/A - 0000 - N/A - N/A - US -
-
-
-
- - wow@example.com - -
-
-
+ <<~TRANSCRIPT + + + + Purchase + + + + 4111111111111111 + + + + Longbob Longsen + 123 + +
+ N/A + 0000 + N/A + N/A + US +
+
+
+
+ + wow@example.com + +
+
+
TRANSCRIPT end def scrubbed_transcript - <<-TRANSCRIPT - - - - Purchase - - - - [FILTERED] - - - - Longbob Longsen - [FILTERED] - -
- N/A - 0000 - N/A - N/A - US -
-
-
-
- - wow@example.com - -
-
-
+ <<~TRANSCRIPT + + + + Purchase + + + + [FILTERED] + + + + Longbob Longsen + [FILTERED] + +
+ N/A + 0000 + N/A + N/A + US +
+
+
+
+ + wow@example.com + +
+
+
TRANSCRIPT end def failed_with_unknown_card_response - <<-RESPONSE - - - - - - - - - + <<~RESPONSE + + + + + + + + + RESPONSE end def successful_store_response - <<-RESPONSE - - - - - - 59424549c291397379f30c5c082dbed8 - - 99411111780163871111 - - - - Created token without payment on 2019-05-23 - - - - - - - - - VISA - VISA_CREDIT - N/A - TARGOBANK AG & CO. KGAA - 4111********1111 - - - - - - + <<~RESPONSE + + + + + + 59424549c291397379f30c5c082dbed8 + + 99411111780163871111 + + + + Created token without payment on 2019-05-23 + + + + + + + + + VISA + VISA_CREDIT + N/A + TARGOBANK AG & CO. KGAA + 4111********1111 + + + + + + RESPONSE end def failed_store_response - <<-RESPONSE - - - - - - - + <<~RESPONSE + + + + + + + RESPONSE end end diff --git a/test/unit/gateways/worldpay_us_test.rb b/test/unit/gateways/worldpay_us_test.rb index ee576daa591..65040db2915 100644 --- a/test/unit/gateways/worldpay_us_test.rb +++ b/test/unit/gateways/worldpay_us_test.rb @@ -67,7 +67,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(/postonly=354275517/, data) end.respond_with(successful_capture_response) @@ -84,7 +84,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(/historykeyid=353583515/, data) assert_match(/orderkeyid=252889136/, data) end.respond_with(successful_refund_response) @@ -102,7 +102,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(/historykeyid=353583515/, data) assert_match(/orderkeyid=252889136/, data) end.respond_with(successful_refund_response) @@ -136,15 +136,15 @@ def test_unsuccessful_verify 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(/ci_billaddr1=456\+My\+Street/, data) assert_match(/ci_billzip=K1C2N6/, data) end.respond_with(successful_purchase_response) @@ -152,16 +152,16 @@ def test_passing_billing_address def test_passing_phone_number 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(/ci_phone=%28555%29555-5555/, data) end.respond_with(successful_purchase_response) end def test_passing_billing_address_without_phone stub_comms do - @gateway.purchase(@amount, @credit_card, :billing_address => address(:phone => nil)) - end.check_request do |endpoint, data, headers| + @gateway.purchase(@amount, @credit_card, billing_address: address(phone: nil)) + end.check_request do |_endpoint, data, _headers| assert_no_match(/udf3/, data) end.respond_with(successful_purchase_response) end @@ -178,7 +178,7 @@ def test_empty_response_fails def test_backup_url response = stub_comms(@gateway) do @gateway.purchase(@amount, @credit_card, use_backup_url: true) - end.check_request do |endpoint, data, headers| + end.check_request do |endpoint, _data, _headers| assert_equal WorldpayUsGateway.backup_url, endpoint end.respond_with(successful_purchase_response) assert_success response @@ -436,94 +436,94 @@ def failed_void_response end def pre_scrubbed - <<-EOS -opening connection to trans.worldpay.us:443... -opened -starting SSL for trans.worldpay.us:443... -SSL established -<- "POST /cgi-bin/process.cgi 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: trans.worldpay.us\r\nContent-Length: 425\r\n\r\n" -<- "acctid=MPNAB&action=ns_quicksale_cc&amount=1.00&ccname=Longbob+Longsen&ccnum=4446661234567892&ci_billaddr1=456+My+Street&ci_billaddr2=Apt+1&ci_billcity=Ottawa&ci_billcountry=CA&ci_billstate=ON&ci_billzip=K1C2N6&ci_companyname=Widgets+Inc&ci_email=&ci_ipaddress=&ci_phone=%28555%29555-5555¤cycode=USD&cvv2=987&expmon=09&expyear=2019&merchantordernumber=67f4f20082e79684f036f25dafe96304&merchantpin=1234567890&subid=SPREE" --> "HTTP/1.1 200 OK\r\n" --> "Date: Tue, 13 Feb 2018 19:28:27 GMT\r\n" --> "Server: Apache\r\n" --> "X-Frame-Options: SAMEORIGIN\r\n" --> "Content-Type: text/html;charset=ISO-8859-1\r\n" --> "Content-Length: 962\r\n" --> "Connection: close\r\n" --> "\r\n" -reading 962 bytes... --> "\r\nAccepted=SALE:036586:477::919067116:N::N\r\nhistoryid=919067116\r\norderid=722189706\r\nAccepted=SALE:036586:477::919067116:N::N\r\nACCOUNTNUMBER=************7892\r\nACCTID=MPNAB\r\nauthcode=036586\r\nAuthNo=SALE:036586:477::919067116:N::N\r\nAVS_RESULT=N\r\nBATCHNUMBER=\r\nCVV2_RESULT=N\r\nDEBIT_TRACE_NUMBER=\r\nENTRYMETHOD=M\r\nhistoryid=919067116\r\nMERCHANT_DBA_ADDR=11121 Willows Road NE\r\nMERCHANT_DBA_CITY=Redmond\r\nMERCHANT_DBA_NAME=Merchant Partners\r\nMERCHANT_DBA_PHONE=4254979909\r\nMERCHANT_DBA_STATE=WA\r\nMERCHANTID=542929804946788\r\nMERCHANTORDERNUMBER=67f4f20082e79684f036f25dafe96304\r\norderid=722189706\r\nPAYTYPE=Visa\r\nPRODUCT_DESCRIPTION=\r\nReason=\r\nRECEIPT_FOOTER=Thank You\r\nrecurid=0\r\nrefcode=919067116-036586\r\nresult=1\r\nSEQUENCE_NUMBER=370609730\r\nStatus=Accepted\r\nSUBID=SPREE\r\nSYSTEMAUDITTRACENUMBER=477\r\nTERMINALID=160551\r\nTRANSGUID=d5701d57-9147-4ded-b596-6805581f081c:266\r\ntransid=370609730\r\ntransresult=APPROVED\r\nVISATRANSACTIONID=088044000036586\r\n" -read 962 bytes -Conn close - EOS + <<~REQUEST + opening connection to trans.worldpay.us:443... + opened + starting SSL for trans.worldpay.us:443... + SSL established + <- "POST /cgi-bin/process.cgi 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: trans.worldpay.us\r\nContent-Length: 425\r\n\r\n" + <- "acctid=MPNAB&action=ns_quicksale_cc&amount=1.00&ccname=Longbob+Longsen&ccnum=4446661234567892&ci_billaddr1=456+My+Street&ci_billaddr2=Apt+1&ci_billcity=Ottawa&ci_billcountry=CA&ci_billstate=ON&ci_billzip=K1C2N6&ci_companyname=Widgets+Inc&ci_email=&ci_ipaddress=&ci_phone=%28555%29555-5555&currencycode=USD&cvv2=987&expmon=09&expyear=2019&merchantordernumber=67f4f20082e79684f036f25dafe96304&merchantpin=1234567890&subid=SPREE" + -> "HTTP/1.1 200 OK\r\n" + -> "Date: Tue, 13 Feb 2018 19:28:27 GMT\r\n" + -> "Server: Apache\r\n" + -> "X-Frame-Options: SAMEORIGIN\r\n" + -> "Content-Type: text/html;charset=ISO-8859-1\r\n" + -> "Content-Length: 962\r\n" + -> "Connection: close\r\n" + -> "\r\n" + reading 962 bytes... + -> "<html><body><plaintext>\r\nAccepted=SALE:036586:477::919067116:N::N\r\nhistoryid=919067116\r\norderid=722189706\r\nAccepted=SALE:036586:477::919067116:N::N\r\nACCOUNTNUMBER=************7892\r\nACCTID=MPNAB\r\nauthcode=036586\r\nAuthNo=SALE:036586:477::919067116:N::N\r\nAVS_RESULT=N\r\nBATCHNUMBER=\r\nCVV2_RESULT=N\r\nDEBIT_TRACE_NUMBER=\r\nENTRYMETHOD=M\r\nhistoryid=919067116\r\nMERCHANT_DBA_ADDR=11121 Willows Road NE\r\nMERCHANT_DBA_CITY=Redmond\r\nMERCHANT_DBA_NAME=Merchant Partners\r\nMERCHANT_DBA_PHONE=4254979909\r\nMERCHANT_DBA_STATE=WA\r\nMERCHANTID=542929804946788\r\nMERCHANTORDERNUMBER=67f4f20082e79684f036f25dafe96304\r\norderid=722189706\r\nPAYTYPE=Visa\r\nPRODUCT_DESCRIPTION=\r\nReason=\r\nRECEIPT_FOOTER=Thank You\r\nrecurid=0\r\nrefcode=919067116-036586\r\nresult=1\r\nSEQUENCE_NUMBER=370609730\r\nStatus=Accepted\r\nSUBID=SPREE\r\nSYSTEMAUDITTRACENUMBER=477\r\nTERMINALID=160551\r\nTRANSGUID=d5701d57-9147-4ded-b596-6805581f081c:266\r\ntransid=370609730\r\ntransresult=APPROVED\r\nVISATRANSACTIONID=088044000036586\r\n" + read 962 bytes + Conn close + REQUEST end def post_scrubbed - <<-EOS -opening connection to trans.worldpay.us:443... -opened -starting SSL for trans.worldpay.us:443... -SSL established -<- "POST /cgi-bin/process.cgi 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: trans.worldpay.us\r\nContent-Length: 425\r\n\r\n" -<- "acctid=MPNAB&action=ns_quicksale_cc&amount=1.00&ccname=Longbob+Longsen&ccnum=[FILTERED]&ci_billaddr1=456+My+Street&ci_billaddr2=Apt+1&ci_billcity=Ottawa&ci_billcountry=CA&ci_billstate=ON&ci_billzip=K1C2N6&ci_companyname=Widgets+Inc&ci_email=&ci_ipaddress=&ci_phone=%28555%29555-5555&currencycode=USD&cvv2=[FILTERED]&expmon=09&expyear=2019&merchantordernumber=67f4f20082e79684f036f25dafe96304&merchantpin=[FILTERED]&subid=SPREE" --> "HTTP/1.1 200 OK\r\n" --> "Date: Tue, 13 Feb 2018 19:28:27 GMT\r\n" --> "Server: Apache\r\n" --> "X-Frame-Options: SAMEORIGIN\r\n" --> "Content-Type: text/html;charset=ISO-8859-1\r\n" --> "Content-Length: 962\r\n" --> "Connection: close\r\n" --> "\r\n" -reading 962 bytes... --> "<html><body><plaintext>\r\nAccepted=SALE:036586:477::919067116:N::N\r\nhistoryid=919067116\r\norderid=722189706\r\nAccepted=SALE:036586:477::919067116:N::N\r\nACCOUNTNUMBER=************7892\r\nACCTID=MPNAB\r\nauthcode=036586\r\nAuthNo=SALE:036586:477::919067116:N::N\r\nAVS_RESULT=N\r\nBATCHNUMBER=\r\nCVV2_RESULT=N\r\nDEBIT_TRACE_NUMBER=\r\nENTRYMETHOD=M\r\nhistoryid=919067116\r\nMERCHANT_DBA_ADDR=11121 Willows Road NE\r\nMERCHANT_DBA_CITY=Redmond\r\nMERCHANT_DBA_NAME=Merchant Partners\r\nMERCHANT_DBA_PHONE=4254979909\r\nMERCHANT_DBA_STATE=WA\r\nMERCHANTID=542929804946788\r\nMERCHANTORDERNUMBER=67f4f20082e79684f036f25dafe96304\r\norderid=722189706\r\nPAYTYPE=Visa\r\nPRODUCT_DESCRIPTION=\r\nReason=\r\nRECEIPT_FOOTER=Thank You\r\nrecurid=0\r\nrefcode=919067116-036586\r\nresult=1\r\nSEQUENCE_NUMBER=370609730\r\nStatus=Accepted\r\nSUBID=SPREE\r\nSYSTEMAUDITTRACENUMBER=477\r\nTERMINALID=160551\r\nTRANSGUID=d5701d57-9147-4ded-b596-6805581f081c:266\r\ntransid=370609730\r\ntransresult=APPROVED\r\nVISATRANSACTIONID=088044000036586\r\n" -read 962 bytes -Conn close - EOS + <<~REQUEST + opening connection to trans.worldpay.us:443... + opened + starting SSL for trans.worldpay.us:443... + SSL established + <- "POST /cgi-bin/process.cgi 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: trans.worldpay.us\r\nContent-Length: 425\r\n\r\n" + <- "acctid=MPNAB&action=ns_quicksale_cc&amount=1.00&ccname=Longbob+Longsen&ccnum=[FILTERED]&ci_billaddr1=456+My+Street&ci_billaddr2=Apt+1&ci_billcity=Ottawa&ci_billcountry=CA&ci_billstate=ON&ci_billzip=K1C2N6&ci_companyname=Widgets+Inc&ci_email=&ci_ipaddress=&ci_phone=%28555%29555-5555&currencycode=USD&cvv2=[FILTERED]&expmon=09&expyear=2019&merchantordernumber=67f4f20082e79684f036f25dafe96304&merchantpin=[FILTERED]&subid=SPREE" + -> "HTTP/1.1 200 OK\r\n" + -> "Date: Tue, 13 Feb 2018 19:28:27 GMT\r\n" + -> "Server: Apache\r\n" + -> "X-Frame-Options: SAMEORIGIN\r\n" + -> "Content-Type: text/html;charset=ISO-8859-1\r\n" + -> "Content-Length: 962\r\n" + -> "Connection: close\r\n" + -> "\r\n" + reading 962 bytes... + -> "<html><body><plaintext>\r\nAccepted=SALE:036586:477::919067116:N::N\r\nhistoryid=919067116\r\norderid=722189706\r\nAccepted=SALE:036586:477::919067116:N::N\r\nACCOUNTNUMBER=************7892\r\nACCTID=MPNAB\r\nauthcode=036586\r\nAuthNo=SALE:036586:477::919067116:N::N\r\nAVS_RESULT=N\r\nBATCHNUMBER=\r\nCVV2_RESULT=N\r\nDEBIT_TRACE_NUMBER=\r\nENTRYMETHOD=M\r\nhistoryid=919067116\r\nMERCHANT_DBA_ADDR=11121 Willows Road NE\r\nMERCHANT_DBA_CITY=Redmond\r\nMERCHANT_DBA_NAME=Merchant Partners\r\nMERCHANT_DBA_PHONE=4254979909\r\nMERCHANT_DBA_STATE=WA\r\nMERCHANTID=542929804946788\r\nMERCHANTORDERNUMBER=67f4f20082e79684f036f25dafe96304\r\norderid=722189706\r\nPAYTYPE=Visa\r\nPRODUCT_DESCRIPTION=\r\nReason=\r\nRECEIPT_FOOTER=Thank You\r\nrecurid=0\r\nrefcode=919067116-036586\r\nresult=1\r\nSEQUENCE_NUMBER=370609730\r\nStatus=Accepted\r\nSUBID=SPREE\r\nSYSTEMAUDITTRACENUMBER=477\r\nTERMINALID=160551\r\nTRANSGUID=d5701d57-9147-4ded-b596-6805581f081c:266\r\ntransid=370609730\r\ntransresult=APPROVED\r\nVISATRANSACTIONID=088044000036586\r\n" + read 962 bytes + Conn close + REQUEST end def pre_scrubbed_check - <<-EOS -opening connection to trans.worldpay.us:443... -opened -starting SSL for trans.worldpay.us:443... -SSL established -<- "POST /cgi-bin/process.cgi 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: trans.worldpay.us\r\nContent-Length: 412\r\n\r\n" -<- "acctid=MPNAB&action=ns_quicksale_check&amount=1.00&ci_billaddr1=456+My+Street&ci_billaddr2=Apt+1&ci_billcity=Ottawa&ci_billcountry=CA&ci_billstate=ON&ci_billzip=K1C2N6&ci_companyname=Widgets+Inc&ci_email=&ci_ipaddress=&ci_phone=%28555%29555-5555&ckaba=244183602&ckacct=15378535&ckaccttype=1&ckno=12345654321&currencycode=USD&merchantordernumber=5ec80ff8210dc9d24248ac2777d6b4f3&merchantpin=1234567890&subid=SPREE" --> "HTTP/1.1 200 OK\r\n" --> "Date: Tue, 13 Feb 2018 19:29:38 GMT\r\n" --> "Server: Apache\r\n" --> "X-Frame-Options: SAMEORIGIN\r\n" --> "Content-Type: text/html;charset=ISO-8859-1\r\n" --> "Content-Length: 414\r\n" --> "Connection: close\r\n" --> "\r\n" -reading 414 bytes... --> "<html><body><plaintext>\r\nDeclined=DECLINED:1103180001:Invalid Bank:\r\nhistoryid=919060608\r\norderid=722196666\r\nACCOUNTNUMBER=****8535\r\nDeclined=DECLINED:1103180001:Invalid Bank:\r\nENTRYMETHOD=KEYED\r\nhistoryid=919060608\r\nMERCHANTORDERNUMBER=5ec80ff8210dc9d24248ac2777d6b4f3\r\norderid=722196666\r\nPAYTYPE=Check\r\nrcode=1103180001\r\nReason=DECLINED:1103180001:Invalid Bank:\r\nrecurid=0\r\nresult=0\r\nStatus=Declined\r\ntransid=0\r\n" -read 414 bytes -Conn close - EOS + <<~REQUEST + opening connection to trans.worldpay.us:443... + opened + starting SSL for trans.worldpay.us:443... + SSL established + <- "POST /cgi-bin/process.cgi 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: trans.worldpay.us\r\nContent-Length: 412\r\n\r\n" + <- "acctid=MPNAB&action=ns_quicksale_check&amount=1.00&ci_billaddr1=456+My+Street&ci_billaddr2=Apt+1&ci_billcity=Ottawa&ci_billcountry=CA&ci_billstate=ON&ci_billzip=K1C2N6&ci_companyname=Widgets+Inc&ci_email=&ci_ipaddress=&ci_phone=%28555%29555-5555&ckaba=244183602&ckacct=15378535&ckaccttype=1&ckno=12345654321&currencycode=USD&merchantordernumber=5ec80ff8210dc9d24248ac2777d6b4f3&merchantpin=1234567890&subid=SPREE" + -> "HTTP/1.1 200 OK\r\n" + -> "Date: Tue, 13 Feb 2018 19:29:38 GMT\r\n" + -> "Server: Apache\r\n" + -> "X-Frame-Options: SAMEORIGIN\r\n" + -> "Content-Type: text/html;charset=ISO-8859-1\r\n" + -> "Content-Length: 414\r\n" + -> "Connection: close\r\n" + -> "\r\n" + reading 414 bytes... + -> "<html><body><plaintext>\r\nDeclined=DECLINED:1103180001:Invalid Bank:\r\nhistoryid=919060608\r\norderid=722196666\r\nACCOUNTNUMBER=****8535\r\nDeclined=DECLINED:1103180001:Invalid Bank:\r\nENTRYMETHOD=KEYED\r\nhistoryid=919060608\r\nMERCHANTORDERNUMBER=5ec80ff8210dc9d24248ac2777d6b4f3\r\norderid=722196666\r\nPAYTYPE=Check\r\nrcode=1103180001\r\nReason=DECLINED:1103180001:Invalid Bank:\r\nrecurid=0\r\nresult=0\r\nStatus=Declined\r\ntransid=0\r\n" + read 414 bytes + Conn close + REQUEST end def post_scrubbed_check - <<-EOS -opening connection to trans.worldpay.us:443... -opened -starting SSL for trans.worldpay.us:443... -SSL established -<- "POST /cgi-bin/process.cgi 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: trans.worldpay.us\r\nContent-Length: 412\r\n\r\n" -<- "acctid=MPNAB&action=ns_quicksale_check&amount=1.00&ci_billaddr1=456+My+Street&ci_billaddr2=Apt+1&ci_billcity=Ottawa&ci_billcountry=CA&ci_billstate=ON&ci_billzip=K1C2N6&ci_companyname=Widgets+Inc&ci_email=&ci_ipaddress=&ci_phone=%28555%29555-5555&ckaba=244183602&ckacct=[FILTERED]&ckaccttype=1&ckno=12345654321&currencycode=USD&merchantordernumber=5ec80ff8210dc9d24248ac2777d6b4f3&merchantpin=[FILTERED]&subid=SPREE" --> "HTTP/1.1 200 OK\r\n" --> "Date: Tue, 13 Feb 2018 19:29:38 GMT\r\n" --> "Server: Apache\r\n" --> "X-Frame-Options: SAMEORIGIN\r\n" --> "Content-Type: text/html;charset=ISO-8859-1\r\n" --> "Content-Length: 414\r\n" --> "Connection: close\r\n" --> "\r\n" -reading 414 bytes... --> "<html><body><plaintext>\r\nDeclined=DECLINED:1103180001:Invalid Bank:\r\nhistoryid=919060608\r\norderid=722196666\r\nACCOUNTNUMBER=****8535\r\nDeclined=DECLINED:1103180001:Invalid Bank:\r\nENTRYMETHOD=KEYED\r\nhistoryid=919060608\r\nMERCHANTORDERNUMBER=5ec80ff8210dc9d24248ac2777d6b4f3\r\norderid=722196666\r\nPAYTYPE=Check\r\nrcode=1103180001\r\nReason=DECLINED:1103180001:Invalid Bank:\r\nrecurid=0\r\nresult=0\r\nStatus=Declined\r\ntransid=0\r\n" -read 414 bytes -Conn close - EOS + <<~REQUEST + opening connection to trans.worldpay.us:443... + opened + starting SSL for trans.worldpay.us:443... + SSL established + <- "POST /cgi-bin/process.cgi 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: trans.worldpay.us\r\nContent-Length: 412\r\n\r\n" + <- "acctid=MPNAB&action=ns_quicksale_check&amount=1.00&ci_billaddr1=456+My+Street&ci_billaddr2=Apt+1&ci_billcity=Ottawa&ci_billcountry=CA&ci_billstate=ON&ci_billzip=K1C2N6&ci_companyname=Widgets+Inc&ci_email=&ci_ipaddress=&ci_phone=%28555%29555-5555&ckaba=244183602&ckacct=[FILTERED]&ckaccttype=1&ckno=12345654321&currencycode=USD&merchantordernumber=5ec80ff8210dc9d24248ac2777d6b4f3&merchantpin=[FILTERED]&subid=SPREE" + -> "HTTP/1.1 200 OK\r\n" + -> "Date: Tue, 13 Feb 2018 19:29:38 GMT\r\n" + -> "Server: Apache\r\n" + -> "X-Frame-Options: SAMEORIGIN\r\n" + -> "Content-Type: text/html;charset=ISO-8859-1\r\n" + -> "Content-Length: 414\r\n" + -> "Connection: close\r\n" + -> "\r\n" + reading 414 bytes... + -> "<html><body><plaintext>\r\nDeclined=DECLINED:1103180001:Invalid Bank:\r\nhistoryid=919060608\r\norderid=722196666\r\nACCOUNTNUMBER=****8535\r\nDeclined=DECLINED:1103180001:Invalid Bank:\r\nENTRYMETHOD=KEYED\r\nhistoryid=919060608\r\nMERCHANTORDERNUMBER=5ec80ff8210dc9d24248ac2777d6b4f3\r\norderid=722196666\r\nPAYTYPE=Check\r\nrcode=1103180001\r\nReason=DECLINED:1103180001:Invalid Bank:\r\nrecurid=0\r\nresult=0\r\nStatus=Declined\r\ntransid=0\r\n" + read 414 bytes + Conn close + REQUEST end end diff --git a/test/unit/multi_response_test.rb b/test/unit/multi_response_test.rb index a60062d0003..2304bbb9a34 100644 --- a/test/unit/multi_response_test.rb +++ b/test/unit/multi_response_test.rb @@ -34,16 +34,16 @@ def test_proxies_last_request r1 = Response.new( true, '1', - {'one' => 1}, - :test => true, - :authorization => 'auth1', - :avs_result => {:code => 'AVS1'}, - :cvv_result => 'CVV1', - :error_code => :card_declined, - :fraud_review => true + { 'one' => 1 }, + test: true, + authorization: 'auth1', + avs_result: { code: 'AVS1' }, + cvv_result: 'CVV1', + error_code: :card_declined, + fraud_review: true ) m.process { r1 } - assert_equal({'one' => 1}, m.params) + assert_equal({ 'one' => 1 }, m.params) assert_equal '1', m.message assert m.test assert_equal 'auth1', m.authorization @@ -56,15 +56,15 @@ def test_proxies_last_request r2 = Response.new( true, '2', - {'two' => 2}, - :test => false, - :authorization => 'auth2', - :avs_result => {:code => 'AVS2'}, - :cvv_result => 'CVV2', - :fraud_review => false + { 'two' => 2 }, + test: false, + authorization: 'auth2', + avs_result: { code: 'AVS2' }, + cvv_result: 'CVV2', + fraud_review: false ) m.process { r2 } - assert_equal({'two' => 2}, m.params) + assert_equal({ 'two' => 2 }, m.params) assert_equal '2', m.message assert !m.test assert_equal 'auth2', m.authorization @@ -80,15 +80,15 @@ def test_proxies_first_request_if_marked r1 = Response.new( true, '1', - {'one' => 1}, - :test => true, - :authorization => 'auth1', - :avs_result => {:code => 'AVS1'}, - :cvv_result => 'CVV1', - :fraud_review => true + { 'one' => 1 }, + test: true, + authorization: 'auth1', + avs_result: { code: 'AVS1' }, + cvv_result: 'CVV1', + fraud_review: true ) m.process { r1 } - assert_equal({'one' => 1}, m.params) + assert_equal({ 'one' => 1 }, m.params) assert_equal '1', m.message assert m.test assert_equal 'auth1', m.authorization @@ -100,15 +100,15 @@ def test_proxies_first_request_if_marked r2 = Response.new( true, '2', - {'two' => 2}, - :test => false, - :authorization => 'auth2', - :avs_result => {:code => 'AVS2'}, - :cvv_result => 'CVV2', - :fraud_review => false + { 'two' => 2 }, + test: false, + authorization: 'auth2', + avs_result: { code: 'AVS2' }, + cvv_result: 'CVV2', + fraud_review: false ) m.process { r2 } - assert_equal({'one' => 1}, m.params) + assert_equal({ 'one' => 1 }, m.params) assert_equal '1', m.message assert m.test assert_equal 'auth1', m.authorization diff --git a/test/unit/network_connection_retries_test.rb b/test/unit/network_connection_retries_test.rb index 49ce4b3d8e6..97cb306e233 100644 --- a/test/unit/network_connection_retries_test.rb +++ b/test/unit/network_connection_retries_test.rb @@ -9,7 +9,7 @@ class MyNewError < StandardError def setup @logger = stubs(:logger) @requester = stubs(:requester) - @ok = stub(:code => 200, :message => 'OK', :body => 'success') + @ok = stub(code: 200, message: 'OK', body: 'success') end def test_eoferror_raises_correctly @@ -78,7 +78,7 @@ def test_invalid_response_error def test_unrecoverable_exception_logged_if_logger_provided @logger.expects(:info).once assert_raises(ActiveMerchant::ConnectionError) do - retry_exceptions :logger => @logger do + retry_exceptions logger: @logger do raise EOFError end end @@ -107,7 +107,7 @@ def test_failure_limit_reached_logs_final_error @requester.expects(:post).times(ActiveMerchant::NetworkConnectionRetries::DEFAULT_RETRIES).raises(Errno::ECONNREFUSED) assert_raises(ActiveMerchant::ConnectionError) do - retry_exceptions(:logger => @logger) do + retry_exceptions(logger: @logger) do @requester.post end end @@ -116,7 +116,7 @@ def test_failure_limit_reached_logs_final_error def test_failure_then_success_with_retry_safe_enabled @requester.expects(:post).times(2).raises(EOFError).then.returns(@ok) - retry_exceptions :retry_safe => true do + retry_exceptions retry_safe: true do @requester.post end end @@ -126,7 +126,7 @@ def test_failure_then_success_logs_success @logger.expects(:info).with(regexp_matches(/success/)) @requester.expects(:post).times(2).raises(EOFError).then.returns(@ok) - retry_exceptions(:logger => @logger, :retry_safe => true) do + retry_exceptions(logger: @logger, retry_safe: true) do @requester.post end end @@ -140,7 +140,7 @@ def test_mixture_of_failures_with_retry_safe_enabled raises(EOFError) assert_raises(ActiveMerchant::ConnectionError) do - retry_exceptions :retry_safe => true do + retry_exceptions retry_safe: true do @requester.post end end @@ -161,7 +161,7 @@ def test_failure_with_ssl_certificate_logs_error_if_logger_specified @requester.expects(:post).raises(OpenSSL::X509::CertificateError) assert_raises(ActiveMerchant::ClientCertificateError) do - retry_exceptions :logger => @logger do + retry_exceptions logger: @logger do @requester.post end end @@ -171,7 +171,7 @@ def test_failure_with_additional_exceptions_specified @requester.expects(:post).raises(MyNewError) assert_raises(ActiveMerchant::ConnectionError) do - retry_exceptions :connection_exceptions => {MyNewError => 'my message'} do + retry_exceptions connection_exceptions: { MyNewError => 'my message' } do @requester.post end end diff --git a/test/unit/network_tokenization_credit_card_test.rb b/test/unit/network_tokenization_credit_card_test.rb index a5ac80e822d..a5808a8fcae 100644 --- a/test/unit/network_tokenization_credit_card_test.rb +++ b/test/unit/network_tokenization_credit_card_test.rb @@ -1,10 +1,9 @@ require 'test_helper' class NetworkTokenizationCreditCardTest < Test::Unit::TestCase - def setup @tokenized_card = ActiveMerchant::Billing::NetworkTokenizationCreditCard.new({ - number: '4242424242424242', :brand => 'visa', + number: '4242424242424242', brand: 'visa', month: default_expiration_date.month, year: default_expiration_date.year, payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', eci: '05' }) @@ -17,6 +16,9 @@ def setup @tokenized_google_pay_card = ActiveMerchant::Billing::NetworkTokenizationCreditCard.new({ source: :google_pay }) + @existing_network_token = ActiveMerchant::Billing::NetworkTokenizationCreditCard.new({ + source: :network_token + }) @tokenized_bogus_pay_card = ActiveMerchant::Billing::NetworkTokenizationCreditCard.new({ source: :bogus_pay }) @@ -44,5 +46,6 @@ def test_source assert_equal @tokenized_android_pay_card.source, :android_pay assert_equal @tokenized_google_pay_card.source, :google_pay assert_equal @tokenized_bogus_pay_card.source, :apple_pay + assert_equal @existing_network_token.source, :network_token end end diff --git a/test/unit/post_data_test.rb b/test/unit/post_data_test.rb index dd22426f862..5d6b265b28b 100644 --- a/test/unit/post_data_test.rb +++ b/test/unit/post_data_test.rb @@ -1,7 +1,7 @@ require 'test_helper' class MyPost < ActiveMerchant::PostData - self.required_fields = [ :ccnumber, :ccexp, :firstname, :lastname, :username, :password, :order_id, :key, :time ] + self.required_fields = %i[ccnumber ccexp firstname lastname username password order_id key time] end class PostDataTest < Test::Unit::TestCase @@ -29,7 +29,7 @@ def test_ignore_blank_fields end def test_dont_ignore_required_blank_fields - ActiveMerchant::PostData.required_fields = [ :name ] + ActiveMerchant::PostData.required_fields = [:name] post = ActiveMerchant::PostData.new assert_equal 0, post.keys.size @@ -45,6 +45,6 @@ def test_dont_ignore_required_blank_fields def test_subclass post = MyPost.new - assert_equal [ :ccnumber, :ccexp, :firstname, :lastname, :username, :password, :order_id, :key, :time ], post.required_fields + assert_equal %i[ccnumber ccexp firstname lastname username password order_id key time], post.required_fields end end diff --git a/test/unit/posts_data_test.rb b/test/unit/posts_data_test.rb index 960992cd0d4..58de35f5d6c 100644 --- a/test/unit/posts_data_test.rb +++ b/test/unit/posts_data_test.rb @@ -1,12 +1,11 @@ require 'test_helper' class PostsDataTests < Test::Unit::TestCase - def setup @url = 'http://example.com' @gateway = SimpleTestGateway.new - @ok = stub(:body => '', :code => '200', :message => 'OK') - @error = stub(:code => 500, :message => 'Internal Server Error', :body => 'failure') + @ok = stub(body: '', code: '200', message: 'OK') + @error = stub(code: 500, message: 'Internal Server Error', body: 'failure') end def teardown diff --git a/test/unit/rails_compatibility_test.rb b/test/unit/rails_compatibility_test.rb index addcb3ec701..ebcbaaf4a72 100644 --- a/test/unit/rails_compatibility_test.rb +++ b/test/unit/rails_compatibility_test.rb @@ -2,7 +2,7 @@ class RailsCompatibilityTest < Test::Unit::TestCase def test_should_be_able_to_access_errors_indifferently - cc = credit_card('4779139500118580', :first_name => '') + cc = credit_card('4779139500118580', first_name: '') silence_deprecation_warnings do assert !cc.valid? diff --git a/test/unit/response_test.rb b/test/unit/response_test.rb index 716d14d7619..a5ed17e5d47 100644 --- a/test/unit/response_test.rb +++ b/test/unit/response_test.rb @@ -2,35 +2,35 @@ class ResponseTest < Test::Unit::TestCase def test_response_success - assert Response.new(true, 'message', :param => 'value').success? - assert !Response.new(false, 'message', :param => 'value').success? + assert Response.new(true, 'message', param: 'value').success? + assert !Response.new(false, 'message', param: 'value').success? end def test_response_without_avs - response = Response.new(true, 'message', :param => 'value') + response = Response.new(true, 'message', param: 'value') assert response.avs_result.has_key?('code') end def test_response_without_cvv - response = Response.new(true, 'message', :param => 'value') + response = Response.new(true, 'message', param: 'value') assert response.cvv_result.has_key?('code') end def test_get_params - response = Response.new(true, 'message', :param => 'value') + response = Response.new(true, 'message', param: 'value') assert_equal ['param'], response.params.keys end def test_avs_result - response = Response.new(true, 'message', {}, :avs_result => { :code => 'A', :street_match => 'Y', :zip_match => 'N' }) + response = Response.new(true, 'message', {}, avs_result: { code: 'A', street_match: 'Y', zip_match: 'N' }) avs_result = response.avs_result assert_equal 'A', avs_result['code'] assert_equal AVSResult.messages['A'], avs_result['message'] end def test_cvv_result - response = Response.new(true, 'message', {}, :cvv_result => 'M') + response = Response.new(true, 'message', {}, cvv_result: 'M') cvv_result = response.cvv_result assert_equal 'M', cvv_result['code'] assert_equal CVVResult.messages['M'], cvv_result['message']