solidus_bolt 0.0.1

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 (173) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +41 -0
  3. data/.gem_release.yml +5 -0
  4. data/.github/stale.yml +17 -0
  5. data/.github_changelog_generator +2 -0
  6. data/.gitignore +20 -0
  7. data/.rspec +2 -0
  8. data/.rubocop.yml +11 -0
  9. data/CHANGELOG.md +1 -0
  10. data/Gemfile +33 -0
  11. data/LICENSE +26 -0
  12. data/README.md +175 -0
  13. data/Rakefile +6 -0
  14. data/app/assets/images/bolt_logo_standard.png +0 -0
  15. data/app/assets/javascripts/authorize_account.js +74 -0
  16. data/app/assets/javascripts/solidus_bolt.js +91 -0
  17. data/app/assets/javascripts/spree/backend/solidus_bolt.js +4 -0
  18. data/app/assets/javascripts/spree/frontend/solidus_bolt.js +18 -0
  19. data/app/assets/stylesheets/spree/backend/solidus_bolt.css +4 -0
  20. data/app/assets/stylesheets/spree/frontend/solidus_bolt.css +4 -0
  21. data/app/controllers/solidus_bolt/accounts_controller.rb +17 -0
  22. data/app/controllers/solidus_bolt/base_controller.rb +21 -0
  23. data/app/controllers/solidus_bolt/webhooks_controller.rb +21 -0
  24. data/app/controllers/spree/admin/bolt_webhooks_controller.rb +34 -0
  25. data/app/controllers/spree/admin/bolts_controller.rb +43 -0
  26. data/app/decorators/controllers/solidus_bolt/spree_checkout_controller/add_addresses_to_bolt.rb +23 -0
  27. data/app/decorators/controllers/solidus_bolt/spree_checkout_controller/refresh_bolt_addresses.rb +17 -0
  28. data/app/decorators/controllers/solidus_bolt/spree_checkout_controller/refresh_bolt_payment_source.rb +17 -0
  29. data/app/decorators/models/solidus_bolt/address_decorator.rb +22 -0
  30. data/app/decorators/models/solidus_bolt/log_entry_decorator.rb +11 -0
  31. data/app/decorators/models/solidus_bolt/order_decorator.rb +44 -0
  32. data/app/decorators/models/solidus_bolt/payment_decorator.rb +11 -0
  33. data/app/decorators/omniauth/strategies/bolt_decorator.rb +16 -0
  34. data/app/jobs/solidus_bolt/add_address_job.rb +11 -0
  35. data/app/models/solidus_bolt/bolt_configuration.rb +74 -0
  36. data/app/models/solidus_bolt/gateway.rb +133 -0
  37. data/app/models/solidus_bolt/payment_method.rb +35 -0
  38. data/app/models/solidus_bolt/payment_source.rb +13 -0
  39. data/app/models/solidus_bolt.rb +7 -0
  40. data/app/overrides/spree/shared/_head/add_bolt_embed_script.html.erb.deface +6 -0
  41. data/app/services/solidus_bolt/accounts/add_address_service.rb +55 -0
  42. data/app/services/solidus_bolt/accounts/add_payment_method_service.rb +45 -0
  43. data/app/services/solidus_bolt/accounts/detail_service.rb +38 -0
  44. data/app/services/solidus_bolt/accounts/detect_account_service.rb +34 -0
  45. data/app/services/solidus_bolt/base_service.rb +55 -0
  46. data/app/services/solidus_bolt/oauth/token_service.rb +43 -0
  47. data/app/services/solidus_bolt/payments/capture_sync_service.rb +24 -0
  48. data/app/services/solidus_bolt/payments/credit_sync_service.rb +44 -0
  49. data/app/services/solidus_bolt/payments/void_sync_service.rb +18 -0
  50. data/app/services/solidus_bolt/server_error.rb +6 -0
  51. data/app/services/solidus_bolt/transactions/authorize_service.rb +72 -0
  52. data/app/services/solidus_bolt/transactions/base_service.rb +28 -0
  53. data/app/services/solidus_bolt/transactions/capture_service.rb +46 -0
  54. data/app/services/solidus_bolt/transactions/detail_service.rb +38 -0
  55. data/app/services/solidus_bolt/transactions/refund_service.rb +46 -0
  56. data/app/services/solidus_bolt/transactions/void_service.rb +44 -0
  57. data/app/services/solidus_bolt/users/refresh_access_token_service.rb +44 -0
  58. data/app/services/solidus_bolt/users/sync_addresses_service.rb +49 -0
  59. data/app/services/solidus_bolt/users/sync_payment_sources_service.rb +50 -0
  60. data/app/services/solidus_bolt/webhooks/create_service.rb +52 -0
  61. data/app/views/spree/admin/bolt_webhooks/new.html.erb +22 -0
  62. data/app/views/spree/admin/bolts/_configuration.html.erb +32 -0
  63. data/app/views/spree/admin/bolts/_form.html.erb +29 -0
  64. data/app/views/spree/admin/bolts/edit.html.erb +6 -0
  65. data/app/views/spree/admin/bolts/show.html.erb +21 -0
  66. data/app/views/spree/admin/payments/source_forms/_bolt.html.erb +1 -0
  67. data/app/views/spree/admin/payments/source_views/_bolt.html.erb +2 -0
  68. data/app/views/spree/api/payments/source_views/_bolt.json.jbuilder +4 -0
  69. data/app/views/spree/checkout/existing_payment/_bolt.html.erb +7 -0
  70. data/app/views/spree/checkout/payment/_bolt.html.erb +1 -0
  71. data/app/views/spree/shared/payment/_bolt.html.erb +19 -0
  72. data/app/webhooks/solidus_bolt/handlers/base_handler.rb +27 -0
  73. data/app/webhooks/solidus_bolt/handlers/capture_handler.rb +13 -0
  74. data/app/webhooks/solidus_bolt/handlers/credit_handler.rb +18 -0
  75. data/app/webhooks/solidus_bolt/handlers/void_handler.rb +11 -0
  76. data/app/webhooks/solidus_bolt/sorter.rb +33 -0
  77. data/bin/console +17 -0
  78. data/bin/rails +7 -0
  79. data/bin/rails-engine +13 -0
  80. data/bin/rails-sandbox +16 -0
  81. data/bin/rake +7 -0
  82. data/bin/sandbox +86 -0
  83. data/bin/setup +8 -0
  84. data/config/initializers/menu_items.rb +14 -0
  85. data/config/locales/en.yml +17 -0
  86. data/config/routes.rb +11 -0
  87. data/db/migrate/20220330094232_create_solidus_bolt_payment_sources.rb +16 -0
  88. data/db/migrate/20220413063328_create_solidus_bolt_bolt_configurations.rb +14 -0
  89. data/db/migrate/20220502005041_swap_url_for_env_boolean_in_bolt_configuration.rb +6 -0
  90. data/db/migrate/20220509102309_rework_solidus_bolt_payment_sources.rb +19 -0
  91. data/db/migrate/20220510075227_add_create_bolt_account_to_solidus_bolt_payment_source.rb +5 -0
  92. data/db/migrate/20220519233043_add_user_to_solidus_bolt_payment_source.rb +5 -0
  93. data/db/migrate/20220526005619_remove_user_id_from_solidus_bolt_payment_source.rb +5 -0
  94. data/db/migrate/20220530102107_rename_bolt_configuration_merchant_id_to_division_public_id.rb +5 -0
  95. data/db/migrate/20220531075527_update_bolt_configuration_environment_column_restrictions.rb +6 -0
  96. data/db/seeds.rb +30 -0
  97. data/lib/generators/solidus_bolt/install/install_generator.rb +78 -0
  98. data/lib/generators/solidus_bolt/install/templates/initializer.rb +8 -0
  99. data/lib/solidus_bolt/configuration.rb +19 -0
  100. data/lib/solidus_bolt/engine.rb +62 -0
  101. data/lib/solidus_bolt/testing_support/factories.rb +32 -0
  102. data/lib/solidus_bolt/version.rb +5 -0
  103. data/lib/solidus_bolt.rb +9 -0
  104. data/lib/tasks/db/seed/solidus_bolt.rake +14 -0
  105. data/lib/views/frontend/spree/shared/_login_bar_items.html.erb +18 -0
  106. data/solidus_bolt.gemspec +46 -0
  107. data/spec/decorators/models/solidus_bolt/address_decorator_spec.rb +24 -0
  108. data/spec/decorators/models/solidus_bolt/order_decorator_spec.rb +36 -0
  109. data/spec/decorators/models/solidus_bolt/payment_decorator_spec.rb +30 -0
  110. data/spec/fixtures/vcr_cassettes/SolidusBolt_Accounts_AddAddressService/_call/with_correct_access_token/receives_a_successful_response.yml +137 -0
  111. data/spec/fixtures/vcr_cassettes/SolidusBolt_Accounts_AddAddressService/_call/with_existing_address/skips_the_add_address_call.yml +82 -0
  112. data/spec/fixtures/vcr_cassettes/SolidusBolt_Accounts_AddAddressService/_call/with_wrong_access_token/gives_an_error.yml +55 -0
  113. data/spec/fixtures/vcr_cassettes/SolidusBolt_Accounts_AddPaymentMethodService/_call/with_correct_access_token/receives_a_successful_response.yml +186 -0
  114. data/spec/fixtures/vcr_cassettes/SolidusBolt_Accounts_AddPaymentMethodService/_call/with_wrong_access_token/gives_an_error.yml +179 -0
  115. data/spec/fixtures/vcr_cassettes/SolidusBolt_Accounts_DetailService/_call/with_correct_access_token/receives_a_successful_response.yml +55 -0
  116. data/spec/fixtures/vcr_cassettes/SolidusBolt_Accounts_DetailService/_call/with_wrong_access_token/gives_an_error.yml +55 -0
  117. data/spec/fixtures/vcr_cassettes/SolidusBolt_Accounts_DetectAccountService/_call/receives_the_correct_response.yml +50 -0
  118. data/spec/fixtures/vcr_cassettes/SolidusBolt_Accounts_DetectAccountService/_call/returns_status_200.yml +50 -0
  119. data/spec/fixtures/vcr_cassettes/SolidusBolt_Oauth_TokenService/_call/makes_the_API_call.yml +59 -0
  120. data/spec/fixtures/vcr_cassettes/SolidusBolt_Transactions_AuthorizeService/when_repeat_payment/_call/makes_the_API_call.yml +305 -0
  121. data/spec/fixtures/vcr_cassettes/SolidusBolt_Transactions_AuthorizeService/with_auto_capture/_call/makes_the_API_call.yml +307 -0
  122. data/spec/fixtures/vcr_cassettes/SolidusBolt_Transactions_AuthorizeService/without_auto_capture/_call/makes_the_API_call.yml +252 -0
  123. data/spec/fixtures/vcr_cassettes/SolidusBolt_Transactions_CaptureService/_call/makes_the_API_call.yml +242 -0
  124. data/spec/fixtures/vcr_cassettes/SolidusBolt_Transactions_DetailService/_call/makes_the_API_call.yml +244 -0
  125. data/spec/fixtures/vcr_cassettes/SolidusBolt_Transactions_RefundService/_call/makes_the_API_call.yml +296 -0
  126. data/spec/fixtures/vcr_cassettes/SolidusBolt_Transactions_VoidService/_call/makes_the_API_call.yml +242 -0
  127. data/spec/fixtures/vcr_cassettes/SolidusBolt_Transactions_VoidService/_call/when_transaction_id_is_missing/makes_the_API_call.yml +242 -0
  128. data/spec/fixtures/vcr_cassettes/SolidusBolt_Transactions_VoidService/_call/when_transaction_reference_is_missing/makes_the_API_call.yml +242 -0
  129. data/spec/fixtures/vcr_cassettes/SolidusBolt_Users_SyncAddressesService/_call/adds_the_bill_address_to_the_user.yml +165 -0
  130. data/spec/fixtures/vcr_cassettes/SolidusBolt_Users_SyncAddressesService/_call/adds_the_ship_address_to_the_user.yml +165 -0
  131. data/spec/fixtures/vcr_cassettes/SolidusBolt_Users_SyncPaymentSourcesService/_call/creates_a_new_payment_source_with_card_ID.yml +55 -0
  132. data/spec/fixtures/vcr_cassettes/SolidusBolt_Webhooks_CreateService/_call/with_all_event/returns_a_webhook_id.yml +54 -0
  133. data/spec/fixtures/vcr_cassettes/SolidusBolt_Webhooks_CreateService/_call/with_an_event/returns_a_webhook_id.yml +54 -0
  134. data/spec/fixtures/vcr_cassettes/SolidusBolt_Webhooks_CreateService/_call/with_empty_event/raises_a_server_error.yml +57 -0
  135. data/spec/jobs/solidus_bolt/add_address_job_spec.rb +18 -0
  136. data/spec/models/solidus_bolt/bolt_configuration_spec.rb +173 -0
  137. data/spec/models/solidus_bolt/gateway_spec.rb +130 -0
  138. data/spec/models/solidus_bolt/payment_method_spec.rb +21 -0
  139. data/spec/models/solidus_bolt/payment_source_spec.rb +22 -0
  140. data/spec/requests/solidus_bolt/accounts_controller_spec.rb +41 -0
  141. data/spec/requests/solidus_bolt/webhooks_controller_spec.rb +122 -0
  142. data/spec/requests/spree/admin/bolt_spec.rb +71 -0
  143. data/spec/requests/spree/admin/bolt_webhook_spec.rb +35 -0
  144. data/spec/requests/spree/checkout_controller_spec.rb +117 -0
  145. data/spec/services/solidus_bolt/accounts/add_address_service_spec.rb +45 -0
  146. data/spec/services/solidus_bolt/accounts/add_payment_method_service_spec.rb +47 -0
  147. data/spec/services/solidus_bolt/accounts/detail_service_spec.rb +32 -0
  148. data/spec/services/solidus_bolt/accounts/detect_account_service_spec.rb +15 -0
  149. data/spec/services/solidus_bolt/base_service_spec.rb +49 -0
  150. data/spec/services/solidus_bolt/oauth/token_service_spec.rb +15 -0
  151. data/spec/services/solidus_bolt/payments/capture_sync_service_spec.rb +27 -0
  152. data/spec/services/solidus_bolt/payments/credit_sync_service_spec.rb +38 -0
  153. data/spec/services/solidus_bolt/payments/void_sync_service_spec.rb +25 -0
  154. data/spec/services/solidus_bolt/transactions/authorize_service_spec.rb +117 -0
  155. data/spec/services/solidus_bolt/transactions/base_service_spec.rb +38 -0
  156. data/spec/services/solidus_bolt/transactions/capture_service_spec.rb +37 -0
  157. data/spec/services/solidus_bolt/transactions/detail_service_spec.rb +31 -0
  158. data/spec/services/solidus_bolt/transactions/refund_service_spec.rb +42 -0
  159. data/spec/services/solidus_bolt/transactions/void_service_spec.rb +70 -0
  160. data/spec/services/solidus_bolt/users/refresh_access_token_service_spec.rb +45 -0
  161. data/spec/services/solidus_bolt/users/sync_addresses_service_spec.rb +74 -0
  162. data/spec/services/solidus_bolt/users/sync_payment_sources_service_spec.rb +25 -0
  163. data/spec/services/solidus_bolt/webhooks/create_service_spec.rb +33 -0
  164. data/spec/spec_helper.rb +37 -0
  165. data/spec/support/bolt_configuration.rb +26 -0
  166. data/spec/support/bolt_helper.rb +66 -0
  167. data/spec/support/vcr.rb +29 -0
  168. data/spec/webhooks/solidus_bolt/handlers/base_handler_spec.rb +13 -0
  169. data/spec/webhooks/solidus_bolt/handlers/capture_handler_spec.rb +24 -0
  170. data/spec/webhooks/solidus_bolt/handlers/credit_handler_spec.rb +32 -0
  171. data/spec/webhooks/solidus_bolt/handlers/void_handler_spec.rb +19 -0
  172. data/spec/webhooks/solidus_bolt/sorter_spec.rb +39 -0
  173. metadata +492 -0
@@ -0,0 +1,32 @@
1
+ <% if @bolt_configuration.present? %>
2
+ <table class="index">
3
+ <thead>
4
+ <tr>
5
+ <th><%= SolidusBolt::BoltConfiguration.human_attribute_name(:merchant_public_id) %></th>
6
+ <th><%= SolidusBolt::BoltConfiguration.human_attribute_name(:environment) %></th>
7
+ <th><%= SolidusBolt::BoltConfiguration.human_attribute_name(:created_at) %></th>
8
+ <th><%= SolidusBolt::BoltConfiguration.human_attribute_name(:updated_at) %></th>
9
+ <th class="actions"></th>
10
+ </tr>
11
+ </thead>
12
+ <tbody>
13
+ <tr>
14
+ <td><%= @bolt_configuration.merchant_public_id %></td>
15
+ <td><%= @bolt_configuration.environment %></td>
16
+ <td>
17
+ <%= @bolt_configuration.created_at.to_s(:long) %>
18
+ </td>
19
+ <td>
20
+ <%= @bolt_configuration.updated_at.to_s(:long) %>
21
+ </td>
22
+ <td class="actions">
23
+ <% if can?(:edit, @bolt_configuration) %>
24
+ <%= link_to edit_btn, edit_admin_bolt_path, class: 'btn btn-primary' %>
25
+ <% end %>
26
+ </td>
27
+ </tr>
28
+ </tbody>
29
+ </table>
30
+ <% else %>
31
+ <p> <%= t('spree.admin.bolt.configuration_not_found') %> </p>
32
+ <% end %>
@@ -0,0 +1,29 @@
1
+ <%= render partial: 'spree/shared/error_messages', locals: { target: @bolt_configuration } %>
2
+ <fieldset class="form-group no-border-bottom no-border-top">
3
+ <div class="row">
4
+ <div id="general_fields" class="col-9">
5
+ <div class="row">
6
+ <div class="col-12">
7
+ <%= f.label :environment %>
8
+ <%= f.select :environment, %w[production sandbox staging] %><br />
9
+ <%= f.label :bearer_token %>
10
+ <%= f.text_field :bearer_token, class: 'fullwidth'%>
11
+ <%= f.label 'Merchant Public Id' %><br />
12
+ <%= f.text_field :merchant_public_id, class: 'fullwidth' %>
13
+ <%= f.label 'Division Public Id' %><br />
14
+ <%= f.text_field :division_public_id, class: 'fullwidth' %>
15
+ <%= f.label :api_key %><br />
16
+ <%= f.text_field :api_key, class: 'fullwidth' %>
17
+ <%= f.label :signing_secret %><br />
18
+ <%= f.text_field :signing_secret, class: 'fullwidth' %>
19
+ <%= f.label :publishable_key %><br />
20
+ <%= f.text_field :publishable_key, class: 'fullwidth' %>
21
+ </div>
22
+ </div>
23
+ <div class="row p-2 justify-content-center">
24
+ <%= f.submit submit_name, class: 'btn btn-primary', data: { disable_with: 'Save' } %>
25
+ <%= link_to 'Cancel', admin_bolt_path, class: 'button' %>
26
+ </div>
27
+ </div>
28
+ </div>
29
+ </fieldset>
@@ -0,0 +1,6 @@
1
+ <fieldset class="no-border-bottom">
2
+ <legend align="center"><%= t('spree.admin.bolt.edit_configuration') %></legend>
3
+ <%= form_for @bolt_configuration, url: admin_bolt_path, method: :put do |f| %>
4
+ <%= render partial: 'form', locals: { f: f, submit_name: 'Update' } %>
5
+ <% end %>
6
+ </fieldset>
@@ -0,0 +1,21 @@
1
+ <% admin_breadcrumb(plural_resource_name(SolidusBolt::BoltConfiguration)) %>
2
+
3
+ <% content_for :page_actions do %>
4
+ <% if SolidusBolt::BoltConfiguration.config_empty? %>
5
+ <li>
6
+ <p>Don't have a <%= image_tag "bolt_logo_standard.png", alt: "Bolt", width: "40" %> Merchant account yet?</p>
7
+ </li>
8
+ <li>
9
+ <%= link_to t('spree.admin.bolt.create_merchant_account'), SolidusBolt::BoltConfiguration::REGISTER_URL, class: 'btn btn-primary', target: '_blank' %>
10
+ </li>
11
+ <% else %>
12
+ <li>
13
+ <%= link_to 'Configure Webhooks', new_admin_bolt_webhook_path, class: 'btn btn-primary' %>
14
+ </li>
15
+ <% end %>
16
+ <% end %>
17
+
18
+ <fieldset class="no-border-bottom">
19
+ <legend align="center"><%= t('spree.admin.bolt.configuration') %></legend>
20
+ <%= render partial: 'configuration', locals: { edit_btn: 'Edit' } %>
21
+ </fieldset>
@@ -0,0 +1 @@
1
+ <%= render 'spree/shared/payment/bolt', frontend: false, payment_method: payment_method %>
@@ -0,0 +1,2 @@
1
+ <p>Card Number: <b>XXXX-XXXX-XXXX-<%= @payment.source.card_last4 %></b></p>
2
+ <p>Expiration:<b> <%= @payment.source.card_expiration %></b></p>
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ json.call(payment_source, :id, :created_at, :card_token, :card_last4, :card_bin, :card_number, :card_expiration,
4
+ :card_postal_code, :card_id, :create_bolt_account)
@@ -0,0 +1,7 @@
1
+ <tr id="<%= dom_id(wallet_payment_source, 'spree')%>" class="<%= cycle('even', 'odd') %>">
2
+ <td><%= wallet_payment_source.payment_source.card_last4 %></td>
3
+ <td><%= wallet_payment_source.payment_source.card_expiration %></td>
4
+ <td>
5
+ <%= radio_button_tag "order[wallet_payment_source_id]", wallet_payment_source.id, default, class: "existing-cc-radio" %>
6
+ </td>
7
+ </tr>
@@ -0,0 +1 @@
1
+ <%= render 'spree/shared/payment/bolt', frontend: true, payment_method: payment_method %>
@@ -0,0 +1,19 @@
1
+ <div id="bolt-container"
2
+ data-publishable-key="<%= payment_method.preferred_bolt_publishable_key %>"
3
+ data-payment-method-id="<%= payment_method.id %>"
4
+ data-frontend="<%= frontend %>"
5
+ data-bolt-user-signed-in="<%= spree_current_user&.user_authentications&.where(provider: 'bolt')&.exists? == true %>"
6
+ ></div>
7
+ <div id="payment-status-container" style="display: none;">
8
+ <div id="account-checkbox"></div>
9
+ <br>
10
+ <button id="bolt-submit-button" type="button">Submit</button>
11
+ <br>
12
+ </div>
13
+ <button id="bolt-card-button" type="button">Pay</button>
14
+
15
+ <% unless frontend %>
16
+ <% content_for :head do %>
17
+ <script id="bolt-embedded" type="text/javascript" src="<%= payment_method.preferred_bolt_base_url %>"></script>
18
+ <% end %>
19
+ <% end %>
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusBolt
4
+ module Handlers
5
+ class BaseHandler
6
+ attr_reader :params
7
+
8
+ def initialize(params)
9
+ @params = params
10
+ end
11
+
12
+ def self.call(params)
13
+ new(params).call
14
+ end
15
+
16
+ def call
17
+ raise NotImplementedError, 'Missing #call method on class'
18
+ end
19
+
20
+ private
21
+
22
+ def payment
23
+ Spree::Payment.find_by(response_code: params[:data][:reference])
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusBolt
4
+ module Handlers
5
+ class CaptureHandler < BaseHandler
6
+ def call
7
+ capture_amount = params[:data][:captures].last[:amount][:amount].to_i
8
+
9
+ SolidusBolt::Payments::CaptureSyncService.call(payment: payment, capture_amount: capture_amount)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusBolt
4
+ module Handlers
5
+ class CreditHandler < BaseHandler
6
+ def call
7
+ payment_response_code = params[:data][:source_transaction][:reference]
8
+ source_payment = Spree::Payment.find_by(response_code: payment_response_code)
9
+ amount = params[:data][:requested_refund_amount][:amount].to_i
10
+ refund_transaction_id = params[:data][:reference]
11
+
12
+ SolidusBolt::Payments::CreditSyncService.call(
13
+ payment: source_payment, amount: amount, transaction_id: refund_transaction_id
14
+ )
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusBolt
4
+ module Handlers
5
+ class VoidHandler < BaseHandler
6
+ def call
7
+ SolidusBolt::Payments::VoidSyncService.call(payment: payment)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusBolt
4
+ class Sorter
5
+ attr_reader :params
6
+
7
+ def self.call(params)
8
+ new(params).call
9
+ end
10
+
11
+ def initialize(params)
12
+ @params = params
13
+ end
14
+
15
+ def call
16
+ handler&.call(params)
17
+ end
18
+
19
+ private
20
+
21
+ def handler
22
+ class_name = "#{event_type.split('.').map(&:capitalize).join}Handler"
23
+
24
+ return unless SolidusBolt::Handlers.const_defined?(class_name)
25
+
26
+ SolidusBolt::Handlers.const_get(class_name)
27
+ end
28
+
29
+ def event_type
30
+ params[:type]
31
+ end
32
+ end
33
+ end
data/bin/console ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # frozen_string_literal: true
4
+
5
+ require "bundler/setup"
6
+ require "solidus_bolt"
7
+
8
+ # You can add fixtures and/or initialization code here to make experimenting
9
+ # with your gem easier. You can also use a different console, if you like.
10
+ $LOAD_PATH.unshift(*Dir["#{__dir__}/../app/*"])
11
+
12
+ # (If you use this, don't forget to add pry to your Gemfile!)
13
+ # require "pry"
14
+ # Pry.start
15
+
16
+ require "irb"
17
+ IRB.start(__FILE__)
data/bin/rails ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ if %w[g generate].include? ARGV.first
4
+ exec "#{__dir__}/rails-engine", *ARGV
5
+ else
6
+ exec "#{__dir__}/rails-sandbox", *ARGV
7
+ end
data/bin/rails-engine ADDED
@@ -0,0 +1,13 @@
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/solidus_bolt/engine', __dir__)
7
+
8
+ # Set up gems listed in the Gemfile.
9
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
10
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
11
+
12
+ require 'rails/all'
13
+ require 'rails/engine/commands'
data/bin/rails-sandbox ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ app_root = 'sandbox'
4
+
5
+ unless File.exist? "#{app_root}/bin/rails"
6
+ warn 'Creating the sandbox app...'
7
+ Dir.chdir "#{__dir__}/.." do
8
+ system "#{__dir__}/sandbox" or begin
9
+ warn 'Automatic creation of the sandbox app failed'
10
+ exit 1
11
+ end
12
+ end
13
+ end
14
+
15
+ Dir.chdir app_root
16
+ exec 'bin/rails', *ARGV
data/bin/rake ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "rubygems"
5
+ require "bundler/setup"
6
+
7
+ load Gem.bin_path("rake", "rake")
data/bin/sandbox ADDED
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -e
4
+
5
+ case "$DB" in
6
+ postgres|postgresql)
7
+ RAILSDB="postgresql"
8
+ ;;
9
+ mysql)
10
+ RAILSDB="mysql"
11
+ ;;
12
+ sqlite|'')
13
+ RAILSDB="sqlite3"
14
+ ;;
15
+ *)
16
+ echo "Invalid DB specified: $DB"
17
+ exit 1
18
+ ;;
19
+ esac
20
+
21
+ if [ ! -z $SOLIDUS_BRANCH ]
22
+ then
23
+ BRANCH=$SOLIDUS_BRANCH
24
+ else
25
+ BRANCH="master"
26
+ fi
27
+
28
+ extension_name="solidus_bolt"
29
+
30
+ # Stay away from the bundler env of the containing extension.
31
+ function unbundled {
32
+ ruby -rbundler -e'b = proc {system *ARGV}; Bundler.respond_to?(:with_unbundled_env) ? Bundler.with_unbundled_env(&b) : Bundler.with_clean_env(&b)' -- $@
33
+ }
34
+
35
+ rm -rf ./sandbox
36
+ unbundled bundle exec rails new sandbox --database="$RAILSDB" \
37
+ --skip-bundle \
38
+ --skip-git \
39
+ --skip-keeps \
40
+ --skip-rc \
41
+ --skip-spring \
42
+ --skip-test \
43
+ --skip-javascript
44
+
45
+ if [ ! -d "sandbox" ]; then
46
+ echo 'sandbox rails application failed'
47
+ exit 1
48
+ fi
49
+
50
+ cd ./sandbox
51
+ cat <<RUBY >> Gemfile
52
+ gem 'solidus', github: 'solidusio/solidus', branch: '$BRANCH'
53
+ gem 'solidus_auth_devise', '>= 2.1.0'
54
+ gem 'rails-i18n'
55
+ gem 'solidus_i18n'
56
+
57
+ gem '$extension_name', path: '..'
58
+
59
+ group :test, :development do
60
+ platforms :mri do
61
+ gem 'pry-byebug'
62
+ end
63
+ end
64
+ RUBY
65
+
66
+ unbundled bundle install --gemfile Gemfile
67
+
68
+ unbundled bundle exec rake db:drop db:create
69
+
70
+ unbundled bundle exec rails generate solidus:install \
71
+ --auto-accept \
72
+ --user_class=Spree::User \
73
+ --enforce_available_locales=true \
74
+ --with-authentication=false \
75
+ --payment-method=none \
76
+ $@
77
+
78
+ unbundled bundle exec rails generate solidus:auth:install
79
+ unbundled bundle exec rails generate ${extension_name}:install
80
+
81
+ echo
82
+ echo "🚀 Sandbox app successfully created for $extension_name!"
83
+ echo "🚀 Using $RAILSDB and Solidus $BRANCH"
84
+ echo "🚀 Use 'export DB=[postgres|mysql|sqlite]' to control the DB adapter"
85
+ echo "🚀 Use 'export SOLIDUS_BRANCH=<BRANCH-NAME>' to control the Solidus version"
86
+ echo "🚀 This app is intended for test purposes."
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ gem install bundler --conservative
7
+ bundle update
8
+ bin/rake clobber
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ Spree::Backend::Config.configure do |config|
4
+ config.locale = 'en'
5
+
6
+ config.menu_items << config.class::MenuItem.new(
7
+ [:bolt],
8
+ 'bolt',
9
+ condition: -> { can?(:admin, :bolt) },
10
+ url: :admin_bolt_path,
11
+ position: 6,
12
+ match_path: %r{/admin/bolt/}
13
+ )
14
+ end
@@ -0,0 +1,17 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+
4
+ en:
5
+ activerecord:
6
+ models:
7
+ solidus_bolt/payment_method: Bolt
8
+ spree:
9
+ admin:
10
+ bolt:
11
+ configuration: 'Bolt Configuration'
12
+ configuration_not_found: 'No Bolt Configuration found'
13
+ edit_configuration: 'Edit Bolt Configuration'
14
+ updated_successfully: 'Bolt Configuration Updated Successfully'
15
+ create_merchant_account: 'Create Merchant Account'
16
+ tab:
17
+ bolt: 'Bolt'
data/config/routes.rb ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ Spree::Core::Engine.routes.draw do
4
+ namespace :admin do
5
+ resource :bolt, only: [:show, :edit, :update]
6
+ resource :bolt_webhook, only: [:new, :create]
7
+ end
8
+
9
+ post '/webhooks/bolt', to: '/solidus_bolt/webhooks#update'
10
+ post '/api/accounts/bolt', to: '/solidus_bolt/accounts#create'
11
+ end
@@ -0,0 +1,16 @@
1
+ class CreateSolidusBoltPaymentSources < ActiveRecord::Migration[6.1]
2
+ def change
3
+ create_table :solidus_bolt_payment_sources do |t|
4
+ t.integer :payment_method_id, index: true
5
+ t.string :transaction_id
6
+ t.string :transaction_reference, null: false
7
+ t.string :transaction_type
8
+ t.string :processor
9
+ t.date :date
10
+ t.string :transaction_status
11
+ t.decimal :amount, precision: 10, scale: 2
12
+ t.string :currency
13
+ t.timestamps
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ class CreateSolidusBoltBoltConfigurations < ActiveRecord::Migration[6.1]
2
+ def change
3
+ create_table :solidus_bolt_bolt_configurations do |t|
4
+ t.string :bearer_token
5
+ t.string :environment_url
6
+ t.string :merchant_public_id
7
+ t.string :merchant_id
8
+ t.string :api_key
9
+ t.string :signing_secret
10
+ t.string :publishable_key
11
+ t.timestamps
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,6 @@
1
+ class SwapUrlForEnvBooleanInBoltConfiguration < ActiveRecord::Migration[6.1]
2
+ def change
3
+ add_column :solidus_bolt_bolt_configurations, :environment, :integer
4
+ remove_column :solidus_bolt_bolt_configurations, :environment_url, :string
5
+ end
6
+ end
@@ -0,0 +1,19 @@
1
+ class ReworkSolidusBoltPaymentSources < ActiveRecord::Migration[6.1]
2
+ def change
3
+ remove_column :solidus_bolt_payment_sources, :transaction_id, :string
4
+ remove_column :solidus_bolt_payment_sources, :transaction_reference, :string
5
+ remove_column :solidus_bolt_payment_sources, :transaction_type, :string
6
+ remove_column :solidus_bolt_payment_sources, :processor, :string
7
+ remove_column :solidus_bolt_payment_sources, :date, :date
8
+ remove_column :solidus_bolt_payment_sources, :transaction_status, :string
9
+ remove_column :solidus_bolt_payment_sources, :amount, :decimal
10
+ remove_column :solidus_bolt_payment_sources, :currency, :string
11
+ add_column :solidus_bolt_payment_sources, :card_token, :string
12
+ add_column :solidus_bolt_payment_sources, :card_last4, :string
13
+ add_column :solidus_bolt_payment_sources, :card_bin, :string
14
+ add_column :solidus_bolt_payment_sources, :card_number, :string
15
+ add_column :solidus_bolt_payment_sources, :card_expiration, :string
16
+ add_column :solidus_bolt_payment_sources, :card_postal_code, :string
17
+ add_column :solidus_bolt_payment_sources, :card_id, :string
18
+ end
19
+ end
@@ -0,0 +1,5 @@
1
+ class AddCreateBoltAccountToSolidusBoltPaymentSource < ActiveRecord::Migration[6.1]
2
+ def change
3
+ add_column :solidus_bolt_payment_sources, :create_bolt_account, :boolean, default: false
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddUserToSolidusBoltPaymentSource < ActiveRecord::Migration[6.1]
2
+ def change
3
+ add_column :solidus_bolt_payment_sources, :user_id, :integer
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class RemoveUserIdFromSolidusBoltPaymentSource < ActiveRecord::Migration[6.1]
2
+ def change
3
+ remove_column :solidus_bolt_payment_sources, :user_id, :integer
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class RenameBoltConfigurationMerchantIdToDivisionPublicId < ActiveRecord::Migration[6.1]
2
+ def change
3
+ rename_column :solidus_bolt_bolt_configurations, :merchant_id, :division_public_id
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ class UpdateBoltConfigurationEnvironmentColumnRestrictions < ActiveRecord::Migration[6.1]
2
+ def change
3
+ remove_column :solidus_bolt_bolt_configurations, :environment, :integer
4
+ add_column :solidus_bolt_bolt_configurations, :environment, :integer, null: false, default: 1
5
+ end
6
+ end
data/db/seeds.rb ADDED
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ solidus_bolt_configuration = SolidusBolt::BoltConfiguration.fetch
4
+
5
+ solidus_bolt_configuration.bearer_token = ENV['BOLT_BEARER_TOKEN']
6
+ solidus_bolt_configuration.environment = ENV['BOLT_ENVIRONMENT']
7
+ solidus_bolt_configuration.merchant_public_id = ENV['BOLT_MERCHANT_PUBLIC_ID']
8
+ solidus_bolt_configuration.division_public_id = ENV['BOLT_DIVISION_PUBLIC_ID']
9
+ solidus_bolt_configuration.api_key = ENV['BOLT_API_KEY']
10
+ solidus_bolt_configuration.signing_secret = ENV['BOLT_SIGNING_SECRET']
11
+ solidus_bolt_configuration.publishable_key = ENV['BOLT_PUBLISHABLE_KEY']
12
+
13
+ solidus_bolt_configuration.save
14
+
15
+ Spree::AuthenticationMethod.find_or_create_by(provider: :bolt) do |authentication_method|
16
+ authentication_method.environment = "development"
17
+ authentication_method.provider = "bolt"
18
+ authentication_method.api_key = SolidusBolt::BoltConfiguration.fetch.publishable_key
19
+ authentication_method.api_secret = SolidusBolt::BoltConfiguration.fetch.api_key
20
+ authentication_method.active = true
21
+ end
22
+
23
+ if ENV['BOLT_API_KEY'] && ENV['BOLT_SIGNING_SECRET'] && ENV['BOLT_PUBLISHABLE_KEY']
24
+ SolidusBolt::PaymentMethod.create!(
25
+ type: 'SolidusBolt::PaymentMethod',
26
+ name: 'Bolt',
27
+ preference_source: 'bolt_credentials',
28
+ active: true
29
+ )
30
+ end