rails 3 активный торговый код покупки - PullRequest
0 голосов
/ 19 мая 2011

Я новичок в рельсах и новичок в активном торговце, просто хочу знать, достаточно ли следующий код для обработки платежей с использованием активного торговца.

Как видите, я использую авторизацию и захват вместо метода покупки.Моя главная проблема - вычитание «кода_возврата» в коде (и его противоположность, когда обработка платежа не выполняется), я не совсем уверен, как с этим справиться в случае состояния гонки или ошибки со стороны платежного шлюза.

Обратите внимание, что переменная транзакции - это переменная экземпляра для модели / таблицы, в которой я храню информацию об ответах платежных шлюзов.

def purchase(item)
  price = price_in_cents(item.value)
  if !item.can_purchase
    errors[:base] << "We are sorry, all items are sold out at the moment."
    return false
  else
    response = GATEWAY.authorize(price, credit_card, purchase_options)
    transactions.create!(:action => "authorize", :value => price, :params => response)
    #p response
    if response.success?
      item.brought_quantity = item.brought_quantity + 1
      if item.save!
        response = GATEWAY.capture(price, response.authorization)
        transactions.create!(:action => "capture", :value => price, :params => response)
        if !response.success?
          errors[:base] << "There were some problem processing your payment, please either try again or contact us at support@foo.com with this error id: 111"
          @rd = RunningDeal.find_by_id(@item.id)
          @rd.brought_quantity = @rd.brought_quantity - 1
          @rd.save!
          return false
        end
      else
        errors[:base] << "We are sorry, all items are sold out at the moment."
        return false
      end
    else
      # problem process their payment, put out error
      errors[:base] << "There were some problem processing your payment, please either try again or contact us at support@foo.com with this error id: 111"
      return false
    end
  end
  return true
end

Редактировать Хорошо, выполнили рефакторинги вот обновленный код, любые комментарии и предложения приветствуются.Я удалила!в транзакции.создать, поскольку эта операция не является достаточно важной, чтобы вызвать исключение.

Вот обновленный код, основанный на обратной связи.

#from running_deal.rb
def decrement_deal_quantity
  self.brought_quantity = self.brought_quantity + 1
  return self.save!
end


def purchase(running_deal)
  price = price_in_cents(running_deal.value)
  if !running_deal.can_purchase
    errors[:base] << "We are sorry, all items are sold out at the moment."
    return false
  else
    auth_resp = GATEWAY.authorize(price, credit_card, purchase_options)
    transactions.create(:action => "authorize", :value => price, :success => auth_resp.success?, :message => auth_resp.message, :authorization => auth_resp.authorization, :params => auth_resp)
    if auth_resp.success?
      begin
        running_deal.decrement_deal_quantity
        cap_resp = GATEWAY.capture(price, auth_resp.authorization)
        transactions.create(:action => "capture", :value => price, :success => cap_resp.success?, :message => cap_resp.message, :authorization => cap_resp.authorization, :params => cap_resp)
      rescue
        GATEWAY.void(auth_resp.authorization, purchase_options) if auth_resp.success?
        errors[:base] << "There were some problem processing your payment, please either try again or contact us at support@foo.com"
        return false
      end
    else
      # problem process their payment, put out error
      errors[:base] << "There were some problem processing your payment, please either try again or contact us at support@foo.com"
      return false
    end
  end
  return true

end

1 Ответ

3 голосов
/ 20 мая 2011

обработка транзакций довольно сложно.

Пара мыслей:

  • если авторизация прошла успешно, захват произойдет в 99,9% случаев. Вам не нужно особо беспокоиться об этом деле.
  • если в вашем коде произошел сбой после успешной авторизации (например, при записи исключения в базу данных), вы должны вызвать void () для шлюза, чтобы удалить авторизацию. В противном случае средства замораживаются на 7 дней.
  • этот код необходимо переместить в метод модели:

      @rd = RunningDeal.find_by_id(@item.id)
      @rd.brought_quantity = @rd.brought_quantity - 1
      @rd.save!
    
  • вам нужно добавить предложение в конец вашего метода, чтобы перехватывать исключения, так как вы вызываете create! (), А не create () (который возвращает true, если сохраняет)

    Rescue Exception => e # ошибка передачи конец

  • неясно, почему, если item.save! не в состоянии ваше сообщение об ошибке указывает, что товар распродан? Это совершенно неясно.

В целом, вы хотите сделать что-то вроде этого:

  • проверить, достаточно ли инвентаря
  • выполнить AUTH
  • начало транзакции БД
  • сохранить / обновить все объекты БД
  • совершить транзакцию
  • выполнить ЗАХВАТ
  • перехватить исключение, и если AUTH был успешным - выполнить VOID

Надеюсь, это поможет.

...