workarea-kount 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +20 -0
  3. data/.eslintrc +24 -0
  4. data/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
  5. data/.github/ISSUE_TEMPLATE/documentation-request.md +17 -0
  6. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  7. data/.github/workflows/ci.yml +58 -0
  8. data/.gitignore +14 -0
  9. data/.rubocop.yml +2 -0
  10. data/CHANGELOG.md +212 -0
  11. data/CODE_OF_CONDUCT.md +3 -0
  12. data/CONTRIBUTING.md +3 -0
  13. data/Gemfile +17 -0
  14. data/LICENSE.md +3 -0
  15. data/README.md +98 -0
  16. data/Rakefile +53 -0
  17. data/app/controllers/workarea/admin/orders_controller.decorator +5 -0
  18. data/app/controllers/workarea/storefront/checkout/place_order_controller.decorator +11 -0
  19. data/app/controllers/workarea/storefront/kount_controller.rb +19 -0
  20. data/app/controllers/workarea/storefront/kount_orders_controller.rb +40 -0
  21. data/app/lib/active_shipping/rate_estimate.decorator +10 -0
  22. data/app/mailers/workarea/storefront/order_mailer.decorator +14 -0
  23. data/app/models/workarea/checkout.decorator +37 -0
  24. data/app/models/workarea/checkout/fraud/kount_analyzer.rb +71 -0
  25. data/app/models/workarea/kount/ens_event.rb +13 -0
  26. data/app/models/workarea/kount/order.rb +14 -0
  27. data/app/models/workarea/order.decorator +62 -0
  28. data/app/models/workarea/order/fraud_decision.decorator +9 -0
  29. data/app/models/workarea/order/item.decorator +8 -0
  30. data/app/models/workarea/order/status/review.rb +13 -0
  31. data/app/models/workarea/payment/credit_card.decorator +13 -0
  32. data/app/models/workarea/payment/payment.decorator +11 -0
  33. data/app/models/workarea/payment/status/kount_declined.rb +13 -0
  34. data/app/models/workarea/payment/status/kount_review.rb +13 -0
  35. data/app/models/workarea/payment/tender/credit_card.decorator +10 -0
  36. data/app/models/workarea/search/admin.decorator +12 -0
  37. data/app/models/workarea/search/admin/order.decorator +7 -0
  38. data/app/models/workarea/shipping/rate_lookup.decorator +26 -0
  39. data/app/models/workarea/shipping/service.decorator +9 -0
  40. data/app/models/workarea/shipping/service_selection.decorator +7 -0
  41. data/app/models/workarea/shipping_option.decorator +27 -0
  42. data/app/services/workarea/kount/cancel_order_under_review.rb +28 -0
  43. data/app/services/workarea/kount/event.rb +43 -0
  44. data/app/services/workarea/kount/event/dmc_event.rb +9 -0
  45. data/app/services/workarea/kount/event/risk_change_event.rb +21 -0
  46. data/app/services/workarea/kount/event/special_alert_event.rb +21 -0
  47. data/app/services/workarea/kount/event/workflow_event.rb +25 -0
  48. data/app/services/workarea/kount/event_batch.rb +37 -0
  49. data/app/services/workarea/kount/order_fraud_update_service.rb +42 -0
  50. data/app/services/workarea/kount/ris_inquiry.rb +120 -0
  51. data/app/services/workarea/kount/ris_inquiry/product.rb +53 -0
  52. data/app/services/workarea/kount/ris_request.rb +84 -0
  53. data/app/services/workarea/kount/ris_update.rb +39 -0
  54. data/app/view_models/workarea/admin/order_view_model.decorator +35 -0
  55. data/app/view_models/workarea/storefront/order_view_model.decorator +11 -0
  56. data/app/views/workarea/admin/orders/_kount.html.haml +28 -0
  57. data/app/views/workarea/admin/orders/kount.html.haml +46 -0
  58. data/app/views/workarea/storefront/checkouts/_kount_data_collector.html.haml +4 -0
  59. data/app/views/workarea/storefront/order_mailer/hold_denial.html.haml +14 -0
  60. data/app/workers/workarea/kount/process_review_order.rb +75 -0
  61. data/app/workers/workarea/kount/update_ris_inquiry.rb +31 -0
  62. data/bin/rails +18 -0
  63. data/config/initializers/appends.rb +11 -0
  64. data/config/initializers/workarea.rb +26 -0
  65. data/config/locales/en.yml +26 -0
  66. data/config/routes.rb +14 -0
  67. data/doc/Kount Technical Specification Guide 5.5.5.pdf +0 -0
  68. data/lib/workarea/kount.rb +87 -0
  69. data/lib/workarea/kount/address.rb +39 -0
  70. data/lib/workarea/kount/bogus_gateway.rb +415 -0
  71. data/lib/workarea/kount/engine.rb +8 -0
  72. data/lib/workarea/kount/errors.rb +2 -0
  73. data/lib/workarea/kount/gateway.rb +50 -0
  74. data/lib/workarea/kount/mappings.rb +195 -0
  75. data/lib/workarea/kount/payment_types.rb +50 -0
  76. data/lib/workarea/kount/response.rb +141 -0
  77. data/lib/workarea/kount/security_mash.rb +79 -0
  78. data/lib/workarea/kount/user_defined_fields.rb +16 -0
  79. data/lib/workarea/kount/version.rb +5 -0
  80. data/lib/workarea/mailer_previews/storefront/order_mailer_preview.rb +10 -0
  81. data/test/dummy/Rakefile +6 -0
  82. data/test/dummy/app/assets/config/manifest.js +4 -0
  83. data/test/dummy/app/assets/images/.keep +0 -0
  84. data/test/dummy/app/assets/javascripts/application.js +13 -0
  85. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  86. data/test/dummy/app/controllers/application_controller.rb +3 -0
  87. data/test/dummy/app/controllers/concerns/.keep +0 -0
  88. data/test/dummy/app/helpers/application_helper.rb +2 -0
  89. data/test/dummy/app/jobs/application_job.rb +2 -0
  90. data/test/dummy/app/mailers/application_mailer.rb +4 -0
  91. data/test/dummy/app/models/concerns/.keep +0 -0
  92. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  93. data/test/dummy/app/views/layouts/mailer.html.erb +13 -0
  94. data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
  95. data/test/dummy/bin/bundle +3 -0
  96. data/test/dummy/bin/rails +4 -0
  97. data/test/dummy/bin/rake +4 -0
  98. data/test/dummy/bin/setup +34 -0
  99. data/test/dummy/bin/update +29 -0
  100. data/test/dummy/config.ru +5 -0
  101. data/test/dummy/config/application.rb +23 -0
  102. data/test/dummy/config/boot.rb +5 -0
  103. data/test/dummy/config/cable.yml +9 -0
  104. data/test/dummy/config/environment.rb +5 -0
  105. data/test/dummy/config/environments/development.rb +56 -0
  106. data/test/dummy/config/environments/production.rb +86 -0
  107. data/test/dummy/config/environments/test.rb +44 -0
  108. data/test/dummy/config/initializers/application_controller_renderer.rb +6 -0
  109. data/test/dummy/config/initializers/assets.rb +11 -0
  110. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  111. data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
  112. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  113. data/test/dummy/config/initializers/inflections.rb +16 -0
  114. data/test/dummy/config/initializers/mime_types.rb +4 -0
  115. data/test/dummy/config/initializers/new_framework_defaults.rb +21 -0
  116. data/test/dummy/config/initializers/session_store.rb +3 -0
  117. data/test/dummy/config/initializers/workarea.rb +5 -0
  118. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  119. data/test/dummy/config/locales/en.yml +23 -0
  120. data/test/dummy/config/puma.rb +47 -0
  121. data/test/dummy/config/routes.rb +6 -0
  122. data/test/dummy/config/secrets.yml +22 -0
  123. data/test/dummy/config/spring.rb +6 -0
  124. data/test/dummy/db/seeds.rb +2 -0
  125. data/test/dummy/lib/assets/.keep +0 -0
  126. data/test/dummy/log/.keep +0 -0
  127. data/test/dummy/public/404.html +67 -0
  128. data/test/dummy/public/422.html +67 -0
  129. data/test/dummy/public/500.html +66 -0
  130. data/test/dummy/public/apple-touch-icon-precomposed.png +0 -0
  131. data/test/dummy/public/apple-touch-icon.png +0 -0
  132. data/test/dummy/public/favicon.ico +0 -0
  133. data/test/factories/kount.rb +164 -0
  134. data/test/integration/workarea/api/admin/payment_transactions_integration_test.decorator +29 -0
  135. data/test/integration/workarea/kount_moneris_integration_test.rb +37 -0
  136. data/test/integration/workarea/storefront/kount_integration_test.rb +37 -0
  137. data/test/integration/workarea/storefront/kount_orders_integration_test.rb +89 -0
  138. data/test/lib/workarea/kount/response_test.rb +95 -0
  139. data/test/lib/workarea/kount/security_mash_test.rb +62 -0
  140. data/test/models/workarea/checkout/fraud/kount_analyzer_test.rb +44 -0
  141. data/test/models/workarea/checkout_test.decorator +22 -0
  142. data/test/models/workarea/order/queries_test.decorator +28 -0
  143. data/test/models/workarea/order_test.decorator +25 -0
  144. data/test/models/workarea/payment/payment_test.rb +106 -0
  145. data/test/models/workarea/payment/saved_credit_card_test.rb +24 -0
  146. data/test/models/workarea/payment_test.decorator +54 -0
  147. data/test/models/workarea/shipping_option_test.rb +29 -0
  148. data/test/services/workarea/kount/event_batch_test.rb +95 -0
  149. data/test/services/workarea/kount/event_test.rb +51 -0
  150. data/test/services/workarea/kount/order_fraud_update_service_test.rb +48 -0
  151. data/test/support/workarea/kount_api_config.rb +27 -0
  152. data/test/system/workarea/kount_system_test.rb +72 -0
  153. data/test/system/workarea/storefront/kount_guest_checkout_system_test.rb +32 -0
  154. data/test/system/workarea/storefront/kount_logged_in_checkout_system_test.rb +102 -0
  155. data/test/test_helper.rb +16 -0
  156. data/test/vcr_cassettes/kount/basic_fraud_test.yml +43 -0
  157. data/test/vcr_cassettes/kount/integration/moneris_new_credit_card.yml +84 -0
  158. data/test/vcr_cassettes/kount/integration/moneris_saved_credit_card.yml +84 -0
  159. data/test/vcr_cassettes/kount/order_fraud_update.yml +82 -0
  160. data/test/workers/workarea/kount/clean_orders_test.rb +40 -0
  161. data/test/workers/workarea/kount/process_review_order_test.rb +100 -0
  162. data/workarea-kount.gemspec +17 -0
  163. metadata +238 -0
@@ -0,0 +1,53 @@
1
+ module Workarea
2
+ module Kount
3
+ class RisInquiry::Product
4
+ attr_reader :order_item
5
+
6
+ def initialize(order_item)
7
+ @order_item = order_item
8
+ end
9
+
10
+ def item
11
+ order_item.sku
12
+ end
13
+
14
+ def type
15
+ catalog_product.name
16
+ end
17
+
18
+ def description
19
+ "#{catalog_product.name} - #{variant_description}".truncate(255)
20
+ end
21
+
22
+ def quantity
23
+ order_item.quantity
24
+ end
25
+
26
+ def price
27
+ order_item.unit_price_cents.floor
28
+ end
29
+
30
+ private
31
+
32
+ def catalog_product
33
+ @catalog_product ||=
34
+ if order_item.product_attributes.present?
35
+ Mongoid::Factory.from_db(Catalog::Product, order_item.product_attributes)
36
+ else
37
+ Catalog::Product.find_by_sku(order_item.sku)
38
+ end
39
+ end
40
+
41
+ def variant
42
+ catalog_product.variants.where(sku: order_item.sku).first
43
+ end
44
+
45
+ def variant_description
46
+ variant
47
+ .details
48
+ .map { |key, value| "#{key}: #{value.join(',')}" }
49
+ .flatten.join(', ')
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,84 @@
1
+ module Workarea
2
+ module Kount
3
+ class RisRequest
4
+ attr_reader :order, :payment, :mode
5
+
6
+ private
7
+
8
+ def base_fields
9
+ {
10
+ MACK: 'Y',
11
+ AUTH: 'A',
12
+ SESS: order.kount_session_id,
13
+ MODE: mode
14
+ }
15
+ end
16
+
17
+ def authorization_transaction
18
+ @authorization_transaction ||= payment
19
+ .credit_card
20
+ .transactions
21
+ .authorizes
22
+ .successful
23
+ .first
24
+ end
25
+
26
+ def avs_response
27
+ return {} unless authorization_transaction.present? && payment.uses_credit_card?
28
+
29
+ avs_code = authorization_transaction.response.avs_result
30
+ case avs_code
31
+ when 'A', 'B', 'O'
32
+ street = 'M'
33
+ zip = 'N'
34
+ when 'L', 'P', 'W', 'Z'
35
+ street = 'N'
36
+ zip = 'M'
37
+ when 'C', 'I', 'K', 'N', '4'
38
+ street = 'N'
39
+ zip = 'N'
40
+ when 'D', 'M', 'H', 'V', 'X', 'Y', '3'
41
+ street = 'M'
42
+ zip = 'M'
43
+ when 'E', 'G', 'R', 'S', 'U', '1', '2'
44
+ street = 'X'
45
+ zip = 'X'
46
+ when 'F'
47
+ street = 'X'
48
+ zip = 'M'
49
+ when 'T'
50
+ street = 'M'
51
+ zip = 'X'
52
+ else
53
+ Kount.log_error "KOUNT WARNING: Unsupported AVS Code: #{avs_code} does not have a corresponding value in Kount. Marking as Unsupported/Unavailable."
54
+ street = 'X'
55
+ zip = 'X'
56
+ end
57
+
58
+ {
59
+ "AVST": street,
60
+ "AVSZ": zip
61
+ }
62
+ end
63
+
64
+ def cvv_response
65
+ return {} unless authorization_transaction.present? && payment.uses_credit_card?
66
+
67
+ cv_code = authorization_transaction.response.cvv_result
68
+ kount_cv_code =
69
+ case cv_code
70
+ when 'M'
71
+ 'M' # match
72
+ when 'N'
73
+ 'N' # no match
74
+ when 'D', 'I', 'P', 'S', 'U', 'X', '1', '2', '3'
75
+ 'X' # unsupported or unavailable
76
+ else
77
+ Kount.log_error "KOUNT WARNING: Unsupported CV Code: #{cv_code} does not have a corresponding value in Kount. Marking as Unsupported/Unavailable."
78
+ 'X'
79
+ end
80
+ { CVVR: kount_cv_code }
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,39 @@
1
+ module Workarea
2
+ module Kount
3
+ class RisUpdate < RisRequest
4
+ attr_reader :options
5
+
6
+ def initialize(order:, payment:, mode: 'U', options: {})
7
+ @order = order
8
+ @payment = payment
9
+ @mode = mode
10
+ @options = options
11
+ end
12
+
13
+ def to_h
14
+ @to_h ||= [
15
+ base_fields,
16
+ kount_transaction_id,
17
+ avs_response,
18
+ cvv_response
19
+ ].reduce(&:merge)
20
+ end
21
+
22
+ def payment_transaction
23
+ @payment_transaction = options[:payment_transaction] ||
24
+ authorization_transaction
25
+ end
26
+
27
+ private
28
+
29
+ def kount_order
30
+ @kount_order ||= options[:kount_order] ||
31
+ Workarea::Kount::Order.find(order.id)
32
+ end
33
+
34
+ def kount_transaction_id
35
+ { TRAN: kount_order.response.transaction_id }
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,35 @@
1
+ module Workarea
2
+ decorate Admin::OrderViewModel, with: :kount do
3
+ def kount_order
4
+ @kount_order ||= Workarea::Kount::Order.find model.id rescue nil
5
+ end
6
+
7
+ def kount_order_success?
8
+ kount_order&.response&.success?
9
+ end
10
+
11
+ def kount_score
12
+ kount_order&.response&.score
13
+ end
14
+
15
+ def kount_credit_cards
16
+ kount_order&.response&.credit_cards
17
+ end
18
+
19
+ def kount_email_addresses
20
+ kount_order&.response&.email_addresses
21
+ end
22
+
23
+ def kount_devices
24
+ kount_order&.response&.devices
25
+ end
26
+
27
+ def kount_rules
28
+ kount_order&.response&.triggered_rules
29
+ end
30
+
31
+ def kount_order_url
32
+ "#{Kount.kount_order_url_base}#{kount_order.response.transaction_id}"
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,11 @@
1
+ module Workarea
2
+ decorate Storefront::OrderViewModel, with: :kount do
3
+ def placed_at
4
+ if model.under_review?
5
+ Time.current
6
+ else
7
+ model.placed_at
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,28 @@
1
+ - if order.kount_order_success?
2
+ .grid__cell
3
+ .card{ class: card_classes(:kount, local_assigns[:active]) }
4
+ = link_to kount_order_path(order), class: 'card__header' do
5
+ %span.card__header-text= t('workarea.admin.orders.cards.kount.title')
6
+ = inline_svg 'workarea/admin/icons/link.svg', class: 'card__icon'
7
+
8
+ - if local_assigns[:active].blank?
9
+ .card__body
10
+ %ul.list-reset
11
+ %li
12
+ %strong= t('workarea.admin.orders.cards.kount.decision')
13
+ #{order.kount_decision.to_s}
14
+ %li
15
+ %strong= t('workarea.admin.orders.cards.kount.score')
16
+ #{order.kount_score}
17
+ %li
18
+ %strong= t('workarea.admin.orders.cards.kount.credit_cards')
19
+ #{order.kount_credit_cards}
20
+ %li
21
+ %strong= t('workarea.admin.orders.cards.kount.email_addresses')
22
+ #{order.kount_email_addresses}
23
+ %li
24
+ %strong= t('workarea.admin.orders.cards.kount.devices')
25
+ #{order.kount_devices}
26
+
27
+ = link_to kount_order_path(order), class: 'card__button' do
28
+ %span.button.button--small= t('workarea.admin.orders.cards.kount.button')
@@ -0,0 +1,46 @@
1
+ - @page_title = t('workarea.admin.orders.kount.title', name: @order.name)
2
+
3
+ .view
4
+ .view__header
5
+ .grid.grid--middle.grid--right
6
+ .grid__cell.grid__cell--50
7
+ .view__heading
8
+ = link_to_index_for(@order)
9
+ %h1= link_to @order.name, url_for(@order)
10
+ .grid__cell.grid__cell--25
11
+ = render_aux_navigation_for(@order)
12
+
13
+ .view__container
14
+ = render_cards_for(@order, :flow)
15
+
16
+ .view__container.view__container--narrow
17
+ .grid
18
+ .grid__cell.grid__cell--50
19
+ %h2= t('workarea.admin.orders.kount.rules_triggered')
20
+ - if @order.kount_rules.present?
21
+ %ul.list-reset
22
+ - @order.kount_rules.each do |rule|
23
+ %li= rule[:rule_description]
24
+ - else
25
+ %span= t('workarea.admin.orders.kount.no_rules_triggered')
26
+ .grid__cell.grid__cell--50
27
+ %ul.list-reset
28
+ %li
29
+ %strong= t('workarea.admin.orders.cards.kount.decision')
30
+ #{@order.kount_decision.to_s}
31
+ %li
32
+ %strong= t('workarea.admin.orders.cards.kount.score')
33
+ #{@order.kount_score}
34
+ %li
35
+ %strong= t('workarea.admin.orders.cards.kount.credit_cards')
36
+ #{@order.kount_credit_cards}
37
+ %li
38
+ %strong= t('workarea.admin.orders.cards.kount.email_addresses')
39
+ #{@order.kount_email_addresses}
40
+ %li
41
+ %strong= t('workarea.admin.orders.cards.kount.devices')
42
+ #{@order.kount_devices}
43
+
44
+ .workflow-bar
45
+ .grid.grid--auto.grid--right.grid--middle
46
+ .grid__cell= link_to t('workarea.admin.orders.kount.view_order_in_kount'), @order.kount_order_url, target: :_blank, class: 'workflow-bar__button'
@@ -0,0 +1,4 @@
1
+ - unless Rails.env.test? || @kount_data_collector_already_appended
2
+ - @kount_data_collector_already_appended = true
3
+ %iframe{ width: 1, height: 1, frameborder: 0, scrolling: 'no', style: 'display:none;', src: kount_data_collector_htm_url }
4
+ %img{ width: 1, height: 1, src: kount_data_collector_gif_url }
@@ -0,0 +1,14 @@
1
+ = append_partials('storefront.hold_denial_mailer.top')
2
+ %tr
3
+ %td
4
+ %table
5
+ %tr
6
+ %td
7
+ %h1= t('workarea.storefront.email.hold_denial.heading', order_id: @order.id)
8
+ %p= t('workarea.storefront.email.hold_denial.info_html').html_safe
9
+
10
+ = render 'summary', order: @order
11
+
12
+ = render 'workarea/storefront/mailers/recommendations', recommendations: @recommendations
13
+
14
+ = append_partials('storefront.hold_denial_mailer.bottom')
@@ -0,0 +1,75 @@
1
+ module Workarea
2
+ module Kount
3
+ class ProcessReviewOrder
4
+ include Sidekiq::Worker
5
+
6
+ sidekiq_options queue: 'high'
7
+ attr_reader :order
8
+
9
+ def perform(order_id, approved, event_string)
10
+ @order = Workarea::Order.find(order_id)
11
+ return unless order.under_review?
12
+
13
+ Workarea::Kount::Order.find(order.id).tap do |kount_order|
14
+ kount_order.ens_events.create!(xml: event_string)
15
+ end
16
+
17
+ with_order_lock do
18
+ if approved
19
+ order.update_attributes(kount_decision: :approve)
20
+ place_order
21
+ else
22
+ order.update_attributes(kount_decision: :decline)
23
+ cancel_order
24
+ end
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def with_order_lock
31
+ order.lock!
32
+ yield
33
+ ensure
34
+ order.unlock!
35
+ end
36
+
37
+ def checkout
38
+ @checkout ||= Workarea::Checkout.new(order)
39
+ end
40
+
41
+ def place_order
42
+ if checkout.handle_kount_approved
43
+ place_order_side_effects
44
+ else
45
+ write_comment
46
+ cancel_order
47
+ end
48
+ end
49
+
50
+ def place_order_side_effects
51
+ Workarea::Storefront::OrderMailer.confirmation(order.id).deliver_now
52
+ end
53
+
54
+ def write_comment
55
+ transaction = Workarea::Payment::Transaction
56
+ .where(payment_id: order.id)
57
+ .order(:updated_at.desc)
58
+ .first
59
+
60
+ body =
61
+ if transaction
62
+ "Kount review order approved but payment declined: #{transaction.message}"
63
+ else
64
+ 'Kount review order approved but failed without a payment transaction.'
65
+ end
66
+
67
+ order.comments.create(body: body)
68
+ end
69
+
70
+ def cancel_order
71
+ Kount::CancelOrderUnderReview.new(order).cancel!
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,31 @@
1
+ module Workarea
2
+ module Kount
3
+ class UpdateRisInquiry
4
+ include Sidekiq::Worker
5
+ include Sidekiq::CallbacksWorker
6
+
7
+ self.inlined = true
8
+ sidekiq_options(
9
+ enqueue_on: { Workarea::Payment::Transaction => :save },
10
+ queue: 'high'
11
+ )
12
+
13
+ def perform(transaction_id)
14
+ transaction = Workarea::Payment::Transaction.find(transaction_id)
15
+ payment = transaction.payment
16
+ order = Workarea::Order.find(payment.id)
17
+ kount_order = Kount::Order.find(payment.id) rescue nil
18
+
19
+ return unless kount_order.present? && payment.credit_card? && transaction.authorize?
20
+
21
+ Workarea::Kount::OrderFraudUpdateService.new(
22
+ order: order,
23
+ payment: payment,
24
+ options: {
25
+ payment_transaction: transaction
26
+ }
27
+ ).perform!
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run 'rails' with Rails gems
3
+ # installed from the root of your application.
4
+
5
+ ENGINE_ROOT = File.expand_path('../..', __FILE__)
6
+ ENGINE_PATH = File.expand_path('../../lib/kount/engine', __FILE__)
7
+
8
+ # Set up gems listed in the Gemfile.
9
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
10
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
11
+
12
+ require 'action_controller/railtie'
13
+ require 'action_view/railtie'
14
+ require 'action_mailer/railtie'
15
+ require 'rails/test_unit/railtie'
16
+ require 'sprockets/railtie'
17
+
18
+ require 'rails/engine/commands'