Module: SpreePaypalCheckout::Gateway::PaymentSessions
- Extended by:
- ActiveSupport::Concern
- Included in:
- SpreePaypalCheckout::Gateway
- Defined in:
- app/models/spree_paypal_checkout/gateway/payment_sessions.rb
Instance Method Summary collapse
-
#complete_payment_session(payment_session:, params: {}) ⇒ Object
Completes a payment session by capturing the PayPal order, creating the Payment record, and transitioning the session.
-
#create_payment_session(order:, amount: nil, external_data: {}) ⇒ Object
Creates a PayPal order via the PayPal Orders API and persists a Spree::PaymentSessions::PaypalCheckout record.
-
#parse_webhook_event(raw_body, headers) ⇒ Object
Parses incoming PayPal webhook events.
- #payment_session_class ⇒ Object
- #session_required? ⇒ Boolean
- #update_payment_session(payment_session:, amount: nil, external_data: {}) ⇒ Object
Instance Method Details
#complete_payment_session(payment_session:, params: {}) ⇒ Object
Completes a payment session by capturing the PayPal order, creating the Payment record, and transitioning the session.
Does NOT complete the order – that is handled by Carts::Complete (called by the storefront or by the webhook handler).
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'app/models/spree_paypal_checkout/gateway/payment_sessions.rb', line 56 def complete_payment_session(payment_session:, params: {}) paypal_order_id = payment_session.external_id response = client.orders.capture_order({ 'id' => paypal_order_id, 'prefer' => 'return=representation' }) # Persist capture data outside the lock so it survives if post-capture bookkeeping fails payment_session.update!(external_data: response.data.as_json) payment_session.order.with_lock do if response.data.status == 'COMPLETED' payment_session.process if payment_session.can_process? payment = payment_session.find_or_create_payment! if payment.present? && !payment.completed? payment.started_processing! if payment.checkout? payment.complete! if payment.can_complete? end create_profile(payment) if payment&.source.present? payment_session.complete unless payment_session.completed? else payment_session.fail if payment_session.can_fail? end end rescue PaypalServerSdk::APIException => e payment_session.fail if payment_session.can_fail? raise Spree::Core::GatewayError, "PayPal API error: #{e.}" end |
#create_payment_session(order:, amount: nil, external_data: {}) ⇒ Object
Creates a PayPal order via the PayPal Orders API and persists a Spree::PaymentSessions::PaypalCheckout record.
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'app/models/spree_paypal_checkout/gateway/payment_sessions.rb', line 18 def create_payment_session(order:, amount: nil, external_data: {}) total = amount.presence || order.total_minus_store_credits return nil if total.zero? protect_from_error do order_presenter = SpreePaypalCheckout::OrderPresenter.new(order) paypal_response = client.orders.create_order(order_presenter.to_json) payment_session_class.create!( order: order, payment_method: self, amount: total, currency: order.currency, status: 'pending', external_id: paypal_response.data.id, customer: order.user, external_data: paypal_response.data.as_json ) end end |
#parse_webhook_event(raw_body, headers) ⇒ Object
Parses incoming PayPal webhook events.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'app/models/spree_paypal_checkout/gateway/payment_sessions.rb', line 91 def parse_webhook_event(raw_body, headers) verify_webhook_signature!(raw_body, headers) event = JSON.parse(raw_body).with_indifferent_access event_type = event[:event_type] resource = event[:resource] || {} paypal_order_id = extract_order_id_from_webhook(event_type, resource) return nil unless paypal_order_id payment_session = Spree::PaymentSessions::PaypalCheckout.find_by( payment_method: self, external_id: paypal_order_id ) return nil unless payment_session case event_type when 'CHECKOUT.ORDER.APPROVED' { action: :authorized, payment_session: payment_session, metadata: { paypal_event: event } } when 'PAYMENT.CAPTURE.COMPLETED' { action: :captured, payment_session: payment_session, metadata: { paypal_event: event } } when 'PAYMENT.CAPTURE.DENIED', 'PAYMENT.CAPTURE.DECLINED' { action: :failed, payment_session: payment_session, metadata: { paypal_event: event } } when 'PAYMENT.CAPTURE.REVERSED', 'PAYMENT.CAPTURE.REFUNDED' { action: :canceled, payment_session: payment_session, metadata: { paypal_event: event } } else nil end end |
#payment_session_class ⇒ Object
12 13 14 |
# File 'app/models/spree_paypal_checkout/gateway/payment_sessions.rb', line 12 def payment_session_class Spree::PaymentSessions::PaypalCheckout end |
#session_required? ⇒ Boolean
8 9 10 |
# File 'app/models/spree_paypal_checkout/gateway/payment_sessions.rb', line 8 def session_required? !SpreePaypalCheckout::Config[:use_legacy_api] end |
#update_payment_session(payment_session:, amount: nil, external_data: {}) ⇒ Object
40 41 42 43 44 45 46 47 48 49 |
# File 'app/models/spree_paypal_checkout/gateway/payment_sessions.rb', line 40 def update_payment_session(payment_session:, amount: nil, external_data: {}) attrs = {} attrs[:amount] = amount if amount.present? if external_data.present? attrs[:external_data] = (payment_session.external_data || {}).merge(external_data.stringify_keys) end payment_session.update!(attrs) if attrs.any? end |