<commit_before>module Spree
  class Payment < Spree::Base
    module Processing
      def process!
        if payment_method && payment_method.source_required?
          if source
            if !processing?
              if payment_method.supports?(source) || token_based?
                if payment_method.auto_capture?
                  purchase!
                else
                  authorize!
                end
              else
                invalidate!
                raise Core::GatewayError.new(Spree.t(:payment_method_not_supported))
              end
            end
          else
            raise Core::GatewayError.new(Spree.t(:payment_processing_failed))
          end
        end
      end

      def authorize!
        started_processing!
        gateway_action(source, :authorize, :pend)
      end

      # Captures the entire amount of a payment.
      def purchase!
        started_processing!
        result = gateway_action(source, :purchase, :complete)
        # This won't be called if gateway_action raises a GatewayError
        capture_events.create!(amount: amount)
      end

      # Takes the amount in cents to capture.
      # Can be used to capture partial amounts of a payment.
      def capture!(amount=nil)
        amount ||= money.money.cents
        return true if completed?
        started_processing!
        protect_from_connection_error do
          check_environment
          # Standard ActiveMerchant capture usage
          response = payment_method.capture(
            amount,
            response_code,
            gateway_options
          )

          money = ::Money.new(amount, currency)
          capture_events.create!(amount: money.to_f)
          handle_response(response, :complete, :failure)
        end
      end

      def void_transaction!
        return true if void?
        protect_from_connection_error do
          check_environment

          if payment_method.payment_profiles_supported?
            # Gateways supporting payment profiles will need access to credit card object because this stores the payment profile information
            # so supply the authorization itself as well as the credit card, rather than just the authorization code
            response = payment_method.void(self.response_code, source, gateway_options)
          else
            # Standard ActiveMerchant void usage
            response = payment_method.void(self.response_code, gateway_options)
          end
          record_response(response)

          if response.success?
            self.response_code = response.authorization
            self.void
          else
            gateway_error(response)
          end
        end
      end

      def credit!(credit_amount=nil)
        raise Core::GatewayError.new(Spree.t(:payment_processing_failed)) if processing?

        started_processing!
        protect_from_connection_error do
          check_environment

          credit_amount ||= credit_allowed >= order.outstanding_balance.abs ? order.outstanding_balance.abs : credit_allowed.abs
          credit_amount = credit_amount.to_f
          credit_cents = Spree::Money.new(credit_amount, currency: currency).money.cents

          if payment_method.payment_profiles_supported?
            response = payment_method.credit(credit_cents, source, response_code, gateway_options)
          else
            response = payment_method.credit(credit_cents, response_code, gateway_options)
          end

          record_response(response)

          if response.success?
            self.update_column(:state, 'completed')
            self.class.create!(
              :order => order,
              :source => self,
              :payment_method => payment_method,
              :amount => credit_amount.abs * -1,
              :response_code => response.authorization,
              :state => 'completed'
            )
          else
            gateway_error(response)
          end
        end
      end<commit_msg>Fix credit action.<commit_after>module Spree
  class Payment < Spree::Base
    module Processing
      def process!
        if payment_method && payment_method.source_required?
          if source
            if !processing?
              if payment_method.supports?(source) || token_based?
                if payment_method.auto_capture?
                  purchase!
                else
                  authorize!
                end
              else
                invalidate!
                raise Core::GatewayError.new(Spree.t(:payment_method_not_supported))
              end
            end
          else
            raise Core::GatewayError.new(Spree.t(:payment_processing_failed))
          end
        end
      end

      def authorize!
        started_processing!
        gateway_action(source, :authorize, :pend)
      end

      # Captures the entire amount of a payment.
      def purchase!
        started_processing!
        result = gateway_action(source, :purchase, :complete)
        # This won't be called if gateway_action raises a GatewayError
        capture_events.create!(amount: amount)
      end

      # Takes the amount in cents to capture.
      # Can be used to capture partial amounts of a payment.
      def capture!(amount=nil)
        amount ||= money.money.cents
        return true if completed?
        started_processing!
        protect_from_connection_error do
          check_environment
          # Standard ActiveMerchant capture usage
          response = payment_method.capture(
            amount,
            response_code,
            gateway_options
          )

          money = ::Money.new(amount, currency)
          capture_events.create!(amount: money.to_f)
          handle_response(response, :complete, :failure)
        end
      end

      def void_transaction!
        return true if void?
        protect_from_connection_error do
          check_environment

          if payment_method.payment_profiles_supported?
            # Gateways supporting payment profiles will need access to credit card object because this stores the payment profile information
            # so supply the authorization itself as well as the credit card, rather than just the authorization code
            response = payment_method.void(self.response_code, source, gateway_options)
          else
            # Standard ActiveMerchant void usage
            response = payment_method.void(self.response_code, gateway_options)
          end
          record_response(response)

          if response.success?
            self.response_code = response.authorization
            self.void
          else
            gateway_error(response)
          end
        end
      end

      def credit!(credit_amount=nil)
        raise Core::GatewayError.new(Spree.t(:payment_processing_failed)) if processing?

        # Calculate credit amount before marking as processing since it messes up the order totals not having payment in completed state.
        credit_amount ||= credit_allowed >= order.outstanding_balance.abs ? order.outstanding_balance.abs : credit_allowed.abs
        credit_amount = credit_amount.to_f

        # Mark as processing to avoid race condition that could send multiple credits to the gateway.
        started_processing!
        protect_from_connection_error do
          check_environment

          credit_cents = Spree::Money.new(credit_amount, currency: currency).money.cents

          if payment_method.payment_profiles_supported?
            response = payment_method.credit(credit_cents, source, response_code, gateway_options)
          else
            response = payment_method.credit(credit_cents, response_code, gateway_options)
          end

          record_response(response)
          # Always set back to 'completed' as initial payment record was successful.
          self.update_column(:state, 'completed')

          if response.success?
            self.class.create!(
              :order => order,
              :source => self,
              :payment_method => payment_method,
              :amount => credit_amount.abs * -1,
              :response_code => response.authorization,
              :state => 'completed'
            )
          else
            gateway_error(response)
          end
        end
      end
{'fraction_non_alphanumeric': 0.05940474755994698, 'fraction_numerical': 0.00024099289070972406, 'mean_word_length': 1.9505865623889087, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5618223', 'n_tokens_mistral': 2040, 'n_tokens_neox': 1946, 'n_words': 539}