workarea-orderbot 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
- data/.github/ISSUE_TEMPLATE/documentation-request.md +17 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/workflows/ci.yml +58 -0
- data/.gitignore +23 -0
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +58 -0
- data/Gemfile +17 -0
- data/LICENSE +52 -0
- data/README.md +100 -0
- data/Rakefile +59 -0
- data/app/assets/images/workarea/admin/orderbot/.keep +0 -0
- data/app/assets/images/workarea/storefront/orderbot/.keep +0 -0
- data/app/assets/javascripts/workarea/admin/orderbot/.keep +0 -0
- data/app/assets/javascripts/workarea/storefront/orderbot/.keep +0 -0
- data/app/assets/stylesheets/workarea/admin/orderbot/.keep +0 -0
- data/app/assets/stylesheets/workarea/storefront/orderbot/.keep +0 -0
- data/app/controllers/.keep +0 -0
- data/app/helpers/.keep +0 -0
- data/app/mailers/.keep +0 -0
- data/app/models/workarea/order.decorator +19 -0
- data/app/models/workarea/orderbot/import_log.rb +19 -0
- data/app/models/workarea/orderbot/pricing_import_data.rb +13 -0
- data/app/models/workarea/orderbot/product_import_data.rb +32 -0
- data/app/models/workarea/user.decorator +7 -0
- data/app/services/workarea/orderbot/child_product.rb +108 -0
- data/app/services/workarea/orderbot/filters.rb +33 -0
- data/app/services/workarea/orderbot/order.rb +146 -0
- data/app/services/workarea/orderbot/order/item.rb +69 -0
- data/app/services/workarea/orderbot/order/tender/credit_card.rb +43 -0
- data/app/services/workarea/orderbot/order/tender/general.rb +32 -0
- data/app/services/workarea/orderbot/order/tender/gift_card.rb +32 -0
- data/app/services/workarea/orderbot/order/tender/store_credit.rb +32 -0
- data/app/services/workarea/orderbot/parent_product.rb +87 -0
- data/app/views/.keep +0 -0
- data/app/workers/workarea/orderbot/fulfillment/import_fulfillments.rb +37 -0
- data/app/workers/workarea/orderbot/fulfillment_importer.rb +50 -0
- data/app/workers/workarea/orderbot/inventory/import_inventory.rb +50 -0
- data/app/workers/workarea/orderbot/inventory_importer.rb +57 -0
- data/app/workers/workarea/orderbot/pricing/import_pricing.rb +42 -0
- data/app/workers/workarea/orderbot/pricing_importer.rb +70 -0
- data/app/workers/workarea/orderbot/product/import_child_products.rb +24 -0
- data/app/workers/workarea/orderbot/product/import_parent_products.rb +32 -0
- data/app/workers/workarea/orderbot/product_importer.rb +72 -0
- data/app/workers/workarea/orderbot/save_order.rb +38 -0
- data/bin/rails +25 -0
- data/config/initializers/configurations.rb +60 -0
- data/config/initializers/scheduled_jobs.rb +28 -0
- data/config/initializers/workarea.rb +16 -0
- data/config/routes.rb +2 -0
- data/lib/workarea/orderbot.rb +43 -0
- data/lib/workarea/orderbot/authentication.rb +41 -0
- data/lib/workarea/orderbot/bogus_gateway.rb +629 -0
- data/lib/workarea/orderbot/engine.rb +10 -0
- data/lib/workarea/orderbot/gateway.rb +102 -0
- data/lib/workarea/orderbot/response.rb +29 -0
- data/lib/workarea/orderbot/version.rb +5 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/config/manifest.js +3 -0
- data/test/dummy/app/assets/images/.keep +0 -0
- data/test/dummy/app/assets/javascripts/application.js +14 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +2 -0
- data/test/dummy/app/controllers/concerns/.keep +0 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/jobs/application_job.rb +2 -0
- data/test/dummy/app/mailers/application_mailer.rb +4 -0
- data/test/dummy/app/models/concerns/.keep +0 -0
- data/test/dummy/app/views/layouts/application.html.erb +15 -0
- data/test/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +25 -0
- data/test/dummy/bin/update +25 -0
- data/test/dummy/config.ru +5 -0
- data/test/dummy/config/application.rb +34 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +52 -0
- data/test/dummy/config/environments/production.rb +83 -0
- data/test/dummy/config/environments/test.rb +45 -0
- data/test/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/test/dummy/config/initializers/assets.rb +12 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/content_security_policy.rb +25 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/workarea.rb +5 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +9 -0
- data/test/dummy/config/locales/en.yml +33 -0
- data/test/dummy/config/puma.rb +34 -0
- data/test/dummy/config/routes.rb +5 -0
- data/test/dummy/config/spring.rb +6 -0
- data/test/dummy/db/seeds.rb +2 -0
- data/test/dummy/lib/assets/.keep +0 -0
- data/test/dummy/log/.keep +0 -0
- data/test/services/workarea/orderbot/order_test.rb +151 -0
- data/test/services/workarea/orderbot/product/child_product_test.rb +255 -0
- data/test/services/workarea/orderbot/product/parent_product_test.rb +106 -0
- data/test/teaspoon_env.rb +6 -0
- data/test/test_helper.rb +10 -0
- data/test/workers/workarea/orderbot/fulfillment/import_fulfillments_test.rb +41 -0
- data/test/workers/workarea/orderbot/fulfillment_importer_test.rb +29 -0
- data/test/workers/workarea/orderbot/inventory/import_inventory_test.rb +49 -0
- data/test/workers/workarea/orderbot/inventory_importer_test.rb +21 -0
- data/test/workers/workarea/orderbot/pricing/import_pricing_test.rb +61 -0
- data/test/workers/workarea/orderbot/pricing_importer_test.rb +29 -0
- data/test/workers/workarea/orderbot/product_importer_test.rb +23 -0
- data/test/workers/workarea/orderbot/save_order_test.rb +41 -0
- data/workarea-orderbot.gemspec +20 -0
- metadata +172 -0
@@ -0,0 +1,70 @@
|
|
1
|
+
module Workarea
|
2
|
+
module Orderbot
|
3
|
+
class PricingImporter
|
4
|
+
include Sidekiq::Worker
|
5
|
+
sidekiq_options retry: 5
|
6
|
+
|
7
|
+
def perform(options = {})
|
8
|
+
return unless Orderbot.api_configured?
|
9
|
+
|
10
|
+
Orderbot::ImportLog.log('pricing') do |last_imported_at|
|
11
|
+
last_import = options[:from_updated_on] || last_imported_at
|
12
|
+
|
13
|
+
pricing_filters = {
|
14
|
+
response_model: "OrderGuideProduct",
|
15
|
+
active: true
|
16
|
+
}
|
17
|
+
|
18
|
+
pricing_response = gateway.get_pricing(pricing_filters)
|
19
|
+
|
20
|
+
raise 'get pricing error' unless pricing_response.success?
|
21
|
+
|
22
|
+
pricing_records = pricing_response.body
|
23
|
+
|
24
|
+
write_prices(pricing_records, last_import)
|
25
|
+
if pricing_response.total_pages.to_i > 1
|
26
|
+
count = 2
|
27
|
+
|
28
|
+
while count <= pricing_response.total_pages.to_i
|
29
|
+
page_filters = pricing_filters.merge(page: count)
|
30
|
+
response = gateway.get_products(page_filters)
|
31
|
+
|
32
|
+
write_prices(response.body, last_import)
|
33
|
+
count = count + 1
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
Workarea::Orderbot::Pricing::ImportPricing.new.perform
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def gateway
|
44
|
+
Workarea::Orderbot.gateway
|
45
|
+
end
|
46
|
+
|
47
|
+
def write_prices(order_guides, last_update_threshold)
|
48
|
+
order_guides.each do | order_guide|
|
49
|
+
|
50
|
+
order_guide_id = order_guide["order_guide_id"]
|
51
|
+
|
52
|
+
# only import the prices if we care about this order guide ID
|
53
|
+
next if order_guide_id != Workarea.config.default_order_guide_id
|
54
|
+
|
55
|
+
products = order_guide["products"]
|
56
|
+
|
57
|
+
products.each do |product|
|
58
|
+
|
59
|
+
next if product["last_updated_on"].present? && Time.parse(product["last_updated_on"]).iso8601 < last_update_threshold.in_time_zone(Workarea.config.orderbot_api_timezone).iso8601
|
60
|
+
|
61
|
+
Orderbot::PricingImportData.create!(
|
62
|
+
order_guide_id: order_guide_id,
|
63
|
+
pricing_data: product
|
64
|
+
)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Workarea
|
2
|
+
module Orderbot
|
3
|
+
module Product
|
4
|
+
class ImportChildProducts
|
5
|
+
include Sidekiq::Worker
|
6
|
+
|
7
|
+
def perform
|
8
|
+
Orderbot::ProductImportData.child_products.each do |child_product|
|
9
|
+
result = begin
|
10
|
+
Workarea::Orderbot::ChildProduct.new(child_product).process
|
11
|
+
rescue StandardError => e
|
12
|
+
child_product.update_attributes!(error_message: e.message)
|
13
|
+
false
|
14
|
+
end
|
15
|
+
|
16
|
+
if result
|
17
|
+
child_product.delete
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Workarea
|
2
|
+
module Orderbot
|
3
|
+
module Product
|
4
|
+
class ImportParentProducts
|
5
|
+
include Sidekiq::Worker
|
6
|
+
|
7
|
+
def perform
|
8
|
+
Orderbot::ProductImportData.parent_products.each do |parent_product|
|
9
|
+
result = begin
|
10
|
+
Orderbot::ParentProduct.new(parent_product).process
|
11
|
+
|
12
|
+
# if a parent product has no children then import the variants
|
13
|
+
# pricing and shipping skus
|
14
|
+
if !parent_product.has_children
|
15
|
+
Orderbot::ChildProduct.new(parent_product).process
|
16
|
+
end
|
17
|
+
|
18
|
+
true
|
19
|
+
rescue StandardError => e
|
20
|
+
parent_product.update_attributes!(error_message: e.message)
|
21
|
+
false
|
22
|
+
end
|
23
|
+
|
24
|
+
if result
|
25
|
+
parent_product.delete
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Workarea
|
2
|
+
module Orderbot
|
3
|
+
class ProductImporter
|
4
|
+
include Sidekiq::Worker
|
5
|
+
sidekiq_options retry: 5
|
6
|
+
|
7
|
+
def perform(options = {})
|
8
|
+
return unless Orderbot.api_configured?
|
9
|
+
|
10
|
+
Orderbot::ImportLog.log('product') do |last_imported_at|
|
11
|
+
last_import = options[:from_updated_on] || last_imported_at
|
12
|
+
|
13
|
+
attrs = {
|
14
|
+
response_model: "integration",
|
15
|
+
sort_by: "LastUpdatedOn"
|
16
|
+
}.merge!(product_filters)
|
17
|
+
|
18
|
+
response = gateway.get_products(attrs)
|
19
|
+
write_products(response.body, last_import)
|
20
|
+
|
21
|
+
if response.total_pages.to_i > 1
|
22
|
+
count = 2
|
23
|
+
|
24
|
+
while count <= response.total_pages.to_i
|
25
|
+
page_attrs = attrs.merge(page: count)
|
26
|
+
response = gateway.get_products(page_attrs)
|
27
|
+
write_products(response.body, last_import)
|
28
|
+
count = count + 1
|
29
|
+
end
|
30
|
+
end
|
31
|
+
# import the ob parent products - Top level workarea prodcuts
|
32
|
+
Orderbot::Product::ImportParentProducts.new.perform
|
33
|
+
|
34
|
+
# import the children products - workarea variants, pricing and shipping skus
|
35
|
+
Orderbot::Product::ImportChildProducts.new.perform
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def write_products(products, last_update_threshold)
|
42
|
+
products.each do | product_data|
|
43
|
+
next if Time.parse(product_data["updated_on"]).iso8601 < last_update_threshold.in_time_zone(Workarea.config.orderbot_api_timezone).iso8601
|
44
|
+
|
45
|
+
parent_product = product_data["parent_id"] == 0
|
46
|
+
parent_product_id = product_data["parent_id"]
|
47
|
+
has_children = product_data["has_children"]
|
48
|
+
product_id = product_data["product_id"]
|
49
|
+
|
50
|
+
ob_record = Orderbot::ProductImportData.find_or_create_by(product_id: product_id)
|
51
|
+
ob_record.update_attributes!(
|
52
|
+
product_data: product_data,
|
53
|
+
parent_product: parent_product,
|
54
|
+
parent_product_id: parent_product_id,
|
55
|
+
has_children: has_children
|
56
|
+
)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def gateway
|
61
|
+
Workarea::Orderbot.gateway
|
62
|
+
end
|
63
|
+
|
64
|
+
def product_filters
|
65
|
+
config_filters = Workarea.config.product_import_filters || {}
|
66
|
+
config_filters.merge!(order_guide: Workarea.config.default_order_guide_id) if Workarea.config.default_order_guide_id.present?
|
67
|
+
|
68
|
+
config_filters
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Workarea
|
2
|
+
module Orderbot
|
3
|
+
class SaveOrder
|
4
|
+
class OrderbotSaveOrderError < StandardError; end
|
5
|
+
include Sidekiq::Worker
|
6
|
+
include Sidekiq::CallbacksWorker
|
7
|
+
|
8
|
+
sidekiq_options(
|
9
|
+
enqueue_on: { Workarea::Order => [:place] },
|
10
|
+
unique: :until_executing
|
11
|
+
)
|
12
|
+
|
13
|
+
def perform(id)
|
14
|
+
return unless Orderbot.api_configured?
|
15
|
+
|
16
|
+
order = Workarea::Order.find(id)
|
17
|
+
orderbot_order = Workarea::Orderbot::Order.new(order.id)
|
18
|
+
response = Workarea::Orderbot.gateway.create_order(orderbot_order.to_a)
|
19
|
+
|
20
|
+
raise OrderbotSaveOrderError, response.error_details unless response.success?
|
21
|
+
raise OrderbotSaveOrderError, messages(response.body) unless created?(response.body) # checks for a 200 response that fails to create the order
|
22
|
+
|
23
|
+
orderbot_order_id = response.body.first["order_id"]
|
24
|
+
order.set_orderbot_exported_data!(orderbot_order_id)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def created?(body)
|
30
|
+
body.first["orderbot_status_code"] == "success"
|
31
|
+
end
|
32
|
+
|
33
|
+
def messages(body)
|
34
|
+
body.first["messages"].join(",")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/bin/rails
ADDED
@@ -0,0 +1,25 @@
|
|
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('..', __dir__)
|
6
|
+
ENGINE_PATH = File.expand_path('../lib/workarea/orderbot/engine', __dir__)
|
7
|
+
APP_PATH = File.expand_path('../test/dummy/config/application', __dir__)
|
8
|
+
|
9
|
+
# Set up gems listed in the Gemfile.
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
11
|
+
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
|
12
|
+
|
13
|
+
require "rails"
|
14
|
+
# Pick the frameworks you want:
|
15
|
+
require "active_model/railtie"
|
16
|
+
require "active_job/railtie"
|
17
|
+
# require "active_record/railtie"
|
18
|
+
# require "active_storage/engine"
|
19
|
+
require "action_controller/railtie"
|
20
|
+
require "action_mailer/railtie"
|
21
|
+
require "action_view/railtie"
|
22
|
+
# require "action_cable/engine"
|
23
|
+
require "sprockets/railtie"
|
24
|
+
require "rails/test_unit/railtie"
|
25
|
+
require 'rails/engine/commands'
|
@@ -0,0 +1,60 @@
|
|
1
|
+
Workarea::Configuration.define_fields do
|
2
|
+
fieldset 'Orderbot', namespaced: false do
|
3
|
+
field 'Orderbot API Email Address',
|
4
|
+
type: :string,
|
5
|
+
description: 'Email Address of Orderbot admin, used to authenticate to the API. This email address is the same that is used to login to the Orderbot admin.',
|
6
|
+
allow_blank: false,
|
7
|
+
encrypted: false
|
8
|
+
|
9
|
+
field 'Orderbot API Password',
|
10
|
+
type: :string,
|
11
|
+
description: 'Password of Orderbot admin, used to authenticate to the API. This password is the same that is used to login to the Orderbot admin.',
|
12
|
+
allow_blank: false,
|
13
|
+
encrypted: true
|
14
|
+
|
15
|
+
field 'Use Orderbot Staging Environment',
|
16
|
+
type: :boolean,
|
17
|
+
description: 'Use the Orderbot staging environment. Only recommended for experimenting with new and custom Orderbot features, talk to your Orderbot support representative for access.',
|
18
|
+
default: false
|
19
|
+
|
20
|
+
field 'Default Order Guide ID',
|
21
|
+
type: :integer,
|
22
|
+
description: 'What order guide ID is used to filter products on import. This value will also be sent when an order is exported to Orderbot.',
|
23
|
+
allow_blank: true
|
24
|
+
|
25
|
+
field 'Inventory Distribution Center ID',
|
26
|
+
type: :integer,
|
27
|
+
description: 'What inventory distribution center to import inventory from. Leaving this field blank will import inventory from all centers and is not recommended. This field will also be used as the default distribution center on order export.',
|
28
|
+
allow_blank: true
|
29
|
+
|
30
|
+
field 'Default Inventory Import Policy',
|
31
|
+
type: :symbol,
|
32
|
+
default: "standard",
|
33
|
+
description: 'The default policy to use when importing inventory from the Orderbot API.',
|
34
|
+
allow_blank: false,
|
35
|
+
values: -> do
|
36
|
+
Workarea.config.inventory_policies.map do |class_name|
|
37
|
+
[class_name.demodulize.titleize, class_name.demodulize.underscore]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
field 'Product Import filters',
|
42
|
+
type: :hash,
|
43
|
+
values_type: :string,
|
44
|
+
default: {},
|
45
|
+
description: 'Additional filters to pass to the API when importing products. For example "group: robots"',
|
46
|
+
allow_blank: true
|
47
|
+
|
48
|
+
field 'Orderbot API Timezone',
|
49
|
+
type: :string,
|
50
|
+
default: "Eastern Time (US & Canada)",
|
51
|
+
description: 'Set this value to match the timezone Orderbot sends any date-time information via the API. Consult with Orderbot before changing this value.',
|
52
|
+
allow_blank: false,
|
53
|
+
values: -> { ActiveSupport::TimeZone.all.map(&:name) }
|
54
|
+
|
55
|
+
field 'Shipping Date Lead Time',
|
56
|
+
type: :duration,
|
57
|
+
default: 3.days,
|
58
|
+
description: 'Lead time used to generate the "ship date" field when an order is placed. This time will added to the current date and sent to Orderbot when an order is placed.'
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Sidekiq::Cron::Job.create(
|
2
|
+
name: 'Workarea::Orderbot::ProductImporter',
|
3
|
+
klass: 'Workarea::Orderbot::ProductImporter',
|
4
|
+
cron: '0 2 * * *',
|
5
|
+
queue: 'low'
|
6
|
+
)
|
7
|
+
|
8
|
+
|
9
|
+
Sidekiq::Cron::Job.create(
|
10
|
+
name: 'Workarea::Orderbot::InventoryImporter',
|
11
|
+
klass: 'Workarea::Orderbot::InventoryImporter',
|
12
|
+
cron: '0 * * * *',
|
13
|
+
queue: 'low'
|
14
|
+
)
|
15
|
+
|
16
|
+
Sidekiq::Cron::Job.create(
|
17
|
+
name: 'Workarea::Orderbot::PricingImporter',
|
18
|
+
klass: 'Workarea::Orderbot::PricingImporter',
|
19
|
+
cron: '30 * * * *',
|
20
|
+
queue: 'low'
|
21
|
+
)
|
22
|
+
|
23
|
+
Sidekiq::Cron::Job.create(
|
24
|
+
name: 'Workarea::Orderbot::FulfillmentImporter',
|
25
|
+
klass: 'Workarea::Orderbot::FulfillmentImporter',
|
26
|
+
cron: '*/20 * * * *',
|
27
|
+
queue: 'low'
|
28
|
+
)
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Workarea.configure do |config|
|
2
|
+
config.orderbot = ActiveSupport::Configurable::Configuration.new
|
3
|
+
config.orderbot.api_timeout = 30
|
4
|
+
config.orderbot.open_timeout = 30
|
5
|
+
|
6
|
+
|
7
|
+
config.orderbot.transaction_id = {
|
8
|
+
'ActiveMerchant::Billing::BogusGateway' => -> (transaction) { transaction.response.authorization },
|
9
|
+
'ActiveMerchant::Billing::StripeGateway' => -> (transaction) { transaction.params['id'] },
|
10
|
+
'ActiveMerchant::Billing::BraintreeBlueGateway' => -> (transaction) { transaction.response.params["braintree_transaction"]["order_id"] },
|
11
|
+
'ActiveMerchant::Billing::MonerisGateway' => -> (transaction) { transaction.response.params["trans_id"] },
|
12
|
+
'ActiveMerchant::Billing::AuthorizeNetCimGateway' => -> (transaction) { transaction.response.params["direct_response"]["transaction_id"] },
|
13
|
+
'ActiveMerchant::Billing::CyberSourceGateway' => -> (transaction) { transaction.response.params["reasonCode"] },
|
14
|
+
'ActiveMerchant::Billing::CheckoutV2Gateway' => -> (transaction) { transaction.response.params["id"] }
|
15
|
+
}
|
16
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'workarea'
|
2
|
+
require 'workarea/storefront'
|
3
|
+
require 'workarea/admin'
|
4
|
+
|
5
|
+
require 'workarea/orderbot/engine'
|
6
|
+
require 'workarea/orderbot/version'
|
7
|
+
|
8
|
+
require 'workarea/orderbot/bogus_gateway'
|
9
|
+
require 'workarea/orderbot/authentication'
|
10
|
+
require 'workarea/orderbot/gateway'
|
11
|
+
require 'workarea/orderbot/response'
|
12
|
+
|
13
|
+
module Workarea
|
14
|
+
module Orderbot
|
15
|
+
def self.config
|
16
|
+
Workarea.config.orderbot
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.api_user_name
|
20
|
+
Workarea.config.orderbot_api_email_address
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.api_password
|
24
|
+
Workarea.config.orderbot_api_password
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.api_configured?
|
28
|
+
api_user_name.present? && api_password.present?
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.test?
|
32
|
+
Workarea.config.use_orderbot_staging_environment
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.gateway
|
36
|
+
if Rails.env.test?
|
37
|
+
Orderbot::BogusGateway.new
|
38
|
+
else
|
39
|
+
Orderbot::Gateway.new(api_user_name: api_user_name, api_password: api_password, test: test?)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Workarea
|
2
|
+
module Orderbot
|
3
|
+
module Authentication
|
4
|
+
def token
|
5
|
+
response = get_token
|
6
|
+
|
7
|
+
body = JSON.parse(response.body)
|
8
|
+
body['token']
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def get_token
|
14
|
+
Rails.cache.fetch(token_cache_key, expires_in: 5.minutes) do
|
15
|
+
conn = Faraday.new(url: rest_endpoint)
|
16
|
+
conn.basic_auth(api_user_name, api_password)
|
17
|
+
conn.get do |req|
|
18
|
+
req.url '/accesstoken'
|
19
|
+
req.headers['Content-Type'] = 'application/json'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def api_user_name
|
25
|
+
options[:api_user_name]
|
26
|
+
end
|
27
|
+
|
28
|
+
def api_password
|
29
|
+
options[:api_password]
|
30
|
+
end
|
31
|
+
|
32
|
+
def test
|
33
|
+
options[:test]
|
34
|
+
end
|
35
|
+
|
36
|
+
def token_cache_key
|
37
|
+
Digest::MD5.hexdigest "#{api_user_name}#{api_password}#{test}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|