<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>assets/checkout.gif</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,6 +1,12 @@
 # Spree Pp Website Standard
 
-Overrides the default Spree checkout process and uses offsite payment processing via PayPal's Website Payment Standard.  There are also `after_notify` and `after_success` hooks which allow you to implment your own custom logic after the standard processing is performed.  These hooks should be added to `checkout_controller` in the extension you are using for your site specific customizations.
+Overrides the default Spree checkout process and uses offsite payment processing via PayPal's Website Payment Standard (WPS).  
+
+You'll want to test this using a paypal sandbox account first.  Once you have a business account, you'll want to turn on Instant Payment Notification (IPN).  This is how your application will be notified when a transaction is complete.  Certain transactions aren't completed immediately.  Because of this we use IPN for your application to get notified when the transaction is complete.  IPN means that our application gets an incoming request from Paypal when the transaction goes through.  To turn IPN on in your sandbox account, login, hit &quot;profile&quot;, and go to Instant Payment Notification Preferences.  You'll need to turn it on, and point it to your http://www.yourdomain.com/notify.  
+
+Regarding Taxes and shipping, we assumed you'd want to use Paypal's system for this, which can also be configured through the &quot;profile&quot; page.  Taxes have been tested (sales tax), but not shipping, so you may want to give that a test run on the sandbox.
+
+There are also `after_notify` and `after_success` hooks which allow you to implment your own custom logic after the standard processing is performed.  These hooks should be added to `checkout_controller` in the extension you are using for your site specific customizations.
 
 For example:
 
@@ -16,6 +22,8 @@ CheckoutController.class_eval do
 end
 &lt;/pre&gt;
 
+
+
  * TODO: User account creation (if necessary) after notify and associate order with a user
  * TODO: Make the paypal account stuff configurable via new preferences system
  * TODO: Taxes</diff>
      <filename>README.markdown</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,14 @@
 class CheckoutController &lt; Spree::BaseController
+  before_filter :verify_authenticity_token, :except =&gt; 'notify'
   
   include ActiveMerchant::Billing::Integrations
   
+  # When people hit the checkout button from other pages
+  # Bring them to the cart where we have them fill out the form
+  def index
+    redirect_to :controller =&gt; 'cart'
+  end
+  
   # You can send in test notifications on the developer page here:
   # https://developer.paypal.com/us/cgi-bin/devscr?cmd=_ipn-link-session
   def notify
@@ -10,17 +17,17 @@ class CheckoutController &lt; Spree::BaseController
 
     # create a transaction which records the details of the notification
     @payment.txns.build :transaction_id =&gt; ipn.transaction_id, :amount =&gt; ipn.gross, :fee =&gt; ipn.fee, 
-      :currency_type =&gt; ipn.currency_type, :status =&gt; ipn.status, :received_at =&gt; ipn.received_at
+      :currency_type =&gt; ipn.currency, :status =&gt; ipn.status, :received_at =&gt; ipn.received_at
     @payment.save                    
     
     if ipn.acknowledge
       case ipn.status
       when &quot;Completed&quot; 
-        if ipn.gross == @order.total
+        if ipn.gross.to_f == @order.total.to_f
           @order.status = Order::Status::PAID
         else
           @order.status = Order::Status::INCOMPLETE
-          logger.error(&quot;Incorrect order total during Paypal's notification, please investigate&quot;)
+          logger.error(&quot;Incorrect order total during Paypal's notification, please investigate (Paypal processed #{ipn.gross}, and order total is #{@order.total})&quot;)
         end
       when &quot;Pending&quot; 
         @order.status = Order::Status::PENDING_PAYMENT
@@ -37,23 +44,27 @@ class CheckoutController &lt; Spree::BaseController
 
     # call notify hook (which will email users, etc.)
     after_notify(@payment) if @order.status == Order::Status::PAID
+    
+    render :nothing =&gt; true
   end
   
   # When they've returned from paypal
+  # Not really &quot;success&quot; as in they've paid.  &quot;Success&quot; as in the transaction is in progress
+  # Notify is called when the transaction is successfull
   def success
     
     ref_hash = params[:invoice]
-    @order = find_order(ref_hash)    
+    @order = find_order(ref_hash)
     
     # create a transaction for the order (record what little information we have from paypal)
-    @payment.txns.build :amount =&gt; params[:mc_gross], :status =&gt; &quot;order-success&quot;
+    @payment.txns.build :amount =&gt; params[:mc_gross], :status =&gt; &quot;order-processed&quot;
     @payment.save                        
     
     # call success hook (which will email users, etc.)
     after_success(@payment)
 
     # Render thank you (unless redirected by hook of course)
-    redirect_to :action =&gt; :thank_you, :id =&gt; @order.id and return
+    redirect_to :action =&gt; :thank_you, :id =&gt; @order.number and return
   end
   
   def after_notify(payment)
@@ -65,7 +76,7 @@ class CheckoutController &lt; Spree::BaseController
   end
 
   def thank_you
-    @order = Order.find(params[:id])
+    @order = Order.find_by_number(params[:id])
   end
     
   private
@@ -82,6 +93,9 @@ class CheckoutController &lt; Spree::BaseController
           # Create a payment for the order
           @payment = PaypalPayment.create(:reference_hash =&gt; ref_hash)
           @order.paypal_payment = @payment
+          # Get the tax &amp; shipping
+          @order.tax_amount = params[:tax].to_f if params[:tax]
+          @order.ship_amount = params[:mc_shipping].to_f if params[:mc_shipping]
           @order.save
           # Destroy the cart (optimistic locking for the cart in case notify is racing us)
           cart.destroy</diff>
      <filename>app/controllers/checkout_controller.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,12 +1,11 @@
 &lt;% if RAILS_ENV == 'development' %&gt;
-&lt;form action=&quot;https://www.sandbox.paypal.com/cgi-bin/webscr&quot; method=&quot;post&quot;&gt;
+&lt;form action=&quot;https://www.sandbox.paypal.com/cgi-bin/webscr&quot; method=&quot;post&quot; onsubmit=&quot;return check_zipcode();&quot;&gt;
 &lt;% else %&gt;
 &lt;form action=&quot;https://www.paypal.com/cgi-bin/webscr&quot; method=&quot;post&quot;&gt;
 &lt;% end %&gt;
 
 &lt;!-- display payment summary here --&gt;
 
-&lt;input name=&quot;commit&quot; type=&quot;submit&quot; value=&quot;Make Payment&quot; /&gt;
 
 &lt;input id=&quot;business&quot; name=&quot;business&quot; type=&quot;hidden&quot; value=&quot;joe@bidness.com&quot; /&gt;
 &lt;input id=&quot;invoice&quot; name=&quot;invoice&quot; type=&quot;hidden&quot; value=&quot;&lt;%= @cart.reference_hash %&gt;&quot; /&gt;
@@ -17,15 +16,19 @@
   &lt;input id=&quot;quantity_&lt;%= index + 1 %&gt;&quot; name=&quot;quantity_&lt;%= index + 1 %&gt;&quot; type=&quot;hidden&quot; value=&quot;&lt;%= item.quantity %&gt;&quot; /&gt;
 &lt;% end %&gt;
 
-&lt;input id=&quot;amount&quot; name=&quot;amount&quot; type=&quot;hidden&quot; value=&quot;58.97&quot; /&gt;
+&lt;!-- input id=&quot;amount&quot; name=&quot;amount&quot; type=&quot;hidden&quot; value=&quot;58.97&quot; /--&gt;
 
 &lt;input name=&quot;no_shipping&quot; type=&quot;hidden&quot; value=&quot;1&quot; /&gt;
 &lt;input id=&quot;cmd&quot; name=&quot;cmd&quot; type=&quot;hidden&quot; value=&quot;_cart&quot; /&gt;
 &lt;input type=&quot;hidden&quot; name=&quot;upload&quot; value=&quot;1&quot; /&gt;
 
-&lt;input id=&quot;country&quot; name=&quot;country&quot; type=&quot;hidden&quot; value=&quot;US&quot; /&gt;
-&lt;input id=&quot;zip&quot; name=&quot;zip&quot; type=&quot;hidden&quot; value=&quot;32828&quot; /&gt;
-
+&lt;p&gt; Please select your country &lt;select name=&quot;country&quot; id=&quot;country&quot;&gt;
+&lt;%= country_options_for_select('United States', ['United States']) %&gt;
+&lt;/select&gt;&lt;/p&gt;
+&lt;span style=&quot;color:red; font-weight:bold; display:none;&quot; id=&quot;needZipcode&quot;&gt;Please enter a valid zipcode.&lt;/span&gt;
+&lt;p&gt;
+Zipcode (if you have one): &lt;input id=&quot;zip&quot; name=&quot;zip&quot; type=&quot;text&quot; value=&quot;&quot; /&gt;
+&lt;/p&gt;
 
 &lt;input id=&quot;notify_url&quot; name=&quot;notify_url&quot; type=&quot;hidden&quot; value=&quot;http://72.189.229.38:3000/notify&quot; /&gt;
 &lt;input id=&quot;return&quot; name=&quot;return&quot; type=&quot;hidden&quot; value=&quot;http://localhost:3000/checkout/success&quot; /&gt;
@@ -35,12 +38,25 @@
 &lt;input id=&quot;no_note&quot; name=&quot;no_note&quot; type=&quot;hidden&quot; value=&quot;1&quot; /&gt;
 &lt;input id=&quot;no_shipping&quot; name=&quot;no_shipping&quot; type=&quot;hidden&quot; value=&quot;1&quot; /&gt;
 &lt;input id=&quot;item_name&quot; name=&quot;item_name&quot; type=&quot;hidden&quot; value=&quot;Store purchase&quot; /&gt;
-
-
 &lt;input id=&quot;return&quot; name=&quot;return&quot; type=&quot;hidden&quot; value=&quot;http://localhost:3000/account/show&quot; /&gt;
 &lt;input id=&quot;currency_code&quot; name=&quot;currency_code&quot; type=&quot;hidden&quot; value=&quot;USD&quot; /&gt;
 &lt;input id=&quot;cancel_return&quot; name=&quot;cancel_return&quot; type=&quot;hidden&quot; value=&quot;http://localhost:3000/account/show&quot; /&gt;
 &lt;input id=&quot;custom&quot; name=&quot;custom&quot; type=&quot;hidden&quot; value=&quot;11&quot; /&gt;
 &lt;input id=&quot;item_number&quot; name=&quot;item_number&quot; type=&quot;hidden&quot; value=&quot;11&quot; / --&gt;
 &lt;!-- input id=&quot;bn&quot; name=&quot;bn&quot; type=&quot;hidden&quot; value=&quot;ActiveMerchant&quot; /--&gt;
-&lt;/form&gt;
\ No newline at end of file
+
+&lt;input name=&quot;commit&quot; type=&quot;submit&quot; value=&quot;Make Payment&quot; /&gt;
+
+&lt;/form&gt;
+
+
+&lt;script type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;
+  function check_zipcode () {
+    if ($('country').value == &quot;United States&quot; &amp;&amp; ($('zip').value == null || $('zip').value.length &lt; 5)) {
+      $('needZipcode').show();
+      return false;
+    } else {
+      return true;
+    }
+  }
+&lt;/script&gt;
\ No newline at end of file</diff>
      <filename>app/views/cart/_paypal_checkout.erb</filename>
    </modified>
    <modified>
      <diff>@@ -1,16 +1,16 @@
 &lt;div id=&quot;shopping-cart&quot;&gt;
-  &lt;h1&gt;&lt;%= :shopping_cart.l(&quot;Shopping Cart&quot;) %&gt;&lt;/h1&gt;
+  &lt;h1&gt;&lt;%= t(&quot;Shopping Cart&quot;) %&gt;&lt;/h1&gt;
   
   &lt;%=error_messages_for :cart_item%&gt;
   
   &lt;% form_tag do-%&gt;
   &lt;table class=&quot;cart-summary&quot; width=&quot;100% &quot;&gt;
     &lt;tr&gt;
-      &lt;th colspan=&quot;2&quot;&gt;&lt;%= :item.l(&quot;Item&quot;) %&gt;&lt;/th&gt;
-      &lt;th&gt;&lt;%= :price.l(&quot;Price&quot;) %&gt;&lt;/th&gt;
-      &lt;th&gt;&lt;%= :qty.l %&gt;&lt;/th&gt;
+      &lt;th colspan=&quot;2&quot;&gt;&lt;%= t(&quot;Item&quot;) %&gt;&lt;/th&gt;
+      &lt;th&gt;&lt;%= t(&quot;Price&quot;) %&gt;&lt;/th&gt;
+      &lt;th&gt;&lt;%= t(&quot;Qty&quot;) %&gt;&lt;/th&gt;
       &lt;!--&lt;th&gt;Delete&lt;/th&gt;--&gt;
-      &lt;th&gt;&lt;%= :total.l(&quot;Total&quot;) %&gt;&lt;/th&gt;
+      &lt;th&gt;&lt;%= t(&quot;Total&quot;) %&gt;&lt;/th&gt;
     &lt;/tr&gt;
     &lt;% for @item in @cart_items %&gt;
     &lt;tr class=&quot;&lt;%= cycle('even', 'odd') %&gt;&quot;&gt;
@@ -22,30 +22,29 @@
         &lt;%= variant_options @item.variant %&gt;&lt;br/&gt;
         &lt;%=truncate(@item.variant.product.description, length = 100, truncate_string = &quot;...&quot;)-%&gt;
       &lt;/td&gt;
-      &lt;td valign=&quot;top&quot; width=&quot;75&quot;&gt;$ &lt;%= sprintf(&quot;%0.2f&quot;, @item.price) %&gt;&lt;/td&gt;
+      &lt;td valign=&quot;top&quot; width=&quot;75&quot;&gt;&lt;%= number_to_currency(@item.price) %&gt;&lt;/td&gt;
       &lt;td valign=&quot;top&quot; width=&quot;50&quot;&gt;&lt;%= text_field &quot;item[]&quot;, :quantity, :size =&gt; 3 -%&gt;&lt;/td&gt;
-      &lt;td valign=&quot;top&quot; width=&quot;75&quot;&gt;$ &lt;%= sprintf(&quot;%0.2f&quot;, @item.price * @item.quantity) unless @item.quantity.nil? %&gt;&lt;/td&gt;
+      &lt;td valign=&quot;top&quot; width=&quot;75&quot;&gt;&lt;%= number_to_currency(@item.price * @item.quantity) unless @item.quantity.nil? %&gt;&lt;/td&gt;
     &lt;/tr&gt;
     &lt;% end %&gt;
   &lt;/table&gt;
   &lt;div id=&quot;subtotal&quot;&gt;
-    &lt;h3&gt;&lt;%= :subtotal.l(&quot;Subtotal&quot;) %&gt; $ &lt;%= sprintf(&quot;%0.2f&quot;, @cart.total) %&gt;&lt;/h3&gt;
-    &lt;%= submit_tag :update.l('Update') %&gt;
-    
+    &lt;h3&gt;&lt;%= &quot;#{t(&quot;Subtotal&quot;)}: #{number_to_currency(@cart.total)}&quot; %&gt;&lt;/h3&gt;
+    &lt;%= submit_tag t('Update') %&gt;
+    &lt;% end %&gt;
+    &lt;%= render :partial =&gt; 'paypal_checkout' %&gt;	
   &lt;/div&gt;
-  &lt;% end %&gt;
+  
   &lt;%if previous_location %&gt;
-  &lt;p&gt;&lt;%=link_to :continue_shopping.l(&quot;Continue Shopping&quot;), products_path %&gt;&lt;/p&gt;
+  &lt;p&gt;&lt;%=link_to t(&quot;Continue Shopping&quot;), products_path %&gt;&lt;/p&gt;
   &lt;%end%&gt;  
   &lt;% unless @cart.cart_items.empty? %&gt;
   &lt;p id=&quot;clear_cart_link&quot;&gt;
     &lt;small&gt;
-      &lt;%= link_to :empty_cart.l(&quot;Empty Cart&quot;), :action =&gt; 'empty' %&gt;
+      &lt;%= link_to t(&quot;Empty Cart&quot;), :action =&gt; 'empty' %&gt;
     &lt;/small&gt;
   &lt;/p&gt;
   &lt;% end %&gt;
 &lt;/div&gt;
 
 
-
-&lt;%= render :partial =&gt; 'paypal_checkout' %&gt;	
\ No newline at end of file</diff>
      <filename>app/views/cart/index.html.erb</filename>
    </modified>
    <modified>
      <diff>@@ -1,16 +1,21 @@
 # Uncomment this if you reference any of your controllers in activate
 require_dependency 'application'
 
+unless RAILS_ENV == 'production'
+  PAYPAL_ACCOUNT = 'joe@bidness.com'
+  ActiveMerchant::Billing::Base.mode = :test
+else
+  PAYPAL_ACCOUNT = 'Gregg@railsenvy.com'
+end
+
 class PpWebsiteStandardExtension &lt; Spree::Extension
   version &quot;1.0&quot;
   description &quot;Describe your extension here&quot;
   url &quot;http://yourwebsite.com/spree_pp_website_standard&quot;
 
-  # define_routes do |map|
-  #   map.namespace :admin do |admin|
-  #     admin.resources :whatever
-  #   end  
-  # end
+  define_routes do |map|
+     map.notify '/notify', :controller =&gt; 'checkout', :action =&gt; 'notify'
+  end
   
   def activate
 </diff>
      <filename>pp_website_standard_extension.rb</filename>
    </modified>
    <modified>
      <diff>@@ -55,7 +55,7 @@ describe CheckoutController do
           
           describe &quot;when the order total is not verified&quot; do      
             before(:each) do
-              @order.should_receive(:total).and_return(1)
+              @order.should_receive(:total).twice.and_return(1)
             end
             it &quot;should change the order status to incomplete&quot; do
               @order.should_receive(:status=).with(Order::Status::INCOMPLETE)</diff>
      <filename>spec/controllers/checkout_controller_spec.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>3913ae2da0bd8adc75d93c83b52a6455e4e089fc</id>
    </parent>
  </parents>
  <author>
    <name>Gregg Pollack</name>
    <email>Gregg@RailsEnvy.com</email>
  </author>
  <url>http://github.com/Gregg/spree-pp-website-standard/commit/dc0eaafed3dac7627e4382c5a3d43c9ab3476540</url>
  <id>dc0eaafed3dac7627e4382c5a3d43c9ab3476540</id>
  <committed-date>2008-08-11T14:35:58-07:00</committed-date>
  <authored-date>2008-08-11T14:35:58-07:00</authored-date>
  <message>Fixed notify, fixed a few redirects, added fields for tax collection</message>
  <tree>983f47b4a39e76b7f04bd9af994004f6cd330f3c</tree>
  <committer>
    <name>Gregg Pollack</name>
    <email>Gregg@RailsEnvy.com</email>
  </committer>
</commit>
