Skip to content

Commit

Permalink
Merge branch 'bug/worldpay_refund_423'
Browse files Browse the repository at this point in the history
  • Loading branch information
John Duff committed Aug 9, 2012
2 parents 01e807f + d3ef666 commit 731ac63
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 24 deletions.
49 changes: 32 additions & 17 deletions lib/active_merchant/billing/gateways/worldpay.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
module ActiveMerchant #:nodoc:
module Billing #:nodoc:
class WorldpayGateway < Gateway
self.test_url = 'https://secure-test.wp3.rbsworldpay.com/jsp/merchant/xml/paymentService.jsp'
self.live_url = 'https://secure.wp3.rbsworldpay.com/jsp/merchant/xml/paymentService.jsp'
self.test_url = 'https://secure-test.worldpay.com/jsp/merchant/xml/paymentService.jsp'
self.live_url = 'https://secure.worldpay.com/jsp/merchant/xml/paymentService.jsp'

self.default_currency = 'GBP'
self.money_format = :cents
self.supported_countries = ['HK', 'US', 'GB', 'AU']
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :maestro]
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :maestro, :laser]
self.homepage_url = 'http://www.worldpay.com/'
self.display_name = 'WorldPay'

Expand All @@ -33,27 +33,27 @@ def purchase(money, payment_method, options = {})

def authorize(money, payment_method, options = {})
requires!(options, :order_id)
commit 'authorize', build_authorization_request(money, payment_method, options)
authorize_request(money, payment_method, options)
end

def capture(money, authorization, options = {})
MultiResponse.new.tap do |r|
r.process{inquire(authorization, options)} unless options[:authorization_validated]
r.process{commit('capture', build_capture_request(money, authorization, options))}
r.process{inquire_request(authorization, options, "AUTHORISED")} unless options[:authorization_validated]
r.process{capture_request(money, authorization, options)}
end
end

def void(authorization, options = {})
MultiResponse.new.tap do |r|
r.process{inquire(authorization, options)}
r.process{commit('cancel', build_void_request(authorization, options))}
r.process{inquire_request(authorization, options, "AUTHORISED")}
r.process{cancel_request(authorization, options)}
end
end

def refund(money, authorization, options = {})
MultiResponse.new.tap do |r|
r.process{inquire(authorization, options)}
r.process{commit('refund', build_refund_request(money, authorization, options))}
r.process{inquire_request(authorization, options, "CAPTURED")}
r.process{refund_request(money, authorization, options)}
end
end

Expand All @@ -63,8 +63,24 @@ def test?

private

def inquire(authorization, options={})
commit('inquiry', build_order_inquiry_request(authorization, options))
def authorize_request(money, payment_method, options)
commit('authorize', build_authorization_request(money, payment_method, options), "AUTHORISED")
end

def capture_request(money, authorization, options)
commit('capture', build_capture_request(money, authorization, options), :ok)
end

def cancel_request(authorization, options)
commit('cancel', build_void_request(authorization, options), :ok)
end

def inquire_request(authorization, options, success_criteria)
commit('inquiry', build_order_inquiry_request(authorization, options), success_criteria)
end

def refund_request(money, authorization, options)
commit('inquiry', build_refund_request(money, authorization, options), :ok)
end

def build_request
Expand Down Expand Up @@ -208,7 +224,7 @@ def parse_element(raw, node)
raw
end

def commit(action, request)
def commit(action, request, success_criteria)
xmr = ssl_post((test? ? self.test_url : self.live_url),
request,
'Content-Type' => 'text/xml',
Expand All @@ -217,12 +233,11 @@ def commit(action, request)
raw = parse(action, xmr)

Response.new(
success_from(raw),
success_from(raw, success_criteria),
message_from(raw),
raw,
:authorization => authorization_from(raw),
:test => test?)

rescue ActiveMerchant::ResponseError => e
if e.response.code.to_s == "401"
return Response.new(false, "Invalid credentials", {}, :test => test?)
Expand All @@ -231,8 +246,8 @@ def commit(action, request)
end
end

def success_from(raw)
(raw[:last_event] == "AUTHORISED" ||
def success_from(raw, success_criteria)
(raw[:last_event] == success_criteria ||
raw[:ok].present?)
end

Expand Down
22 changes: 16 additions & 6 deletions test/remote/gateways/remote_worldpay_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,22 @@ def test_void
assert_failure @gateway.void('bogus')
end

def test_refund
assert_success(auth = @gateway.authorize(@amount, @credit_card, @options))
assert_success @gateway.refund(@amount, auth.authorization)

assert_failure @gateway.refund(@amount, 'bogus')
end
# Worldpay has a delay between asking for a transaction to be captured and actually marking it as captured
# These tests work if you take the auth code, wait some time and then request the refund
#def test_refund
# assert_success(auth = @gateway.authorize(@amount, @credit_card, @options))
# assert_success auth
# assert_equal 'SUCCESS', auth.message
# assert auth.authorization
# puts auth.authorization
# assert capture = @gateway.capture(@amount, auth.authorization)
# assert_success @gateway.refund(@amount, auth.authorization)
#end
#
#def test_refund_existing_transaction
# assert_success resp = @gateway.refund(@amount, "7c85e685c35115689ff9c429be9f65e7")
# puts resp.inspect
#end

def test_currency
assert_success(result = @gateway.authorize(@amount, @credit_card, @options.merge(:currency => 'USD')))
Expand Down
54 changes: 53 additions & 1 deletion test/unit/gateways/worldpay_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,19 @@ def test_require_order_id
def test_purchase_does_not_run_inquiry
response = stub_comms do
@gateway.purchase(@amount, @credit_card, @options)
end.respond_with(successful_authorize_response)
end.respond_with(successful_capture_response)

assert_success response
assert_equal %w(authorize capture), response.responses.collect{|e| e.params["action"]}
end

def test_successful_refund
response = stub_comms do
@gateway.refund(@amount, @options[:order_id], @options)
end.respond_with(successful_refund_inquiry_response, successful_refund_response)
assert_success response
end

def test_capture
response = stub_comms do
response = @gateway.authorize(@amount, @credit_card, @options)
Expand Down Expand Up @@ -324,6 +332,50 @@ def successful_inquiry_response
RESPONSE
end

def successful_refund_inquiry_response
<<-RESPONSE
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE paymentService PUBLIC "-//Bibit//DTD Bibit PaymentService v1//EN"
"http://dtd.bibit.com/paymentService_v1.dtd">
<paymentService version="1.4" merchantCode="SPREEDLY">
<reply>
<orderStatus orderCode="d192c159d5730d339c03fa1a8dc796eb">
<payment>
<paymentMethod>VISA-SSL</paymentMethod>
<amount value="100" currencyCode="GBP" exponent="2" debitCreditIndicator="credit"/>
<lastEvent>CAPTURED</lastEvent>
<CVCResultCode description="UNKNOWN"/>
<AVSResultCode description="NOT SUPPLIED BY SHOPPER"/>
<balance accountType="IN_PROCESS_AUTHORISED">
<amount value="100" currencyCode="GBP" exponent="2" debitCreditIndicator="credit"/>
</balance>
<cardNumber>4111********1111</cardNumber>
<riskScore value="1"/>
</payment>
<date dayOfMonth="20" month="04" year="2011" hour="22" minute="24" second="0"/>
</orderStatus>
</reply>
</paymentService>
RESPONSE
end

def successful_refund_response
<<-RESPONSE
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE paymentService PUBLIC "-//WorldPay//DTD WorldPay PaymentService v1//EN"
"http://dtd.worldpay.com/paymentService_v1.dtd">
<paymentService version="1.4" merchantCode="SPREEDLY">
<reply>
<ok>
<refundReceived orderCode="1">
<amount value="100" currencyCode="GBP" exponent="2" debitCreditIndicator="credit"/>
</refundReceived>
</ok>
</reply>
</paymentService>
RESPONSE
end

def sample_authorization_request
<<-REQUEST
<?xml version="1.0" encoding="UTF-8"?>
Expand Down

0 comments on commit 731ac63

Please sign in to comment.