I need to use an order’s id value in a validation. Basically, I am
charging an order via a credit card API. I only want ot save the order
if the credit card authorization was approved. I also want to send the
order id to the credit card API as a transaction reference. And last
but not least I want to add an error to the order object if the
transaction is declined.
The problem is that I do not have an id for the order until I save it,
but I don;t want to save it until I know the authorization was
successful.
I don’t want to use an after_create hook beacuse I want to do an
“errors.add :card_number” to prevent the saving and display a nice error
to the user
Any advice?
heres my validation method so far:
def validate_on_create
# validate that the credit card authorization is successful
auth = CreditCard.authorize(self, :card => card_number,
:expiration => card_exp,
:cvv => card_cvv)
if auth[:result] == ‘A’
self.authcode = auth[:authCode]
else
errors.add :card_number, ‘^The credit card was declined.’
end
end
I know this isn’t a direct answer, but could you consider storing a
failed order in any case with a flag set to indicate that it was not
authorized? This would give you a record of orders that fail which might
be useful if you have problems with fraud attempts or even with the
validation process. What if the validation problems are with the card
authoriser rather than the card holder? At least you’d be able to get in
touch with the customer and apologise. Also, if a customer contacts you
and complains his card wasn’t authorized, at least you’ve some
indication what the problem was.
One way of achieving what you want programmatically would be to have a
“next order number” table with a single record with a single id field.
Update this for each order and make sure the id field in your order
table is not auto-increment. i.e. Set the order id from this reference
table.
Julian
Curtis S. wrote:
On 6/19/06, Julian G. [email protected] wrote:
One way of achieving what you want programmatically would be to have a
“next order number” table with a single record with a single id field.
Update this for each order and make sure the id field in your order
table is not auto-increment. i.e. Set the order id from this reference
table.
I was with you up to the end. I would keep the ActiveRecord id
autonumber and create a separate field for your credit card
authorization id. This way it’s not tied to a primary key and you get
all of the rest of the AR magic.
You will get a customer calling and complaining. They will be even
more upset if the order information was not captured. And it will
eventually turn into a headache. Better off to save the data. This
is 10 years of “call center” supervisory experience talking. 
-Curtis
Thanks guys, I think I am starting to understand this won’t really work
as a validation anyway. Mainly because a validation error just doesnt
seem like the place to report a declined card.
Looks like I will be saving it, then doing the authorization, and then
flagging it as declined.
Thanks for the nudge in the right direction.
On 6/19/06, Julian G. [email protected] wrote:
One way of achieving what you want programmatically would be to have a
“next order number” table with a single record with a single id field.
Update this for each order and make sure the id field in your order
table is not auto-increment. i.e. Set the order id from this reference
table.
I was with you up to the end. I would keep the ActiveRecord id
autonumber and create a separate field for your credit card
authorization id. This way it’s not tied to a primary key and you get
all of the rest of the AR magic.
You will get a customer calling and complaining. They will be even
more upset if the order information was not captured. And it will
eventually turn into a headache. Better off to save the data. This
is 10 years of “call center” supervisory experience talking. 
-Curtis