<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>opensoul.org - Paypal IPN in Rails with Active Merchant Changes</title>
  <id>tag:opensoul.org,2010:/2006/9/16/paypal-ipn-in-rails-with-active-merchant/changes</id>
  <generator version="0.8.0" uri="http://mephistoblog.com">Mephisto Drax</generator>
  <link href="http://opensoul.org/2006/9/16/paypal-ipn-in-rails-with-active-merchant/changes.xml" rel="self" type="application/atom+xml"/>
  <link href="/2006/9/16/paypal-ipn-in-rails-with-active-merchant" rel="alternate" type="text/html"/>
  <updated>2007-09-05T13:10:23Z</updated>
  <entry xml:base="http://opensoul.org/">
    <author>
      <name>brandon</name>
    </author>
    <id>tag:opensoul.org,2007-09-05:362:7</id>
    <published>2006-09-16T20:49:00Z</published>
    <updated>2007-09-05T13:10:23Z</updated>
    <link href="http://opensoul.org/2006/9/16/paypal-ipn-in-rails-with-active-merchant" rel="alternate" type="text/html"/>
    <title>Paypal IPN in Rails with Active Merchant</title>
<content type="html">&lt;p&gt;&lt;a href=&quot;http://home.leetsoft.com/am/&quot;&gt;Active Merchant&lt;/a&gt; makes it extremely simple to use Paypal &lt;abbr title=&quot;Instant Payment Notification&quot;&gt;&lt;span class=&quot;caps&quot;&gt;IPN&lt;/span&gt;&lt;/abbr&gt;. Here is a simple guide for getting &lt;span class=&quot;caps&quot;&gt;IPN&lt;/span&gt; up and running.&lt;/p&gt;

&lt;h3&gt;Sign up for a &lt;a href=&quot;https://developer.paypal.com/&quot;&gt;Paypal sandbox account&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Paypal provides a sandbox environment that mimics their production environment, with the exception that it doesn&#8217;t actually process the transactions.  This is extremely useful for development and testing.  It allows you to create multiple fake accounts and generate bank accounts and credit cards. More information can be found on Paypal&#8217;s &lt;a href=&quot;http://www.paypal.com/cgi-bin/webscr?cmd=_ipn-test-about-outside&quot;&gt;Testing Instant Payment Notification&lt;/a&gt; page.&lt;/p&gt;
&lt;p&gt;Unfortunately, I&#8217;ve signed up for two different developer accounts and I&#8217;ve had trouble logging in with both of them.  I&#8217;ve tried resetting my password, but I still can&#8217;t log in.  Fortunately, I already have my sandbox accounts set up and don&#8217;t really have a need for it (except to write this guide).&lt;/p&gt;

&lt;h3&gt;Create a Personal account and add a credit card&lt;/h3&gt;
&lt;p&gt;After you sign up for your developer account, create a personal sandbox account and add a credit card.&lt;/p&gt;

&lt;h3&gt;Create a Business account and add a checking&lt;/h3&gt;
&lt;p&gt;Next, create a business sandbox account and add a checking account.&lt;/p&gt;

&lt;h3&gt;Install the money gem&lt;/h3&gt;
&lt;pre&gt;sudo gem install money&lt;/pre&gt;

&lt;h3&gt;Install the Active Merchant plugin&lt;/h3&gt;
&lt;pre&gt;script/plugin install http://activemerchant.googlecode.com/svn/trunk/active_merchant&lt;/pre&gt;

&lt;h3&gt;Create a form that submits to Paypal&lt;/h3&gt;
&lt;p&gt;Include &lt;code&gt;ActiveMerchant::Billing::Integrations&lt;/code&gt; in a controller to add Active Merchant&#8217;s helpers.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class PaymentsController &amp;lt; ApplicationController
  include ActiveMerchant::Billing::Integrations

  def create
    @enrollment = current_user.enrollments.find(params[:id])
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the view, use &lt;code&gt;payment_service_for&lt;/code&gt; to create a form that submits to Paypal to process the payment.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;erb&quot;&gt;&amp;lt;% payment_service_for @enrollment.id, PAYPAL_ACCOUNT,
        :amount =&amp;gt; @enrollment.course.deposit, :currency =&amp;gt; 'USD',
        :service =&amp;gt; :paypal do |service| 

    service.customer :first_name =&amp;gt; @enrollment.student.first_name,
        :last_name =&amp;gt; @enrollment.student.last_name,
        :phone =&amp;gt; @enrollment.student.phone,
        :email =&amp;gt; @enrollment.student.email
    service.billing_address :city =&amp;gt; @enrollment.student.city,
        :address1 =&amp;gt; @enrollment.student.street,
        :state =&amp;gt; @enrollment.student.state,
        :country =&amp;gt; 'USA',
        :zip =&amp;gt; @enrollment.student.zip
    service.item_name &amp;quot;#{@enrollment.course.program} Deposit&amp;quot;
    service.invoice @enrollment.invoice.id
    service.tax '0.00'

    service.notify_url url_for(:only_path =&amp;gt; false, :action =&amp;gt; 'notify')
    service.return_url url_for(:only_path =&amp;gt; false,
        :controller =&amp;gt; 'account', :action =&amp;gt; 'show')
    service.cancel_return_url url_for(:only_path =&amp;gt; false,
        :controller =&amp;gt; 'account', :action =&amp;gt; 'show') %&amp;gt;

    &amp;lt;!-- display payment summary here --&amp;gt;

    &amp;lt;%= submit_tag 'Make Payment' %&amp;gt;
&amp;lt;% end %&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The code above refers to the constant &lt;code&gt;PAYPAL_ACCOUNT&lt;/code&gt;, which I define in &lt;code&gt;environment.rb&lt;/code&gt;.  I also set Active Merchant to use test mode, which directs it to use Paypal&#8217;s sandbox:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;unless RAILS_ENV == 'production'
  PAYPAL_ACCOUNT = 'sandboxaccount@example.com'
  ActiveMerchant::Billing::Base.mode = :test
else
  PAYPAL_ACCOUNT = 'paypalaccount@example.com'
end&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Create an action that processes the &lt;span class=&quot;caps&quot;&gt;IPN&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;After the above form submits to Paypal and the user makes a payment, Paypal will post data about the transaction to your server.  Set up an action to receive the post:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  def notify
    notify = Paypal::Notification.new(request.raw_post)
    enrollment = Enrollment.find(notify.item_id)

    if notify.acknowledge
      @payment = Payment.find_by_confirmation(notify.transaction_id) ||
        enrollment.invoice.payments.create(:amount =&amp;gt; notify.amount,
          :payment_method =&amp;gt; 'paypal', :confirmation =&amp;gt; notify.transaction_id,
          :description =&amp;gt; notify.params['item_name'], :status =&amp;gt; notify.status,
          :test =&amp;gt; notify.test?)
      begin
        if notify.complete?
          @payment.status = notify.status
        else
          logger.error(&amp;quot;Failed to verify Paypal's notification, please investigate&amp;quot;)
        end
      rescue =&amp;gt; e
        @payment.status = 'Error'
        raise
      ensure
        @payment.save
      end
    end
    render :nothing =&amp;gt; true
  end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Depending on the model for your application, this action will obviously look different. The important part is that you pass the raw post data from the request to &lt;code&gt;Paypal::Notification.new&lt;/code&gt;, and call &lt;code&gt;notify.acknowledge&lt;/code&gt; to connect back to Paypal to verify the data.&lt;/p&gt;

&lt;h3&gt;Enable &lt;span class=&quot;caps&quot;&gt;IPN&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;Lastly, log into the business account that you created above, go to &lt;em&gt;&#8220;Instant Payment Notification Preferences&#8221;&lt;/em&gt; in your profile, and set the &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; that Paypal should post back to after payments. (Note: this needs to be a publicly accessible &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;.)&lt;/p&gt;</content>  </entry>
  <entry xml:base="http://opensoul.org/">
    <author>
      <name>brandon</name>
    </author>
    <id>tag:opensoul.org,2007-08-08:357:6</id>
    <published>2006-09-16T20:49:00Z</published>
    <updated>2007-08-08T16:42:24Z</updated>
    <link href="http://opensoul.org/2006/9/16/paypal-ipn-in-rails-with-active-merchant" rel="alternate" type="text/html"/>
    <title>Paypal IPN in Rails with Active Merchant</title>
<content type="html">&lt;p&gt;&lt;a href=&quot;http://home.leetsoft.com/am/&quot;&gt;Active Merchant&lt;/a&gt; makes it extremely simple to use Paypal &lt;abbr title=&quot;Instant Payment Notification&quot;&gt;&lt;span class=&quot;caps&quot;&gt;IPN&lt;/span&gt;&lt;/abbr&gt;. Here is a simple guide for getting &lt;span class=&quot;caps&quot;&gt;IPN&lt;/span&gt; up and running.&lt;/p&gt;

&lt;h3&gt;Sign up for a &lt;a href=&quot;https://developer.paypal.com/&quot;&gt;Paypal sandbox account&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Paypal provides a sandbox environment that mimics their production environment, with the exception that it doesn&#8217;t actually process the transactions.  This is extremely useful for development and testing.  It allows you to create multiple fake accounts and generate bank accounts and credit cards. More information can be found on Paypal&#8217;s &lt;a href=&quot;http://www.paypal.com/cgi-bin/webscr?cmd=_ipn-test-about-outside&quot;&gt;Testing Instant Payment Notification&lt;/a&gt; page.&lt;/p&gt;
&lt;p&gt;Unfortunately, I&#8217;ve signed up for two different developer accounts and I&#8217;ve had trouble logging in with both of them.  I&#8217;ve tried resetting my password, but I still can&#8217;t log in.  Fortunately, I already have my sandbox accounts set up and don&#8217;t really have a need for it (except to write this guide).&lt;/p&gt;

&lt;h3&gt;Create a Personal account and add a credit card&lt;/h3&gt;
&lt;p&gt;After you sign up for your developer account, create a personal sandbox account and add a credit card.&lt;/p&gt;

&lt;h3&gt;Create a Business account and add a checking&lt;/h3&gt;
&lt;p&gt;Next, create a business sandbox account and add a checking account.&lt;/p&gt;

&lt;h3&gt;Install the money gem&lt;/h3&gt;
&lt;pre&gt;sudo gem install money&lt;/pre&gt;

&lt;h3&gt;Install the Active Merchant plugin&lt;/h3&gt;
&lt;pre&gt;script/plugin install svn://home.leetsoft.com/active_merchant/trunk/active_merchant/&lt;/pre&gt;

&lt;h3&gt;Create a form that submits to Paypal&lt;/h3&gt;
&lt;p&gt;Include &lt;code&gt;ActiveMerchant::Billing::Integrations&lt;/code&gt; in a controller to add Active Merchant&#8217;s helpers.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class PaymentsController &amp;lt; ApplicationController
  include ActiveMerchant::Billing::Integrations

  def create
    @enrollment = current_user.enrollments.find(params[:id])
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the view, use &lt;code&gt;payment_service_for&lt;/code&gt; to create a form that submits to Paypal to process the payment.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;erb&quot;&gt;&amp;lt;% payment_service_for @enrollment.id, PAYPAL_ACCOUNT,
        :amount =&amp;gt; @enrollment.course.deposit, :currency =&amp;gt; 'USD',
        :service =&amp;gt; :paypal do |service| 

    service.customer :first_name =&amp;gt; @enrollment.student.first_name,
        :last_name =&amp;gt; @enrollment.student.last_name,
        :phone =&amp;gt; @enrollment.student.phone,
        :email =&amp;gt; @enrollment.student.email
    service.billing_address :city =&amp;gt; @enrollment.student.city,
        :address1 =&amp;gt; @enrollment.student.street,
        :state =&amp;gt; @enrollment.student.state,
        :country =&amp;gt; 'USA',
        :zip =&amp;gt; @enrollment.student.zip
    service.item_name &amp;quot;#{@enrollment.course.program} Deposit&amp;quot;
    service.invoice @enrollment.invoice.id
    service.tax '0.00'

    service.notify_url url_for(:only_path =&amp;gt; false, :action =&amp;gt; 'notify')
    service.return_url url_for(:only_path =&amp;gt; false,
        :controller =&amp;gt; 'account', :action =&amp;gt; 'show')
    service.cancel_return_url url_for(:only_path =&amp;gt; false,
        :controller =&amp;gt; 'account', :action =&amp;gt; 'show') %&amp;gt;

    &amp;lt;!-- display payment summary here --&amp;gt;

    &amp;lt;%= submit_tag 'Make Payment' %&amp;gt;
&amp;lt;% end %&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The code above refers to the constant &lt;code&gt;PAYPAL_ACCOUNT&lt;/code&gt;, which I define in &lt;code&gt;environment.rb&lt;/code&gt;.  I also set Active Merchant to use test mode, which directs it to use Paypal&#8217;s sandbox:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;unless ENV['RAILS_ENV'] == 'production'
  PAYPAL_ACCOUNT = 'sandboxaccount@example.com'
  ActiveMerchant::Billing::Base.mode = :test
else
  PAYPAL_ACCOUNT = 'paypalaccount@example.com'
end&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Create an action that processes the &lt;span class=&quot;caps&quot;&gt;IPN&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;After the above form submits to Paypal and the user makes a payment, Paypal will post data about the transaction to your server.  Set up an action to receive the post:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  def notify
    notify = Paypal::Notification.new(request.raw_post)
    enrollment = Enrollment.find(notify.item_id)

    if notify.acknowledge
      @payment = Payment.find_by_confirmation(notify.transaction_id) ||
        enrollment.invoice.payments.create(:amount =&amp;gt; notify.amount,
          :payment_method =&amp;gt; 'paypal', :confirmation =&amp;gt; notify.transaction_id,
          :description =&amp;gt; notify.params['item_name'], :status =&amp;gt; notify.status,
          :test =&amp;gt; notify.test?)
      begin
        if notify.complete?
          @payment.status = notify.status
        else
          logger.error(&amp;quot;Failed to verify Paypal's notification, please investigate&amp;quot;)
        end
      rescue =&amp;gt; e
        @payment.status = 'Error'
        raise
      ensure
        @payment.save
      end
    end
    render :nothing =&amp;gt; true
  end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Depending on the model for your application, this action will obviously look different. The important part is that you pass the raw post data from the request to &lt;code&gt;Paypal::Notification.new&lt;/code&gt;, and call &lt;code&gt;notify.acknowledge&lt;/code&gt; to connect back to Paypal to verify the data.&lt;/p&gt;

&lt;h3&gt;Enable &lt;span class=&quot;caps&quot;&gt;IPN&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;Lastly, log into the business account that you created above, go to &lt;em&gt;&#8220;Instant Payment Notification Preferences&#8221;&lt;/em&gt; in your profile, and set the &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; that Paypal should post back to after payments. (Note: this needs to be a publicly accessible &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;.)&lt;/p&gt;</content>  </entry>
  <entry xml:base="http://opensoul.org/">
    <author>
      <name>brandon</name>
    </author>
    <id>tag:opensoul.org,2006-10-25:155:5</id>
    <published>2006-09-16T20:49:00Z</published>
    <updated>2006-10-25T02:43:47Z</updated>
    <link href="http://opensoul.org/2006/9/16/paypal-ipn-in-rails-with-active-merchant" rel="alternate" type="text/html"/>
    <title>Paypal IPN in Rails with Active Merchant</title>
<content type="html">&lt;p&gt;&lt;a href=&quot;http://home.leetsoft.com/am/&quot;&gt;Active Merchant&lt;/a&gt; makes it extremely simple to use Paypal &lt;abbr title=&quot;Instant Payment Notification&quot;&gt;&lt;span class=&quot;caps&quot;&gt;IPN&lt;/span&gt;&lt;/abbr&gt;. Here is a simple guide for getting &lt;span class=&quot;caps&quot;&gt;IPN&lt;/span&gt; up and running.&lt;/p&gt;

&lt;h3&gt;Sign up for a &lt;a href=&quot;https://developer.paypal.com/&quot;&gt;Paypal sandbox account&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Paypal provides a sandbox environment that mimics their production environment, with the exception that it doesn&#8217;t actually process the transactions.  This is extremely useful for development and testing.  It allows you to create multiple fake accounts and generate bank accounts and credit cards. More information can be found on Paypal&#8217;s &lt;a href=&quot;http://www.paypal.com/cgi-bin/webscr?cmd=_ipn-test-about-outside&quot;&gt;Testing Instant Payment Notification&lt;/a&gt; page.&lt;/p&gt;
&lt;p&gt;Unfortunately, I&#8217;ve signed up for two different developer accounts and I&#8217;ve had trouble logging in with both of them.  I&#8217;ve tried resetting my password, but I still can&#8217;t log in.  Fortunately, I already have my sandbox accounts set up and don&#8217;t really have a need for it (except to write this guide).&lt;/p&gt;

&lt;h3&gt;Create a Personal account and add a credit card&lt;/h3&gt;
&lt;p&gt;After you sign up for your developer account, create a personal sandbox account and add a credit card.&lt;/p&gt;

&lt;h3&gt;Create a Business account and add a checking&lt;/h3&gt;
&lt;p&gt;Next, create a business sandbox account and add a checking account.&lt;/p&gt;

&lt;h3&gt;Install the money gem&lt;/h3&gt;
&lt;pre&gt;sudo gem install money&lt;/pre&gt;

&lt;h3&gt;Install the Active Merchant plugin&lt;/h3&gt;
&lt;pre&gt;script/plugin install svn://home.leetsoft.com/active_merchant/trunk/active_merchant/&lt;/pre&gt;

&lt;h3&gt;Create a form that submits to Paypal&lt;/h3&gt;
&lt;p&gt;Include &lt;code&gt;ActiveMerchant::Billing::Integrations&lt;/code&gt; in a controller to add Active Merchant&#8217;s helpers.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class PaymentsController &amp;lt; ApplicationController
  include ActiveMerchant::Billing::Integrations

  def create
    @enrollment = current_user.enrollments.find(params[:id])
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the view, use &lt;code&gt;payment_service_for&lt;/code&gt; to create a form that submits to Paypal to process the payment.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;erb&quot;&gt;&amp;lt;% payment_service_for @enrollment.id, PAYPAL_ACCOUNT,
        :amount =&amp;gt; @enrollment.course.deposit, :currency =&amp;gt; 'USD',
        :service =&amp;gt; :paypal do |service| 

    service.customer :first_name =&amp;gt; @enrollment.student.first_name,
        :last_name =&amp;gt; @enrollment.student.last_name,
        :phone =&amp;gt; @enrollment.student.phone,
        :email =&amp;gt; @enrollment.student.email
    service.billing_address :city =&amp;gt; @enrollment.student.city,
        :address1 =&amp;gt; @enrollment.student.street,
        :state =&amp;gt; @enrollment.student.state,
        :country =&amp;gt; 'USA',
        :zip =&amp;gt; @enrollment.student.zip
    service.item_name &quot;#{@enrollment.course.program} Deposit&quot; 
    service.invoice @enrollment.invoice.id
    service.tax '0.00'

    service.notify_url url_for(:only_path =&amp;gt; false, :action =&amp;gt; 'notify')
    service.return_url url_for(:only_path =&amp;gt; false,
        :controller =&amp;gt; 'account', :action =&amp;gt; 'show')
    service.cancel_return_url url_for(:only_path =&amp;gt; false,
        :controller =&amp;gt; 'account', :action =&amp;gt; 'show') %&amp;gt;

    &amp;lt;!-- display payment summary here --&amp;gt;

    &amp;lt;%= submit_tag 'Make Payment' %&amp;gt;
&amp;lt;% end %&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The code above refers to the constant &lt;code&gt;PAYPAL_ACCOUNT&lt;/code&gt;, which I define in &lt;code&gt;environment.rb&lt;/code&gt;.  I also set Active Merchant to use test mode, which directs it to use Paypal&#8217;s sandbox:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;unless ENV['RAILS_ENV'] == 'production'
  PAYPAL_ACCOUNT = 'sandboxaccount@example.com'
  ActiveMerchant::Billing::Base.mode = :test
else
  PAYPAL_ACCOUNT = 'paypalaccount@example.com'
end&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Create an action that processes the &lt;span class=&quot;caps&quot;&gt;IPN&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;After the above form submits to Paypal and the user makes a payment, Paypal will post data about the transaction to your server.  Set up an action to receive the post:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  def notify
    notify = Paypal::Notification.new(request.raw_post)
    enrollment = Enrollment.find(notify.item_id)

    if notify.acknowledge
      @payment = Payment.find_by_confirmation(notify.transaction_id) ||
        enrollment.invoice.payments.create(:amount =&amp;gt; notify.amount,
          :payment_method =&amp;gt; 'paypal', :confirmation =&amp;gt; notify.transaction_id,
          :description =&amp;gt; notify.params['item_name'], :status =&amp;gt; notify.status,
          :test =&amp;gt; notify.test?)
      begin
        if notify.complete?
          @payment.status = notify.status
        else
          logger.error(&quot;Failed to verify Paypal's notification, please investigate&quot;)
        end
      rescue =&amp;gt; e
        @payment.status = 'Error'
        raise
      ensure
        @payment.save
      end
    end
    render :nothing =&amp;gt; true
  end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Depending on the model for your application, this action will obviously look different. The important part is that you pass the raw post data from the request to &lt;code&gt;Paypal::Notification.new&lt;/code&gt;, and call &lt;code&gt;notify.acknowledge&lt;/code&gt; to connect back to Paypal to verify the data.&lt;/p&gt;

&lt;h3&gt;Enable &lt;span class=&quot;caps&quot;&gt;IPN&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;Lastly, log into the business account that you created above, go to &lt;em&gt;&#8220;Instant Payment Notification Preferences&#8221;&lt;/em&gt; in your profile, and set the &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; that Paypal should post back to after payments. (Note: this needs to be a publicly accessible &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;.)&lt;/p&gt;</content>  </entry>
  <entry xml:base="http://opensoul.org/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:opensoul.org,2006-10-23:147:4</id>
    <published>2006-09-16T20:49:00Z</published>
    <updated>2006-10-23T21:07:39Z</updated>
    <link href="http://opensoul.org/2006/9/16/paypal-ipn-in-rails-with-active-merchant" rel="alternate" type="text/html"/>
    <title>Paypal IPN in Rails with Active Merchant</title>
<content type="html">&lt;p&gt;&lt;a href=&quot;http://home.leetsoft.com/am/&quot;&gt;Active Merchant&lt;/a&gt; makes it extremely simple to use Paypal &lt;abbr title=&quot;Instant Payment Notification&quot;&gt;&lt;span class=&quot;caps&quot;&gt;IPN&lt;/span&gt;&lt;/abbr&gt;. Here is a simple guide for getting &lt;span class=&quot;caps&quot;&gt;IPN&lt;/span&gt; up and running.&lt;/p&gt;

&lt;h3&gt;Sign up for a &lt;a href=&quot;https://developer.paypal.com/&quot;&gt;Paypal sandbox account&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Paypal provides a sandbox environment that mimics their production environment, with the exception that it doesn&#8217;t actually process the transactions.  This is extremely useful for development and testing.  It allows you to create multiple fake accounts and generate bank accounts and credit cards. More information can be found on Paypal&#8217;s &lt;a href=&quot;http://www.paypal.com/cgi-bin/webscr?cmd=_ipn-test-about-outside&quot;&gt;Testing Instant Payment Notification&lt;/a&gt; page.&lt;/p&gt;
&lt;p&gt;Unfortunately, I&#8217;ve signed up for two different developer accounts and I&#8217;ve had trouble logging in with both of them.  I&#8217;ve tried resetting my password, but I still can&#8217;t log in.  Fortunately, I already have my sandbox accounts set up and don&#8217;t really have a need for it (except to write this guide).&lt;/p&gt;

&lt;h3&gt;Create a Personal account and add a credit card&lt;/h3&gt;
&lt;p&gt;After you sign up for your developer account, create a personal sandbox account and add a credit card.&lt;/p&gt;

&lt;h3&gt;Create a Business account and add a checking&lt;/h3&gt;
&lt;p&gt;Next, create a business sandbox account and add a checking account.&lt;/p&gt;

&lt;h3&gt;Install the money gem&lt;/h3&gt;
&lt;pre&gt;sudo gem install money&lt;/pre&gt;

&lt;h3&gt;Install the Active Merchant plugin&lt;/h3&gt;
&lt;pre&gt;script/plugin install svn://home.leetsoft.com/active_merchant/trunk/active_merchant/&lt;/pre&gt;

&lt;h3&gt;Create a form that submits to Paypal&lt;/h3&gt;
&lt;p&gt;Include &lt;code&gt;ActiveMerchant::Billing::Integrations&lt;/code&gt; in a controller to add Active Merchant&#8217;s helpers.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class PaymentsController &amp;lt; ApplicationController
  include ActiveMerchant::Billing::Integrations

  def create
    @enrollment = current_user.enrollments.find(params[:id])
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the view, use &lt;code&gt;payment_service_for&lt;/code&gt; to create a form that submits to Paypal to process the payment.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;erb&quot;&gt;&amp;lt;% payment_service_for @enrollment.id, PAYPAL_ACCOUNT,
        :amount =&gt; @enrollment.course.deposit, :currency =&gt; 'USD',
        :service =&gt; :paypal do |service| 

    service.customer :first_name =&gt; @enrollment.student.first_name,
        :last_name =&gt; @enrollment.student.last_name,
        :phone =&gt; @enrollment.student.phone,
        :email =&gt; @enrollment.student.email
    service.billing_address :city =&gt; @enrollment.student.city,
        :address1 =&gt; @enrollment.student.street,
        :state =&gt; @enrollment.student.state,
        :country =&gt; 'USA',
        :zip =&gt; @enrollment.student.zip
    service.item_name &quot;#{@enrollment.course.program} Deposit&quot; 
    service.invoice @enrollment.invoice.id
    service.tax '0.00'

    service.notify_url url_for(:only_path =&gt; false, :action =&gt; 'notify')
    service.return_url url_for(:only_path =&gt; false,
        :controller =&gt; 'account', :action =&gt; 'show')
    service.cancel_return_url url_for(:only_path =&gt; false,
        :controller =&gt; 'account', :action =&gt; 'show') %&gt;

    &amp;lt;!-- display payment summary here --&gt;

    &amp;lt;%= submit_tag 'Make Payment' %&gt;
&amp;lt;% end %&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The code above refers to the constant &lt;code&gt;PAYPAL_ACCOUNT&lt;/code&gt;, which I define in &lt;code&gt;environment.rb&lt;/code&gt;.  I also set Active Merchant to use test mode, which directs it to use Paypal&#8217;s sandbox:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;unless ENV['RAILS_ENV'] == 'production'
  PAYPAL_ACCOUNT = 'sandboxaccount@example.com'
  ActiveMerchant::Billing::Base.mode = :test
else
  PAYPAL_ACCOUNT = 'paypalaccount@example.com'
end&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Create an action that processes the &lt;span class=&quot;caps&quot;&gt;IPN&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;After the above form submits to Paypal and the user makes a payment, Paypal will post data about the transaction to your server.  Set up an action to receive the post:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  def notify
    notify = Paypal::Notification.new(request.raw_post)
    enrollment = Enrollment.find(notify.item_id)

    if notify.acknowledge
      @payment = Payment.find_by_confirmation(notify.transaction_id) ||
        enrollment.invoice.payments.create(:amount =&gt; notify.amount,
          :payment_method =&gt; 'paypal', :confirmation =&gt; notify.transaction_id,
          :description =&gt; notify.params['item_name'], :status =&gt; notify.status,
          :test =&gt; notify.test?)
      begin
        if notify.complete?
          @payment.status = notify.status
        else
          logger.error(&quot;Failed to verify Paypal's notification, please investigate&quot;)
        end
      rescue =&gt; e
        @payment.status = 'Error'
        raise
      ensure
        @payment.save
      end
    end
    render :nothing =&gt; true
  end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Depending on the model for your application, this action will obviously look different. The important part is that you pass the raw post data from the request to &lt;code&gt;Paypal::Notification.new&lt;/code&gt;, and call &lt;code&gt;notify.acknowledge&lt;/code&gt; to connect back to Paypal to verify the data.&lt;/p&gt;

&lt;h3&gt;Enable &lt;span class=&quot;caps&quot;&gt;IPN&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;Lastly, log into the business account that you created above, go to &lt;em&gt;&#8220;Instant Payment Notification Preferences&#8221;&lt;/em&gt; in your profile, and set the &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; that Paypal should post back to after payments. (Note: this needs to be a publicly accessible &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;.)&lt;/p&gt;</content>  </entry>
  <entry xml:base="http://opensoul.org/">
    <author>
      <name>brandon</name>
    </author>
    <id>tag:opensoul.org,2006-10-23:145:3</id>
    <published>2006-09-16T20:49:52Z</published>
    <updated>2006-10-23T04:39:55Z</updated>
    <link href="http://opensoul.org/2006/9/16/paypal-ipn-in-rails-with-active-merchant" rel="alternate" type="text/html"/>
    <title>Paypal IPN in Rails with Active Merchant</title>
<content type="html">&lt;p&gt;&lt;a href=&quot;http://home.leetsoft.com/am/&quot;&gt;Active Merchant&lt;/a&gt; makes it extremely simple to use Paypal &lt;abbr title=&quot;Instant Payment Notification&quot;&gt;&lt;span class=&quot;caps&quot;&gt;IPN&lt;/span&gt;&lt;/abbr&gt;. Here is a simple guide for getting &lt;span class=&quot;caps&quot;&gt;IPN&lt;/span&gt; up and running.&lt;/p&gt;

&lt;h3&gt;Sign up for a &lt;a href=&quot;https://developer.paypal.com/&quot;&gt;Paypal sandbox account&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Paypal provides a sandbox environment that mimics their production environment, with the exception that it doesn&#8217;t actually process the transactions.  This is extremely useful for development and testing.  It allows you to create multiple fake accounts and generate bank accounts and credit cards. More information can be found on Paypal&#8217;s &lt;a href=&quot;http://www.paypal.com/cgi-bin/webscr?cmd=_ipn-test-about-outside&quot;&gt;Testing Instant Payment Notification&lt;/a&gt; page.&lt;/p&gt;
&lt;p&gt;Unfortunately, I&#8217;ve signed up for two different developer accounts and I&#8217;ve had trouble logging in with both of them.  I&#8217;ve tried resetting my password, but I still can&#8217;t log in.  Fortunately, I already have my sandbox accounts set up and don&#8217;t really have a need for it (except to write this guide).&lt;/p&gt;

&lt;h3&gt;Create a Personal account and add a credit card&lt;/h3&gt;
&lt;p&gt;After you sign up for your developer account, create a personal sandbox account and add a credit card.&lt;/p&gt;

&lt;h3&gt;Create a Business account and add a checking&lt;/h3&gt;
&lt;p&gt;Next, create a business sandbox account and add a checking account.&lt;/p&gt;

&lt;h3&gt;Install the money gem&lt;/h3&gt;
&lt;pre&gt;sudo gem install money&lt;/pre&gt;

&lt;h3&gt;Install the Active Merchant plugin&lt;/h3&gt;
&lt;pre&gt;script/plugin install svn://home.leetsoft.com/active_merchant/trunk/active_merchant/&lt;/pre&gt;

&lt;h3&gt;Create a form that submits to Paypal&lt;/h3&gt;
&lt;p&gt;Include &lt;code&gt;ActiveMerchant::Billing::Integrations&lt;/code&gt; in a controller to add Active Merchant&#8217;s helpers.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class PaymentsController &amp;lt; ApplicationController
  include ActiveMerchant::Billing::Integrations

  def create
    @enrollment = current_user.enrollments.find(params[:id])
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the view, use &lt;code&gt;payment_service_for&lt;/code&gt; to create a form that submits to Paypal to process the payment.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;erb&quot;&gt;&amp;lt;% payment_service_for @enrollment.id, PAYPAL_ACCOUNT,
        :amount =&gt; @enrollment.course.deposit, :currency =&gt; 'USD',
        :service =&gt; :paypal do |service| 

    service.customer :first_name =&gt; @enrollment.student.first_name,
        :last_name =&gt; @enrollment.student.last_name,
        :phone =&gt; @enrollment.student.phone,
        :email =&gt; @enrollment.student.email
    service.billing_address :city =&gt; @enrollment.student.city,
        :address1 =&gt; @enrollment.student.street,
        :state =&gt; @enrollment.student.state,
        :country =&gt; 'USA',
        :zip =&gt; @enrollment.student.zip
    service.item_name &quot;#{@enrollment.course.program} Deposit&quot; 
    service.invoice @enrollment.invoice.id
    service.tax '0.00'

    service.notify_url url_for(:only_path =&gt; false, :action =&gt; 'notify')
    service.return_url url_for(:only_path =&gt; false,
        :controller =&gt; 'account', :action =&gt; 'show')
    service.cancel_return_url url_for(:only_path =&gt; false,
        :controller =&gt; 'account', :action =&gt; 'show') %&gt;

    &amp;lt;!-- display payment summary here --&gt;

    &amp;lt;%= submit_tag 'Make Payment' %&gt;
&amp;lt;% end %&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The code above refers to the constant &lt;code&gt;PAYPAL_ACCOUNT&lt;/code&gt;, which I define in &lt;code&gt;environment.rb&lt;/code&gt;.  I also set Active Merchant to use test mode, which directs it to use Paypal&#8217;s sandbox:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;unless ENV['RAILS_ENV'] == 'production'
  PAYPAL_ACCOUNT = 'sandboxaccount@example.com'
  ActiveMerchant::Billing::Base.mode = :test
else
  PAYPAL_ACCOUNT = 'paypalaccount@example.com'
end&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Create an action that processes the &lt;span class=&quot;caps&quot;&gt;IPN&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;After the above form submits to Paypal and the user makes a payment, Paypal will post data about the transaction to your server.  Set up an action to receive the post:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  def notify
    notify = Paypal::Notification.new(request.raw_post)
    enrollment = Enrollment.find(notify.item_id)

    if notify.acknowledge
      @payment = Payment.find_by_confirmation(notify.transaction_id) ||
        enrollment.invoice.payments.create(:amount =&gt; notify.amount,
          :payment_method =&gt; 'paypal', :confirmation =&gt; notify.transaction_id,
          :description =&gt; notify.params['item_name'], :status =&gt; notify.status,
          :test =&gt; notify.test?)
      begin
        if notify.complete?
          @payment.status = notify.status
        else
          logger.error(&quot;Failed to verify Paypal's notification, please investigate&quot;)
        end
      rescue =&gt; e
        @payment.status = 'Error'
        raise
      ensure
        @payment.save
      end
    end
    render :nothing =&gt; true
  end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Depending on the model for your application, this action will obviously look different. The important part is that you pass the raw post data from the request to &lt;code&gt;Paypal::Notification.new&lt;/code&gt;, and call &lt;code&gt;notify.acknowledge&lt;/code&gt; to connect back to Paypal to verify the data.&lt;/p&gt;

&lt;h3&gt;Enable &lt;span class=&quot;caps&quot;&gt;IPN&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;Lastly, log into the business account that you created above, go to &lt;em&gt;&#8220;Instant Payment Notification Preferences&#8221;&lt;/em&gt; in your profile, and set the &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; that Paypal should post back to after payments. (Note: this needs to be a publicly accessible &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;.)&lt;/p&gt;</content>  </entry>
</feed>
