Thought I would get someone elses opinion on this one.
The app I have processes credit card transactions with bank networks.
Right now I have one processor done with 2-3 more to add. The basic
design of the app is that when a request is received I determine which
network it''s going to go to, then instantiate the class for that
network and call it''s submit function. Processing the request
involves several layers. First we decide the type of request, then
submit the request onto another class that handles that type of
request (auth,capture,credit, etc). There are a lot of checks done on
both the input, and the data that is sent to the bank network before
it''s sent.
Here is the basic structure of the class which handles the event loop.
Lots of stuff left out..
class Server < EventMachine::Connection
def receive_request
process_request(req)
end
def process_request(req)
# determine processing network
case network
when ''vital''
v = Vital::Process.new(req,self)
v.submit
when ''firstdata''
send_line "Not Implemented"
when ''none''
send_line "Invalid Merchant"
end
end
end
The Vital module then determines the type of request, gets the
merchant information from the database, puts the data into a struct
for this type of request, and then calls something like
Vital::Authorize.request which actually processes the request.
Ok so I''m slowly getting to the real question. Starting from the top
I''m passing an instance of Server all the way down the chain, and the
response is sent to the client by calling serverinstance.send_line at
the place where the error occured. Well actually there is a function
that formats the response, but since each type of request has a
slightly different response format, the formatting is done at that
level. For instance the first part of Vital::Authorize below show the
methods that format the response, and how they are called in the
request method. My question is this. Is it bad form to call
send_line way down the chain like this? I could pass the error
message all the way back up to the top and call send_line there, but
there are lots of places in the code where send_line can be called.
It''s kind of like a giant pipeline where checks need to be done all
along the way.
module Vital
module Vital::Authorize
class Request
def initialize(req,server,mconf,logger,dbh,pubkey)
@req = req
@logger = logger
@dbh = dbh
@pubkey = pubkey
@server = server
@mconf = mconf
@date = DateTime.now
@date = @date.strftime("%Y-%m-%d %H:%M:%S")
@sequence_number = nil
@parity = StringParity.new
@lrc = Lrc.new
@creditcard = CreditCard.new
end
def
reply_success(status,amount,approval_code,authorization_text,avs_result,cvv_result,transaction_id)
reply = STX + status + FS + @req.id + FS + amount + FS +
approval_code + FS + authorization_text + FS + avs_result + FS +
cvv_result + F
S + transaction_id + ETX
@logger.debug("reply_success: #{reply}")
@server.send_line(reply)
rescue Exception => e
reply_fail("Error sending reply #{e}") and return
end
def reply_fail(r)
reply = STX + "0" + FS + r + ETX
@logger.debug("reply_fail: #{reply}")
@server.send_line(reply)
end
def request
@sequence_number = Vital::Util::Sequence.get_next(@req.merchant_id, at
dbh)
if @req.amount.nil? or @req.amount.empty?
reply_fail("Amount missing") and return
end
end
## lots more beyond here..
end ## End of Vital::Authorize