<commit_before>require 'paypal-sdk-merchant'
module Spree
  class Gateway::PayPalExpress < Gateway
    preference :use_new_layout, :boolean, default: true
    preference :login, :string
    preference :password, :string
    preference :signature, :string
    preference :server, :string, default: 'sandbox'
    preference :solution, :string, default: 'Mark'
    preference :landing_page, :string, default: 'Billing'
    preference :logourl, :string, default: ''

    def supports?(source)
      true
    end

    def provider_class
      ::PayPal::SDK::Merchant::API
    end

    def provider
      ::PayPal::SDK.configure(
        mode: preferred_server.present? ? preferred_server : "sandbox",
        username: preferred_login,
        password: <PASSWORD>,
        signature: preferred_signature)
      provider_class.new
    end

    def auto_capture?
      false
    end

    def method_type
      'paypal'
    end

    # amount :: float
    # express_checkout :: Spree::PaypalExpressCheckout
    # gateway_options :: hash
    def authorize(amount, express_checkout, gateway_options={})
      response =
        do_authorize(express_checkout.token, express_checkout.payer_id)

      # TODO don't do this, use authorization instead
      # this is a hold over from old code.
      # I don't think this actually even used by anything?
      express_checkout.update transaction_id: response.authorization

      response
    end

    # https://developer.paypal.com/docs/classic/api/merchant/DoCapture_API_Operation_NVP/
    # for more information
    def capture(amount_cents, authorization, options = {})
      do_capture(amount_cents, authorization, options[:currency])
    end

    def refund(payment, amount)
      refund_type = payment.amount == amount.to_f ? "Full" : "Partial"
      refund_transaction = provider.build_refund_transaction(
        { TransactionID: payment.source.transaction_id,
          RefundType: refund_type,
          Amount: {
            currencyID: payment.currency,
            value: amount },
          RefundSource: "any" })
      refund_transaction_response = provider.refund_transaction(refund_transaction)
      if refund_transaction_response.success?
        payment.source.update_attributes(
          { refunded_at: Time.now,
            refund_transaction_id: refund_transaction_response.RefundTransactionID,
            state: "refunded",
            refund_type: refund_type
        })

        payment.class.create!(
          order: payment.order,
          source: payment,
          payment_method: payment.payment_method,
          amount: amount.to_f.abs * -1,
          response_code: refund_transaction_response.RefundTransactionID,
          state: 'completed'
        )
      end
      refund_transaction_response
    end

    def server_domain
      self.preferred_server == "live" ?  "" : "sandbox."
    end

    def express_checkout_url(pp_response, extra_params={})
      params = {
        token: pp_response.Token
      }.merge(extra_params)

      if self.preferred_use_new_layout
        "https://www.#{server_domain}paypal.com/checkoutnow/2?"
      else
        "https://www.#{server_domain}paypal.com/cgi-bin/webscr?" +
          "cmd=_express-checkout&force_sa=true&"
      end +
      encode_www_form(params)
    end

    def do_authorize(token, payer_id)
      response =
        self.
        provider.
        do_express_checkout_payment(
          checkout_payment_params(token, payer_id))

      build_response(response, authorization_transaction_id(response))
    end

    def do_capture(amount_cents, authorization, currency)
      response = provider.
        do_capture(
          provider.build_do_capture(
            amount: amount_cents / 100.0,
            authorization_id: authorization,
            completetype: "Complete",
            currencycode: options[:currency]))

      build_response(response, capture_transaction_id(response))
    end

    def capture_transaction_id(response)
      response.do_capture_response_details.payment_info.transaction_id
    end

    def error_message(response)
      response.
        errors.
        map(&:long_message).
        join(" ")
    end

    # response ::
    #   PayPal::SDK::Merchant::DataTypes::DoExpressCheckoutPaymentResponseType
    def authorization_transaction_id(response)
      response.
        do_express_checkout_payment_response_details.
        payment_info.
        first.
        transaction_id
    end

    def build_response(response, transaction_id)
      ActiveMerchant::Billing::Response.new(
        response.success?,
        error_message(response),
        response.to_hash,<commit_msg>Change active merchant response message<commit_after>require 'paypal-sdk-merchant'
module Spree
  class Gateway::PayPalExpress < Gateway
    preference :use_new_layout, :boolean, default: true
    preference :login, :string
    preference :password, :string
    preference :signature, :string
    preference :server, :string, default: 'sandbox'
    preference :solution, :string, default: 'Mark'
    preference :landing_page, :string, default: 'Billing'
    preference :logourl, :string, default: ''

    def supports?(source)
      true
    end

    def provider_class
      ::PayPal::SDK::Merchant::API
    end

    def provider
      ::PayPal::SDK.configure(
        mode: preferred_server.present? ? preferred_server : "sandbox",
        username: preferred_login,
        password: <PASSWORD>,
        signature: preferred_signature)
      provider_class.new
    end

    def auto_capture?
      false
    end

    def method_type
      'paypal'
    end

    # amount :: float
    # express_checkout :: Spree::PaypalExpressCheckout
    # gateway_options :: hash
    def authorize(amount, express_checkout, gateway_options={})
      response =
        do_authorize(express_checkout.token, express_checkout.payer_id)

      # TODO don't do this, use authorization instead
      # this is a hold over from old code.
      # I don't think this actually even used by anything?
      express_checkout.update transaction_id: response.authorization

      response
    end

    # https://developer.paypal.com/docs/classic/api/merchant/DoCapture_API_Operation_NVP/
    # for more information
    def capture(amount_cents, authorization, options = {})
      do_capture(amount_cents, authorization, options[:currency])
    end

    def refund(payment, amount)
      refund_type = payment.amount == amount.to_f ? "Full" : "Partial"
      refund_transaction = provider.build_refund_transaction(
        { TransactionID: payment.source.transaction_id,
          RefundType: refund_type,
          Amount: {
            currencyID: payment.currency,
            value: amount },
          RefundSource: "any" })
      refund_transaction_response = provider.refund_transaction(refund_transaction)
      if refund_transaction_response.success?
        payment.source.update_attributes(
          { refunded_at: Time.now,
            refund_transaction_id: refund_transaction_response.RefundTransactionID,
            state: "refunded",
            refund_type: refund_type
        })

        payment.class.create!(
          order: payment.order,
          source: payment,
          payment_method: payment.payment_method,
          amount: amount.to_f.abs * -1,
          response_code: refund_transaction_response.RefundTransactionID,
          state: 'completed'
        )
      end
      refund_transaction_response
    end

    def server_domain
      self.preferred_server == "live" ?  "" : "sandbox."
    end

    def express_checkout_url(pp_response, extra_params={})
      params = {
        token: pp_response.Token
      }.merge(extra_params)

      if self.preferred_use_new_layout
        "https://www.#{server_domain}paypal.com/checkoutnow/2?"
      else
        "https://www.#{server_domain}paypal.com/cgi-bin/webscr?" +
          "cmd=_express-checkout&force_sa=true&"
      end +
      encode_www_form(params)
    end

    def do_authorize(token, payer_id)
      response =
        self.
        provider.
        do_express_checkout_payment(
          checkout_payment_params(token, payer_id))

      build_response(response, authorization_transaction_id(response))
    end

    def do_capture(amount_cents, authorization, currency)
      response = provider.
        do_capture(
          provider.build_do_capture(
            amount: amount_cents / 100.0,
            authorization_id: authorization,
            completetype: "Complete",
            currencycode: options[:currency]))

      build_response(response, capture_transaction_id(response))
    end

    def capture_transaction_id(response)
      response.do_capture_response_details.payment_info.transaction_id
    end

    # response ::
    #   PayPal::SDK::Merchant::DataTypes::DoExpressCheckoutPaymentResponseType
    def authorization_transaction_id(response)
      response.
        do_express_checkout_payment_response_details.
        payment_info.
        first.
        transaction_id
    end

    def build_response(response, transaction_id)
      ActiveMerchant::Billing::Response.new(
        response.success?,
        JSON.pretty_generate(response.to_hash),
        response.to_hash,
{'fraction_non_alphanumeric': 0.08558411975268468, 'fraction_numerical': 0.0013016596160104132, 'mean_word_length': 2.7494916632777553, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 6, 'lorem ipsum': 0, 'www.': 6, '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': '5552780', 'n_tokens_mistral': 2643, 'n_tokens_neox': 2570, 'n_words': 512}