Last active
December 8, 2015 23:38
-
-
Save chrisbloom7/51e1471f910f6f692684 to your computer and use it in GitHub Desktop.
Integration tests for PayPal Express Checkout using TestUnit in Rails 2.3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# lib/express_checkout.rb | |
require 'paypal-sdk-merchant' | |
module PayPal | |
module Merchant | |
class ExpressCheckout | |
def initialize(opts = {}) | |
@api = PayPal::SDK::Merchant::API.new | |
@return_url = opts[:return_url] | |
@cancel_url = opts[:cancel_url] | |
@notify_url = opts[:notify_url] | |
end | |
def express_checkout_url(token) | |
@api.express_checkout_url(token) | |
end | |
def ipn_valid?(raw_post_data) | |
@api.ipn_valid?(raw_post_data) | |
end | |
# The SetExpressCheckout API operation initiates an Express Checkout transaction. | |
def set_express_checkout(order) | |
# Build your array of ordered product hashes. Ex: | |
ordered_products = order.ordered_products.collect{ |product| { | |
:name => product.descriptive_name, | |
:quantity => product.quantity, | |
:price => rounded_number(product.price * (product.payment? ? -1 : 1)), | |
}} | |
# Build request object | |
request = { | |
:SetExpressCheckoutRequestDetails => { | |
:ReturnURL => @return_url, | |
:CancelURL => @cancel_url, | |
:PaymentDetails => [{ | |
# Total cost of the transaction to the buyer. If shipping cost and tax | |
# charges are known, include them in this value. If not, this value | |
# should be the current sub-total of the order. | |
:OrderTotal => { | |
:currencyID => "USD", | |
:value => rounded_number(order.owed) | |
}, | |
# Sum of cost of all items in this order. For digital goods, this field is required. | |
:ItemTotal => { | |
:currencyID => "USD", | |
:value => rounded_number(order.sub_total) | |
}, | |
# Total shipping costs for this order. | |
:ShippingTotal => (order.ship_method? ? { | |
:currencyID => "USD", | |
:value => rounded_number(order.ship_cost) | |
} : nil), | |
# Sum of tax for all items in this order. | |
:TaxTotal => ((order.walk_in? || order.shipping_state.present?) ? { | |
:currencyID => "USD", | |
:value => rounded_number(order.sales_tax) | |
} : nil), | |
# Your URL for receiving Instant Payment Notification (IPN) about this transaction. If you do not specify this value in the request, the notification URL from your Merchant Profile is used, if one exists. | |
:NotifyURL => @notify_url, | |
# `Address` to which the order is shipped | |
:ShipToAddress => { | |
# Person's name associated with this shipping address. It is required if using a shipping address. | |
:Name => order.order_shipping_address.try(:shipping_address).try(:name), | |
# Street Name | |
:Street1 => order.order_shipping_address.try(:shipping_address).try(:line1), | |
# City | |
:CityName => order.order_shipping_address.try(:shipping_address).try(:city), | |
# State | |
:StateOrProvince => order.order_shipping_address.try(:shipping_address).try(:state), | |
# Country | |
:Country => order.order_shipping_address.try(:shipping_address).try(:country_record).try(:code), | |
# Postal Code | |
:PostalCode => order.order_shipping_address.try(:shipping_address).try(:zip) | |
}, | |
# Details about each individual item included in the order. | |
:PaymentDetailsItem => ordered_products.collect{|ordered_product| | |
{ | |
# Item name. This field is required when you pass a value for ItemCategory. | |
:Name => ordered_product[:name], | |
# Item quantity. This field is required when you pass a value for ItemCategory. For digital goods (ItemCategory=Digital), this field is required. | |
:Quantity => ordered_product[:quantity], | |
# Cost of item. This field is required when you pass a value for ItemCategory. | |
:Amount => { | |
:currencyID => "USD", | |
:value => ordered_product[:price] | |
}, | |
} | |
}, | |
# How you want to obtain payment. | |
:PaymentAction => "Sale" | |
}] # PaymentDetails | |
} # SetExpressCheckoutRequestDetails | |
} # request | |
set_express_checkout = @api.build_set_express_checkout(request) | |
# Make API call & get response | |
set_express_checkout_response = @api.set_express_checkout(set_express_checkout) | |
end | |
# The GetExpressCheckoutDetails API operation obtains information about an Express Checkout transaction. | |
def get_express_checkout(token) | |
# Build request object | |
get_express_checkout_details = @api.build_get_express_checkout_details({ | |
# A timestamped token, the value of which was returned by `SetExpressCheckout` response. | |
:Token => token | |
}) | |
# Make API call & get response | |
get_express_checkout_details_response = @api.get_express_checkout_details(get_express_checkout_details) | |
end | |
# The DoExpressCheckoutPayment API operation completes an Express Checkout | |
# transaction. If you set up a billing agreement in your SetExpressCheckout | |
# API call, the billing agreement is created when you call the | |
# DoExpressCheckoutPayment API operation. | |
def do_express_checkout(order, token, payer_id) | |
# Build request object | |
request = { | |
:DoExpressCheckoutPaymentRequestDetails => { | |
# How you want to obtain payment. | |
:PaymentAction => "Sale", | |
# The timestamped token value that was returned in the | |
# `SetExpressCheckout` response and passed in the | |
# `GetExpressCheckoutDetails` request. | |
:Token => token, | |
# Unique paypal buyer account identification number as returned in `GetExpressCheckoutDetails` Response | |
:PayerID => payer_id, | |
# information about the payment | |
:PaymentDetails => [{ | |
# Total cost of the transaction to the buyer. If shipping cost and tax | |
# charges are known, include them in this value. If not, this value | |
# should be the current sub-total of the order. | |
:OrderTotal => { | |
:currencyID => "USD", | |
:value => rounded_number(order.owed) | |
}, | |
# Your URL for receiving Instant Payment Notification (IPN) about this transaction. If you do not specify this value in the request, the notification URL from your Merchant Profile is used, if one exists. | |
:NotifyURL => @notify_url | |
}] # PaymentDetails | |
} # DoExpressCheckoutPaymentRequestDetails | |
} # request | |
do_express_checkout_payment = @api.build_do_express_checkout_payment(request) | |
# Make API call & get response | |
do_express_checkout_payment_response = @api.do_express_checkout_payment(do_express_checkout_payment) | |
end | |
private | |
# Similar to number_with_precision from | |
# actionpack/lib/action_view/helpers/number_helper.rb | |
def rounded_number(number) | |
precision = 2 | |
begin | |
rounded_number = (Float(number) * (10 ** precision)).round.to_f / 10 ** precision | |
"%01.#{precision}f" % rounded_number | |
rescue | |
number | |
end | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# test/unit/lib/express_checkout_test.rb | |
require 'test_helper' | |
class ExpressCheckoutTest < ActiveSupport::TestCase | |
context "an ExpressCheckout instance" do | |
setup do | |
PayPal::SDK.configure( | |
:mode => "sandbox", | |
:app_id => "dummy", | |
:username => "dummy", | |
:password => "dummy", | |
:signature => "dummy" | |
) | |
@ec = PayPal::Merchant::ExpressCheckout.new | |
end | |
context "set_express_checkout" do | |
context "with a valid response" do | |
setup do | |
FakeWeb.register_uri( | |
:post, | |
PayPal::SDK::Merchant::API.new.service_endpoint, | |
:content_type => "application/xml", | |
:status => ["200", "OK"], | |
:body => File.read(Rails.root.join("test/fixtures/express_checkout/success/set.xml")) | |
) | |
@response = @ec.set_express_checkout(Order.new) | |
end | |
should "be successful" do | |
assert @response.success? | |
end | |
should "include a token" do | |
assert_present @response.Token | |
end | |
end | |
context "with an invalid response" do | |
setup do | |
FakeWeb.register_uri( | |
:post, | |
PayPal::SDK::Merchant::API.new.service_endpoint, | |
:content_type => "application/xml", | |
:status => ["200", "OK"], | |
:body => File.read(Rails.root.join("test/fixtures/express_checkout/failure/set.xml")) | |
) | |
@response = @ec.set_express_checkout(Order.new) | |
end | |
should "not be successful" do | |
assert !@response.success? | |
end | |
should "not include a token" do | |
assert_nil @response.Token | |
end | |
end | |
end | |
context "get_express_checkout" do | |
context "with a valid response" do | |
setup do | |
FakeWeb.register_uri( | |
:post, | |
PayPal::SDK::Merchant::API.new.service_endpoint, | |
:content_type => "application/xml", | |
:status => ["200", "OK"], | |
:body => File.read(Rails.root.join("test/fixtures/express_checkout/success/get.xml")) | |
) | |
@response = @ec.get_express_checkout("TOKEN") | |
end | |
should "be successful" do | |
assert @response.success? | |
end | |
should "include the payer ID" do | |
assert_present @response.GetExpressCheckoutDetailsResponseDetails.PayerInfo.PayerID | |
end | |
end | |
context "with an invalid response" do | |
setup do | |
FakeWeb.register_uri( | |
:post, | |
PayPal::SDK::Merchant::API.new.service_endpoint, | |
:content_type => "application/xml", | |
:status => ["200", "OK"], | |
:body => File.read(Rails.root.join("test/fixtures/express_checkout/failure/get.xml")) | |
) | |
@response = @ec.get_express_checkout("TOKEN") | |
end | |
should "not be successful" do | |
assert !@response.success? | |
end | |
should "not include the payer ID" do | |
assert_nil @response.GetExpressCheckoutDetailsResponseDetails.PayerInfo.PayerID | |
end | |
end | |
end | |
context "do_express_checkout" do | |
context "with a valid response" do | |
setup do | |
FakeWeb.register_uri( | |
:post, | |
PayPal::SDK::Merchant::API.new.service_endpoint, | |
:content_type => "application/xml", | |
:status => ["200", "OK"], | |
:body => File.read(Rails.root.join("test/fixtures/express_checkout/success/do.xml")) | |
) | |
@response = @ec.do_express_checkout(Order.new, "TOKEN", "PAYER_ID") | |
end | |
should "be successful" do | |
assert @response.success? | |
end | |
should "include the transaction ID" do | |
assert_present @response.DoExpressCheckoutPaymentResponseDetails.PaymentInfo[0].TransactionID | |
end | |
end | |
context "with an invalid response" do | |
setup do | |
FakeWeb.register_uri( | |
:post, | |
PayPal::SDK::Merchant::API.new.service_endpoint, | |
:content_type => "application/xml", | |
:status => ["200", "OK"], | |
:body => File.read(Rails.root.join("test/fixtures/express_checkout/failure/do.xml")) | |
) | |
@response = @ec.do_express_checkout(Order.new, "TOKEN", "PAYER_ID") | |
end | |
should "not be successful" do | |
assert !@response.success? | |
end | |
should "not include the transaction ID" do | |
assert_blank @response.DoExpressCheckoutPaymentResponseDetails.PaymentInfo | |
end | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- test/fixtures/express_checkout/failure/do.xml --> | |
<?xml version="1.0" encoding="UTF-8"?> | |
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:cc="urn:ebay:apis:CoreComponentTypes" xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext" xmlns:ed="urn:ebay:apis:EnhancedDataTypes" xmlns:ebl="urn:ebay:apis:eBLBaseComponents" xmlns:ns="urn:ebay:api:PayPalAPI"> | |
<SOAP-ENV:Header> | |
<Security xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext" xsi:type="wsse:SecurityType"/> | |
<RequesterCredentials xmlns="urn:ebay:api:PayPalAPI" xsi:type="ebl:CustomSecurityHeaderType"> | |
<Credentials xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:UserIdPasswordType"> | |
<Username xsi:type="xs:string"/> | |
<Password xsi:type="xs:string"/> | |
<Signature xsi:type="xs:string"/> | |
<Subject xsi:type="xs:string"/> | |
</Credentials> | |
</RequesterCredentials> | |
</SOAP-ENV:Header> | |
<SOAP-ENV:Body id="_0"> | |
<DoExpressCheckoutPaymentResponse xmlns="urn:ebay:api:PayPalAPI"> | |
<Timestamp xmlns="urn:ebay:apis:eBLBaseComponents">2013-10-22T18:21:23Z</Timestamp> | |
<Ack xmlns="urn:ebay:apis:eBLBaseComponents">Failure</Ack> | |
<CorrelationID xmlns="urn:ebay:apis:eBLBaseComponents">123456789012</CorrelationID> | |
<Errors xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:ErrorType"> | |
<ShortMessage xsi:type="xs:string">Error</ShortMessage> | |
<LongMessage xsi:type="xs:string">Error</LongMessage> | |
<ErrorCode xsi:type="xs:token">99999</ErrorCode> | |
<SeverityCode xmlns="urn:ebay:apis:eBLBaseComponents">Error</SeverityCode> | |
</Errors> | |
<Version xmlns="urn:ebay:apis:eBLBaseComponents">106.0</Version> | |
<Build xmlns="urn:ebay:apis:eBLBaseComponents">8208991</Build> | |
<DoExpressCheckoutPaymentResponseDetails xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:DoExpressCheckoutPaymentResponseDetailsType"/> | |
</DoExpressCheckoutPaymentResponse> | |
</SOAP-ENV:Body> | |
</SOAP-ENV:Envelope> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- test/fixtures/express_checkout/failure/get.xml --> | |
<?xml version="1.0" encoding="UTF-8"?> | |
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:cc="urn:ebay:apis:CoreComponentTypes" xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext" xmlns:ed="urn:ebay:apis:EnhancedDataTypes" xmlns:ebl="urn:ebay:apis:eBLBaseComponents" xmlns:ns="urn:ebay:api:PayPalAPI"> | |
<SOAP-ENV:Header> | |
<Security xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext" xsi:type="wsse:SecurityType"/> | |
<RequesterCredentials xmlns="urn:ebay:api:PayPalAPI" xsi:type="ebl:CustomSecurityHeaderType"> | |
<Credentials xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:UserIdPasswordType"> | |
<Username xsi:type="xs:string"/> | |
<Password xsi:type="xs:string"/> | |
<Signature xsi:type="xs:string"/> | |
<Subject xsi:type="xs:string"/> | |
</Credentials> | |
</RequesterCredentials> | |
</SOAP-ENV:Header> | |
<SOAP-ENV:Body id="_0"> | |
<GetExpressCheckoutDetailsResponse xmlns="urn:ebay:api:PayPalAPI"> | |
<Timestamp xmlns="urn:ebay:apis:eBLBaseComponents">2013-10-22T18:19:50Z</Timestamp> | |
<Ack xmlns="urn:ebay:apis:eBLBaseComponents">Failure</Ack> | |
<CorrelationID xmlns="urn:ebay:apis:eBLBaseComponents">123456789012</CorrelationID> | |
<Errors xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:ErrorType"> | |
<ShortMessage xsi:type="xs:string">Error</ShortMessage> | |
<LongMessage xsi:type="xs:string">Error</LongMessage> | |
<ErrorCode xsi:type="xs:token">99999</ErrorCode> | |
<SeverityCode xmlns="urn:ebay:apis:eBLBaseComponents">Error</SeverityCode> | |
</Errors> | |
<Version xmlns="urn:ebay:apis:eBLBaseComponents">106.0</Version> | |
<Build xmlns="urn:ebay:apis:eBLBaseComponents">8208991</Build> | |
<GetExpressCheckoutDetailsResponseDetails xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:GetExpressCheckoutDetailsResponseDetailsType"> | |
<ContactPhone xsi:type="ebl:ContactPhoneType"/> | |
<PayerInfo xsi:type="ebl:PayerInfoType"> | |
<Payer xsi:type="ebl:EmailAddressType"/> | |
<PayerID xsi:type="ebl:UserIDType"/> | |
<PayerStatus xsi:type="ebl:PayPalUserStatusCodeType">unverified</PayerStatus> | |
<PayerName xsi:type="ebl:PersonNameType"> | |
<Salutation xmlns="urn:ebay:apis:eBLBaseComponents"/> | |
<FirstName xmlns="urn:ebay:apis:eBLBaseComponents"/> | |
<MiddleName xmlns="urn:ebay:apis:eBLBaseComponents"/> | |
<LastName xmlns="urn:ebay:apis:eBLBaseComponents"/> | |
<Suffix xmlns="urn:ebay:apis:eBLBaseComponents"/> | |
</PayerName> | |
<PayerBusiness xsi:type="xs:string"/> | |
<Address xsi:type="ebl:AddressType"> | |
<Name xsi:type="xs:string"/> | |
<Street1 xsi:type="xs:string"/> | |
<Street2 xsi:type="xs:string"/> | |
<CityName xsi:type="xs:string"/> | |
<StateOrProvince xsi:type="xs:string"/> | |
<CountryName/> | |
<PostalCode xsi:type="xs:string"/> | |
<AddressOwner xsi:type="ebl:AddressOwnerCodeType">PayPal</AddressOwner> | |
<AddressStatus xsi:type="ebl:AddressStatusCodeType">None</AddressStatus> | |
</Address> | |
</PayerInfo> | |
<PaymentDetails xsi:type="ebl:PaymentDetailsType"> | |
<ShipToAddress xsi:type="ebl:AddressType"> | |
<Name xsi:type="xs:string"/> | |
<Street1 xsi:type="xs:string"/> | |
<Street2 xsi:type="xs:string"/> | |
<CityName xsi:type="xs:string"/> | |
<StateOrProvince xsi:type="xs:string"/> | |
<CountryName/> | |
<Phone xsi:type="xs:string"/> | |
<PostalCode xsi:type="xs:string"/> | |
<AddressID xsi:type="xs:string"/> | |
<AddressOwner xsi:type="ebl:AddressOwnerCodeType">PayPal</AddressOwner> | |
<ExternalAddressID xsi:type="xs:string"/> | |
<AddressStatus xsi:type="ebl:AddressStatusCodeType">None</AddressStatus> | |
<AddressNormalizationStatus xsi:type="ebl:AddressNormalizationStatusCodeType">None</AddressNormalizationStatus> | |
</ShipToAddress> | |
<SellerDetails xsi:type="ebl:SellerDetailsType"/> | |
<PaymentRequestID xsi:type="xs:string"/> | |
<OrderURL xsi:type="xs:string"/> | |
<SoftDescriptor xsi:type="xs:string"/> | |
</PaymentDetails> | |
<CheckoutStatus xsi:type="xs:string"/> | |
<PaymentRequestInfo xsi:type="ebl:PaymentRequestInfoType"/> | |
</GetExpressCheckoutDetailsResponseDetails> | |
</GetExpressCheckoutDetailsResponse> | |
</SOAP-ENV:Body> | |
</SOAP-ENV:Envelope> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- test/fixtures/express_checkout/failure/set.xml --> | |
<?xml version="1.0" encoding="UTF-8"?> | |
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:cc="urn:ebay:apis:CoreComponentTypes" xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext" xmlns:ed="urn:ebay:apis:EnhancedDataTypes" xmlns:ebl="urn:ebay:apis:eBLBaseComponents" xmlns:ns="urn:ebay:api:PayPalAPI"> | |
<SOAP-ENV:Header> | |
<Security xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext" xsi:type="wsse:SecurityType"/> | |
<RequesterCredentials xmlns="urn:ebay:api:PayPalAPI" xsi:type="ebl:CustomSecurityHeaderType"> | |
<Credentials xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:UserIdPasswordType"> | |
<Username xsi:type="xs:string"/> | |
<Password xsi:type="xs:string"/> | |
<Signature xsi:type="xs:string"/> | |
<Subject xsi:type="xs:string"/> | |
</Credentials> | |
</RequesterCredentials> | |
</SOAP-ENV:Header> | |
<SOAP-ENV:Body id="_0"> | |
<SetExpressCheckoutResponse xmlns="urn:ebay:api:PayPalAPI"> | |
<Timestamp xmlns="urn:ebay:apis:eBLBaseComponents">2013-10-22T18:22:35Z</Timestamp> | |
<Ack xmlns="urn:ebay:apis:eBLBaseComponents">Failure</Ack> | |
<CorrelationID xmlns="urn:ebay:apis:eBLBaseComponents">123456789012</CorrelationID> | |
<Errors xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:ErrorType"> | |
<ShortMessage xsi:type="xs:string">Error</ShortMessage> | |
<LongMessage xsi:type="xs:string">Error</LongMessage> | |
<ErrorCode xsi:type="xs:token">99999</ErrorCode> | |
<SeverityCode xmlns="urn:ebay:apis:eBLBaseComponents">Error</SeverityCode> | |
</Errors> | |
<Version xmlns="urn:ebay:apis:eBLBaseComponents">106.0</Version> | |
<Build xmlns="urn:ebay:apis:eBLBaseComponents">8208991</Build> | |
</SetExpressCheckoutResponse> | |
</SOAP-ENV:Body> | |
</SOAP-ENV:Envelope> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Gemfile | |
gem 'paypal-sdk-merchant' | |
group :test do | |
gem 'fakeweb', '1.2.6' | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# test/integration/orders_test.rb | |
require File.dirname(__FILE__) + '/../test_helper' | |
class OrdersTest < ActionController::IntegrationTest | |
context 'paying with PayPal Express Checkout' do | |
setup do | |
stub_express_checkout | |
end | |
should "succeed when checking out from the shopping cart page" do | |
# do your normal test flow. All fakeweb requests are already configured | |
end | |
context 'when PayPal sends us something we didn\'t expect' do | |
# Testing for Webrat::PageLoadError doesn't feel like the right way to do | |
# this, but I've yet to find another way to properly assert that an | |
# Exception has occured and bubbled up to a HTTP 500 status error | |
should "raise an error when something goes wrong when trying to setup express checkout" do | |
# setup your test up to the point where the customer would first initiate an EC transaction | |
stub_express_checkout_for_failure(:set) | |
assert_raises(Webrat::PageLoadError) { | |
# do something that triggers the PayPal::Merchant::ExpressCheckout.set_express_checkout method | |
} | |
end | |
should "raise an error when something goes wrong when returning from express checkout" do | |
# setup your test up to the point where the customer would first initiate an EC transaction | |
# (probably the same work flow as above) | |
stub_express_checkout_for_failure(:get) | |
assert_raises(Webrat::PageLoadError) { | |
# do something that triggers the PayPal::Merchant::ExpressCheckout.get_express_checkout method | |
} | |
end | |
should "raise an error if something goes wrong when trying to do the final charge to PayPal Express" do | |
# setup your test up to the point where the customer would finalize their EC transaction, like from | |
# an order review page | |
stub_express_checkout_for_failure(:do) | |
assert_raises(Webrat::PageLoadError) { | |
# do something that triggers the PayPal::Merchant::ExpressCheckout.do_express_checkout method | |
} | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- test/fixtures/express_checkout/success/do.xml --> | |
<?xml version="1.0" encoding="UTF-8"?> | |
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:cc="urn:ebay:apis:CoreComponentTypes" xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext" xmlns:ed="urn:ebay:apis:EnhancedDataTypes" xmlns:ebl="urn:ebay:apis:eBLBaseComponents" xmlns:ns="urn:ebay:api:PayPalAPI"> | |
<SOAP-ENV:Header> | |
<Security xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext" xsi:type="wsse:SecurityType"/> | |
<RequesterCredentials xmlns="urn:ebay:api:PayPalAPI" xsi:type="ebl:CustomSecurityHeaderType"> | |
<Credentials xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:UserIdPasswordType"> | |
<Username xsi:type="xs:string"/> | |
<Password xsi:type="xs:string"/> | |
<Signature xsi:type="xs:string"/> | |
<Subject xsi:type="xs:string"/> | |
</Credentials> | |
</RequesterCredentials> | |
</SOAP-ENV:Header> | |
<SOAP-ENV:Body id="_0"> | |
<DoExpressCheckoutPaymentResponse xmlns="urn:ebay:api:PayPalAPI"> | |
<Timestamp xmlns="urn:ebay:apis:eBLBaseComponents">2013-10-22T18:04:18Z</Timestamp> | |
<Ack xmlns="urn:ebay:apis:eBLBaseComponents">Success</Ack> | |
<CorrelationID xmlns="urn:ebay:apis:eBLBaseComponents">123456789012</CorrelationID> | |
<Version xmlns="urn:ebay:apis:eBLBaseComponents">106.0</Version> | |
<Build xmlns="urn:ebay:apis:eBLBaseComponents">8208991</Build> | |
<DoExpressCheckoutPaymentResponseDetails xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:DoExpressCheckoutPaymentResponseDetailsType"> | |
<Token xsi:type="ebl:ExpressCheckoutTokenType">TOKEN</Token> | |
<PaymentInfo xsi:type="ebl:PaymentInfoType"> | |
<TransactionID>8A683475YD980084Y</TransactionID> | |
<ParentTransactionID xsi:type="ebl:TransactionId"/> | |
<ReceiptID/> | |
<TransactionType xsi:type="ebl:PaymentTransactionCodeType">express-checkout</TransactionType> | |
<PaymentType xsi:type="ebl:PaymentCodeType">instant</PaymentType> | |
<PaymentDate xsi:type="xs:dateTime">2013-10-22T18:04:18Z</PaymentDate> | |
<GrossAmount xsi:type="cc:BasicAmountType" currencyID="USD">39.00</GrossAmount> | |
<FeeAmount xsi:type="cc:BasicAmountType" currencyID="USD">1.43</FeeAmount> | |
<TaxAmount xsi:type="cc:BasicAmountType" currencyID="USD">0.00</TaxAmount> | |
<ExchangeRate xsi:type="xs:string"/> | |
<PaymentStatus xsi:type="ebl:PaymentStatusCodeType">Completed</PaymentStatus> | |
<PendingReason xsi:type="ebl:PendingStatusCodeType">none</PendingReason> | |
<ReasonCode xsi:type="ebl:ReversalReasonCodeType">none</ReasonCode> | |
<ProtectionEligibility xsi:type="xs:string">Eligible</ProtectionEligibility> | |
<ProtectionEligibilityType xsi:type="xs:string">ItemNotReceivedEligible,UnauthorizedPaymentEligible</ProtectionEligibilityType> | |
<SellerDetails xsi:type="ebl:SellerDetailsType"> | |
<SecureMerchantAccountID xsi:type="ebl:UserIDType">ACCOUNTID</SecureMerchantAccountID> | |
</SellerDetails> | |
</PaymentInfo> | |
<SuccessPageRedirectRequested xsi:type="xs:string">false</SuccessPageRedirectRequested> | |
<CoupledPaymentInfo xsi:type="ebl:CoupledPaymentInfoType"/> | |
</DoExpressCheckoutPaymentResponseDetails> | |
</DoExpressCheckoutPaymentResponse> | |
</SOAP-ENV:Body> | |
</SOAP-ENV:Envelope> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- test/fixtures/express_checkout/success/get.xml --> | |
<?xml version="1.0" encoding="UTF-8"?> | |
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:cc="urn:ebay:apis:CoreComponentTypes" xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext" xmlns:ed="urn:ebay:apis:EnhancedDataTypes" xmlns:ebl="urn:ebay:apis:eBLBaseComponents" xmlns:ns="urn:ebay:api:PayPalAPI"> | |
<SOAP-ENV:Header> | |
<Security xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext" xsi:type="wsse:SecurityType"/> | |
<RequesterCredentials xmlns="urn:ebay:api:PayPalAPI" xsi:type="ebl:CustomSecurityHeaderType"> | |
<Credentials xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:UserIdPasswordType"> | |
<Username xsi:type="xs:string"/> | |
<Password xsi:type="xs:string"/> | |
<Signature xsi:type="xs:string"/> | |
<Subject xsi:type="xs:string"/> | |
</Credentials> | |
</RequesterCredentials> | |
</SOAP-ENV:Header> | |
<SOAP-ENV:Body id="_0"> | |
<GetExpressCheckoutDetailsResponse xmlns="urn:ebay:api:PayPalAPI"> | |
<Timestamp xmlns="urn:ebay:apis:eBLBaseComponents">2013-10-22T18:02:56Z</Timestamp> | |
<Ack xmlns="urn:ebay:apis:eBLBaseComponents">Success</Ack> | |
<CorrelationID xmlns="urn:ebay:apis:eBLBaseComponents">123456789012</CorrelationID> | |
<Version xmlns="urn:ebay:apis:eBLBaseComponents">106.0</Version> | |
<Build xmlns="urn:ebay:apis:eBLBaseComponents">8208991</Build> | |
<GetExpressCheckoutDetailsResponseDetails xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:GetExpressCheckoutDetailsResponseDetailsType"> | |
<Token xsi:type="ebl:ExpressCheckoutTokenType">TOKEN</Token> | |
<ContactPhone xsi:type="ebl:ContactPhoneType">555-123-4567</ContactPhone> | |
<PayerInfo xsi:type="ebl:PayerInfoType"> | |
<Payer xsi:type="ebl:EmailAddressType">payer@gmail.com</Payer> | |
<PayerID xsi:type="ebl:UserIDType">PAYERID</PayerID> | |
<PayerStatus xsi:type="ebl:PayPalUserStatusCodeType">verified</PayerStatus> | |
<PayerName xsi:type="ebl:PersonNameType"> | |
<Salutation xmlns="urn:ebay:apis:eBLBaseComponents"/> | |
<FirstName xmlns="urn:ebay:apis:eBLBaseComponents">Personal</FirstName> | |
<MiddleName xmlns="urn:ebay:apis:eBLBaseComponents"/> | |
<LastName xmlns="urn:ebay:apis:eBLBaseComponents">User</LastName> | |
<Suffix xmlns="urn:ebay:apis:eBLBaseComponents"/> | |
</PayerName> | |
<PayerCountry xsi:type="ebl:CountryCodeType">US</PayerCountry> | |
<PayerBusiness xsi:type="xs:string"/> | |
<Address xsi:type="ebl:AddressType"> | |
<Name xsi:type="xs:string">Person Namerson</Name> | |
<Street1 xsi:type="xs:string">123 City Street</Street1> | |
<Street2 xsi:type="xs:string"/> | |
<CityName xsi:type="xs:string">Townville</CityName> | |
<StateOrProvince xsi:type="xs:string">NY</StateOrProvince> | |
<Country xsi:type="ebl:CountryCodeType">US</Country> | |
<CountryName>United States</CountryName> | |
<PostalCode xsi:type="xs:string">12345</PostalCode> | |
<AddressOwner xsi:type="ebl:AddressOwnerCodeType">PayPal</AddressOwner> | |
<AddressStatus xsi:type="ebl:AddressStatusCodeType">Confirmed</AddressStatus> | |
</Address> | |
</PayerInfo> | |
<PaymentDetails xsi:type="ebl:PaymentDetailsType"> | |
<OrderTotal xsi:type="cc:BasicAmountType" currencyID="USD">39.00</OrderTotal> | |
<ItemTotal xsi:type="cc:BasicAmountType" currencyID="USD">39.00</ItemTotal> | |
<ShippingTotal xsi:type="cc:BasicAmountType" currencyID="USD">0.00</ShippingTotal> | |
<HandlingTotal xsi:type="cc:BasicAmountType" currencyID="USD">0.00</HandlingTotal> | |
<TaxTotal xsi:type="cc:BasicAmountType" currencyID="USD">0.00</TaxTotal> | |
<NotifyURL xsi:type="xs:string">http://localhost/</NotifyURL> | |
<ShipToAddress xsi:type="ebl:AddressType"> | |
<Name xsi:type="xs:string">Person Namerson</Name> | |
<Street1 xsi:type="xs:string">123 City Street</Street1> | |
<Street2 xsi:type="xs:string"/> | |
<CityName xsi:type="xs:string">Townville</CityName> | |
<StateOrProvince xsi:type="xs:string">NY</StateOrProvince> | |
<Country xsi:type="ebl:CountryCodeType">US</Country> | |
<CountryName>United States</CountryName> | |
<Phone xsi:type="xs:string"/> | |
<PostalCode xsi:type="xs:string">12345</PostalCode> | |
<AddressID xsi:type="xs:string"/> | |
<AddressOwner xsi:type="ebl:AddressOwnerCodeType">PayPal</AddressOwner> | |
<ExternalAddressID xsi:type="xs:string"/> | |
<AddressStatus xsi:type="ebl:AddressStatusCodeType">Confirmed</AddressStatus> | |
<AddressNormalizationStatus xsi:type="ebl:AddressNormalizationStatusCodeType">None</AddressNormalizationStatus> | |
</ShipToAddress> | |
<PaymentDetailsItem xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:PaymentDetailsItemType"> | |
<Name xsi:type="xs:string">Long Johns</Name> | |
<Quantity>1</Quantity> | |
<Tax xsi:type="cc:BasicAmountType" currencyID="USD">0.00</Tax> | |
<Amount xsi:type="cc:BasicAmountType" currencyID="USD">21.00</Amount> | |
<EbayItemPaymentDetailsItem xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:EbayItemPaymentDetailsItemType"/> | |
<ItemCategory xsi:type="ebl:ItemCategoryType">Physical</ItemCategory> | |
</PaymentDetailsItem> | |
<PaymentDetailsItem xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:PaymentDetailsItemType"> | |
<Name xsi:type="xs:string">Short Johns</Name> | |
<Quantity>1</Quantity> | |
<Tax xsi:type="cc:BasicAmountType" currencyID="USD">0.00</Tax> | |
<Amount xsi:type="cc:BasicAmountType" currencyID="USD">18.00</Amount> | |
<EbayItemPaymentDetailsItem xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:EbayItemPaymentDetailsItemType"/> | |
<ItemCategory xsi:type="ebl:ItemCategoryType">Physical</ItemCategory> | |
</PaymentDetailsItem> | |
<InsuranceTotal xsi:type="cc:BasicAmountType" currencyID="USD">0.00</InsuranceTotal> | |
<ShippingDiscount xsi:type="cc:BasicAmountType" currencyID="USD">0.00</ShippingDiscount> | |
<InsuranceOptionOffered xsi:type="xs:string">false</InsuranceOptionOffered> | |
<SellerDetails xsi:type="ebl:SellerDetailsType"/> | |
<PaymentRequestID xsi:type="xs:string"/> | |
<OrderURL xsi:type="xs:string"/> | |
<SoftDescriptor xsi:type="xs:string"/> | |
</PaymentDetails> | |
<CheckoutStatus xsi:type="xs:string">PaymentActionNotInitiated</CheckoutStatus> | |
<PaymentRequestInfo xsi:type="ebl:PaymentRequestInfoType"/> | |
</GetExpressCheckoutDetailsResponseDetails> | |
</GetExpressCheckoutDetailsResponse> | |
</SOAP-ENV:Body> | |
</SOAP-ENV:Envelope> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- test/fixtures/express_checkout/success/set.xml --> | |
<?xml version="1.0" encoding="UTF-8"?> | |
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:cc="urn:ebay:apis:CoreComponentTypes" xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext" xmlns:ed="urn:ebay:apis:EnhancedDataTypes" xmlns:ebl="urn:ebay:apis:eBLBaseComponents" xmlns:ns="urn:ebay:api:PayPalAPI"> | |
<SOAP-ENV:Header> | |
<Security xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext" xsi:type="wsse:SecurityType"/> | |
<RequesterCredentials xmlns="urn:ebay:api:PayPalAPI" xsi:type="ebl:CustomSecurityHeaderType"> | |
<Credentials xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:UserIdPasswordType"> | |
<Username xsi:type="xs:string"/> | |
<Password xsi:type="xs:string"/> | |
<Signature xsi:type="xs:string"/> | |
<Subject xsi:type="xs:string"/> | |
</Credentials> | |
</RequesterCredentials> | |
</SOAP-ENV:Header> | |
<SOAP-ENV:Body id="_0"> | |
<SetExpressCheckoutResponse xmlns="urn:ebay:api:PayPalAPI"> | |
<Timestamp xmlns="urn:ebay:apis:eBLBaseComponents">2013-10-22T17:56:51Z</Timestamp> | |
<Ack xmlns="urn:ebay:apis:eBLBaseComponents">Success</Ack> | |
<CorrelationID xmlns="urn:ebay:apis:eBLBaseComponents">123456789012</CorrelationID> | |
<Version xmlns="urn:ebay:apis:eBLBaseComponents">106.0</Version> | |
<Build xmlns="urn:ebay:apis:eBLBaseComponents">8208991</Build> | |
<Token xsi:type="ebl:ExpressCheckoutTokenType">TOKEN</Token> | |
</SetExpressCheckoutResponse> | |
</SOAP-ENV:Body> | |
</SOAP-ENV:Envelope> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# test/test_helper.rb | |
require 'fakeweb' | |
PayPal::SDK::Core::Config.logger = Logger.new('/dev/null') | |
# If you're using webrat | |
Webrat.configure do |config| | |
config.mode = :rails | |
# Not sure why, but it seems that enabling this can result in PayPal | |
# reporting errors falsely, though the tests still appear to pass. | |
config.open_error_files = false | |
end | |
class ActionController::IntegrationTest | |
def setup_fakeweb_for_express_checkout | |
FakeWeb.register_uri( | |
:post, | |
PayPal::SDK::Merchant::API.new.service_endpoint, | |
:content_type => "application/xml", | |
:status => ["200", "OK"], | |
:body => File.read(Rails.root.join("test/fixtures/express_checkout/success/get.xml")) | |
) | |
end | |
def teardown_fakeweb_for_express_checkout | |
FakeWeb::Registry.instance.uri_map[FakeWeb::Registry.instance.send(:normalize_uri, PayPal::SDK::Merchant::API.new.service_endpoint)] = {} | |
end | |
def stub_express_checkout | |
setup_fakeweb_for_express_checkout | |
api = PayPal::SDK::Merchant::API.new | |
PayPal::Merchant::ExpressCheckout.any_instance.stubs(:express_checkout_url).returns(return_order_express_checkout_url) | |
stub_express_checkout_for(:set) | |
stub_express_checkout_for(:get) | |
stub_express_checkout_for(:do) | |
teardown_fakeweb_for_express_checkout | |
end | |
def stub_express_checkout_for_failure(method, file_name = nil) | |
stub_express_checkout_for(method, "failure", file_name) | |
end | |
def stub_express_checkout_for(method, response = "success", file_name = nil) | |
setup_fakeweb_for_express_checkout | |
api = PayPal::SDK::Merchant::API.new | |
case method.to_sym | |
when :do | |
method = :do_express_checkout | |
data_type = PayPal::SDK::Merchant::DataTypes::DoExpressCheckoutPaymentResponseType | |
file_name ||= "do" | |
when :get | |
method = :get_express_checkout | |
data_type = PayPal::SDK::Merchant::DataTypes::GetExpressCheckoutDetailsResponseType | |
file_name ||= "get" | |
else | |
method = :set_express_checkout | |
data_type = PayPal::SDK::Merchant::DataTypes::SetExpressCheckoutResponseType | |
file_name ||= "set" | |
end | |
PayPal::Merchant::ExpressCheckout.any_instance.stubs(method).returns( | |
data_type.new(api.format_response({ | |
:response => FakeWeb.response_for(:post, api.service_endpoint).tap { |resp| | |
resp.instance_variable_set("@body", File.read(Rails.root.join("test/fixtures/express_checkout/#{response}/#{file_name}.xml"))) | |
} | |
})[:data]) | |
) | |
teardown_fakeweb_for_express_checkout | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment