Class: SolidusBraintree::Gateway
- Inherits:
-
Spree::PaymentMethod
- Object
- Spree::PaymentMethod
- SolidusBraintree::Gateway
- Includes:
- RequestProtection
- Defined in:
- app/models/solidus_braintree/gateway.rb
Defined Under Namespace
Classes: TokenGenerationDisabledError
Constant Summary collapse
- NON_VOIDABLE_STATUS_ERROR_REGEXP =
Error message from Braintree that gets returned by a non voidable transaction
/can only be voided if status is authorized/
- TOKEN_GENERATION_DISABLED_MESSAGE =
'Token generation is disabled. ' \ 'To re-enable set the `token_generation_enabled` preference on the ' \ 'gateway to `true`.'
- ALLOWED_BRAINTREE_OPTIONS =
[ :device_data, :device_session_id, :merchant_account_id, :order_id ].freeze
- VOIDABLE_STATUSES =
[ Braintree::Transaction::Status::SubmittedForSettlement, Braintree::Transaction::Status::SettlementPending, Braintree::Transaction::Status::Authorized ].freeze
Instance Method Summary collapse
-
#authorize(money_cents, source, gateway_options) ⇒ Response
Authorize a payment to be captured later.
- #braintree ⇒ Object
-
#cancel(response_code) ⇒ Response
Will either refund or void the payment depending on its state.
-
#capture(money_cents, response_code, _gateway_options) ⇒ Response
Collect funds from an authorized payment.
-
#create_profile(payment) ⇒ SolidusBraintree::Customer
Creates a new customer profile in Braintree.
-
#credit(money_cents, _source, response_code, _gateway_options) ⇒ Response
Used to refeund a customer for an already settled transaction.
- #gateway_options ⇒ Object
-
#generate_token ⇒ String
The token that should be used along with the Braintree js-client sdk.
- #partial_name ⇒ Object (also: #method_type)
- #payment_profiles_supported? ⇒ Boolean
- #payment_source_class ⇒ Object
-
#purchase(money_cents, source, gateway_options) ⇒ Response
Create a payment and submit it for settlement all at once.
- #reusable_sources(order) ⇒ Object
- #sources_by_order(order) ⇒ Object
-
#try_void(payment) ⇒ Response|FalseClass
Will void the payment depending on its state or return false.
-
#void(response_code, _source, _gateway_options) ⇒ Response
Used to cancel a transaction before it is settled.
Methods included from RequestProtection
Instance Method Details
#authorize(money_cents, source, gateway_options) ⇒ Response
Authorize a payment to be captured later.
126 127 128 129 130 131 132 133 134 135 |
# File 'app/models/solidus_braintree/gateway.rb', line 126 def (money_cents, source, ) protected_request do result = braintree.transaction.sale( amount: dollars(money_cents), **(source, ) ) Response.build(result) end end |
#braintree ⇒ Object
83 84 85 |
# File 'app/models/solidus_braintree/gateway.rb', line 83 def braintree @braintree ||= Braintree::Gateway.new() end |
#cancel(response_code) ⇒ Response
Will either refund or void the payment depending on its state.
If the transaction has not yet been settled, we can void the transaction. Otherwise, we need to issue a refund.
190 191 192 193 194 195 196 197 198 199 |
# File 'app/models/solidus_braintree/gateway.rb', line 190 def cancel(response_code) transaction = protected_request do braintree.transaction.find(response_code) end if VOIDABLE_STATUSES.include?(transaction.status) void(response_code, nil, {}) else credit(cents(transaction.amount), nil, response_code, {}) end end |
#capture(money_cents, response_code, _gateway_options) ⇒ Response
Collect funds from an authorized payment.
144 145 146 147 148 149 150 151 152 |
# File 'app/models/solidus_braintree/gateway.rb', line 144 def capture(money_cents, response_code, ) protected_request do result = braintree.transaction.submit_for_settlement( response_code, dollars(money_cents) ) Response.build(result) end end |
#create_profile(payment) ⇒ SolidusBraintree::Customer
Creates a new customer profile in Braintree
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'app/models/solidus_braintree/gateway.rb', line 232 def create_profile(payment) source = payment.source return if source.token.present? || source.customer.present? || source.nonce.nil? result = braintree.customer.create(customer_profile_params(payment)) fail ::Spree::Core::GatewayError, result. unless result.success? customer = result.customer source.create_customer!(braintree_customer_id: customer.id).tap do if customer.payment_methods.any? source.token = customer.payment_methods.last.token end source.save! end end |
#credit(money_cents, _source, response_code, _gateway_options) ⇒ Response
Used to refeund a customer for an already settled transaction.
160 161 162 163 164 165 166 167 168 |
# File 'app/models/solidus_braintree/gateway.rb', line 160 def credit(money_cents, _source, response_code, ) protected_request do result = braintree.transaction.refund( response_code, dollars(money_cents) ) Response.build(result) end end |
#gateway_options ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 |
# File 'app/models/solidus_braintree/gateway.rb', line 87 def { environment: preferred_environment.to_sym, merchant_id: preferred_merchant_id, public_key: preferred_public_key, private_key: preferred_private_key, http_open_timeout: preferred_http_open_timeout, http_read_timeout: preferred_http_read_timeout, logger: logger } end |
#generate_token ⇒ String
Returns The token that should be used along with the Braintree js-client sdk.
270 271 272 273 274 275 276 |
# File 'app/models/solidus_braintree/gateway.rb', line 270 def generate_token unless preferred_token_generation_enabled raise TokenGenerationDisabledError, TOKEN_GENERATION_DISABLED_MESSAGE end braintree.client_token.generate end |
#partial_name ⇒ Object Also known as: method_type
74 75 76 |
# File 'app/models/solidus_braintree/gateway.rb', line 74 def partial_name "braintree" end |
#payment_profiles_supported? ⇒ Boolean
278 279 280 |
# File 'app/models/solidus_braintree/gateway.rb', line 278 def payment_profiles_supported? true end |
#payment_source_class ⇒ Object
79 80 81 |
# File 'app/models/solidus_braintree/gateway.rb', line 79 def payment_source_class Source end |
#purchase(money_cents, source, gateway_options) ⇒ Response
Create a payment and submit it for settlement all at once.
107 108 109 110 111 112 113 114 115 116 |
# File 'app/models/solidus_braintree/gateway.rb', line 107 def purchase(money_cents, source, ) protected_request do result = braintree.transaction.sale( amount: dollars(money_cents), **(source, , submit_for_settlement: true) ) Response.build(result) end end |
#reusable_sources(order) ⇒ Object
287 288 289 290 291 292 293 294 295 296 297 298 |
# File 'app/models/solidus_braintree/gateway.rb', line 287 def reusable_sources(order) if order.completed? sources_by_order(order) elsif order.user_id payment_source_class.where( payment_method_id: id, user_id: order.user_id ).with_payment_profile else [] end end |
#sources_by_order(order) ⇒ Object
282 283 284 285 |
# File 'app/models/solidus_braintree/gateway.rb', line 282 def sources_by_order(order) source_ids = order.payments.where(payment_method_id: id).pluck(:source_id).uniq payment_source_class.where(id: source_ids).with_payment_profile end |
#try_void(payment) ⇒ Response|FalseClass
Will void the payment depending on its state or return false
Used by Solidus >= 2.4 instead of cancel
If the transaction has not yet been settled, we can void the transaction. Otherwise, we return false so Solidus creates a refund instead.
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'app/models/solidus_braintree/gateway.rb', line 211 def try_void(payment) transaction = braintree.transaction.find(payment.response_code) if transaction.status.in? SolidusBraintree::Gateway::VOIDABLE_STATUSES # Sometimes Braintree returns a voidable status although it is not voidable anymore. # When we try to void that transaction we receive an error and need to return false # so Solidus can create a refund instead. begin void(payment.response_code, nil, {}) rescue ActiveMerchant::ConnectionError => e e..match(NON_VOIDABLE_STATUS_ERROR_REGEXP) ? false : raise(e) end else false end end |
#void(response_code, _source, _gateway_options) ⇒ Response
Used to cancel a transaction before it is settled.
175 176 177 178 179 180 |
# File 'app/models/solidus_braintree/gateway.rb', line 175 def void(response_code, _source, ) protected_request do result = braintree.transaction.void(response_code) Response.build(result) end end |