Class: Spree::PaypalPlatform::Gateway

Inherits:
Gateway
  • Object
show all
Includes:
PaymentSessions
Defined in:
app/models/spree/paypal_platform/gateway.rb,
app/models/spree/paypal_platform/gateway/payment_sessions.rb

Overview

PayPal Checkout payment method.

One method covers the PayPal wallet, Apple Pay, and Card Fields. Extra wallets are recorded as PaymentSources on the same gateway rather than as separate payment methods.

Defined Under Namespace

Modules: PaymentSessions Classes: GatewayResponse

Instance Method Summary collapse

Methods included from PaymentSessions

#complete_payment_session, #create_payment_session, #parse_webhook_event, #payment_session_class, #session_required?, #update_payment_session

Instance Method Details

#apple_pay_enabled?TrueClass, FalseClass

Whether the storefront should offer Apple Pay for this method.

Domain registration with PayPal is still required; this flag only advertises the capability.

Returns:

  • (TrueClass, FalseClass)


105
106
107
# File 'app/models/spree/paypal_platform/gateway.rb', line 105

def apple_pay_enabled?
  preferred_enable_apple_pay
end

#authorize(_amount_in_cents, _payment_source, _gateway_options = {}) ⇒ Object

Raises:

  • (NotImplementedError)

    always — authorize-then-capture is unused



170
171
172
# File 'app/models/spree/paypal_platform/gateway.rb', line 170

def authorize(_amount_in_cents, _payment_source, _gateway_options = {})
  raise NotImplementedError, 'PayPal Checkout captures in one step; use #purchase'
end

#cancel(authorization, payment = nil) ⇒ GatewayResponse

Cancel a payment: refund if captured, otherwise void.

Parameters:

  • authorization (String)
  • payment (Spree::Payment, NilClass) (defaults to: nil)

Returns:



268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
# File 'app/models/spree/paypal_platform/gateway.rb', line 268

def cancel(authorization, payment = nil)
  protect_from_error do
    if payment&.completed?
      amount = payment.credit_allowed
      return success(authorization, {}) if amount.zero?

      refund = payment.refunds.create!(
        amount: amount,
        reason: Spree::RefundReason.order_canceled_reason,
        refunder_id: payment.order.canceler_id
      )

      success(payment.response_code, refund.response.params)
    else
      response = client.payments.void_payment({
                                                'authorization_id' => authorization,
                                                'prefer' => 'return=representation'
                                              })

      success(authorization, response.data.as_json)
    end
  end
end

#capture(_amount_in_cents, paypal_id, gateway_options = {}) ⇒ GatewayResponse

Capture a previously created PayPal order.

Parameters:

  • amount_in_cents (Integer)
  • paypal_id (String)

    PayPal order ID

  • gateway_options (Hash) (defaults to: {})

Returns:



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'app/models/spree/paypal_platform/gateway.rb', line 194

def capture(_amount_in_cents, paypal_id, gateway_options = {})
  protect_from_error do
    order = find_order(gateway_options[:order_id])
    return failure('Order not found') unless order

    response = client.orders.capture_order({
                                             'id' => paypal_id,
                                             'prefer' => 'return=representation'
                                           })

    if response.data.status == 'COMPLETED'
      success(response.data.id, response.data.as_json)
    else
      failure('Failed to capture PayPal payment', response.data)
    end
  end
end

#card_fields_enabled?TrueClass, FalseClass

Whether the storefront should offer Card Fields for this method.

Returns:

  • (TrueClass, FalseClass)


114
115
116
# File 'app/models/spree/paypal_platform/gateway.rb', line 114

def card_fields_enabled?
  preferred_enable_card_fields
end

#clientPaypalServerSdk::Client

Returns:

  • (PaypalServerSdk::Client)


148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'app/models/spree/paypal_platform/gateway.rb', line 148

def client
  @client ||= PaypalServerSdk::Client.new(
    client_credentials_auth_credentials: PaypalServerSdk::ClientCredentialsAuthCredentials.new(
      o_auth_client_id: preferred_client_id,
      o_auth_client_secret: preferred_client_secret
    ),
    environment: preferred_test_mode ? PaypalServerSdk::Environment::SANDBOX : PaypalServerSdk::Environment::PRODUCTION,
    logging_configuration: PaypalServerSdk::LoggingConfiguration.new(
      log_level: Logger::WARN,
      request_logging_config: PaypalServerSdk::RequestLoggingConfiguration.new(
        log_body: false
      ),
      response_logging_config: PaypalServerSdk::ResponseLoggingConfiguration.new(
        log_headers: false
      )
    )
  )
end

#configuration_guide_partial_nameString

Returns:

  • (String)


86
87
88
# File 'app/models/spree/paypal_platform/gateway.rb', line 86

def configuration_guide_partial_name
  'spree_paypal_platform'
end

#create_profile(payment) ⇒ Spree::GatewayCustomer, NilClass

Persist a gateway-customer profile for a signed-in buyer.

Parameters:

  • payment (Spree::Payment)

Returns:

  • (Spree::GatewayCustomer, NilClass)


133
134
135
136
137
138
139
140
141
142
143
# File 'app/models/spree/paypal_platform/gateway.rb', line 133

def create_profile(payment)
  user = payment.order.user
  return if user.blank?
  return if payment.source.blank?
  return unless payment.source.is_a?(PaymentSources::Paypal)

   = payment.source.
  return if .blank?

  payment.payment_method.gateway_customers.find_or_create_by(user: user, profile_id: )
end

#credit(amount_in_cents, _payment_source, paypal_payment_id, gateway_options = {}) ⇒ GatewayResponse

Refund a captured PayPal payment.

Parameters:

  • amount_in_cents (Integer)
  • _payment_source (Object)
  • paypal_payment_id (String)
  • gateway_options (Hash) (defaults to: {})

Returns:



240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'app/models/spree/paypal_platform/gateway.rb', line 240

def credit(amount_in_cents, _payment_source, paypal_payment_id, gateway_options = {})
  refund_originator = gateway_options[:originator]
  order = refund_originator.respond_to?(:order) ? refund_originator.order : refund_originator

  return failure('Order not found') unless order

  protect_from_error do
    payload = {
      capture_id: paypal_payment_id,
      amount: {
        value: (amount_in_cents / 100.0).to_s,
        currency_code: order.currency.upcase
      }
    }.deep_stringify_keys

    response = client.payments.refund_captured_payment(payload)

    success(response.data.id, response.data.as_json)
  end
end

#default_nameString

Returns:

  • (String)


58
59
60
# File 'app/models/spree/paypal_platform/gateway.rb', line 58

def default_name
  'PayPal'
end

#description_partial_nameString

Returns:

  • (String)


79
80
81
# File 'app/models/spree/paypal_platform/gateway.rb', line 79

def description_partial_name
  'spree_paypal_platform'
end

#method_typeString

Returns:

  • (String)


65
66
67
# File 'app/models/spree/paypal_platform/gateway.rb', line 65

def method_type
  'spree_paypal_platform'
end

#payment_icon_nameString

Returns:

  • (String)


72
73
74
# File 'app/models/spree/paypal_platform/gateway.rb', line 72

def payment_icon_name
  'paypal'
end

#payment_profiles_supported?TrueClass

Returns:

  • (TrueClass)


51
52
53
# File 'app/models/spree/paypal_platform/gateway.rb', line 51

def payment_profiles_supported?
  true
end

#payment_source_classClass

Default source class for admin "previous cards" lookups. Actual captured payments may also be PaymentSources::ApplePay or PaymentSources::Card.

Returns:

  • (Class)


44
45
46
# File 'app/models/spree/paypal_platform/gateway.rb', line 44

def payment_source_class
  PaymentSources::Paypal
end

#provider_classClass

Returns:

  • (Class)


33
34
35
# File 'app/models/spree/paypal_platform/gateway.rb', line 33

def provider_class
  self.class
end

#purchase(amount_in_cents, payment_source, gateway_options = {}) ⇒ GatewayResponse

Purchase is authorize + capture in one step.

Parameters:

  • amount_in_cents (Integer)
  • payment_source (#paypal_id)
  • gateway_options (Hash) (defaults to: {})

Returns:



182
183
184
# File 'app/models/spree/paypal_platform/gateway.rb', line 182

def purchase(amount_in_cents, payment_source, gateway_options = {})
  capture(amount_in_cents, payment_source.paypal_id, gateway_options)
end

#source_partial_nameString

Returns:

  • (String)


93
94
95
# File 'app/models/spree/paypal_platform/gateway.rb', line 93

def source_partial_name
  'paypal_platform'
end

#void(authorization, _source, _gateway_options = {}) ⇒ GatewayResponse

Void a PayPal authorization.

Parameters:

  • authorization (String)
  • _source (Object)
  • gateway_options (Hash)

Returns:



220
221
222
223
224
225
226
227
228
229
# File 'app/models/spree/paypal_platform/gateway.rb', line 220

def void(authorization, _source, _gateway_options = {})
  protect_from_error do
    response = client.payments.void_payment({
                                              'authorization_id' => authorization,
                                              'prefer' => 'return=representation'
                                            })

    success(authorization, response.data.as_json)
  end
end

#webhook_urlString, NilClass

Returns:

  • (String, NilClass)


121
122
123
124
125
# File 'app/models/spree/paypal_platform/gateway.rb', line 121

def webhook_url
  return nil unless store

  "#{store.url_or_custom_domain}/api/v3/webhooks/payments/#{prefixed_id}"
end