spree_braintree_vzero 3.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.codeclimate.yml +15 -0
- data/.gitignore +19 -0
- data/.rspec +1 -0
- data/.travis.yml +63 -0
- data/Appraisals +45 -0
- data/CONTRIBUTING.md +28 -0
- data/Gemfile +14 -0
- data/LICENSE +26 -0
- data/README.md +83 -0
- data/Rakefile +21 -0
- data/app/assets/images/credit_cards/icons/jcb.png +0 -0
- data/app/assets/javascripts/spree/backend/payments.js +19 -0
- data/app/assets/javascripts/spree/backend/spree_braintree_vzero.js +81 -0
- data/app/assets/javascripts/spree/frontend/spree_braintree_vzero.js +68 -0
- data/app/assets/stylesheets/spree/backend/spree_braintree_vzero.css +5 -0
- data/app/controllers/spree/admin/payments_controller_decorator.rb +43 -0
- data/app/controllers/spree/api/v1/braintree_client_token_controller.rb +31 -0
- data/app/controllers/spree/checkout_controller_decorator.rb +38 -0
- data/app/controllers/spree/orders_controller_decorator.rb +62 -0
- data/app/controllers/spree/user_sessions_controller_decorator.rb +15 -0
- data/app/helpers/spree/admin/decorated_navigation_helper.rb +10 -0
- data/app/helpers/spree/admin/payment_methods_helper.rb +101 -0
- data/app/helpers/spree/braintree_helper.rb +27 -0
- data/app/models/braintree/successful_result_decorator.rb +21 -0
- data/app/models/spree/address_decorator.rb +18 -0
- data/app/models/spree/braintree_checkout.rb +105 -0
- data/app/models/spree/gateway/braintree_vzero_base.rb +168 -0
- data/app/models/spree/gateway/braintree_vzero_base/address.rb +33 -0
- data/app/models/spree/gateway/braintree_vzero_base/braintree_user.rb +25 -0
- data/app/models/spree/gateway/braintree_vzero_base/purchase_data.rb +48 -0
- data/app/models/spree/gateway/braintree_vzero_base/transaction.rb +39 -0
- data/app/models/spree/gateway/braintree_vzero_base/utils.rb +108 -0
- data/app/models/spree/gateway/braintree_vzero_drop_in_ui.rb +24 -0
- data/app/models/spree/gateway/braintree_vzero_hosted_fields.rb +28 -0
- data/app/models/spree/gateway/braintree_vzero_paypal_express.rb +36 -0
- data/app/models/spree/order_decorator.rb +153 -0
- data/app/models/spree/payment_decorator.rb +10 -0
- data/app/models/spree/payment_processing_decorator.rb +61 -0
- data/app/models/spree/preferences/preferable_decorator.rb +54 -0
- data/app/overrides/spree/admin/orders/customer_details/_form.rb +8 -0
- data/app/overrides/spree/admin/payment_methods/_form.rb +10 -0
- data/app/overrides/spree/admin/shared/_order_summary.rb +23 -0
- data/app/overrides/spree/admin/shared/_refunds.rb +13 -0
- data/app/overrides/spree/checkout/_new_user.rb +6 -0
- data/app/overrides/spree/checkout/_payment.rb +20 -0
- data/app/overrides/spree/checkout/registration.rb +6 -0
- data/app/overrides/spree/orders/edit.rb +6 -0
- data/app/overrides/spree/shared/_order_details.rb +13 -0
- data/app/overrides/spree/shared/_payment.rb +28 -0
- data/app/views/spree/admin/payment_methods/_braintree_vzero_form.html.erb +83 -0
- data/app/views/spree/admin/payments/source_forms/_braintree_vzero_dropin_ui.html.erb +1 -0
- data/app/views/spree/admin/payments/source_forms/_braintree_vzero_hosted_fields.html.erb +1 -0
- data/app/views/spree/admin/payments/source_forms/_braintree_vzero_paypal_express.html.erb +1 -0
- data/app/views/spree/admin/payments/source_forms/braintree_vzero/_payments.html.erb +87 -0
- data/app/views/spree/admin/payments/source_views/_braintree_vzero_dropin_ui.html.erb +1 -0
- data/app/views/spree/admin/payments/source_views/_braintree_vzero_hosted_fields.html.erb +1 -0
- data/app/views/spree/admin/payments/source_views/_braintree_vzero_paypal_express.html.erb +1 -0
- data/app/views/spree/admin/payments/source_views/braintree_vzero/_payment.html.erb +17 -0
- data/app/views/spree/braintree_vzero/_paypal_checkout.html.erb +87 -0
- data/app/views/spree/checkout/payment/_braintree_vzero_dropin_ui.html.erb +4 -0
- data/app/views/spree/checkout/payment/_braintree_vzero_hosted_fields.html.erb +4 -0
- data/app/views/spree/checkout/payment/_braintree_vzero_paypal_express.html.erb +4 -0
- data/app/views/spree/checkout/payment/braintree_vzero/_buttons.html.erb +11 -0
- data/app/views/spree/checkout/payment/braintree_vzero/_dropin_on_error_callback.js.erb +3 -0
- data/app/views/spree/checkout/payment/braintree_vzero/_dropin_on_ready_callback.js.erb +1 -0
- data/app/views/spree/checkout/payment/braintree_vzero/_hosted_fields_on_field_event_callback.js.erb +12 -0
- data/app/views/spree/checkout/payment/braintree_vzero/_hosted_fields_styles.js.erb +29 -0
- data/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb +84 -0
- data/app/views/spree/checkout/payment/braintree_vzero/_three_d_secure.html.erb +218 -0
- data/app/views/spree/shared/braintree_vzero/_dropin.js.erb +70 -0
- data/app/views/spree/shared/braintree_vzero/_hosted.js.erb +66 -0
- data/app/views/spree/shared/braintree_vzero/_paypal.js.erb +39 -0
- data/bin/rails +7 -0
- data/config/initializers/extend_spree_permitted_checkout_attributes.rb +5 -0
- data/config/initializers/prepend_helpers.rb +1 -0
- data/config/locales/en.yml +79 -0
- data/config/routes.rb +7 -0
- data/db/migrate/20150904143013_create_spree_braintree_checkouts.rb +9 -0
- data/db/migrate/20151002094655_add_braintree_id_to_spree_addresses.rb +5 -0
- data/db/migrate/20151018123907_add_braintree_token_and_nonce_to_spree_payments.rb +6 -0
- data/db/migrate/20151027135109_add_paypal_email_to_spree_braintree_checkout.rb +5 -0
- data/db/migrate/20151028095515_add_advanced_fraud_data_to_spree_braintree_checkout.rb +5 -0
- data/db/migrate/20151202095956_add_risk_id_and_risk_decision_to_spree_braintree_checkouts.rb +6 -0
- data/db/migrate/20151211100203_add_braintree_last_digits_and_braintree_card_type_to_spree_braintree_checkouts.rb +6 -0
- data/db/migrate/20160112153422_add_admin_payment_to_spree_braintree_checkout.rb +5 -0
- data/gemfiles/spree_3_5.gemfile +12 -0
- data/gemfiles/spree_3_5_spree_auth_devise.gemfile +13 -0
- data/gemfiles/spree_3_7.gemfile +12 -0
- data/gemfiles/spree_3_7_spree_auth_devise.gemfile +13 -0
- data/gemfiles/spree_4_0.gemfile +11 -0
- data/gemfiles/spree_4_0_spree_auth_devise.gemfile +12 -0
- data/gemfiles/spree_master.gemfile +11 -0
- data/gemfiles/spree_master_spree_auth_devise.gemfile +12 -0
- data/lib/generators/spree_braintree_vzero/install/install_generator.rb +34 -0
- data/lib/spree_braintree_vzero.rb +6 -0
- data/lib/spree_braintree_vzero/engine.rb +28 -0
- data/lib/spree_braintree_vzero/factories.rb +10 -0
- data/lib/spree_braintree_vzero/railtie.rb +8 -0
- data/lib/spree_braintree_vzero/version.rb +17 -0
- data/lib/tasks/spree_braintree_vzero.rake +6 -0
- data/spec/controllers/spree/api/v1/braintree_client_token_controller_spec.rb +49 -0
- data/spec/controllers/spree/checkout_controller_spec.rb +85 -0
- data/spec/controllers/spree/orders_controller_spec.rb +97 -0
- data/spec/factories/braintree_checkout_factory.rb +7 -0
- data/spec/factories/braintree_gateway_factory.rb +35 -0
- data/spec/factories/payment_factory_decorator.rb +28 -0
- data/spec/features/spree/admin/log_entries_spec.rb +63 -0
- data/spec/models/gateway/braintree_vzero_base/address_spec.rb +28 -0
- data/spec/models/gateway/braintree_vzero_base/purchase_data_spec.rb +57 -0
- data/spec/models/gateway/braintree_vzero_base_spec.rb +346 -0
- data/spec/models/gateway/braintree_vzero_dropin_ui_spec.rb +35 -0
- data/spec/models/gateway/braintree_vzero_hosted_fields_spec.rb +35 -0
- data/spec/models/spree/order_spec.rb +186 -0
- data/spec/spec_helper.rb +100 -0
- data/spec/support/vcr.rb +10 -0
- data/spec/vcr/Log_entries/with_a_failed_log_entry/shows_a_failed_attempt.yml +91 -0
- data/spec/vcr/Log_entries/with_a_successful_log_entry/shows_a_successful_attempt.yml +113 -0
- data/spec/vcr/Spree_Api_V1_BraintreeClientTokenController/POST_create/guest_checkout/returns_proper_json_data_when_gateway_not_specified.yml +90 -0
- data/spec/vcr/Spree_Api_V1_BraintreeClientTokenController/POST_create/guest_checkout/returns_proper_json_data_when_gateway_specified.yml +90 -0
- data/spec/vcr/Spree_Api_V1_BraintreeClientTokenController/POST_create/user_checkout/returns_proper_json_data_when_gateway_not_specified.yml +191 -0
- data/spec/vcr/Spree_Api_V1_BraintreeClientTokenController/POST_create/user_checkout/returns_proper_json_data_when_gateway_specified.yml +191 -0
- data/spec/vcr/Spree_CheckoutController/_update/braintree_payment/advanced_fraud_data_in_source_should_be_updated.yml +71 -0
- data/spec/vcr/Spree_CheckoutController/_update/braintree_payment/when_token_credit_card_data_in_source_should_be_updated_from_Braintree_Vault.yml +139 -0
- data/spec/vcr/Spree_CheckoutController/_update/braintree_paypal_express_payment/amount_in_payment_should_be_updated.yml +280 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_capture/captures_authorized_amount/updates_Payment_state.yml +206 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_credit/with_refundable_state/should_be_a_success.yml +211 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_credit/with_unrefundable_state/should_not_be_a_success.yml +177 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/data_from_admin_panel/should_include_only_essential_data.yml +78 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/does_not_store_Transaction_in_Vault_by_default.yml +111 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/returns_false_with_invalid_nonce.yml +88 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/returns_false_with_invalid_token.yml +88 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/returns_success_with_valid_token.yml +113 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/returns_suceess_with_valid_nonce.yml +111 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/using_Vault/saves_Braintree_Address_id_to_Spree_Address_when_address_is_being_saved.yml +130 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/using_Vault/saves_unique_Braintree_Addresses_ids.yml +143 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/using_Vault/sends_empty_address_id_when_address_is_already_in_vault.yml +553 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/using_Vault/stores_Transaction.yml +181 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/with_3DSecure_option_turned_on/performs_3DSecure_check.yml +112 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/with_3DSecure_option_turned_on/returns_error.yml +112 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/with_advanced_fraud_tool_enabled/returns_fraud_data.yml +111 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/with_advanced_fraud_tool_enabled/returns_success.yml +111 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_settle/settles_authorized_amount/does_not_update_Order_payment_state.yml +204 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_settle/settles_authorized_amount/prepares_Checkout_for_status_updating.yml +204 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_settle/settles_authorized_amount/submits_Transaction_for_settlement.yml +377 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_settle/settles_authorized_amount/updates_Payment_state.yml +203 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_update_states/does_not_update_completed_Checkout_on_subsequent_runs.yml +202 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_update_states/updates_Order_payment_state_when_Checkout_is_updated.yml +202 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_update_states/updates_Payment_state_when_Checkout_is_updated.yml +202 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_update_states/updates_payment_State.yml +202 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_void/with_unvoidable_state/should_not_change_payment_source_state.yml +178 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_void/with_voidable_state/should_change_payment_source_state_to_voided.yml +199 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/generates_token_for_User_registered_in_Braintree.yml +356 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/generates_token_for_new_User.yml +189 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/generates_token_without_User.yml +89 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/with_invalid_credentials/raises_Braintree_error.yml +62 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase_Address/_create/creates_Braintree_Address.yml +84 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase_Address/_create/deletes_Braintree_Address.yml +141 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase_Address/_create/finds_Braintree_Address.yml +148 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase_Address/_create/updates_Braintree_Address.yml +154 -0
- data/spec/vcr/Spree_Order/complete_with_braintree_vzero_standard_payment/with_auto_capture/should_complete_payment.yml +116 -0
- data/spec/vcr/Spree_Order/complete_with_braintree_vzero_standard_payment/with_auto_capture/should_update_payment_s_response_code.yml +111 -0
- data/spec/vcr/Spree_Order/complete_with_braintree_vzero_standard_payment/with_auto_capture/should_update_payment_s_source_state_and_transaction_id.yml +111 -0
- data/spec/vcr/Spree_Order/complete_with_braintree_vzero_standard_payment/without_auto_capture/should_pend_payment.yml +111 -0
- data/spec/vcr/Spree_Order/complete_with_braintree_vzero_standard_payment/without_auto_capture/should_update_payment_s_response_code.yml +111 -0
- data/spec/vcr/Spree_Order/complete_with_braintree_vzero_standard_payment/without_auto_capture/should_update_payment_s_source_state_and_transaction_id.yml +110 -0
- data/spree_braintree_vzero.gemspec +52 -0
- data/vendor/assets/javascripts/maskedinput/jquery.maskedinput.min.js +7 -0
- metadata +643 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
module Spree
|
2
|
+
class Gateway::BraintreeVzeroHostedFields < Spree::Gateway::BraintreeVzeroBase
|
3
|
+
preference :checkout_form_id, :string, default: 'checkout_form_payment'
|
4
|
+
preference :error_messages_container_id, :string, default: 'content'
|
5
|
+
preference :number_selector, :string, default: '#hosted-fields-number'
|
6
|
+
preference :number_placeholder, :string, default: 'Card Number'
|
7
|
+
preference :cvv_selector, :string, default: '#hosted-fields-cvv'
|
8
|
+
preference :cvv_placeholder, :string, default: 'Cvv code'
|
9
|
+
preference :expiration_date_selector, :string, default: '#hosted-fields-expiration-date'
|
10
|
+
preference :expiration_date_placeholder, :string, default: 'Card Expiration Date'
|
11
|
+
preference :store_payments_in_vault, :select, default: -> { { values: [:do_not_store, :store_only_on_success, :store_all] } }
|
12
|
+
preference :'3dsecure', :boolean_select, default: false
|
13
|
+
|
14
|
+
after_save :disable_dropin_gateways, if: proc {
|
15
|
+
active? && (saved_changes.keys & %w[active id]).any?
|
16
|
+
}
|
17
|
+
|
18
|
+
def method_type
|
19
|
+
'braintree_vzero_hosted_fields'
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def disable_dropin_gateways
|
25
|
+
Spree::Gateway::BraintreeVzeroDropInUi.update_all(active: false)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Spree
|
2
|
+
class Gateway::BraintreeVzeroPaypalExpress < Spree::Gateway::BraintreeVzeroBase
|
3
|
+
preference :paypal_display_on_cart, :boolean_select, default: true
|
4
|
+
preference :store_payments_in_vault, :select, default: -> { { values: [:do_not_store, :store_all] } }
|
5
|
+
preference :paypal_display_name, :string
|
6
|
+
preference :checkout_form_id, :string, default: 'checkout_form_payment'
|
7
|
+
preference :error_messages_container_id, :string, default: 'content'
|
8
|
+
|
9
|
+
def method_type
|
10
|
+
'braintree_vzero_paypal_express'
|
11
|
+
end
|
12
|
+
|
13
|
+
def push_order_to_state(order, state, email)
|
14
|
+
order.update_column(:email, email)
|
15
|
+
order.next! until order.state.eql?(state)
|
16
|
+
order.update_column(:email, nil)
|
17
|
+
end
|
18
|
+
|
19
|
+
def find_identifier_hash(payment, utils)
|
20
|
+
token = payment[:braintree_token] || vaulted_token_by_email(payment, utils)
|
21
|
+
if token.present?
|
22
|
+
{ payment_method_token: token }
|
23
|
+
else
|
24
|
+
{ payment_method_nonce: payment[:braintree_nonce] }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def vaulted_token_by_email(payment, utils)
|
31
|
+
utils.customer_payment_methods('paypal').find do |customer_payment|
|
32
|
+
customer_payment.try(:email).eql?(payment.source.paypal_email)
|
33
|
+
end.try(:token)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
module Spree
|
2
|
+
module OrderDecorator
|
3
|
+
def self.prepended(base)
|
4
|
+
base.state_machine.before_transition to: :complete, do: :process_paypal_express_payments
|
5
|
+
end
|
6
|
+
|
7
|
+
def save_paypal_address(type, address_hash)
|
8
|
+
return if address_hash.blank?
|
9
|
+
address = Spree::Address.new(prepare_address_hash(address_hash))
|
10
|
+
return unless address.save
|
11
|
+
|
12
|
+
update_column("#{type}_id", address.id)
|
13
|
+
end
|
14
|
+
|
15
|
+
def save_paypal_payment(options)
|
16
|
+
options[:source] = Spree::BraintreeCheckout.create!(options.slice(:paypal_email, :advanced_fraud_data))
|
17
|
+
payments.create(options.slice(:braintree_nonce, :payment_method_id, :source))
|
18
|
+
end
|
19
|
+
|
20
|
+
def set_billing_address
|
21
|
+
return if bill_address_id
|
22
|
+
return unless ship_address_id
|
23
|
+
|
24
|
+
address = Spree::Address.create(shipping_address.attributes.except('id', 'updated_at', 'created_at', 'braintree_id'))
|
25
|
+
update_column(:bill_address_id, address.try(:id))
|
26
|
+
end
|
27
|
+
|
28
|
+
# override needed to add braintree source attribute
|
29
|
+
def update_from_params(params, permitted_params, request_env = {})
|
30
|
+
success = false
|
31
|
+
@updating_params = params
|
32
|
+
run_callbacks :updating_from_params do
|
33
|
+
# Set existing card after setting permitted parameters because
|
34
|
+
# rails would slice parameters containg ruby objects, apparently
|
35
|
+
existing_card_id = @updating_params[:order] ? @updating_params[:order].delete(:existing_card) : nil
|
36
|
+
|
37
|
+
attributes = @updating_params[:order] ? @updating_params[:order].permit(permitted_params).delete_if { |_k, v| v.nil? } : {}
|
38
|
+
payment_attributes = attributes[:payments_attributes].first if attributes[:payments_attributes].present?
|
39
|
+
|
40
|
+
if existing_card_id.present?
|
41
|
+
credit_card = Spree::CreditCard.find existing_card_id
|
42
|
+
if credit_card.user_id != user_id || credit_card.user_id.blank?
|
43
|
+
raise Spree::Core::GatewayError, Spree.t(:invalid_credit_card)
|
44
|
+
end
|
45
|
+
|
46
|
+
credit_card.verification_value = params[:cvc_confirm] if params[:cvc_confirm].present?
|
47
|
+
|
48
|
+
attributes[:payments_attributes].first[:source] = credit_card
|
49
|
+
attributes[:payments_attributes].first[:payment_method_id] = credit_card.payment_method_id
|
50
|
+
attributes[:payments_attributes].first.delete :source_attributes
|
51
|
+
end
|
52
|
+
|
53
|
+
if payment_attributes.present?
|
54
|
+
payment_attributes[:request_env] = request_env
|
55
|
+
|
56
|
+
if (token = payment_attributes[:braintree_token]).present?
|
57
|
+
payment_attributes[:source] = Spree::BraintreeCheckout.create_from_token(token, payment_attributes[:payment_method_id])
|
58
|
+
elsif payment_attributes[:braintree_nonce].present?
|
59
|
+
payment_attributes[:source] = Spree::BraintreeCheckout.create_from_params(params)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
success = update(attributes)
|
64
|
+
set_shipments_cost if shipments.any?
|
65
|
+
end
|
66
|
+
|
67
|
+
@updating_params = nil
|
68
|
+
success
|
69
|
+
end
|
70
|
+
|
71
|
+
def payment_required?
|
72
|
+
# default payment processing requires order to have state == payment
|
73
|
+
# so there is no need to divide this method for checkout steps and actual payment processing
|
74
|
+
return false if paid_with_paypal_express?
|
75
|
+
total.to_f > 0.0
|
76
|
+
end
|
77
|
+
|
78
|
+
def confirmation_required?
|
79
|
+
Spree::Config[:always_include_confirm_step] ||
|
80
|
+
payments.valid.map(&:payment_method).compact.any?(&:payment_profiles_supported?) ||
|
81
|
+
# setting payment_profiles_supported? for braintree gateways would require few additional changes in payments profiles system
|
82
|
+
braintree_confirmation_required? || state == 'confirm'
|
83
|
+
end
|
84
|
+
|
85
|
+
def paid_with_braintree?
|
86
|
+
payments.valid.map(&:payment_method).compact.any? { |p| p.is_a?(Spree::Gateway::BraintreeVzeroBase) }
|
87
|
+
end
|
88
|
+
|
89
|
+
def paid_with_paypal_express?
|
90
|
+
payments.valid.map(&:payment_method).compact.any? { |p| p.is_a?(Spree::Gateway::BraintreeVzeroPaypalExpress) }
|
91
|
+
end
|
92
|
+
|
93
|
+
def invalidate_paypal_express_payments
|
94
|
+
return unless paid_with_paypal_express?
|
95
|
+
|
96
|
+
payments.valid.each do |payment|
|
97
|
+
payment.invalidate! if payment.payment_method.is_a?(Spree::Gateway::BraintreeVzeroPaypalExpress)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def no_phone_number?
|
102
|
+
[ship_address, bill_address].each do |address|
|
103
|
+
return true if address.try(:phone).eql?(I18n.t('braintree.phone_number_placeholder'))
|
104
|
+
end
|
105
|
+
false
|
106
|
+
end
|
107
|
+
|
108
|
+
def remove_phone_number_placeholder
|
109
|
+
[ship_address, bill_address].each do |address|
|
110
|
+
address.update_column(:phone, nil) if address.try(:phone).eql?(I18n.t('braintree.phone_number_placeholder'))
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
def braintree_confirmation_required?
|
117
|
+
paid_with_braintree? && state.eql?('payment')
|
118
|
+
end
|
119
|
+
|
120
|
+
def prepare_address_hash(hash)
|
121
|
+
hash.delete_if { |e| hash[e].eql?('undefined') }
|
122
|
+
country_id = Spree::Country.find_by(iso: hash.delete(:country)).try(:id)
|
123
|
+
|
124
|
+
hash[:country_id] = country_id
|
125
|
+
state_param = hash.delete(:state)
|
126
|
+
state = Spree::State.where('spree_states.abbr = :abbr OR upper(spree_states.name) = :name',
|
127
|
+
abbr: state_param, name: state_param.upcase).find_by(country_id: country_id)
|
128
|
+
hash[:state_id] = state.try(:id)
|
129
|
+
hash[:phone] ||= I18n.t('braintree.phone_number_placeholder')
|
130
|
+
|
131
|
+
return hash if hash[:full_name].blank?
|
132
|
+
|
133
|
+
full_name = hash.delete(:full_name).split(' ')
|
134
|
+
hash[:lastname] = full_name.slice!(-1)
|
135
|
+
hash[:firstname] = full_name.join(' ')
|
136
|
+
hash
|
137
|
+
end
|
138
|
+
|
139
|
+
def process_paypal_express_payments
|
140
|
+
return unless paid_with_paypal_express?
|
141
|
+
|
142
|
+
if payments.valid.empty?
|
143
|
+
order.errors.add(:base, Spree.t(:no_payment_found))
|
144
|
+
false
|
145
|
+
else
|
146
|
+
payments.valid.last.update(amount: order_total_after_store_credit)
|
147
|
+
process_payments!
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
::Spree::Order.prepend(Spree::OrderDecorator)
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Spree
|
2
|
+
module PaymentProcessingDecorator
|
3
|
+
def self.prepended(base)
|
4
|
+
base.delegate :settle, to: :provider
|
5
|
+
end
|
6
|
+
|
7
|
+
def settle!
|
8
|
+
handle_payment_preconditions { process_settle }
|
9
|
+
end
|
10
|
+
|
11
|
+
def gateway_action(source, action, success_state)
|
12
|
+
protect_from_connection_error do
|
13
|
+
response = payment_method.send(action, money.money.cents,
|
14
|
+
source,
|
15
|
+
gateway_options)
|
16
|
+
success_state = set_proper_state(success_state, response, action)
|
17
|
+
handle_response(response, success_state, :failure)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def process_settle
|
24
|
+
started_processing!
|
25
|
+
gateway_action(source, :settle, :started_processing)
|
26
|
+
end
|
27
|
+
|
28
|
+
def gateway_error(error)
|
29
|
+
if error.is_a? ActiveMerchant::Billing::Response
|
30
|
+
text = error.params['message'] || error.params['response_reason_text'] || error.message
|
31
|
+
elsif error.is_a? ActiveMerchant::ConnectionError
|
32
|
+
text = Spree.t(:unable_to_connect_to_gateway)
|
33
|
+
elsif error.is_a? Braintree::ErrorResult
|
34
|
+
text = error.message
|
35
|
+
else
|
36
|
+
text = error.to_s
|
37
|
+
end
|
38
|
+
logger.error(Spree.t(:gateway_error))
|
39
|
+
logger.error(" #{error.to_yaml}")
|
40
|
+
raise Spree::Core::GatewayError, text
|
41
|
+
end
|
42
|
+
|
43
|
+
def set_proper_state(current_state, response, action)
|
44
|
+
return current_state unless action.eql?(:purchase)
|
45
|
+
return current_state unless source.is_a?(Spree::BraintreeCheckout)
|
46
|
+
utils = Spree::Gateway::BraintreeVzeroBase::Utils.new(payment_method, order)
|
47
|
+
state = utils.map_payment_status(response.try(:transaction).try(:status))
|
48
|
+
|
49
|
+
case state
|
50
|
+
when 'completed'
|
51
|
+
'complete'
|
52
|
+
when 'pending'
|
53
|
+
'pend'
|
54
|
+
else
|
55
|
+
current_state
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
::Spree::Payment.prepend(Spree::PaymentProcessingDecorator)
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Spree
|
2
|
+
module Preferences
|
3
|
+
module PreferableDecorator
|
4
|
+
private
|
5
|
+
|
6
|
+
def convert_preference_value(value, type)
|
7
|
+
case type
|
8
|
+
when :string, :text, :select
|
9
|
+
value.to_s
|
10
|
+
when :password
|
11
|
+
value.to_s
|
12
|
+
when :decimal
|
13
|
+
BigDecimal.new(value.to_s)
|
14
|
+
when :integer
|
15
|
+
value.to_i
|
16
|
+
when :boolean, :boolean_select
|
17
|
+
if value.is_a?(FalseClass) ||
|
18
|
+
value.nil? ||
|
19
|
+
value == 0 ||
|
20
|
+
value =~ /^(f|false|0)$/i ||
|
21
|
+
(value.respond_to?(:empty?) && value.empty?)
|
22
|
+
false
|
23
|
+
else
|
24
|
+
true
|
25
|
+
end
|
26
|
+
when :array
|
27
|
+
value.is_a?(Array) ? value : Array.wrap(value)
|
28
|
+
when :hash
|
29
|
+
case value.class.to_s
|
30
|
+
when 'Hash'
|
31
|
+
value
|
32
|
+
when 'String'
|
33
|
+
# only works with hashes whose keys are strings
|
34
|
+
JSON.parse value.gsub('=>', ':')
|
35
|
+
when 'Array'
|
36
|
+
begin
|
37
|
+
value.try(:to_h)
|
38
|
+
rescue TypeError
|
39
|
+
Hash[*value]
|
40
|
+
rescue ArgumentError
|
41
|
+
raise 'An even count is required when passing an array to be converted to a hash'
|
42
|
+
end
|
43
|
+
else
|
44
|
+
value.class.ancestors.include?(Hash) ? value : {}
|
45
|
+
end
|
46
|
+
else
|
47
|
+
value
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
::Spree::Preferences::Preferable.prepend(Spree::Preferences::PreferableDecorator)
|
@@ -0,0 +1,8 @@
|
|
1
|
+
Deface::Override.new(
|
2
|
+
virtual_path: 'spree/admin/orders/customer_details/_form',
|
3
|
+
name: 'Add warning for braintree admins',
|
4
|
+
insert_after: '[data-hook="customer_fields"]',
|
5
|
+
text: '<div class="alert alert-warning">
|
6
|
+
<%= I18n.t("braintree.admin.guest_checkout_warning") %>
|
7
|
+
</div>'
|
8
|
+
)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Deface::Override.new(
|
2
|
+
virtual_path: 'spree/admin/payment_methods/_form',
|
3
|
+
name: 'Use custom form partial for braintree vzero payment method',
|
4
|
+
surround: '[data-hook="admin_payment_method_form_fields"]',
|
5
|
+
text: '<% if @object.kind_of?(Spree::Gateway::BraintreeVzeroBase) %>
|
6
|
+
<%= render "braintree_vzero_form", f: f %>
|
7
|
+
<% else %>
|
8
|
+
<%= render_original %>
|
9
|
+
<% end %>'
|
10
|
+
)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Deface::Override.new(
|
2
|
+
virtual_path: 'spree/admin/shared/_order_summary',
|
3
|
+
name: 'Add Risk ID & Risk Decision to Order Summary',
|
4
|
+
insert_bottom: 'tbody.additional-info',
|
5
|
+
text: '<% if @order.paid_with_braintree? %>
|
6
|
+
<tr>
|
7
|
+
<td data-hook="admin_order_tab_risk_id">
|
8
|
+
<strong><%= Spree.t("admin.risk_id") %>:</strong>
|
9
|
+
</td>
|
10
|
+
<td id="risk_id">
|
11
|
+
<%= @order.payments.valid.take.try(:source).try(:risk_id) %>
|
12
|
+
</td>
|
13
|
+
</tr>
|
14
|
+
<tr>
|
15
|
+
<td data-hook="admin_order_tab_risk_decision">
|
16
|
+
<strong><%= Spree.t("admin.risk_decision") %>:</strong>
|
17
|
+
</td>
|
18
|
+
<td id="risk_id">
|
19
|
+
<%= @order.payments.valid.take.try(:source).try(:risk_decision) %>
|
20
|
+
</td>
|
21
|
+
</tr>
|
22
|
+
<% end %>'
|
23
|
+
)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Deface::Override.new(
|
2
|
+
virtual_path: 'spree/admin/shared/_refunds',
|
3
|
+
name: 'Remove refund edit button',
|
4
|
+
surround: 'erb[loud]:contains("edit_admin_order_payment_refund_path")',
|
5
|
+
text: '<% unless refund.payment.source_type.eql?(Spree::BraintreeCheckout.to_s) %><%= render_original %><% end %>'
|
6
|
+
)
|
7
|
+
|
8
|
+
Deface::Override.new(
|
9
|
+
virtual_path: 'spree/admin/shared/_refunds',
|
10
|
+
name: 'Fix spree identifier search',
|
11
|
+
replace: 'erb[loud]:contains("refund.payment.identifier")',
|
12
|
+
text: '<%= refund.payment.number %>'
|
13
|
+
)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Deface::Override.new(
|
2
|
+
virtual_path: 'spree/checkout/_payment',
|
3
|
+
name: 'Modifies Paypal Express payment method on checkout',
|
4
|
+
surround: 'erb[loud]:contains("Spree.t(method.name, :scope => :payment_methods, :default => method.name)")',
|
5
|
+
text: %{
|
6
|
+
<% if method.is_a?(Spree::Gateway::BraintreeVzeroPaypalExpress) %>
|
7
|
+
<img src="https://www.paypalobjects.com/webstatic/mktg/logo/pp_cc_mark_37x23.jpg" border="0" alt="PayPal Logo">
|
8
|
+
<a href="https://www.paypal.com/webapps/mpp/paypal-popup" title="<%= Spree.t(:how_paypal_works) %>" onclick="javascript:window.open('https://www.paypal.com/webapps/mpp/paypal-popup', 'WIPaypal','toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=1060, height=700'); return false;"> <%= Spree.t(:what_is_paypal) %></a>
|
9
|
+
<% else %>
|
10
|
+
<%= render_original %>
|
11
|
+
<% end %>
|
12
|
+
}
|
13
|
+
)
|
14
|
+
|
15
|
+
Deface::Override.new(
|
16
|
+
virtual_path: 'spree/checkout/_payment',
|
17
|
+
name: 'Adds necessary buttons for Braintree payment methods',
|
18
|
+
insert_after: 'erb[loud]:contains("submit_tag")',
|
19
|
+
partial: 'spree/checkout/payment/braintree_vzero/buttons'
|
20
|
+
)
|