Skip to content

Instantly share code, notes, and snippets.

@janx
Created July 9, 2009 03:18
Show Gist options
  • Save janx/143396 to your computer and use it in GitHub Desktop.
Save janx/143396 to your computer and use it in GitHub Desktop.
# application/moneyhats/app/models/order.rb
# pending - The initial order state. No successful or unsuccessful
# payments have been attempted on the order.
# authorized - A successful order authorization has been made. The
# order is ready for fulfillment and payment capture.
# paid - The authorized payment has been captured.
# payment_declined - Authorization has been attempted, but failed.
# The order can still be authorized in a subsequent
# authorization attempt.
acts_as_state_machine :initial => :pending
state :pending
state :authorized
state :paid
state :payment_declined
event :payment_authorized do
transitions :from => :pending, :to => :authorized
transitions :from => :payment_declined, :to => :authorized
end
event :payment_captured do
transitions :from => :authorized,
:to => :paid
end
event :transaction_declined do
transitions :from => :pending,
:to => :payment_declined
transitions :from => :payment_declined,
:to => :payment_declined
transitions :from => :authorized,
:to => :authorized
end
# application/moneyhats/app/models/order.rb
def authorize_payment(credit_card, options = {})
options[:order_id] = number
transaction do
authorization = OrderTransaction.authorize(amount, credit_card, options)
transactions.push(authorization)
if authorization.success?
payment_authorized!
else
transaction_declined!
end
authorization
end
end
def capture_payment(options = {})
transaction do
capture = OrderTransaction.capture(amount, authorization_reference, options)
transactions.push(capture)
if capture.success?
payment_captured!
else
transaction_declined!
end
capture
end
end
# application/moneyhats/app/models/order.rb
def authorization_reference
if authorization = transactions.find_by_action_and_success('authorization', true, :order => 'id ASC')
authorization.reference
end
end
# application/moneyhats/test/fixtures/orders.yml
pending:
description: pending order
amount: 100
state: pending
authorized:
description: authorized order
amount: 100
state: authorized
uncapturable:
description: authorized, but uncapturable
amount: 100
state: authorized
uncapturable_error:
description: authorized, but uncapturable due to error
amount: 100
state: authorized
# application/moneyhats/test/fixtures/order_transactions.yml
successful_authorization:
action: authorization
order: authorized
amount: 100
success: true
reference: 123
message: The transaction was successful
authorization_with_failing_reference:
action: authorization
order: uncapturable
amount: 100
success: true
reference: 2
message: The transaction was successful
authorization_with_error_reference:
action: authorization
order: uncapturable_error
amount: 100
success: true
reference: 1
message: The transaction was successful
# application/moneyhats/test/unit/order_test.rb
def test_successful_order_authorization
order = orders(:pending)
credit_card = credit_card(:number => '1')
assert_difference 'order.transactions.count' do
authorization = order.authorize_payment(credit_card)
assert_equal authorization.reference, order.authorization_reference
assert authorization.success?
assert order.authorized?
end
end
def test_failed_order_authorization
order = orders(:pending)
credit_card = credit_card(:number => '2')
assert_difference 'order.transactions.count' do
authorization = order.authorize_payment(credit_card)
assert_nil order.authorization_reference
assert !authorization.success?
assert order.payment_declined?
end
end
def test_exception_raised_during_authorization
order = orders(:pending)
credit_card = credit_card(:number => '3')
assert_difference 'order.transactions.count' do
authorization = order.authorize_payment(credit_card)
assert_nil order.authorization_reference
assert !authorization.success?
assert order.payment_declined?
end
end
def test_successful_payment_capture
order = orders(:authorized)
assert_difference 'order.transactions.count' do
capture = order.capture_payment
assert order.paid?
assert capture.success?
end
end
def test_failed_payment_capture
order = orders(:uncapturable)
assert_difference 'order.transactions.count' do
capture = order.capture_payment
assert order.authorized?
assert !capture.success?
end
end
def test_error_during_payment_capture
order = orders(:uncapturable_error)
assert_difference 'order.transactions.count' do
capture = order.capture_payment
assert order.authorized?
assert !capture.success?
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment