<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/atom10full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US">
  <title>Cody Fauser - Show all</title>
  <id>tag:www.codyfauser.com,2008:mephisto/</id>
  <generator version="0.7.3" uri="http://mephistoblog.com">Mephisto Noh-Varr</generator>
  
  <link href="http://www.codyfauser.com/" rel="alternate" type="text/html" />
  <updated>2008-11-19T19:40:26Z</updated>
  <link rel="self" href="http://feeds.feedburner.com/codyfauser" type="application/atom+xml" /><entry xml:base="http://www.codyfauser.com/">
    <author>
      <name>cody</name>
    </author>
    <id>tag:www.codyfauser.com,2008-11-19:788</id>
    <published>2008-11-19T12:55:00Z</published>
    <updated>2008-11-19T19:40:26Z</updated>
    <category term="Ruby" />
    <category term="active merchant" />
    <category term="presentation" />
    <category term="ruby" />
    <link href="http://www.codyfauser.com/2008/11/19/payment-processing-with-activemerchant" rel="alternate" type="text/html" />
    <title>Payment Processing with ActiveMerchant</title>
<content type="html">
            &lt;p&gt;&lt;a href='http://www.codyfauser.com/assets/2008/11/19/Payment_Processing_with_ActiveMerchant.pdf'&gt;&lt;img src='http://www.codyfauser.com/assets/2008/11/19/Payment_Processing_with_ActiveMerchant.001.jpg' alt='' /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Today I gave my presentation on Payment Processing with ActiveMerchant at the &lt;a href='http://www.voicesthatmatter.com/ruby2008/'&gt;Voices that Matter Professional Ruby  Conference&lt;/a&gt;. The conference has a wonderful intimate atmosphere, similar to RubyFringe, and follows the same single track format. &lt;a href='http://www.codyfauser.com/assets/2008/11/19/Payment_Processing_with_ActiveMerchant.pdf'&gt;Download the slides&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.codyfauser.com/">
    <author>
      <name>cody</name>
    </author>
    <id>tag:www.codyfauser.com,2008-10-03:608</id>
    <published>2008-10-03T00:25:00Z</published>
    <updated>2008-10-03T00:31:58Z</updated>
    <category term="Announcements" />
    <category term="presentations" />
    <link href="http://www.codyfauser.com/2008/10/3/presenting-at-voices-that-matter-professional-ruby-conference" rel="alternate" type="text/html" />
    <title>Presenting at Voices that Matter: Professional Ruby Conference</title>
<content type="html">
            &lt;p&gt;&lt;img src='http://www.codyfauser.com/assets/2008/10/3/Ruby125x125.jpg' alt='Voices that Matter: Professional Ruby Conference' /&gt;&lt;/p&gt;

&lt;p&gt;I will be doing a presentation on payment processing with &lt;a href='http://www.activemerchant.org'&gt;Active Merchant&lt;/a&gt; at the &lt;a href='http://www.voicesthatmatter.com/ruby2008/'&gt;Voices that Matter: Professional Ruby Conference&lt;/a&gt; a.k.a. &lt;a href='http://obiefernandez.com/'&gt;ObieConf&lt;/a&gt;. The conference is running from November 17-20, 2008 in Boston, MA. The list of speakers looks very impressive.&lt;/p&gt;

&lt;p&gt;If you're interested in attending the conference you can use the discount code PRDPKRL to get a $200 discount on registration. Hope to see you there!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.codyfauser.com/">
    <author>
      <name>cody</name>
    </author>
    <id>tag:www.codyfauser.com,2008-08-29:505</id>
    <published>2008-08-29T14:42:00Z</published>
    <updated>2008-08-29T15:17:42Z</updated>
    <category term="ruby,presenatation" />
    <link href="http://www.codyfauser.com/2008/8/29/ruby-presentation-for-open-source-bootcamp" rel="alternate" type="text/html" />
    <title>Ruby Presentation for Open Source Bootcamp</title>
<content type="html">
            &lt;p&gt;Last night I gave a presentation on Ruby for &lt;a href='http://www.osbootcamp.org/' title='OSBOOTCAMP'&gt;Open Source Bootcamp&lt;/a&gt; #8.  The event was held at &lt;a href='http://thecodefactory.ca/'&gt;The Code Factory&lt;/a&gt;, a very impressive co-working space in downtown Ottawa. I went on last after &lt;a href='http://babyl.dyndns.org/croisee/'&gt;Yanick Champoux&lt;/a&gt;, who presented on Perl, and Michael P. Soulier, who presented on Python. Both presentations were excellent.&lt;/p&gt;


	&lt;p&gt;&lt;img src='http://www.codyfauser.com/assets/2008/8/29/20080828_21-00-39.jpg' alt='' /&gt;&lt;/p&gt;


	&lt;p&gt;I had forgotten how eerily similar Perl’s syntax is to Ruby. I was speaking with Michael after the talks and he mentioned that this actually causes quite a lot of trouble for people fluent in Perl when moving to Ruby. He mentioned that quite a few times he would write out a Perlism in Ruby, but that the code just wouldn’t behave as expected. For example, the fact that 0 is true in Ruby causes a lot of grief when writing idiomatic Perl.&lt;/p&gt;


	&lt;p&gt;The other thing I noticed was that although Ruby and Python people are always having huge flame wars about which language is better, both groups have similar goals: to rapidly develop applications, and to enjoy themselves while doing it. Although at this point I favour the syntax of Ruby over Python, I am definitely interested in doing a full project with Python in the future.&lt;/p&gt;


	&lt;p&gt;You can &lt;a href='http://www.codyfauser.com/assets/2008/8/29/OS_Bootcamp_-_Ruby.pdf'&gt;download the slides&lt;/a&gt; and you can get the videos, once available, from &lt;a href='http://www.osbootcamp.org/index.php?page=yow8'&gt;the page for the event&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.codyfauser.com/">
    <author>
      <name>cody</name>
    </author>
    <id>tag:www.codyfauser.com,2008-07-15:483</id>
    <published>2008-07-15T14:07:00Z</published>
    <updated>2008-07-15T14:17:39Z</updated>
    <category term="git ogre" />
    <link href="http://www.codyfauser.com/2008/7/15/excellent-git-presentation-at-ogre" rel="alternate" type="text/html" />
    <title>Excellent Git Presentation at OGRE</title>
<content type="html">
            &lt;p&gt;&lt;a href='http://www.jukie.net/~bart/'&gt;Bart Trojanowski&lt;/a&gt; was kind enough to come to our Ottawa Ruby meeting &lt;a href='http://groups.google.com/group/ogre-list'&gt;OGRE&lt;/a&gt; and do a presentation Git. &lt;/p&gt;

&lt;p&gt;I had seen Bart present a few years ago at an OCLUG meeting here in Ottawa and he was very knowledgeable and a great presenter. Therefore, I was was very excited to see him do a presentation on Git. The presentation was fantastic and my level of Git knowledge was increased significantly, especially my understanding of how Git works internally.&lt;/p&gt;

&lt;p&gt;The entire presentation was recorded as a &lt;a href='http://excess.org/article/2008/07/ogre-git-tutorial/'&gt;screencast&lt;/a&gt; and there is also a &lt;a href='http://edgyu.excess.org/git-tutorial/2008-07-09/intro-to-git.pdf'&gt;PDF version of the slides&lt;/a&gt;. I would definitely recommend checking them out.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.codyfauser.com/">
    <author>
      <name>cody</name>
    </author>
    <id>tag:www.codyfauser.com,2008-07-04:478</id>
    <published>2008-07-04T09:43:00Z</published>
    <updated>2008-07-15T14:03:44Z</updated>
    <category term="rails" />
    <link href="http://www.codyfauser.com/2008/7/4/rails-http-status-code-to-symbol-mapping" rel="alternate" type="text/html" />
    <title>Rails HTTP Status Code to Symbol Mapping</title>
<content type="html">
            &lt;p&gt;Recently I had been wondering what the complete list of HTTP status code symbols was in Rails. Searching through Rails didn't yield any results for a symbol like &lt;code&gt;:unprocessable_entity&lt;/code&gt;. Digging around in the Rails source code I found the file &lt;code&gt;actionpack/lib/action_controller/status_codes.rb&lt;/code&gt;, which has the mapping of the status code to the status message. Then Rails defines the symbol to status code mapping dynamically from the status message.&lt;/p&gt;

&lt;p&gt;The symbol used is an underscored version of the status message with no spaces. A quick Ruby script yields the following mapping:&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;&lt;th&gt;Status Code&lt;/th&gt;&lt;th&gt;Status Message&lt;/th&gt;&lt;th&gt;Symbol&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;1xx Informational&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;100&lt;/td&gt;&lt;td&gt;Continue&lt;/td&gt;&lt;td&gt;:continue&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;101&lt;/td&gt;&lt;td&gt;Switching Protocols&lt;/td&gt;&lt;td&gt;:switching_protocols&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;102&lt;/td&gt;&lt;td&gt;Processing&lt;/td&gt;&lt;td&gt;:processing&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;2xx Success&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;200&lt;/td&gt;&lt;td&gt;OK&lt;/td&gt;&lt;td&gt;:ok&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;201&lt;/td&gt;&lt;td&gt;Created&lt;/td&gt;&lt;td&gt;:created&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;202&lt;/td&gt;&lt;td&gt;Accepted&lt;/td&gt;&lt;td&gt;:accepted&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;203&lt;/td&gt;&lt;td&gt;Non-Authoritative Information&lt;/td&gt;&lt;td&gt;:non_authoritative_information&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;204&lt;/td&gt;&lt;td&gt;No Content&lt;/td&gt;&lt;td&gt;:no_content&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;205&lt;/td&gt;&lt;td&gt;Reset Content&lt;/td&gt;&lt;td&gt;:reset_content&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;206&lt;/td&gt;&lt;td&gt;Partial Content&lt;/td&gt;&lt;td&gt;:partial_content&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;207&lt;/td&gt;&lt;td&gt;Multi-Status&lt;/td&gt;&lt;td&gt;:multi_status&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;226&lt;/td&gt;&lt;td&gt;IM Used&lt;/td&gt;&lt;td&gt;:im_used&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;3xx Redirection&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;300&lt;/td&gt;&lt;td&gt;Multiple Choices&lt;/td&gt;&lt;td&gt;:multiple_choices&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;301&lt;/td&gt;&lt;td&gt;Moved Permanently&lt;/td&gt;&lt;td&gt;:moved_permanently&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;302&lt;/td&gt;&lt;td&gt;Found&lt;/td&gt;&lt;td&gt;:found&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;303&lt;/td&gt;&lt;td&gt;See Other&lt;/td&gt;&lt;td&gt;:see_other&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;304&lt;/td&gt;&lt;td&gt;Not Modified&lt;/td&gt;&lt;td&gt;:not_modified&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;305&lt;/td&gt;&lt;td&gt;Use Proxy&lt;/td&gt;&lt;td&gt;:use_proxy&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;307&lt;/td&gt;&lt;td&gt;Temporary Redirect&lt;/td&gt;&lt;td&gt;:temporary_redirect&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;4xx Client Error&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;400&lt;/td&gt;&lt;td&gt;Bad Request&lt;/td&gt;&lt;td&gt;:bad_request&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;401&lt;/td&gt;&lt;td&gt;Unauthorized&lt;/td&gt;&lt;td&gt;:unauthorized&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;402&lt;/td&gt;&lt;td&gt;Payment Required&lt;/td&gt;&lt;td&gt;:payment_required&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;403&lt;/td&gt;&lt;td&gt;Forbidden&lt;/td&gt;&lt;td&gt;:forbidden&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;404&lt;/td&gt;&lt;td&gt;Not Found&lt;/td&gt;&lt;td&gt;:not_found&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;405&lt;/td&gt;&lt;td&gt;Method Not Allowed&lt;/td&gt;&lt;td&gt;:method_not_allowed&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;406&lt;/td&gt;&lt;td&gt;Not Acceptable&lt;/td&gt;&lt;td&gt;:not_acceptable&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;407&lt;/td&gt;&lt;td&gt;Proxy Authentication Required&lt;/td&gt;&lt;td&gt;:proxy_authentication_required&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;408&lt;/td&gt;&lt;td&gt;Request Timeout&lt;/td&gt;&lt;td&gt;:request_timeout&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;409&lt;/td&gt;&lt;td&gt;Conflict&lt;/td&gt;&lt;td&gt;:conflict&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;410&lt;/td&gt;&lt;td&gt;Gone&lt;/td&gt;&lt;td&gt;:gone&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;411&lt;/td&gt;&lt;td&gt;Length Required&lt;/td&gt;&lt;td&gt;:length_required&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;412&lt;/td&gt;&lt;td&gt;Precondition Failed&lt;/td&gt;&lt;td&gt;:precondition_failed&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;413&lt;/td&gt;&lt;td&gt;Request Entity Too Large&lt;/td&gt;&lt;td&gt;:request_entity_too_large&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;414&lt;/td&gt;&lt;td&gt;Request-URI Too Long&lt;/td&gt;&lt;td&gt;:request_uri_too_long&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;415&lt;/td&gt;&lt;td&gt;Unsupported Media Type&lt;/td&gt;&lt;td&gt;:unsupported_media_type&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;416&lt;/td&gt;&lt;td&gt;Requested Range Not Satisfiable&lt;/td&gt;&lt;td&gt;:requested_range_not_satisfiable&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;417&lt;/td&gt;&lt;td&gt;Expectation Failed&lt;/td&gt;&lt;td&gt;:expectation_failed&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;422&lt;/td&gt;&lt;td&gt;Unprocessable Entity&lt;/td&gt;&lt;td&gt;:unprocessable_entity&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;423&lt;/td&gt;&lt;td&gt;Locked&lt;/td&gt;&lt;td&gt;:locked&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;424&lt;/td&gt;&lt;td&gt;Failed Dependency&lt;/td&gt;&lt;td&gt;:failed_dependency&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;426&lt;/td&gt;&lt;td&gt;Upgrade Required&lt;/td&gt;&lt;td&gt;:upgrade_required&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;5xx Server Error&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;500&lt;/td&gt;&lt;td&gt;Internal Server Error&lt;/td&gt;&lt;td&gt;:internal_server_error&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;501&lt;/td&gt;&lt;td&gt;Not Implemented&lt;/td&gt;&lt;td&gt;:not_implemented&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;502&lt;/td&gt;&lt;td&gt;Bad Gateway&lt;/td&gt;&lt;td&gt;:bad_gateway&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;503&lt;/td&gt;&lt;td&gt;Service Unavailable&lt;/td&gt;&lt;td&gt;:service_unavailable&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;504&lt;/td&gt;&lt;td&gt;Gateway Timeout&lt;/td&gt;&lt;td&gt;:gateway_timeout&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;505&lt;/td&gt;&lt;td&gt;HTTP Version Not Supported&lt;/td&gt;&lt;td&gt;:http_version_not_supported&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;507&lt;/td&gt;&lt;td&gt;Insufficient Storage&lt;/td&gt;&lt;td&gt;:insufficient_storage&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;510&lt;/td&gt;&lt;td&gt;Not Extended&lt;/td&gt;&lt;td&gt;:not_extended&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;h3&gt;Update&lt;/h3&gt;

&lt;p&gt;The &lt;a href='http://cheat.errtheblog.com/'&gt;cheat&lt;/a&gt; gem contains a cheat sheet for the status codes. You can get the gem and view the status codes as follows:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
sudo gem install cheat
cheat status_codes
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Thanks for the info Josh.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.codyfauser.com/">
    <author>
      <name>cody</name>
    </author>
    <id>tag:www.codyfauser.com,2008-05-20:477</id>
    <published>2008-05-20T19:12:00Z</published>
    <updated>2008-05-20T19:32:52Z</updated>
    <category term="Announcements" />
    <category term="activemerchant" />
    <link href="http://www.codyfauser.com/2008/5/20/activemerchant-on-github" rel="alternate" type="text/html" />
    <title>ActiveMerchant on GitHub</title>
<content type="html">
            &lt;p&gt;&lt;img src='http://www.codyfauser.com/assets/2008/5/20/activemerchantp.png' alt='' /&gt;&lt;/p&gt;


	&lt;p&gt;The &lt;a href='http://activemerchant.org'&gt;ActiveMerchant&lt;/a&gt; &lt;a href='http://github.com/Shopify/active_merchant'&gt;source repository&lt;/a&gt; has made the move over to &lt;a href='https://github.com/'&gt;GitHub&lt;/a&gt;. I think the social development GitHub provides will be a perfect fit for ActiveMerchant. We’ve also moved the &lt;a href='http://jadedpixel.lighthouseapp.com/projects/11599-active-merchant'&gt;ActiveMerchant bug tracker&lt;/a&gt; over to &lt;a href='http://lighthouseapp.com/'&gt;Lighthouse&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;
If you’re looking to get up to speed on payment processing and payment processing with ActiveMerchant then be sure to check out my &lt;a href='http://peepcode.com/products/activemerchant-pdf'&gt;PeepCode ActiveMerchant &lt;span class='caps'&gt;PDF&lt;/span&gt;&lt;/a&gt; which was given a &lt;a href='http://www.rubyinside.com/activemerchant-book-by-cody-fauser-714.html'&gt;very favorable review&lt;/a&gt; at &lt;a href='http://www.rubyinside.com'&gt;RubyInside&lt;/a&gt;.
&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.codyfauser.com/">
    <author>
      <name>cody</name>
    </author>
    <id>tag:www.codyfauser.com,2008-01-25:392</id>
    <published>2008-01-25T21:16:00Z</published>
    <updated>2008-01-25T21:18:17Z</updated>
    <category term="Announcements" />
    <category term="shopify" />
    <link href="http://www.codyfauser.com/2008/1/25/shopify-info-redesigned" rel="alternate" type="text/html" />
    <title>Shopify.info Redesigned</title>
<content type="html">
            &lt;p&gt;&lt;a href='http://troubleseeker.com/'&gt;Daniel&lt;/a&gt;, our designer, has just finished the redesign of the &lt;a href='http://www.shopify.info/?ref=cody-fauser'&gt;Shopify brochure page&lt;/a&gt; and it looks fantastic. The page features a beautiful redesign, fantastic video overview of some of Shopify's features, as well as profiles and interviews with some of Shopify's highest profile clients. If you're in the market for an e-commerce store or if you're into eye candy then you'll definitely want to go and check it out.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.codyfauser.com/">
    <author>
      <name>cody</name>
    </author>
    <id>tag:www.codyfauser.com,2008-01-17:319</id>
    <published>2008-01-17T13:00:00Z</published>
    <updated>2008-01-29T14:44:52Z</updated>
    <category term="Rails" />
    <category term="Ruby" />
    <category term="activemerchant,paypal" />
    <link href="http://www.codyfauser.com/2008/1/17/paypal-express-payments-with-activemerchant" rel="alternate" type="text/html" />
    <title>PayPal Express Payments with ActiveMerchant</title>
<content type="html">
            &lt;p&gt;There is a lot of confusion over the myriad of services that PayPal offers for accepting PayPal payments.  In reality there are two ways of accepting PayPal payments.&lt;/p&gt;

&lt;h3&gt;PayPal Website Payments Standard&lt;/h3&gt;

&lt;p&gt;Website Payments Standard is the basic service PayPal offers for accepting PayPal payments.  Website Payments Standard requires the creation of an HTML form that is posted to PayPal.  The user is redirected to the PayPal website where they complete their payment.  They are then redirected back to the seller's website at the end of the process where it is possible to display an order confirmation, or other information. Very basic, easy to setup, but also quite limited.  &lt;/p&gt;

&lt;h3&gt;PayPal Express&lt;/h3&gt;

&lt;p&gt;PayPal Express is a much more powerful alternative to PayPal Website Payments Standard.  The downside is that it is slightly more complicated. However, I am going to show how easy it is to get PayPal Express working with ActiveMerchant.  PayPal Express has several benefits including support for Authorization and Capture.  Website Payments Standard also has support for Authorization and Capture, but the seller has to actually login to their PayPal account to capture the funds. PayPal Express also keeps control of the payment flow on your page, instead of PayPal's.  The user is only redirected to PayPal briefly to confirm payment, and then they are sent back to the seller's page to complete the payment.  There are several advantages to this, but I think the biggest is that you can rely on PayPal to provide address information for the buyer and then determine additional shipping or other charges to add to the total of the order.&lt;/p&gt;

&lt;p&gt;Now that I've provided a bit of background on PayPal Express I'm going to show how simple it is to integrate into Rails application. The code is based on the integration of PayPal Express into &lt;a href='http://www.shopify.info/?ref=cody-fauser'&gt;Shopify&lt;/a&gt;. The applicable integration points from the &lt;a href='https://www.paypal.com/en_US/ pdf/PP_ExpressCheckout_IntegrationGuide.pdf'&gt;PayPal Express Checkout Integration Guide&lt;/a&gt; will be noted throughout the example. If you like you can download the completed Sprockets application &lt;a href='http://www.codyfauser.com/assets/2008/1/17/sprockets.tar.gz'&gt;sprockets.tar.gz&lt;/a&gt;. You will need at least Rails 2.0.2 Gems to run the Sprockets application. You will only need to add your API credentials into the application, which is described in the example text.&lt;/p&gt;

&lt;p&gt;First, in order to use the sandbox, you'll need a PayPal Sandbox buyer and seller to work with. See &lt;a href='https://www.paypal.com/IntegrationCenter/ic_sandbox.html'&gt;Sandbox Testing&lt;/a&gt; for more information on getting these accounts setup. The seller account must be either a Premier Account or Business Account in order to work with PayPal Express. Don't forget to activate the account using the &lt;em&gt;Test Email&lt;/em&gt; link in Developer Central. Email isn't really sent in the sandbox. It just accumulates in the Developer Central inbox. Then you'll have to confirm your bank account using the &lt;em&gt;Get Verified&lt;/em&gt; link while logged in as the test user.&lt;/p&gt;

&lt;p&gt;Create a new Rails application.  I am going to name my project Sprockets, which is what I'll be selling on my site:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
$ rails sprockets
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you can enter the project and install ActiveMerchant as a plugin:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
$ cd sprockets
$ ./script/plugin install http://activemerchant.googlecode.com/svn/trunk/active_merchant
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The first thing to do is to configure ActiveMerchant.  By default ActiveMerchant uses the production environment of a payment gateway, so we have to force ActiveMerchant into test mode while we're running in the Rails development environment.  This is easily accomplished by opening up &lt;code&gt;config/environments/development.rb&lt;/code&gt; and adding the following code to the bottom of the file:&lt;/p&gt;

&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;config.after_initialize &lt;span class='r'&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='co'&gt;ActiveMerchant&lt;/span&gt;::&lt;span class='co'&gt;Billing&lt;/span&gt;::&lt;span class='co'&gt;Base&lt;/span&gt;.mode = &lt;span class='sy'&gt;:test&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;The preceding code ensures that the PayPal Sandbox will be used for the test payments, and waits until the entire application is loaded before doing the configuration.&lt;/p&gt;

&lt;p&gt;The next thing to do is to login to the &lt;a href='http://developer.paypal.com'&gt;PayPal Sandbox&lt;/a&gt; and launch the sandbox for the &lt;em&gt;seller&lt;/em&gt; account you previously created.  Click the &lt;em&gt;My Account&lt;/em&gt; link followed by the &lt;em&gt;Profile _ link.  Then click _API Access&lt;/em&gt; underneath &lt;em&gt;Account Information&lt;/em&gt;. Select &lt;em&gt;Request API signature&lt;/em&gt; and then click &lt;em&gt;Agree and Submit&lt;/em&gt;. Record the &lt;em&gt;API username&lt;/em&gt;, &lt;em&gt;API Password&lt;/em&gt;, and &lt;em&gt;Signature&lt;/em&gt;. We'll be using them shortly.&lt;/p&gt;

&lt;p&gt;Now that all of the configuration has been completed we can move onto actually accepting payments.  Let's generate a controller &lt;code&gt;PaymentsController&lt;/code&gt; that will be used to accept the payments from PayPal. &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
$ ./script/generate controller payments index confirm complete
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We created the controller with the action &lt;code&gt;index&lt;/code&gt;, &lt;code&gt;confirm&lt;/code&gt;, &lt;code&gt;complete&lt;/code&gt; actions in the controller along with their associated views. Let's open up the &lt;code&gt;index.html.erb&lt;/code&gt; template and add the PayPal Express logo that the customer will click to make payment. &lt;/p&gt;

&lt;p&gt;The first thing we need to do is include the &lt;code&gt;ActiveMerchant::Billing&lt;/code&gt; namespace into the controller so that we can access the classes from ActiveMerchant with less typing:&lt;/p&gt;

&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;span class='r'&gt;class&lt;/span&gt; &lt;span class='cl'&gt;PaymentsController&lt;/span&gt; &amp;lt; &lt;span class='co'&gt;ApplicationController&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  include &lt;span class='co'&gt;ActiveMerchant&lt;/span&gt;::&lt;span class='co'&gt;Billing&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;I'm assuming that you have created a common layout, such as &lt;code&gt;application.html.erb&lt;/code&gt; to provide the required HTML structure for the page. The &lt;code&gt;index&lt;/code&gt; action represents &lt;em&gt;Integration Point 1a&lt;/em&gt; from the Integration Guide. &lt;code&gt;index.html.erb&lt;/code&gt; looks as follows:&lt;/p&gt;

&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&amp;lt;h1&amp;gt;&lt;span class='co'&gt;Purchase&lt;/span&gt; &lt;span class='co'&gt;Sprockets&lt;/span&gt;&amp;lt;&lt;span class='rx'&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;span class='k'&gt;h1&amp;gt;&lt;tt&gt;
&lt;/tt&gt;&amp;lt;p&amp;gt;Thank you for your decision to purchase our sprockets.&amp;lt;&lt;/span&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;/span&gt;p&amp;gt;&lt;tt&gt;
&lt;/tt&gt;&amp;lt;p&amp;gt;&lt;span class='co'&gt;Your&lt;/span&gt; order total is &lt;span class='gv'&gt;$50&lt;/span&gt;.&lt;span class='i'&gt;00&lt;/span&gt;&amp;lt;&lt;span class='rx'&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;span class='k'&gt;p&amp;gt;&lt;tt&gt;
&lt;/tt&gt;&amp;lt;p&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  &amp;lt;%= link_to image_tag('https:&lt;/span&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;/span&gt;/www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif&lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;), :action =&amp;gt; &lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;checkout&lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt; %&amp;gt;&lt;tt&gt;
&lt;/tt&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Clicking the PayPal Express button do a &lt;code&gt;GET&lt;/code&gt; request on the &lt;code&gt;checkout&lt;/code&gt; action. The &lt;code&gt;checkout&lt;/code&gt; action is where we setup the purchase with PayPal and get the token identifying the purchase from PayPal. We didn't generate the &lt;code&gt;checkout&lt;/code&gt; action initially because it doesn't require a view. The &lt;code&gt;checkout&lt;/code&gt; action represents &lt;em&gt;Integration Point 1b&lt;/em&gt; from the Integration Guide. Define the &lt;code&gt;checkout&lt;/code&gt; action as follows:&lt;/p&gt;

&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;span class='r'&gt;def&lt;/span&gt; &lt;span class='fu'&gt;checkout&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  setup_response = gateway.setup_purchase(&lt;span class='i'&gt;5000&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;    &lt;span class='sy'&gt;:ip&lt;/span&gt;                =&amp;gt; request.remote_ip,&lt;tt&gt;
&lt;/tt&gt;    &lt;span class='sy'&gt;:return_url&lt;/span&gt;        =&amp;gt; url_for(&lt;span class='sy'&gt;:action&lt;/span&gt; =&amp;gt; &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;confirm&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class='sy'&gt;:only_path&lt;/span&gt; =&amp;gt; &lt;span class='pc'&gt;false&lt;/span&gt;),&lt;tt&gt;
&lt;/tt&gt;    &lt;span class='sy'&gt;:cancel_return_url&lt;/span&gt; =&amp;gt; url_for(&lt;span class='sy'&gt;:action&lt;/span&gt; =&amp;gt; &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;index&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class='sy'&gt;:only_path&lt;/span&gt; =&amp;gt; &lt;span class='pc'&gt;false&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  )&lt;tt&gt;
&lt;/tt&gt;  redirect_to gateway.redirect_url_for(setup_response.token)&lt;tt&gt;
&lt;/tt&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;&lt;code&gt;gateway&lt;/code&gt; is actually a method which constructs the &lt;code&gt;PaypalExpressGateway&lt;/code&gt; if it hasn't been already:&lt;/p&gt;

&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;private&lt;tt&gt;
&lt;/tt&gt;&lt;span class='r'&gt;def&lt;/span&gt; &lt;span class='fu'&gt;gateway&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='iv'&gt;@gateway&lt;/span&gt; ||= &lt;span class='co'&gt;PaypalExpressGateway&lt;/span&gt;.new(&lt;tt&gt;
&lt;/tt&gt;    &lt;span class='sy'&gt;:login&lt;/span&gt; =&amp;gt; &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;API Login&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;    &lt;span class='sy'&gt;:password&lt;/span&gt; =&amp;gt; &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;API Password&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;    &lt;span class='sy'&gt;:signature&lt;/span&gt; =&amp;gt; &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;API Signature&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  )&lt;tt&gt;
&lt;/tt&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;As you can see, we're constructing the gateway using the credentials provided to us earlier in the PayPal Sandbox and returning the new instance of the gateway.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;setup_purchase()&lt;/code&gt; method informs PayPal of the details of the purchase we're going to make and returns a token. &lt;code&gt;5000&lt;/code&gt; is the amount in cents of the purchase, which is $50.00. ActiveMerchant only accepts amounts in cents. The customer's IP address, passed in using the &lt;code&gt;:ip&lt;/code&gt; option, is a required option, and helps PayPal reduce fraud. The &lt;code&gt;:return_url&lt;/code&gt; option is the absolute URL that the customer will be redirected to after their purchase, and &lt;code&gt;:cancel_return_url&lt;/code&gt; is the URL the customer will return to if they cancel the purchase.&lt;/p&gt;

&lt;p&gt;Finally, we redirect the customer to PayPal. The URL is constructed by passing the &lt;code&gt;token&lt;/code&gt; returned in the &lt;code&gt;setup_purchase()&lt;/code&gt; call to the &lt;code&gt;redirect_url_for()&lt;/code&gt; method provided by the gateway.&lt;/p&gt;

&lt;p&gt;Now if you load http://localhost:3000/payments in your browser and click the PayPal Express button you should be redirected to PayPal. You will need to be logged into the PayPal Developer Central at the time you click the button in order for the sandbox to load correctly. You can now log in to PayPal using the Sandbox &lt;em&gt;buyer&lt;/em&gt; account that you created earlier. Once logged in you will see the details of the purchase. You'll also see the link to cancel the transaction below the &lt;em&gt;Continue&lt;/em&gt; button. The time spent on PayPal's site represents &lt;em&gt;Integration Point 2a&lt;/em&gt; and &lt;em&gt;Integration Point 2b&lt;/em&gt; from the Integration Guide. Clicking the &lt;em&gt;Continue&lt;/em&gt; button will redirect your browser back to the Sprockets application &lt;code&gt;confirm&lt;/code&gt; action. The redirection back to our application represents &lt;em&gt;Integration Point 2c&lt;/em&gt; from the Integration guide. We already have a confirm action, but it just displays the default message put in the template by the Rails generator.&lt;/p&gt;

&lt;p&gt;Let's enhance the &lt;code&gt;confirm&lt;/code&gt; action as follows:&lt;/p&gt;

&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;span class='r'&gt;def&lt;/span&gt; &lt;span class='fu'&gt;confirm&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  redirect_to &lt;span class='sy'&gt;:action&lt;/span&gt; =&amp;gt; &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;index&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class='r'&gt;unless&lt;/span&gt; params[&lt;span class='sy'&gt;:token&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  details_response = gateway.details_for(params[&lt;span class='sy'&gt;:token&lt;/span&gt;])&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class='r'&gt;if&lt;/span&gt; !details_response.success?&lt;tt&gt;
&lt;/tt&gt;    &lt;span class='iv'&gt;@message&lt;/span&gt; = details_response.message&lt;tt&gt;
&lt;/tt&gt;    render &lt;span class='sy'&gt;:action&lt;/span&gt; =&amp;gt; &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;error&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class='r'&gt;return&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='r'&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;tt&gt;
&lt;/tt&gt;  &lt;span class='iv'&gt;@address&lt;/span&gt; = details_response.address&lt;tt&gt;
&lt;/tt&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;First, we request the details of the purchase from PayPal using the &lt;code&gt;details_for()&lt;/code&gt; method, which takes the &lt;code&gt;token&lt;/code&gt; param as its first argument. If we successful get the details for the purchase then we display the &lt;code&gt;confirm.html.erb&lt;/code&gt; template. Otherwise, we render the the &lt;code&gt;error.html.erb&lt;/code&gt; template. &lt;code&gt;error.html.erb&lt;/code&gt; looks as follows:&lt;/p&gt;

&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&amp;lt;h1&amp;gt;&lt;span class='co'&gt;Error&lt;/span&gt;&amp;lt;&lt;span class='rx'&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;span class='k'&gt;h1&amp;gt;&lt;tt&gt;
&lt;/tt&gt;&amp;lt;p&amp;gt;Unfortunately an error occurred: &amp;lt;%= @message %&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;/span&gt;p&amp;gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;The &lt;code&gt;confirm.html.erb&lt;/code&gt; templates displays the customer's PayPal address and asks them if they want to complete the payment. Displaying the review page represents &lt;em&gt;Integration Point 3a&lt;/em&gt; from the Integration guide. This is the customer's opportunity to review the details of their order, change shipping methods, etc. It looks like this:&lt;/p&gt;

&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&amp;lt;h1&amp;gt;&lt;span class='co'&gt;Please&lt;/span&gt; &lt;span class='co'&gt;Confirm&lt;/span&gt; &lt;span class='co'&gt;Your&lt;/span&gt; &lt;span class='co'&gt;Payment&lt;/span&gt; &lt;span class='co'&gt;Details&lt;/span&gt;&amp;lt;&lt;span class='rx'&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;span class='k'&gt;h1&amp;gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;lt;table&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Name&amp;lt;&lt;/span&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;/span&gt;td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;%= &lt;span class='iv'&gt;@address&lt;/span&gt;[&lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;name&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;] &lt;span class='s'&gt;&lt;span class='dl'&gt;%&amp;gt;&lt;/span&gt;&lt;span class='k'&gt;&amp;lt;/td&lt;/span&gt;&lt;span class='dl'&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&amp;lt;&lt;span class='rx'&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;span class='k'&gt;tr&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Company&amp;lt;&lt;/span&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;/span&gt;td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;%= &lt;span class='iv'&gt;@address&lt;/span&gt;[&lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;company&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;] &lt;span class='s'&gt;&lt;span class='dl'&gt;%&amp;gt;&lt;/span&gt;&lt;span class='k'&gt;&amp;lt;/td&lt;/span&gt;&lt;span class='dl'&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&amp;lt;&lt;span class='rx'&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;span class='k'&gt;tr&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Address 1&amp;lt;&lt;/span&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;/span&gt;td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;%= &lt;span class='iv'&gt;@address&lt;/span&gt;[&lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;address1&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;] &lt;span class='s'&gt;&lt;span class='dl'&gt;%&amp;gt;&lt;/span&gt;&lt;span class='k'&gt;&amp;lt;/td&lt;/span&gt;&lt;span class='dl'&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&amp;lt;&lt;span class='rx'&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;span class='k'&gt;tr&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Address 2&amp;lt;&lt;/span&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;/span&gt;td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;%= &lt;span class='iv'&gt;@address&lt;/span&gt;[&lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;address2&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;] &lt;span class='s'&gt;&lt;span class='dl'&gt;%&amp;gt;&lt;/span&gt;&lt;span class='k'&gt;&amp;lt;/td&lt;/span&gt;&lt;span class='dl'&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&amp;lt;&lt;span class='rx'&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;span class='k'&gt;tr&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;City&amp;lt;&lt;/span&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;/span&gt;td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;%= &lt;span class='iv'&gt;@address&lt;/span&gt;[&lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;city&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;] &lt;span class='s'&gt;&lt;span class='dl'&gt;%&amp;gt;&lt;/span&gt;&lt;span class='k'&gt;&amp;lt;/td&lt;/span&gt;&lt;span class='dl'&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&amp;lt;&lt;span class='rx'&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;span class='k'&gt;tr&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;State&amp;lt;&lt;/span&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;/span&gt;td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;%= &lt;span class='iv'&gt;@address&lt;/span&gt;[&lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;state&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;] &lt;span class='s'&gt;&lt;span class='dl'&gt;%&amp;gt;&lt;/span&gt;&lt;span class='k'&gt;&amp;lt;/td&lt;/span&gt;&lt;span class='dl'&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&amp;lt;&lt;span class='rx'&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;span class='k'&gt;tr&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Country&amp;lt;&lt;/span&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;/span&gt;td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;%= &lt;span class='iv'&gt;@address&lt;/span&gt;[&lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;country&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;] &lt;span class='s'&gt;&lt;span class='dl'&gt;%&amp;gt;&lt;/span&gt;&lt;span class='k'&gt;&amp;lt;/td&lt;/span&gt;&lt;span class='dl'&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&amp;lt;&lt;span class='rx'&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;span class='k'&gt;tr&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Zip&amp;lt;&lt;/span&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;/span&gt;td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;%= &lt;span class='iv'&gt;@address&lt;/span&gt;[&lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;zip&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;] &lt;span class='s'&gt;&lt;span class='dl'&gt;%&amp;gt;&lt;/span&gt;&lt;span class='k'&gt;&amp;lt;/td&lt;/span&gt;&lt;span class='dl'&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&amp;lt;&lt;span class='rx'&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;span class='k'&gt;tr&amp;gt;&lt;tt&gt;
&lt;/tt&gt;&amp;lt;&lt;/span&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;/span&gt;table&amp;gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;lt;% form_tag &lt;span class='sy'&gt;:action&lt;/span&gt; =&amp;gt; &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;complete&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class='sy'&gt;:token&lt;/span&gt; =&amp;gt; params[&lt;span class='sy'&gt;:token&lt;/span&gt;], &lt;span class='sy'&gt;:payer_id&lt;/span&gt; =&amp;gt; params[&lt;span class='sy'&gt;:PayerID&lt;/span&gt;] &lt;span class='r'&gt;do&lt;/span&gt; &lt;span class='s'&gt;&lt;span class='dl'&gt;%&amp;gt;&lt;/span&gt;&lt;span class='k'&gt;&lt;tt&gt;
&lt;/tt&gt;  &amp;lt;%= submit_tag 'Complete Payment' %&lt;/span&gt;&lt;span class='dl'&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;lt;% &lt;span class='r'&gt;end&lt;/span&gt; &lt;span class='s'&gt;&lt;span class='dl'&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;When the customer clicks the &lt;em&gt;Complete Payment&lt;/em&gt; button they will post their &lt;code&gt;token&lt;/code&gt;, and &lt;code&gt;PayerID&lt;/code&gt;, which were returned from PayPal, back to the &lt;code&gt;complete&lt;/code&gt; action where we'll inform PayPal to complete the purchase. Completing the purchase represents &lt;em&gt;Integration Point 3b&lt;/em&gt; from the Integration Guide. It looks as follows:&lt;/p&gt;

&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;span class='r'&gt;def&lt;/span&gt; &lt;span class='fu'&gt;complete&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  purchase = gateway.purchase(&lt;span class='i'&gt;5000&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;    &lt;span class='sy'&gt;:ip&lt;/span&gt;       =&amp;gt; request.remote_ip,&lt;tt&gt;
&lt;/tt&gt;    &lt;span class='sy'&gt;:payer_id&lt;/span&gt; =&amp;gt; params[&lt;span class='sy'&gt;:payer_id&lt;/span&gt;],&lt;tt&gt;
&lt;/tt&gt;    &lt;span class='sy'&gt;:token&lt;/span&gt;    =&amp;gt; params[&lt;span class='sy'&gt;:token&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;  )&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class='r'&gt;if&lt;/span&gt; !purchase.success?&lt;tt&gt;
&lt;/tt&gt;    &lt;span class='iv'&gt;@message&lt;/span&gt; = purchase.message&lt;tt&gt;
&lt;/tt&gt;    render &lt;span class='sy'&gt;:action&lt;/span&gt; =&amp;gt; &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;error&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class='r'&gt;return&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='r'&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;This looks similar to when we initially setup the purchase, but we're calling &lt;code&gt;purchase()&lt;/code&gt; instead of &lt;code&gt;setup_purchase()&lt;/code&gt;. If the purchase is successful then we render the &lt;code&gt;complete.html.erb&lt;/code&gt; template. Displaying the final success message represents &lt;em&gt;Integration Point 4&lt;/em&gt; from the Integration Guide, which is the final step. It looks like:&lt;/p&gt;

&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;span class='ta'&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Thank you for your purchase&lt;span class='ta'&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;The entire flow of the purchase is very flexible. The initial amount of the &lt;code&gt;setup_purchase()&lt;/code&gt; method doesn't even need to match the final amount sent in &lt;code&gt;purchase()&lt;/code&gt;. This allows for the buyer to change their mind about their order details during the checkout flow in your site. This is useful for situations where the customer may want to add high priority shipping, a discount code, or gift wrapping while reviewing their order. There is a lot of data that can be provided to PayPal throughout the integration. Take a look at the Integration Guide for a complete overview of all that is possible.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.codyfauser.com/">
    <author>
      <name>cody</name>
    </author>
    <id>tag:www.codyfauser.com,2007-10-20:385</id>
    <published>2007-10-20T16:17:00Z</published>
    <updated>2008-01-18T15:05:17Z</updated>
    <category term="writing" />
    <link href="http://www.codyfauser.com/2007/10/20/scrivener-the-best-thing-since-sliced-bread" rel="alternate" type="text/html" />
    <title>Scrivener, the best writing tool since sliced bread</title>
<content type="html">
            &lt;p&gt;Have you ever wanted to write something, but felt so bogged down by the tools that you gave up? Even worse is if you don't even have the option of giving up. When I was writing &lt;a href='http://www.oreilly.com/catalog/rjsrails/'&gt;RJS Templates for Rails&lt;/a&gt; using the O'Reilly Word template there were many moments when I thought that I may end it all.  Thankfully, that didn't happen.&lt;/p&gt;

&lt;p&gt;I have a profound hatred for Microsoft Word.  I feel like its entire codebase exists solely to make my writing experience miserable. Capitalizing everything I need lowercase, formatting my paragraphs in ways that I don't want, just messing with my document to ruin my weekend. I'm sure it is possible to make Word do what I want, but I just don't feel like it is worth the effort. I don't want to waste my time figuring out how to make Word work for me, when what I want to do is really simple. I just want to write text. Is this a lot to ask for?&lt;/p&gt;

&lt;p&gt;Thankfully, &lt;a href='http://blog.leetsoft.com'&gt;Tobias Lütke&lt;/a&gt; let me know about &lt;a href='http://www.literatureandlatte.com/scrivener.html'&gt;Scrivener&lt;/a&gt;. What can I say? Scrivener is fantastic. Scrivener not only gets out of my way when I'm writing, it actually has features that help with the process of writing. Scrivener helps in all the areas where it counts when it comes to writing. Organization, taking notes, keeping lists of reference material, storing research documents right in the project. Scrivener feels like a combination of a simple text editor with the power of an organizational tool like Omni Outliner built right in. You can create an outline in minutes, reorganize by dragging sections around, look at high level views of a section in a cork board view, and then turn off the entire UI when you're ready to get down to writing by entering the full screen typewriter mode.&lt;/p&gt;

&lt;p&gt;There are many, many more killer features that I won't get into here. Do yourself a favour and get the demo. Better yet, just buy it. It only costs $34.99, which is less than you're going to spend next week at Starbucks anyway. You can get up to speed with all the features in less than an hour with the included tutorials.&lt;/p&gt;

&lt;p&gt;&lt;img src='http://www.codyfauser.com/assets/2007/10/20/ActiveMerchant_PeepCode.scriv_-_Introduction.jpg' alt='ActiveMerchant PeepCode Screenshot' /&gt;&lt;/p&gt;

&lt;div&gt;&amp;nbsp;&lt;/div&gt;
          </content>  </entry>
  <entry xml:base="http://www.codyfauser.com/">
    <author>
      <name>cody</name>
    </author>
    <id>tag:www.codyfauser.com,2007-05-27:365</id>
    <published>2007-05-27T16:39:00Z</published>
    <updated>2007-05-27T16:41:18Z</updated>
    <category term="Rails" />
    <category term="rails" />
    <category term="testing" />
    <link href="http://www.codyfauser.com/2007/5/27/loading-all-rails-test-fixtures-with-fixtures-all" rel="alternate" type="text/html" />
    <title>Loading all Rails test fixtures with fixtures :all</title>
<content type="html">
            &lt;p&gt;Are you as tired as we were of loading 20+ different fixtures in each of your Rails test classes?  We were, and we even added a method &lt;em&gt;all_fixtures()&lt;/em&gt; to &lt;em&gt;test_helper.rb&lt;/em&gt; to do the loading of all our fixtures for us.&lt;/p&gt;

&lt;p&gt;Thankfully though, we don't need our own helper method anymore, as the Rails &lt;em&gt;fixtures()&lt;/em&gt; method will now accept a symbol &lt;em&gt;:all&lt;/em&gt;, which will instruct the test helper to load all of your fixtures automatically.&lt;/p&gt;

&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class='co'&gt;File&lt;/span&gt;.dirname(&lt;span class='pc'&gt;__FILE__&lt;/span&gt;) + &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;/../test_helper&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='r'&gt;class&lt;/span&gt; &lt;span class='cl'&gt;ShopTest&lt;/span&gt; &amp;lt; &lt;span class='co'&gt;Test&lt;/span&gt;::&lt;span class='co'&gt;Unit&lt;/span&gt;::&lt;span class='co'&gt;TestCase&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  fixtures &lt;span class='sy'&gt;:all&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='c'&gt;# Your tests here&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;As of Rails 1.2.3 this feature has not yet been merged from the trunk.   This means that you'll either need to run Edge Rails from Subversion, or install the beta Rails gems as follows:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
sudo gem install -s http://gems.rubyonrails.org rails -y
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Happy testing!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.codyfauser.com/">
    <author>
      <name>cody</name>
    </author>
    <id>tag:www.codyfauser.com,2007-04-02:303</id>
    <published>2007-04-02T20:45:00Z</published>
    <updated>2007-04-02T20:46:02Z</updated>
    <category term="Announcements" />
    <link href="http://www.codyfauser.com/2007/4/2/i-am-in-a-magazine" rel="alternate" type="text/html" />
    <title>I'm in a Magazine!</title>
<content type="html">
            &lt;div&gt; 
&lt;a href='http://2magazine.com/2007/03/cancuncouplemakeover/index.php'&gt;&lt;img src='http://www.codyfauser.com/assets/2007/4/2/SpringCMOpener.jpg' alt='2 Magazine March 2007 Cover' /&gt;&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;Back in January my wife Maria and I were lucky enough to go on an all expenses paid vacation to &lt;a href='http://www.clubmed.us/cgi-bin/clubmed55/SP/villagesHeading.do?CODPER=07E&amp;amp;CODRUB=0&amp;amp;CODLSC=CANC&amp;amp;PAYS=115&amp;amp;LANG=US'&gt;Club Med Cancún Yucután&lt;/a&gt;.  What was the catch?  Well, the entire trip was a makeover for a magazine in Toronto called &lt;a href='http://2magazine.com/'&gt;2 Magazine&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The trip was a blast and we were fortunate enough to be photographed for the magazine by the incredible Toronto based photographer &lt;a href='http://jamespattyn.com/'&gt;James Pattyn&lt;/a&gt;.  The entire week was also documented on video by Mark and Evan from &lt;a href='http://www.viralmediagroup.com/'&gt;Viral Media Group&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Special thanks to the entire 2Magazine crew including Diane, Beth, Margo, Jamie, Keri, Mark, and Evan.  It was an awesome experience that we will never forget.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://www.2magazine.com/couplemakeovertv/'&gt;&lt;img src='http://www.codyfauser.com/assets/2007/4/2/Picture_2.png' alt='2 Magazine Cancun 2007 Makeover Video' /&gt;&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.codyfauser.com/">
    <author>
      <name>cody</name>
    </author>
    <id>tag:www.codyfauser.com,2007-03-14:278</id>
    <published>2007-03-14T03:07:00Z</published>
    <updated>2007-03-14T03:36:41Z</updated>
    <category term="Ruby" />
    <category term="ruby" />
    <link href="http://www.codyfauser.com/2007/3/14/ruby-power-simplicity-and-beauty" rel="alternate" type="text/html" />
    <title>Ruby - Power, Simplicity, and Beauty</title>
<content type="html">
            &lt;p&gt;Tonight while reading through &lt;a href='http://www.martinfowler.com/books.html#refactoring'&gt;Refactoring&lt;/a&gt; by &lt;a href='http://www.martinfowler.com/'&gt;Martin Fowler&lt;/a&gt; I was once again amazed by power, beauty, and simplicity of Ruby.  Wait, hold on, aren't the code examples in Refactoring in Java?  Yes, that is precisely the point.  All day I am lucky enough to write Ruby, but sometimes I need to take a look back over the other side of the fence to appreciate where I'm at.  Let me tell you that the grass is definitely not green over there.&lt;/p&gt;

&lt;p&gt;Consider the simple method being extracted on page 27 of the book:&lt;/p&gt;

&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;private double getTotalCharge() {&lt;tt&gt;
&lt;/tt&gt;  double result = 0;&lt;tt&gt;
&lt;/tt&gt;  Enumeration rentals = _rentals.elements();&lt;tt&gt;
&lt;/tt&gt;  while (rentals.hasMoreElements()) {&lt;tt&gt;
&lt;/tt&gt;    Rental each = (Rental) rentals.nextElement();&lt;tt&gt;
&lt;/tt&gt;    result += each.getCharge();&lt;tt&gt;
&lt;/tt&gt;  }&lt;tt&gt;
&lt;/tt&gt;  return result;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Basically the code is just iterating over the collection of &lt;em&gt;Rental&lt;/em&gt; objects and calculating the total charge.  Simple enough.  The equivalent using &lt;em&gt;inject&lt;/em&gt; with Ruby:&lt;/p&gt;

&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='r'&gt;def&lt;/span&gt; &lt;span class='fu'&gt;get_total_charge&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    rentals.inject{ |sum, rental| sum + rental.get_charge }&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='r'&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Then, with the new &lt;a href='http://api.rubyonrails.org/classes/Enumerable.html'&gt;sum&lt;/a&gt; method added to Enumerable in Rails it gets even simpler:&lt;/p&gt;

&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='r'&gt;def&lt;/span&gt; &lt;span class='fu'&gt;get_total_charge&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    rentals.sum{ |r| r.get_charge }&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='r'&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;This just goes to show the power and expressiveness of Ruby.  With so many fewer keystrokes, and lines of code, it is so much easier to focus on the problem at hand.  &lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.codyfauser.com/">
    <author>
      <name>cody</name>
    </author>
    <id>tag:www.codyfauser.com,2007-03-09:275</id>
    <published>2007-03-09T20:00:00Z</published>
    <updated>2007-03-09T20:37:10Z</updated>
    <category term="paypal" />
    <link href="http://www.codyfauser.com/2007/3/9/switch-solo-cards-with-website-payments-pro-uk-payflow-and-xmlpay" rel="alternate" type="text/html" />
    <title>Switch &amp; Solo Cards with Website Payments Pro UK (Payflow) and XMLPay</title>
<content type="html">
            &lt;p&gt;While implementing support for &lt;a href='https://www.paypal.com/uk/cgi-bin/webscr?cmd=_wp-pro-overview-outside'&gt;PayPal Website Payments Pro UK&lt;/a&gt; in &lt;a href='http://activemerchant.org'&gt;ActiveMerchant&lt;/a&gt; I ran across a small problem while processing the UK cards Switch &amp;amp; Solo.&lt;/p&gt;

&lt;p&gt;Switch &amp;amp; Solo cards are a special case when processing credit cards, as they need some additional information. The additional information is either the card issue number or start date, as printed on the card.  The problem is that the XMLPay guide provided by PayPal doesn't exactly specify where to put this information.  If you dig around in the schema it appears as though you can place the CardIssue or CardStart element within a Level3Invoice element, however that didn't seem to work, and always returned the error &lt;em&gt;"Field format error: CARDSTART or CARDISSUE must be present"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;After some trial and error, and a helping hand in the right direction from Todd Sieber at PayPal, I was finally able to successfully process the Switch &amp;amp; Solo cards using the ExtData elements within the &lt;em&gt;Card&lt;/em&gt; element of the XML request:&lt;/p&gt;

&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='ta'&gt;&amp;lt;Card&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='ta'&gt;&amp;lt;CardType&amp;gt;&lt;/span&gt;Switch&lt;span class='ta'&gt;&amp;lt;/CardType&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='ta'&gt;&amp;lt;CardNum&amp;gt;&lt;/span&gt;5641820000000005&lt;span class='ta'&gt;&amp;lt;/CardNum&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='ta'&gt;&amp;lt;ExpDate&amp;gt;&lt;/span&gt;200801&lt;span class='ta'&gt;&amp;lt;/ExpDate&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='ta'&gt;&amp;lt;NameOnCard&amp;gt;&lt;/span&gt;Cody Fauser&lt;span class='ta'&gt;&amp;lt;/NameOnCard&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='ta'&gt;&amp;lt;CVNum&amp;gt;&lt;/span&gt;123&lt;span class='ta'&gt;&amp;lt;/CVNum&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='ta'&gt;&amp;lt;ExtData&lt;/span&gt; &lt;span class='an'&gt;Name&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;CardIssue&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class='an'&gt;Value&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;01&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class='ta'&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='ta'&gt;&amp;lt;ExtData&lt;/span&gt; &lt;span class='an'&gt;Name&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;CardStart&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class='an'&gt;Value&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;0299&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class='ta'&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='ta'&gt;&amp;lt;/Card&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;You only need either the CardIssue or CardStart element to be present, but for illustrative purposes I included them both.&lt;/p&gt;

&lt;p&gt;One other thing to note is that XMLPay API will no longer be updated by PayPal.  So if you are writing new code then you might as well just stick to the Name-Value pair API.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.codyfauser.com/">
    <author>
      <name>cody</name>
    </author>
    <id>tag:www.codyfauser.com,2007-01-08:63</id>
    <published>2007-01-08T04:16:00Z</published>
    <updated>2007-02-01T14:29:09Z</updated>
    <category term="Announcements" />
    <link href="http://www.codyfauser.com/2007/1/8/move-to-mephisto" rel="alternate" type="text/html" />
    <title>Move to Mephisto</title>
<content type="html">
            &lt;p&gt;I finally bit the bullet and moved my blog over to &lt;a href='http://mephistoblog.com'&gt;Mephisto&lt;/a&gt;.  So far I am loving it.  Thanks to &lt;a href='http://encytemedia.com'&gt;Justin Palmer&lt;/a&gt; and &lt;a href='http://techno-weenie.net/'&gt;Rick Olson&lt;/a&gt; for all of their hard work that went into making this an awesome application.&lt;/p&gt;

&lt;p&gt;I migrated from Typo and used the great howto &lt;a href='http://octopod.info/2006/6/12/converting-typo-to-mephisto'&gt;Converting Typo to Mephisto&lt;/a&gt; on the &lt;a href='http://octopod.info'&gt;Octoblog&lt;/a&gt;.  What an awesome name for a blog!  The only thing I did differently, since I'm using the latest code from the Mephisto trunk, was the support for Typo style article URLs.  I just opened up config/routes.rb and tweaked it to look as follows:&lt;/p&gt;

&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='co'&gt;ActionController&lt;/span&gt;::&lt;span class='co'&gt;Routing&lt;/span&gt;::&lt;span class='co'&gt;Routes&lt;/span&gt;.draw &lt;span class='r'&gt;do&lt;/span&gt; |map|&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='co'&gt;Mephisto&lt;/span&gt;::&lt;span class='co'&gt;Routing&lt;/span&gt;.connect_with map &lt;span class='r'&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    map.connect &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;articles/*path&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class='sy'&gt;:controller&lt;/span&gt; =&amp;gt; &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;mephisto&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class='sy'&gt;:action&lt;/span&gt; =&amp;gt; &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;dispatch&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='r'&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
          </content>  </entry>
  <entry xml:base="http://www.codyfauser.com/">
    <author>
      <name>cody</name>
    </author>
    <id>tag:www.codyfauser.com,2006-11-22:15</id>
    <published>2006-11-22T04:43:00Z</published>
    <updated>2007-01-08T03:25:26Z</updated>
    <category term="Announcements" />
    <category term="Ruby" />
    <category term="api,xml,ebay,ruby" />
    <link href="http://www.codyfauser.com/2006/11/22/ebay-api-client-for-ruby" rel="alternate" type="text/html" />
    <title>eBay API Client for Ruby</title>
<content type="html">
            &lt;p&gt;I recently released my &lt;a href='http://rubyforge.org/projects/ebayapi'&gt;Ruby client for the eBay XML API&lt;/a&gt;.  The &lt;a href='http://ebay.googlecode.com/svn/'&gt;source  code&lt;/a&gt; can be found on &lt;a href='http://code.google.com'&gt;Google Code&lt;/a&gt;. Benefits of this implementation include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple and easy to use Ruby implementation.&lt;/li&gt;
&lt;li&gt;Ability to return a raw response for calls that return an extremely large response such as GetCategoriesRequest.&lt;/li&gt;
&lt;li&gt;Up-to-date with the latest eBay API version 485.&lt;/li&gt;
&lt;li&gt;Months of usage in a production environment.&lt;/li&gt;
&lt;li&gt;Support for Platform Notifications baked right in.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enough talking about why you should use this library, let's get started with the eBay equivalent to 'Hello World', which is the GeteBayOfficialTime call.&lt;/p&gt;

&lt;p&gt;Firstly you'll need to sign up for an eBay developer account.  You can &lt;a href='http://developer.ebay.com/join'&gt;sign up&lt;/a&gt; at the &lt;a href='http://developer.ebay.com/'&gt;eBay Developer Center&lt;/a&gt;. Once you have signed up you need to follow the directions in the confirmation email to get your Developer ID, Application ID, and Certificate ID. Record this information, as you'll need it when setting up the eBay client.&lt;/p&gt;

&lt;p&gt;Now you need to &lt;a href='http://developer.ebay.com/DevZone/sandboxuser.asp'&gt;setup a sandbox user&lt;/a&gt; to make API calls on behalf of.  &lt;/p&gt;

&lt;p&gt;Next you'll need to &lt;a href='http://developer.ebay.com/tokentool/http://developer.ebay.com/tokentool/'&gt;generate your Authentication Token&lt;/a&gt;. Simply enter the information you previously recorded into the form, select the sandbox environment from the dropdown menu and click the "Continue to generate token" link. Then sign in as the sandbox user you just created above and agree to allow your developer account to make API calls on behalf of the sandbox user.  Record the Authentication Token that is now displayed.&lt;/p&gt;

&lt;p&gt;The Authentication Token is your means of sending requests for different users. All you have to do to send a request for a different eBay user is change the Authentication Token that pass into the API call you are making.  Of course, you'll need permission to make API calls on their behalf.&lt;/p&gt;

&lt;p&gt;Now that we have all of the information needed for authenticating the API calls we can setup the configuration file that we'll use for the following example.&lt;/p&gt;

&lt;p&gt;Start by creating a file &lt;em&gt;config.rb&lt;/em&gt; and place the following code into it:&lt;/p&gt;

&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='co'&gt;Ebay&lt;/span&gt;::&lt;span class='co'&gt;Api&lt;/span&gt;.configure &lt;span class='r'&gt;do&lt;/span&gt; |ebay|&lt;tt&gt;
&lt;/tt&gt;  ebay.auth_token = &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;YOUR AUTH TOKEN HERE&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  ebay.dev_id = &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;YOUR DEVELOPER ID HERE&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  ebay.app_id = &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;YOUR APPLICATION ID HERE&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  ebay.cert = &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;YOUR CERTIFICATE HERE&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='c'&gt;# The default environment is the production environment&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='c'&gt;# Override by setting use_sandbox to true&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  ebay.use_sandbox = &lt;span class='pc'&gt;true&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Obviously you'll want to place your own IDs and tokens into the configuration.&lt;/p&gt;

&lt;p&gt;After you've signed up for the Developer Program and you have the API configuration ready to go you can get started installing the &lt;a href='http://rubyforge.org/projects/ebayapi'&gt;Ruby ebayapi gem&lt;/a&gt;.  Install this gem as by running:&lt;/p&gt;

&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;gt; sudo gem install ebayapi -y&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;The -y flag tells gems to install all the dependencies that the the gem requires.&lt;/p&gt;

&lt;p&gt;Now that you've got the API client installed we can finally go ahead and get the official eBay time from eBay's servers.&lt;/p&gt;

&lt;p&gt;Create a file named &lt;em&gt;official_time.rb&lt;/em&gt;, in the same directory as the &lt;em&gt;config.rb&lt;/em&gt; file we created earlier, and place the following code in it:&lt;/p&gt;

&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='c'&gt;#!/usr/bin/env ruby&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;rubygems&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;ebay&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='c'&gt;# Include the API configuration&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;config&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='c'&gt;# Create the eBay client&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;ebay = &lt;span class='co'&gt;Ebay&lt;/span&gt;::&lt;span class='co'&gt;Api&lt;/span&gt;.new&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='c'&gt;# Get the official eBay time&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;response = ebay.get_ebay_official_time&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='c'&gt;# Display the time to the user&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;puts response.timestamp&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Now you can run this simple application:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
&gt; ruby official_time.rb
# =&gt; Wed Nov 22 06:03:35 UTC 2006
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That was easy. Once we got all of the IDs and tokens that eBay requires, that is.  Next time I'll go into some more depth and background the client.&lt;/p&gt;

&lt;p&gt;In the meantime you can checkout the &lt;a href='http://ebay.googlecode.com/svn/trunk/examples/'&gt;examples&lt;/a&gt; I've provided in the source. Happy coding.&lt;/p&gt;
          </content>  </entry>
<feedburner:awareness xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://api.feedburner.com/awareness/1.0/GetFeedData?uri=codyfauser</feedburner:awareness></feed>
