<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<id>tag:old.nabble.com,2006:forum-27137</id>
	<title>Nabble - GetPaid for Plone - Dev</title>
	<updated>2009-11-23T16:45:15Z</updated>
	<link rel="self" type="application/atom+xml" href="http://old.nabble.com/GetPaid-for-Plone---Dev-f27137.xml" />
	<link rel="alternate" type="text/html" href="http://old.nabble.com/GetPaid-for-Plone---Dev-f27137.html" />
	<subtitle type="html">This mailing list is used for discussion of the product, its use, future, and connecting with the community using it.</subtitle>
	
<entry>
	<id>tag:old.nabble.com,2006:post-26488768</id>
	<title>Re: Reviewed Brandon's work: some suggestions</title>
	<published>2009-11-23T16:45:15Z</published>
	<updated>2009-11-23T16:45:15Z</updated>
	<author>
		<name>Mikko Ohtamaa</name>
	</author>
	<content type="html">&amp;gt;
&lt;br&gt;&amp;gt; I'm just trying out multiplepaymentprocessors branch, which offsite
&lt;br&gt;&amp;gt; payment processors should I test with? Currently only see the onsite
&lt;br&gt;&amp;gt; nullpayment.
&lt;br&gt;&lt;br&gt;Currently there should be
&lt;br&gt;&lt;br&gt;* PayPal (not sure which branch was correct)
&lt;br&gt;&lt;br&gt;* Luottokunta (Finnish credit card processing)
&lt;br&gt;&lt;br&gt;* Verkkomaksut (Again, Finnish generic payment processor)
&lt;br&gt;&lt;br&gt;Also I think there is one special processor for making real purchases
&lt;br&gt;without doing the actual payment, for internal purchases of the store
&lt;br&gt;owner.
&lt;br&gt;&lt;br&gt;Cheers,
&lt;br&gt;-Mikko
&lt;br&gt;&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt; I am willing to help to merge multiplepaymentprocessor branch with
&lt;br&gt;&amp;gt;&amp;gt; brandon and brandon branch with trunk if
&lt;br&gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt; 1) Community &amp;quot;decision making process&amp;quot; sees this as a necessary
&lt;br&gt;&amp;gt;&amp;gt; requirement for the future
&lt;br&gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt; 2) There is someone else willing to put hours on the issue
&lt;br&gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; +1
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt; -Mikko
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; Cheers,
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;  Marton
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; --
&lt;br&gt;&amp;gt; GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt;&amp;nbsp;(overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt;&amp;nbsp;(code and issue tracker)
&lt;br&gt;&amp;gt; You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
&lt;br&gt;&amp;gt; To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26488768&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
&lt;br&gt;&amp;gt; To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26488768&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; For more options, visit this group at
&lt;br&gt;&amp;gt; &lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;&amp;gt;
&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;Mikko Ohtamaa
&lt;br&gt;Managing director, Red Innovation Ltd.
&lt;br&gt;+358 40 743 9707
&lt;br&gt;www.redinnovation.com
&lt;br&gt;Every problem is solvable if you can throw enough energy drinks at it
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt;&amp;nbsp;(overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt;&amp;nbsp;(code and issue tracker)
&lt;br&gt;You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
&lt;br&gt;To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26488768&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
&lt;br&gt;To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26488768&amp;i=3&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
&lt;br&gt;&lt;br&gt;For more options, visit this group at
&lt;br&gt;&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Reviewed-Brandon%27s-work%3A-some-suggestions-tp26355777p26488768.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26487469</id>
	<title>Re: Reviewed Brandon's work: some suggestions</title>
	<published>2009-11-23T14:43:07Z</published>
	<updated>2009-11-23T14:43:07Z</updated>
	<author>
		<name>Marton Schimcsig</name>
	</author>
	<content type="html">Hi,
&lt;br&gt;&lt;br&gt;On Nov 15, 2:59 am, Moo &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26487469&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;mi...@...&lt;/a&gt;&amp;gt; wrote:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; Hi,
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; I just went through Brandon's work. Looks nice to me, though there are
&lt;br&gt;&amp;gt; some show stopping issues.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; The offsite payment processor interface was empty. It is very
&lt;br&gt;&amp;gt; difficult for third parties to implement payment processor unless
&lt;br&gt;&amp;gt; interfaces are documented with the required precision.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; If I read the core correctly there can be just one on-site payment
&lt;br&gt;&amp;gt; processor. Also, the wizard step to choose payment processor is
&lt;br&gt;&amp;gt; missing.
&lt;/div&gt;&lt;br&gt;&lt;br&gt;The wizard step is not needed here.
&lt;br&gt;The checkout process should be done with as few click from the buyer
&lt;br&gt;as possible. This is important point for the shop owners.
&lt;br&gt;With paypal standard, you get a checkout button from the payment
&lt;br&gt;provider and put it on your site anywhere, allowing the customer the
&lt;br&gt;start the payment immediately. Later the payment processor can be
&lt;br&gt;asked and/or will notify the shop about the transaction.
&lt;br&gt;&lt;br&gt;With paypal express checkout, you have to ask the paypal server for a
&lt;br&gt;token, before you can generate the checkout button, so the extra step
&lt;br&gt;in checkout process after selecting paypal is needed.
&lt;br&gt;The current paypal module in trunk works with paypal standard.
&lt;br&gt;&lt;br&gt;&amp;gt; As is, this work is useless for many use cases, like
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; * Having a wire payment processor
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; * Choose between credit card and wire payment
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; * Choose between different on-sites processors (imagine different
&lt;br&gt;&amp;gt; processor for different credit cards)
&lt;br&gt;&amp;gt;
&lt;br&gt;&lt;br&gt;&lt;br&gt;In Brandon's branch you can use offsite processors and onsite
&lt;br&gt;processor together, the buyer can choose between them during the
&lt;br&gt;checkout.
&lt;br&gt;However the offsite button rendering is done with black magic, a
&lt;br&gt;refactoring would be nice.
&lt;br&gt;&lt;br&gt;&lt;br&gt;&amp;gt; What's the status of the future of Brandon's work? In
&lt;br&gt;&amp;gt; multiplepaymentprocessor support for these use cases exist.
&lt;br&gt;&lt;br&gt;&lt;br&gt;I'm just trying out multiplepaymentprocessors branch, which offsite
&lt;br&gt;payment processors should I test with? Currently only see the onsite
&lt;br&gt;nullpayment.
&lt;br&gt;&lt;br&gt;&lt;br&gt;&amp;gt; I am willing to help to merge multiplepaymentprocessor branch with
&lt;br&gt;&amp;gt; brandon and brandon branch with trunk if
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; 1) Community &amp;quot;decision making process&amp;quot; sees this as a necessary
&lt;br&gt;&amp;gt; requirement for the future
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; 2) There is someone else willing to put hours on the issue
&lt;br&gt;&amp;gt;
&lt;br&gt;&lt;br&gt;+1
&lt;br&gt;&lt;br&gt;&lt;br&gt;&amp;gt; -Mikko
&lt;br&gt;&lt;br&gt;Cheers,
&lt;br&gt;&lt;br&gt;&amp;nbsp;Marton
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt;&amp;nbsp;(overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt;&amp;nbsp;(code and issue tracker)
&lt;br&gt;You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
&lt;br&gt;To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26487469&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
&lt;br&gt;To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26487469&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
&lt;br&gt;&lt;br&gt;For more options, visit this group at
&lt;br&gt;&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Reviewed-Brandon%27s-work%3A-some-suggestions-tp26355777p26487469.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26382321</id>
	<title>Re: Reviewed Brandon's work: some suggestions</title>
	<published>2009-11-16T16:19:33Z</published>
	<updated>2009-11-16T16:19:33Z</updated>
	<author>
		<name>Christopher Johnson-7</name>
	</author>
	<content type="html">Hi Mikko,&lt;br&gt;&lt;br&gt;Thanks for helping us understand the differences between the multisite branch and the no overrides branch. My understanding is we really just need some more feedback on how it is set up, feedback on how clear the documentation for creating a payment processor is, and the design that was used. We&amp;#39;ve had little other testing that I know of, so thanks for your comments. I&amp;#39;m testing on a site with one onsite and one offsite. We have implemented 2 processors with the offsite interfaces based on Brandon&amp;#39;s branch (NMI and &lt;a href=&quot;http://authorize.net&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;authorize.net&lt;/a&gt;). &lt;br&gt;
&lt;br&gt;In discussing the use cases, we didn&amp;#39;t know of any that would require multiple onsite payment processors. In my experience, the kinds of providers that let you do onsite usually involve a monthly fee, so site owners are unlikely to subscribe to more than one (cheaper to pay one to add a particular credit card service, like American Express or Discover, than to have an entire different service). However, I see how this could raise an issue if a Purchase Order or Bank Order implementation is made using the same infrastructure. It would probably behave like an onsite processor, and then it may not be possible for a merchant to have both a onsite payment and offline payment. &lt;br&gt;
&lt;br&gt;Hopefully what is there can be modified to account for this potential use case. Also, the button alignment needs some work on the cart screen and portlet :)&lt;br&gt;&lt;br&gt;-chris&lt;br&gt;&lt;br&gt;&lt;div class=&quot;gmail_quote&quot;&gt;On Sun, Nov 15, 2009 at 6:24 AM, Moo &lt;span dir=&quot;ltr&quot;&gt;&amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26382321&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;mikko@...&lt;/a&gt;&amp;gt;&lt;/span&gt; wrote:&lt;br&gt;
&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;&quot;&gt;More issues:&lt;br&gt;
&lt;br&gt;
One cannot present paymeny processor options as a schema reference&lt;br&gt;
(options_interface). They payment processor must be able to customize&lt;br&gt;
its own form view as zope.schema cannot be used to express all form&lt;br&gt;
use cases (custom widgets and so on...).&lt;br&gt;
&lt;br&gt;
-Mikko&lt;br&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div class=&quot;h5&quot;&gt;&lt;br&gt;
&amp;gt; I just went through Brandon&amp;#39;s work. Looks nice to me, though there are&lt;br&gt;
&amp;gt; some show stopping issues.&lt;br&gt;
&amp;gt;&lt;br&gt;
&amp;gt; The offsite payment processor interface was empty. It is very&lt;br&gt;
&amp;gt; difficult for third parties to implement payment processor unless&lt;br&gt;
&amp;gt; interfaces are documented with the required precision.&lt;br&gt;
&amp;gt;&lt;br&gt;
&amp;gt; If I read the core correctly there can be just one on-site payment&lt;br&gt;
&amp;gt; processor. Also, the wizard step to choose payment processor is&lt;br&gt;
&amp;gt; missing.&lt;br&gt;
&amp;gt;&lt;br&gt;
&amp;gt; As is, this work is useless for many use cases, like&lt;br&gt;
&amp;gt;&lt;br&gt;
&amp;gt; * Having a wire payment processor&lt;br&gt;
&amp;gt;&lt;br&gt;
&amp;gt; * Choose between credit card and wire payment&lt;br&gt;
&amp;gt;&lt;br&gt;
&amp;gt; * Choose between different on-sites processors (imagine different&lt;br&gt;
&amp;gt; processor for different credit cards)&lt;br&gt;
&amp;gt;&lt;br&gt;
&amp;gt; What&amp;#39;s the status of the future of Brandon&amp;#39;s work? In&lt;br&gt;
&amp;gt; multiplepaymentprocessor support for these use cases exist.&lt;br&gt;
&amp;gt;&lt;br&gt;
&amp;gt; I am willing to help to merge multiplepaymentprocessor branch with&lt;br&gt;
&amp;gt; brandon and brandon branch with trunk if&lt;br&gt;
&amp;gt;&lt;br&gt;
&amp;gt; 1) Community &amp;quot;decision making process&amp;quot; sees this as a necessary&lt;br&gt;
&amp;gt; requirement for the future&lt;br&gt;
&amp;gt;&lt;br&gt;
&amp;gt; 2) There is someone else willing to put hours on the issue&lt;br&gt;
&amp;gt;&lt;br&gt;
&amp;gt; -Mikko&lt;br&gt;
&lt;br&gt;
--&lt;br&gt;
GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt; (overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt; (code and issue tracker)&lt;br&gt;

You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.&lt;br&gt;
To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26382321&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;&lt;br&gt;
To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26382321&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev%2Bunsubscribe@...&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
For more options, visit this group at&lt;br&gt;
&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;br&gt;&lt;br clear=&quot;all&quot;&gt;&lt;br&gt;-- &lt;br&gt;Cofounder and CEO&lt;br&gt;
ifPeople - Innovation for People&lt;br&gt;&lt;a href=&quot;http://www.ifpeople.net&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;www.ifpeople.net&lt;/a&gt;&lt;br&gt;t: 678-608-3408&lt;br&gt;130 Boulevard NE, #6&lt;br&gt;Atlanta, GA 30312&lt;br&gt;

&lt;p&gt;&lt;/p&gt;

-- &lt;br /&gt;
GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt; (overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt; (code and issue tracker)&lt;br /&gt;
You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.&lt;br /&gt;
To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26382321&amp;i=3&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;&lt;br /&gt;
To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26382321&amp;i=4&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;&lt;br /&gt;
&amp;nbsp;&lt;br /&gt;
For more options, visit this group at&lt;br /&gt;
&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Reviewed-Brandon%27s-work%3A-some-suggestions-tp26355777p26382321.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26379755</id>
	<title>Re: The future of GetPaid?</title>
	<published>2009-11-16T13:25:20Z</published>
	<updated>2009-11-16T13:25:20Z</updated>
	<author>
		<name>Mikko Ohtamaa</name>
	</author>
	<content type="html">Hi,&lt;br&gt;&lt;br&gt;&lt;div class=&quot;gmail_quote&quot;&gt;&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;&quot;&gt;&lt;br&gt;Thanks for sharing your notes after the conference and sprint. Certainly some of the points you mention are an accurate description of the current state of GetPaid (ie there is no product manager now), but I think your characterization of GetPaid&amp;#39;s viable underestimates both the product and the people in the community and I wanted to respond and provide some of the information that was shared in the conference presentation as well. &lt;br&gt;
&lt;/blockquote&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Thanks for very good response Chris. I hope I was not over-critical with some of my points, I must some I love getpaid very much though feeling the frustration now and then, like many of us do. It&amp;#39;s almost there that you could use it for Plone commercing needs, but it gives some problems which would be solved if you used external shopping system. I was hoping that my email would inspire some discussion so people, even ones who didn&amp;#39;t go to conference, could see that the train is still going :)&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;&quot;&gt;&lt;br&gt;There are several sites that have been launched with GetPaid already. About two dozen are listed at &lt;a href=&quot;http://www.plonegetpaid.com/why/sites-using-getpaid&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com/why/sites-using-getpaid&lt;/a&gt; .  Some are just &amp;quot;out of the box&amp;quot; GetPaid and work well for the client as is, some are customized (and many of the docs about how to achieve the customizations shown are linked to in the presentation I gave at the ploneconf2009: &lt;a href=&quot;http://snurl.com/getpaid-slides&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://snurl.com/getpaid-slides&lt;/a&gt; ). &lt;/blockquote&gt;
&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;I think the barrier comes when you need to have some &amp;quot;deeper&amp;quot; customizations. Like having a new field on Order. You basically need to go to hand-edit getpaid.core or override various, various, adapters and templates. Which makes it difficult as it is not very clear how things are connected. Getpaid architecture, nice as it is, tries very hard to keep &amp;quot;architecture&amp;quot; (getpaid.core) and &amp;quot;implementation&amp;quot; (Products.PloneGetPaid) separate from each other. For example, payment processor contain both architectural and UI drop ins. The problem comes with latter when people create plug-ins which need to use overrides.zcml to get things done. However these problems are just technical, and they can be solved when community knows what they are aiming at and have time do the work. This issue has been already discussed partially with&amp;#39;s Brandon&amp;#39;s work on payment processors.&lt;/div&gt;
&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;&quot;&gt;&lt;br&gt;Regarding people who are playing roles to maintain the product, GetPaid has gone through a period of activity and evolution, several releases. Unfortunately, I left some of this story out of the presentation in Budapest. Perrito (Horacio Duran) has managed a release (0.6.2, I believe) and Lucie at SIx Feet Up has managed releases over the 0.7 series of PloneGetPaid, and David Glick from Groundwire has been involved since ~0.8. These are all people in the Plone community who are/were involved over a period when they were using GetPaid and were working to make it better for their needs. I&amp;#39;m hoping that is what we are starting again as a community. &lt;br&gt;
&lt;/blockquote&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Great :) The problem is that no one really knows when to commit trunk. Lots of patches end up being in the bug reports and email attachment (like the late issues with inter-database references), when there is no a single point of contact who would help to maintain the trunk. As already discussed, some nice ideas come up.&lt;/div&gt;
&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&amp;gt;The project is now in a period where we need new people with interest in ecommerce in Plone to step up and lead in various aspects of the project. That&amp;#39;s an invitation I extended during the presentation at the conference. There are &amp;gt;several people interested in getting the remaining needed functionalities (downloadable files, premium content, others), and the model we took in organizing this project originally (see Social Sourcing presentation, &amp;gt;&lt;a href=&quot;http://www.ifpeople.net/solutions/social-sourcing&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;www.ifpeople.net/solutions/social-sourcing&lt;/a&gt; ) was about getting people involved upfront in a round of changes. So yes, as you point out, there was an original architect who is no longer active in the project. But, of the other sponsors, &amp;gt;supporters and contributors at the very outset of the project, about 3/4 are still involved in the project in one way or another, which gives us a solid basis of community around GetPaid. Now it&amp;#39;s time to get the community involved in &amp;gt;actively shaping the future again. &lt;/div&gt;
&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Here we are!&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Cheers,&lt;/div&gt;&lt;div&gt; Mikko&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

-- &lt;br /&gt;
GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt; (overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt; (code and issue tracker)&lt;br /&gt;
You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.&lt;br /&gt;
To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26379755&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;&lt;br /&gt;
To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26379755&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;&lt;br /&gt;
&amp;nbsp;&lt;br /&gt;
For more options, visit this group at&lt;br /&gt;
&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/The-future-of-GetPaid--tp26355889p26379755.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26379381</id>
	<title>Re: The future of GetPaid?</title>
	<published>2009-11-16T13:00:12Z</published>
	<updated>2009-11-16T13:00:12Z</updated>
	<author>
		<name>Matt Halstead-3</name>
	</author>
	<content type="html">I agree with Chris here. I would see the following would help:
&lt;br&gt;&lt;br&gt;- some life breathed into &lt;a href=&quot;http://plone.org/products/getpaid/roadmap&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://plone.org/products/getpaid/roadmap&lt;/a&gt;&lt;br&gt;... there are many features and core fixes that people are
&lt;br&gt;contributing to, it would be useful to list these and bring them
&lt;br&gt;together as proposals that could be discussed and timelined
&lt;br&gt;&lt;br&gt;- a set of rotating release managers, with each release manager
&lt;br&gt;delegating responsibility for certain proposals in the timeline which
&lt;br&gt;are coming up for release and ensuring the release goes ahead.
&lt;br&gt;&lt;br&gt;- it is quite difficult to get a sense of what testing is required
&lt;br&gt;when a new feature or fix is added and I think this may stop a lot of
&lt;br&gt;individuals contributing to the code where their local need requires
&lt;br&gt;some changes. The number of combinations of getpaid packages and plone
&lt;br&gt;versions is quite high (I'm including all the different payment
&lt;br&gt;processors in there) and it feels like quite a large task to test
&lt;br&gt;these in relation to a change that you want to make. It would be nice
&lt;br&gt;to have a recipe and some kind of delegation for testing too. I would
&lt;br&gt;like to at least see each payment processor having a 'current' owner
&lt;br&gt;whose responsibility it is to test their processor for a given release
&lt;br&gt;candidate.
&lt;br&gt;&lt;br&gt;One of the most difficult aspects of helping to maintain this code is
&lt;br&gt;that as a developer you are seldom using it each day (unlike core
&lt;br&gt;plone components and addons that you rely on for perhaps most of your
&lt;br&gt;site's function). So contribution seems to be adhoc on a need to fix
&lt;br&gt;something basis, which makes momentum difficult to maintain. Finding
&lt;br&gt;some funding to maintain some continued part-time contribution for a
&lt;br&gt;number of people (which could rotate over time) would probably help. I
&lt;br&gt;don't think many people would have to contribute much per month for
&lt;br&gt;the right momentum to be achieved.
&lt;br&gt;&lt;br&gt;cheers
&lt;br&gt;Matt
&lt;br&gt;&lt;br&gt;&lt;br&gt;On Nov 17, 7:32 am, Christopher Johnson &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26379381&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;cjj.ifpeo...@...&lt;/a&gt;&amp;gt;
&lt;br&gt;wrote:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; Hi Mikko,
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; Thanks for sharing your notes after the conference and sprint. Certainly
&lt;br&gt;&amp;gt; some of the points you mention are an accurate description of the current
&lt;br&gt;&amp;gt; state of GetPaid (ie there is no product manager now), but I think your
&lt;br&gt;&amp;gt; characterization of GetPaid's viable underestimates both the product and the
&lt;br&gt;&amp;gt; people in the community and I wanted to respond and provide some of the
&lt;br&gt;&amp;gt; information that was shared in the conference presentation as well.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; One thing to clarify though about the purpose of the project - GetPaid isn't
&lt;br&gt;&amp;gt; meant to attract ecommerce people to using Plone. It's meant to keep people
&lt;br&gt;&amp;gt; from leaving Plone because they have ecommerce needs. This was what drove
&lt;br&gt;&amp;gt; the origin of the project and I think today is still relevant. If people
&lt;br&gt;&amp;gt; want only ecommerce and don't care about all the power Plone brings, there's
&lt;br&gt;&amp;gt; little reason they should use GetPaid.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; The architecture does have a fairly high barrier to entry for developers. In
&lt;br&gt;&amp;gt; part, because it was created as a zope3 product in the very early days of
&lt;br&gt;&amp;gt; zope3 products for Plone. So a python programmer with no Plone knowledge
&lt;br&gt;&amp;gt; will have to ramp up on some technologies before being able to customize it.
&lt;br&gt;&amp;gt; I think this can be said about Plone in general these days also.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; But, that depends on how you want to customize it...there are many things
&lt;br&gt;&amp;gt; that are fairly straight forward to do. If that weren't the case, we
&lt;br&gt;&amp;gt; wouldn't have had such huge growth in add ons for the product and payment
&lt;br&gt;&amp;gt; processors over the last year (over twice as much code overall and over
&lt;br&gt;&amp;gt; twice as many payment processors). And most of the time, that's what someone
&lt;br&gt;&amp;gt; implementing a site needs to do.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; There are several sites that have been launched with GetPaid already. About
&lt;br&gt;&amp;gt; two dozen are listed athttp://www.plonegetpaid.com/why/sites-using-getpaid.  Some are just
&lt;br&gt;&amp;gt; &amp;quot;out of the box&amp;quot; GetPaid and work well for the client as
&lt;br&gt;&amp;gt; is, some are customized (and many of the docs about how to achieve the
&lt;br&gt;&amp;gt; customizations shown are linked to in the presentation I gave at the
&lt;br&gt;&amp;gt; ploneconf2009:&lt;a href=&quot;http://snurl.com/getpaid-slides&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://snurl.com/getpaid-slides&lt;/a&gt;).
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; Regarding people who are playing roles to maintain the product, GetPaid has
&lt;br&gt;&amp;gt; gone through a period of activity and evolution, several releases.
&lt;br&gt;&amp;gt; Unfortunately, I left some of this story out of the presentation in
&lt;br&gt;&amp;gt; Budapest. Perrito (Horacio Duran) has managed a release (0.6.2, I believe)
&lt;br&gt;&amp;gt; and Lucie at SIx Feet Up has managed releases over the 0.7 series of
&lt;br&gt;&amp;gt; PloneGetPaid, and David Glick from Groundwire has been involved since ~0.8.
&lt;br&gt;&amp;gt; These are all people in the Plone community who are/were involved over a
&lt;br&gt;&amp;gt; period when they were using GetPaid and were working to make it better for
&lt;br&gt;&amp;gt; their needs. I'm hoping that is what we are starting again as a community.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; The project is now in a period where we need new people with interest in
&lt;br&gt;&amp;gt; ecommerce in Plone to step up and lead in various aspects of the project.
&lt;br&gt;&amp;gt; That's an invitation I extended during the presentation at the conference.
&lt;br&gt;&amp;gt; There are several people interested in getting the remaining needed
&lt;br&gt;&amp;gt; functionalities (downloadable files, premium content, others), and the model
&lt;br&gt;&amp;gt; we took in organizing this project originally (see Social Sourcing
&lt;br&gt;&amp;gt; presentation,www.ifpeople.net/solutions/social-sourcing) was about getting
&lt;br&gt;&amp;gt; people involved upfront in a round of changes. So yes, as you point out,
&lt;br&gt;&amp;gt; there was an original architect who is no longer active in the project. But,
&lt;br&gt;&amp;gt; of the other sponsors, supporters and contributors at the very outset of the
&lt;br&gt;&amp;gt; project, about 3/4 are still involved in the project in one way or another,
&lt;br&gt;&amp;gt; which gives us a solid basis of community around GetPaid. Now it's time to
&lt;br&gt;&amp;gt; get the community involved in actively shaping the future again.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; In doing this, I'm willing to help transfer knowledge I have about the
&lt;br&gt;&amp;gt; product to those who want to take a role in the community. Also, I think it
&lt;br&gt;&amp;gt; would be great to have a collaborative design process at this point, as we
&lt;br&gt;&amp;gt; did originally, so the new people involved in GetPaid can shape where the
&lt;br&gt;&amp;gt; product is going. I'm willing to help those involved in this also, and if
&lt;br&gt;&amp;gt; needed, to raise additional funds for the buildout of features/refactoring
&lt;br&gt;&amp;gt; for GetPaid.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; With the knowledge of our community, we should be able to unlock the good
&lt;br&gt;&amp;gt; stuff in GetPaid and make it much more accessible for those using the
&lt;br&gt;&amp;gt; system.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; Best wishes,
&lt;br&gt;&amp;gt; Chris
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; On Sat, Nov 14, 2009 at 9:18 PM, Moo &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26379381&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;mi...@...&lt;/a&gt;&amp;gt; wrote:
&lt;br&gt;&amp;gt; &amp;gt; Hi,
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; I participated the GetPaid sprint in Budapest. There were some worries
&lt;br&gt;&amp;gt; &amp;gt; among the participants for which I have ginve thoughts afterwards.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; Many people would love to use GetPaid for creating shops, but it won't
&lt;br&gt;&amp;gt; &amp;gt; do it.
&lt;br&gt;&amp;gt; &amp;gt; Currently there are huge gaps within the code (payment processors,
&lt;br&gt;&amp;gt; &amp;gt; taxes, variant items, architecture limitations) which are necessities
&lt;br&gt;&amp;gt; &amp;gt; for a basic shop functionality. If you want to use GetPaid, be
&lt;br&gt;&amp;gt; &amp;gt; prepared to spent countless of hours writing everything from scratch
&lt;br&gt;&amp;gt; &amp;gt; and &amp;quot;fight against the framework&amp;quot;.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; Until we have a solid working shop platform I suggest not mentioning
&lt;br&gt;&amp;gt; &amp;gt; &amp;quot;shop&amp;quot; onwww.plonegetpaid.comand actually tell the people to seek
&lt;br&gt;&amp;gt; &amp;gt; help from Python shopping products.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; Also, GetPaid future does not look very bright. Since the orignal work
&lt;br&gt;&amp;gt; &amp;gt; was sponsored, the orignal authors have not been very activate with
&lt;br&gt;&amp;gt; &amp;gt; the community. With the current state of the code it is hard to get
&lt;br&gt;&amp;gt; &amp;gt; anything done unless you have years of Plone experience. Most users
&lt;br&gt;&amp;gt; &amp;gt; who would like to use or develop GetPaid don't necessarily have this.
&lt;br&gt;&amp;gt; &amp;gt; They might try and get frustrated after couple of hours.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; There is also lack of release manager or trunk maintainer. There is no
&lt;br&gt;&amp;gt; &amp;gt; one &amp;quot;in control&amp;quot; and people may or may not commit something into
&lt;br&gt;&amp;gt; &amp;gt; trunk. The vision and active maintenance is missing. There is no
&lt;br&gt;&amp;gt; &amp;gt; roadmap. There is no committed maintainers. This kind of organization
&lt;br&gt;&amp;gt; &amp;gt; may fit for small static components like most of those in Plone
&lt;br&gt;&amp;gt; &amp;gt; collective, but it definite doesn't seem to work with GetPaid.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; So, should people looking for shopping products abandon GetPaid in
&lt;br&gt;&amp;gt; &amp;gt; favour of other solutions? There is so much good work in GetPaid, but
&lt;br&gt;&amp;gt; &amp;gt; it is so hard to get anything out of it.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; -Mikko
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; --
&lt;br&gt;&amp;gt; &amp;gt; GetPaid for Plone:&lt;a href=&quot;http://www.plonegetpaid.com(overview&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com(overview&lt;/a&gt;&amp;nbsp;info) |
&lt;br&gt;&amp;gt; &amp;gt;&lt;a href=&quot;http://code.google.com/p/getpaid(code&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid(code&lt;/a&gt;&amp;nbsp;and issue tracker)
&lt;br&gt;&amp;gt; &amp;gt; You received this message because you are subscribed to the Google Groups
&lt;br&gt;&amp;gt; &amp;gt; &amp;quot;getpaid-dev&amp;quot; group.
&lt;br&gt;&amp;gt; &amp;gt; To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26379381&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
&lt;br&gt;&amp;gt; &amp;gt; To unsubscribe from this group, send email to
&lt;br&gt;&amp;gt; &amp;gt; &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26379381&amp;i=3&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;&amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26379381&amp;i=4&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev%2Bunsubscribe@...&lt;/a&gt;&amp;gt;
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; For more options, visit this group at
&lt;br&gt;&amp;gt; &amp;gt;&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; --
&lt;br&gt;&amp;gt; Cofounder and CEO
&lt;br&gt;&amp;gt; ifPeople - Innovation for Peoplewww.ifpeople.net
&lt;br&gt;&amp;gt; t: 678-608-3408
&lt;br&gt;&amp;gt; 130 Boulevard NE, #6
&lt;br&gt;&amp;gt; Atlanta, GA 30312
&lt;/div&gt;&lt;br&gt;-- 
&lt;br&gt;GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt;&amp;nbsp;(overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt;&amp;nbsp;(code and issue tracker)
&lt;br&gt;You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
&lt;br&gt;To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26379381&amp;i=5&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
&lt;br&gt;To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26379381&amp;i=6&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
&lt;br&gt;&lt;br&gt;For more options, visit this group at
&lt;br&gt;&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/The-future-of-GetPaid--tp26355889p26379381.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26377071</id>
	<title>Re: The future of GetPaid?</title>
	<published>2009-11-16T10:32:56Z</published>
	<updated>2009-11-16T10:32:56Z</updated>
	<author>
		<name>Christopher Johnson-7</name>
	</author>
	<content type="html">Hi Mikko,&lt;br&gt;&lt;br&gt;Thanks for sharing your notes after the conference and sprint. Certainly some of the points you mention are an accurate description of the current state of GetPaid (ie there is no product manager now), but I think your characterization of GetPaid&amp;#39;s viable underestimates both the product and the people in the community and I wanted to respond and provide some of the information that was shared in the conference presentation as well. &lt;br&gt;
&lt;br&gt;One thing to clarify though about the purpose of the project - GetPaid isn&amp;#39;t meant to attract ecommerce people to using Plone. It&amp;#39;s meant to keep people from leaving Plone because they have ecommerce needs. This was what drove the origin of the project and I think today is still relevant. If people want only ecommerce and don&amp;#39;t care about all the power Plone brings, there&amp;#39;s little reason they should use GetPaid. &lt;br&gt;
&lt;br&gt;The architecture does have a fairly high barrier to entry for developers. In part, because it was created as a zope3 product in the very early days of zope3 products for Plone. So a python programmer with no Plone knowledge will have to ramp up on some technologies before being able to customize it. I think this can be said about Plone in general these days also. &lt;br&gt;
&lt;br&gt;But, that depends on how you want to customize it...there are many things that are fairly straight forward to do. If that weren&amp;#39;t the case, we wouldn&amp;#39;t have had such huge growth in add ons for the product and payment processors over the last year (over twice as much code overall and over twice as many payment processors). And most of the time, that&amp;#39;s what someone implementing a site needs to do. &lt;br&gt;
&lt;br&gt;There are several sites that have been launched with GetPaid already. About two dozen are listed at &lt;a href=&quot;http://www.plonegetpaid.com/why/sites-using-getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com/why/sites-using-getpaid&lt;/a&gt; .  Some are just &amp;quot;out of the box&amp;quot; GetPaid and work well for the client as is, some are customized (and many of the docs about how to achieve the customizations shown are linked to in the presentation I gave at the ploneconf2009: &lt;a href=&quot;http://snurl.com/getpaid-slides&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://snurl.com/getpaid-slides&lt;/a&gt; ). &lt;br&gt;
&lt;br&gt;Regarding people who are playing roles to maintain the product, GetPaid has gone through a period of activity and evolution, several releases. Unfortunately, I left some of this story out of the presentation in Budapest. Perrito (Horacio Duran) has managed a release (0.6.2, I believe) and Lucie at SIx Feet Up has managed releases over the 0.7 series of PloneGetPaid, and David Glick from Groundwire has been involved since ~0.8. These are all people in the Plone community who are/were involved over a period when they were using GetPaid and were working to make it better for their needs. I&amp;#39;m hoping that is what we are starting again as a community. &lt;br&gt;
&lt;br&gt;The project is now in a period where we need new people with interest in ecommerce in Plone to step up and lead in various aspects of the project. That&amp;#39;s an invitation I extended during the presentation at the conference. There are several people interested in getting the remaining needed functionalities (downloadable files, premium content, others), and the model we took in organizing this project originally (see Social Sourcing presentation, &lt;a href=&quot;http://www.ifpeople.net/solutions/social-sourcing&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;www.ifpeople.net/solutions/social-sourcing&lt;/a&gt; ) was about getting people involved upfront in a round of changes. So yes, as you point out, there was an original architect who is no longer active in the project. But, of the other sponsors, supporters and contributors at the very outset of the project, about 3/4 are still involved in the project in one way or another, which gives us a solid basis of community around GetPaid. Now it&amp;#39;s time to get the community involved in actively shaping the future again. &lt;br&gt;
&lt;br&gt;In doing this, I&amp;#39;m willing to help transfer knowledge I have about the product to those who want to take a role in the community. Also, I think it would be great to have a collaborative design process at this point, as we did originally, so the new people involved in GetPaid can shape where the product is going. I&amp;#39;m willing to help those involved in this also, and if needed, to raise additional funds for the buildout of features/refactoring for GetPaid. &lt;br&gt;
&lt;br&gt;With the knowledge of our community, we should be able to unlock the good stuff in GetPaid and make it much more accessible for those using the system. &lt;br&gt;&lt;br&gt;Best wishes,&lt;br&gt;Chris&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;div class=&quot;gmail_quote&quot;&gt;
On Sat, Nov 14, 2009 at 9:18 PM, Moo &lt;span dir=&quot;ltr&quot;&gt;&amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26377071&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;mikko@...&lt;/a&gt;&amp;gt;&lt;/span&gt; wrote:&lt;br&gt;&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;&quot;&gt;
Hi,&lt;br&gt;
&lt;br&gt;
I participated the GetPaid sprint in Budapest. There were some worries&lt;br&gt;
among the participants for which I have ginve thoughts afterwards.&lt;br&gt;
&lt;br&gt;
Many people would love to use GetPaid for creating shops, but it won&amp;#39;t&lt;br&gt;
do it.&lt;br&gt;
Currently there are huge gaps within the code (payment processors,&lt;br&gt;
taxes, variant items, architecture limitations) which are necessities&lt;br&gt;
for a basic shop functionality. If you want to use GetPaid, be&lt;br&gt;
prepared to spent countless of hours writing everything from scratch&lt;br&gt;
and &amp;quot;fight against the framework&amp;quot;.&lt;br&gt;
&lt;br&gt;
Until we have a solid working shop platform I suggest not mentioning&lt;br&gt;
&amp;quot;shop&amp;quot; on &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;www.plonegetpaid.com&lt;/a&gt; and actually tell the people to seek&lt;br&gt;
help from Python shopping products.&lt;br&gt;
&lt;br&gt;
Also, GetPaid future does not look very bright. Since the orignal work&lt;br&gt;
was sponsored, the orignal authors have not been very activate with&lt;br&gt;
the community. With the current state of the code it is hard to get&lt;br&gt;
anything done unless you have years of Plone experience. Most users&lt;br&gt;
who would like to use or develop GetPaid don&amp;#39;t necessarily have this.&lt;br&gt;
They might try and get frustrated after couple of hours.&lt;br&gt;
&lt;br&gt;
There is also lack of release manager or trunk maintainer. There is no&lt;br&gt;
one &amp;quot;in control&amp;quot; and people may or may not commit something into&lt;br&gt;
trunk. The vision and active maintenance is missing. There is no&lt;br&gt;
roadmap. There is no committed maintainers. This kind of organization&lt;br&gt;
may fit for small static components like most of those in Plone&lt;br&gt;
collective, but it definite doesn&amp;#39;t seem to work with GetPaid.&lt;br&gt;
&lt;br&gt;
So, should people looking for shopping products abandon GetPaid in&lt;br&gt;
favour of other solutions? There is so much good work in GetPaid, but&lt;br&gt;
it is so hard to get anything out of it.&lt;br&gt;
&lt;br&gt;
-Mikko&lt;br&gt;
&lt;font color=&quot;#888888&quot;&gt;&lt;br&gt;
--&lt;br&gt;
GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt; (overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt; (code and issue tracker)&lt;br&gt;

You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.&lt;br&gt;
To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26377071&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;&lt;br&gt;
To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26377071&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev%2Bunsubscribe@...&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
For more options, visit this group at&lt;br&gt;
&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;/font&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;br&gt;&lt;br clear=&quot;all&quot;&gt;&lt;br&gt;-- &lt;br&gt;Cofounder and CEO&lt;br&gt;ifPeople - Innovation for People&lt;br&gt;
&lt;a href=&quot;http://www.ifpeople.net&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;www.ifpeople.net&lt;/a&gt;&lt;br&gt;t: 678-608-3408&lt;br&gt;130 Boulevard NE, #6&lt;br&gt;Atlanta, GA 30312&lt;br&gt;

&lt;p&gt;&lt;/p&gt;

-- &lt;br /&gt;
GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt; (overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt; (code and issue tracker)&lt;br /&gt;
You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.&lt;br /&gt;
To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26377071&amp;i=3&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;&lt;br /&gt;
To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26377071&amp;i=4&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;&lt;br /&gt;
&amp;nbsp;&lt;br /&gt;
For more options, visit this group at&lt;br /&gt;
&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/The-future-of-GetPaid--tp26355889p26377071.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26376192</id>
	<title>Re: Taxes implementation ready to be merged</title>
	<published>2009-11-16T09:39:17Z</published>
	<updated>2009-11-16T09:39:17Z</updated>
	<author>
		<name>Christopher Johnson-7</name>
	</author>
	<content type="html">Hi Mikko,&lt;br&gt;&lt;br&gt;Thanks for the notes and the work on getting taxes working! &lt;br&gt;&lt;br&gt;I just wanted to get clarification on your email. The subject said the work was ready to merge, but the text said you have not implemented taxes. It looks from your notes that it is ready, so I just wanted to clarify. &lt;br&gt;
&lt;br&gt;With what you have done, how does someone create a new tax configuration (ie for another country, or for a state within a country)? &lt;br&gt;&lt;br&gt;Thanks again,&lt;br&gt;&lt;br&gt;Chris&lt;br&gt;&lt;br&gt;&lt;div class=&quot;gmail_quote&quot;&gt;On Sat, Nov 14, 2009 at 9:43 PM, Moo &lt;span dir=&quot;ltr&quot;&gt;&amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26376192&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;mikko@...&lt;/a&gt;&amp;gt;&lt;/span&gt; wrote:&lt;br&gt;
&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;&quot;&gt;Hi,&lt;br&gt;
&lt;br&gt;
I have not implemented working salex tax implementation for GetPaid.&lt;br&gt;
It will work in both United States and Europe.&lt;br&gt;
&lt;br&gt;
Below are notes. Updates notes txt available here for the future&lt;br&gt;
readers:&lt;br&gt;
&lt;br&gt;
&lt;a href=&quot;https://getpaid.googlecode.com/svn/Products.PloneGetPaid/branches/miohtama-taxes/Products/PloneGetPaid/docs/taxes_and_prices.txt&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;https://getpaid.googlecode.com/svn/Products.PloneGetPaid/branches/miohtama-taxes/Products/PloneGetPaid/docs/taxes_and_prices.txt&lt;/a&gt;&lt;br&gt;

&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
Taxes and prices&lt;br&gt;
----------------&lt;br&gt;
&lt;br&gt;
Problem: Depending on the country sales taxes may be included in the&lt;br&gt;
store prices or they&lt;br&gt;
may be applied to the total on the checkout.&lt;br&gt;
&lt;br&gt;
* In Scandinavia sales taxes are included in the consumer visible&lt;br&gt;
prices&lt;br&gt;
&lt;br&gt;
* In US sales taxes depend on the state and are applied on the&lt;br&gt;
checkout&lt;br&gt;
&lt;br&gt;
To support both behaviors GetPaid must be sales tax aware&lt;br&gt;
&lt;br&gt;
* How store owner manages taxes internally: are they put in the price&lt;br&gt;
data or should system calculate them afterwards&lt;br&gt;
&lt;br&gt;
* How consumer sees the prices: does the price tag contain taxes or&lt;br&gt;
not&lt;br&gt;
&lt;br&gt;
getpaid.core.interfaces.IPriceValueAdjuster is an utility to tackle&lt;br&gt;
this problem.&lt;br&gt;
It provides methods&lt;br&gt;
&lt;br&gt;
* To get tax and tax free prices&lt;br&gt;
&lt;br&gt;
* To get user visible prices&lt;br&gt;
&lt;br&gt;
* Extendable tax behavior: subclass and override this utility to have&lt;br&gt;
custom tax algorithms&lt;br&gt;
&lt;br&gt;
* Different taxes for different item categories: line item and content&lt;br&gt;
item adapters can be used&lt;br&gt;
  to return item specific tax percent&lt;br&gt;
&lt;br&gt;
Where should be used&lt;br&gt;
--------------------&lt;br&gt;
&lt;br&gt;
* When totals are queried: CartTotals, checkout&lt;br&gt;
&lt;br&gt;
* When item prices are displayed: portlets, page templates&lt;br&gt;
&lt;br&gt;
* When invoice or recipient is generated&lt;br&gt;
&lt;br&gt;
Products.PloneGetPaid.price module contains documentation how to use&lt;br&gt;
IPriceValueAdjuster.&lt;br&gt;
&lt;br&gt;
Backward incompatible changes&lt;br&gt;
-----------------------------&lt;br&gt;
&lt;br&gt;
The following backward incompatible changes have been made:&lt;br&gt;
&lt;br&gt;
* Querying ILineContainerTotals utility needs to have&lt;br&gt;
IPriceValueAdjuster argument&lt;br&gt;
&lt;br&gt;
* Remove of getpaid.core.tax.TaxUtility&lt;br&gt;
&lt;br&gt;
Code migration examples are available in Products.PloneGetPaid.price&lt;br&gt;
module.&lt;br&gt;
&lt;br&gt;
Necessary changes have been made to most of the parts of PloneGetPaid&lt;br&gt;
and getpaid.core.&lt;br&gt;
Some use cases might have slipped under the radar.&lt;br&gt;
&lt;br&gt;
This work deals with sales tax only. getpaid.core support multiple tax&lt;br&gt;
bases somehow.&lt;br&gt;
getpaid.core.tax.TaxUtility and getpaid.core.interfaces.ITaxUtility&lt;br&gt;
have been&lt;br&gt;
removed, since they had no working implementations. getpaid.core.cart&lt;br&gt;
uses now IPriceValueAdjuster directly. If one wants to support various&lt;br&gt;
taxes&lt;br&gt;
with getpaid.core it would need serious changes to user interface and&lt;br&gt;
GetPaid subsystems&lt;br&gt;
in any case.&lt;br&gt;
&lt;br&gt;
Discussion&lt;br&gt;
----------&lt;br&gt;
&lt;br&gt;
The serious problem is that getpaid.core.order.Order class exposes&lt;br&gt;
getTotal()&lt;br&gt;
by directly inhering from CartItemTotals. It should not do this.&lt;br&gt;
&lt;br&gt;
* When using getTotals() etc. functionality the site context is&lt;br&gt;
available and&lt;br&gt;
  you cannot access such values as the current tax settings&lt;br&gt;
&lt;br&gt;
* Currently you need to resort zope.app.component.hooks.getSite hack&lt;br&gt;
to&lt;br&gt;
  have context inside tese functions.&lt;br&gt;
&lt;br&gt;
I suggest deprecating getTotals() and CartItemTotals totally.&lt;br&gt;
They should be replaced with site-aware adapters which can access&lt;br&gt;
context data.&lt;br&gt;
&lt;br&gt;
Also, when the order is create at least the following data&lt;br&gt;
should be copied to the order to make orders future proof&lt;br&gt;
&lt;br&gt;
* Used taxes&lt;br&gt;
&lt;br&gt;
* Item price as taxed, tax free and taxes applied to item&lt;br&gt;
&lt;br&gt;
Work available&lt;br&gt;
--------------&lt;br&gt;
&lt;br&gt;
2009/11: Available in getpaid.core and Products.PloneGetPaid miohtama-&lt;br&gt;
taxes branch.&lt;br&gt;
Branch is based on brandon-no-overrides branch.&lt;br&gt;
&lt;br&gt;
Files touched&lt;br&gt;
&lt;br&gt;
* getpaid.core.interfaces&lt;br&gt;
&lt;br&gt;
* getpaid.core.cart&lt;br&gt;
&lt;br&gt;
* Products.PloneGetPaid.interfaces&lt;br&gt;
&lt;br&gt;
* Products.PloneGetPaid.price&lt;br&gt;
&lt;br&gt;
* Products.PloneGetPaid.tests.base&lt;br&gt;
&lt;br&gt;
* Products.PloneGetPaid.tests.test_taxes_and_prices&lt;br&gt;
&lt;br&gt;
* Products.PloneGetPaid.browser.cart&lt;br&gt;
&lt;br&gt;
*&lt;br&gt;
&lt;font color=&quot;#888888&quot;&gt;&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
--&lt;br&gt;
GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt; (overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt; (code and issue tracker)&lt;br&gt;

You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.&lt;br&gt;
To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26376192&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;&lt;br&gt;
To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26376192&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev%2Bunsubscribe@...&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
For more options, visit this group at&lt;br&gt;
&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;/font&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;br&gt;&lt;br clear=&quot;all&quot;&gt;&lt;br&gt;-- &lt;br&gt;Cofounder and CEO&lt;br&gt;ifPeople - Innovation for People&lt;br&gt;
&lt;a href=&quot;http://www.ifpeople.net&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;www.ifpeople.net&lt;/a&gt;&lt;br&gt;t: 678-608-3408&lt;br&gt;130 Boulevard NE, #6&lt;br&gt;Atlanta, GA 30312&lt;br&gt;

&lt;p&gt;&lt;/p&gt;

-- &lt;br /&gt;
GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt; (overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt; (code and issue tracker)&lt;br /&gt;
You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.&lt;br /&gt;
To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26376192&amp;i=3&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;&lt;br /&gt;
To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26376192&amp;i=4&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;&lt;br /&gt;
&amp;nbsp;&lt;br /&gt;
For more options, visit this group at&lt;br /&gt;
&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Taxes-implementation-ready-to-be-merged-tp26355990p26376192.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26358279</id>
	<title>Re: Reviewed Brandon's work: some suggestions</title>
	<published>2009-11-15T03:24:25Z</published>
	<updated>2009-11-15T03:24:25Z</updated>
	<author>
		<name>Mikko Ohtamaa</name>
	</author>
	<content type="html">More issues:
&lt;br&gt;&lt;br&gt;One cannot present paymeny processor options as a schema reference
&lt;br&gt;(options_interface). They payment processor must be able to customize
&lt;br&gt;its own form view as zope.schema cannot be used to express all form
&lt;br&gt;use cases (custom widgets and so on...).
&lt;br&gt;&lt;br&gt;-Mikko
&lt;br&gt;&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; I just went through Brandon's work. Looks nice to me, though there are
&lt;br&gt;&amp;gt; some show stopping issues.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; The offsite payment processor interface was empty. It is very
&lt;br&gt;&amp;gt; difficult for third parties to implement payment processor unless
&lt;br&gt;&amp;gt; interfaces are documented with the required precision.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; If I read the core correctly there can be just one on-site payment
&lt;br&gt;&amp;gt; processor. Also, the wizard step to choose payment processor is
&lt;br&gt;&amp;gt; missing.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; As is, this work is useless for many use cases, like
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; * Having a wire payment processor
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; * Choose between credit card and wire payment
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; * Choose between different on-sites processors (imagine different
&lt;br&gt;&amp;gt; processor for different credit cards)
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; What's the status of the future of Brandon's work? In
&lt;br&gt;&amp;gt; multiplepaymentprocessor support for these use cases exist.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; I am willing to help to merge multiplepaymentprocessor branch with
&lt;br&gt;&amp;gt; brandon and brandon branch with trunk if
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; 1) Community &amp;quot;decision making process&amp;quot; sees this as a necessary
&lt;br&gt;&amp;gt; requirement for the future
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; 2) There is someone else willing to put hours on the issue
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; -Mikko
&lt;/div&gt;&lt;br&gt;-- 
&lt;br&gt;GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt;&amp;nbsp;(overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt;&amp;nbsp;(code and issue tracker)
&lt;br&gt;You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
&lt;br&gt;To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26358279&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
&lt;br&gt;To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26358279&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
&lt;br&gt;&lt;br&gt;For more options, visit this group at
&lt;br&gt;&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Reviewed-Brandon%27s-work%3A-some-suggestions-tp26355777p26358279.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26355990</id>
	<title>Taxes implementation ready to be merged</title>
	<published>2009-11-14T18:43:12Z</published>
	<updated>2009-11-14T18:43:12Z</updated>
	<author>
		<name>Mikko Ohtamaa</name>
	</author>
	<content type="html">Hi,
&lt;br&gt;&lt;br&gt;I have not implemented working salex tax implementation for GetPaid.
&lt;br&gt;It will work in both United States and Europe.
&lt;br&gt;&lt;br&gt;Below are notes. Updates notes txt available here for the future
&lt;br&gt;readers:
&lt;br&gt;&lt;br&gt;&lt;a href=&quot;https://getpaid.googlecode.com/svn/Products.PloneGetPaid/branches/miohtama-taxes/Products/PloneGetPaid/docs/taxes_and_prices.txt&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://getpaid.googlecode.com/svn/Products.PloneGetPaid/branches/miohtama-taxes/Products/PloneGetPaid/docs/taxes_and_prices.txt&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;Taxes and prices
&lt;br&gt;----------------
&lt;br&gt;&lt;br&gt;Problem: Depending on the country sales taxes may be included in the
&lt;br&gt;store prices or they
&lt;br&gt;may be applied to the total on the checkout.
&lt;br&gt;&lt;br&gt;* In Scandinavia sales taxes are included in the consumer visible
&lt;br&gt;prices
&lt;br&gt;&lt;br&gt;* In US sales taxes depend on the state and are applied on the
&lt;br&gt;checkout
&lt;br&gt;&lt;br&gt;To support both behaviors GetPaid must be sales tax aware
&lt;br&gt;&lt;br&gt;* How store owner manages taxes internally: are they put in the price
&lt;br&gt;data or should system calculate them afterwards
&lt;br&gt;&lt;br&gt;* How consumer sees the prices: does the price tag contain taxes or
&lt;br&gt;not
&lt;br&gt;&lt;br&gt;getpaid.core.interfaces.IPriceValueAdjuster is an utility to tackle
&lt;br&gt;this problem.
&lt;br&gt;It provides methods
&lt;br&gt;&lt;br&gt;* To get tax and tax free prices
&lt;br&gt;&lt;br&gt;* To get user visible prices
&lt;br&gt;&lt;br&gt;* Extendable tax behavior: subclass and override this utility to have
&lt;br&gt;custom tax algorithms
&lt;br&gt;&lt;br&gt;* Different taxes for different item categories: line item and content
&lt;br&gt;item adapters can be used
&lt;br&gt;&amp;nbsp; to return item specific tax percent
&lt;br&gt;&lt;br&gt;Where should be used
&lt;br&gt;--------------------
&lt;br&gt;&lt;br&gt;* When totals are queried: CartTotals, checkout
&lt;br&gt;&lt;br&gt;* When item prices are displayed: portlets, page templates
&lt;br&gt;&lt;br&gt;* When invoice or recipient is generated
&lt;br&gt;&lt;br&gt;Products.PloneGetPaid.price module contains documentation how to use
&lt;br&gt;IPriceValueAdjuster.
&lt;br&gt;&lt;br&gt;Backward incompatible changes
&lt;br&gt;-----------------------------
&lt;br&gt;&lt;br&gt;The following backward incompatible changes have been made:
&lt;br&gt;&lt;br&gt;* Querying ILineContainerTotals utility needs to have
&lt;br&gt;IPriceValueAdjuster argument
&lt;br&gt;&lt;br&gt;* Remove of getpaid.core.tax.TaxUtility
&lt;br&gt;&lt;br&gt;Code migration examples are available in Products.PloneGetPaid.price
&lt;br&gt;module.
&lt;br&gt;&lt;br&gt;Necessary changes have been made to most of the parts of PloneGetPaid
&lt;br&gt;and getpaid.core.
&lt;br&gt;Some use cases might have slipped under the radar.
&lt;br&gt;&lt;br&gt;This work deals with sales tax only. getpaid.core support multiple tax
&lt;br&gt;bases somehow.
&lt;br&gt;getpaid.core.tax.TaxUtility and getpaid.core.interfaces.ITaxUtility
&lt;br&gt;have been
&lt;br&gt;removed, since they had no working implementations. getpaid.core.cart
&lt;br&gt;uses now IPriceValueAdjuster directly. If one wants to support various
&lt;br&gt;taxes
&lt;br&gt;with getpaid.core it would need serious changes to user interface and
&lt;br&gt;GetPaid subsystems
&lt;br&gt;in any case.
&lt;br&gt;&lt;br&gt;Discussion
&lt;br&gt;----------
&lt;br&gt;&lt;br&gt;The serious problem is that getpaid.core.order.Order class exposes
&lt;br&gt;getTotal()
&lt;br&gt;by directly inhering from CartItemTotals. It should not do this.
&lt;br&gt;&lt;br&gt;* When using getTotals() etc. functionality the site context is
&lt;br&gt;available and
&lt;br&gt;&amp;nbsp; you cannot access such values as the current tax settings
&lt;br&gt;&lt;br&gt;* Currently you need to resort zope.app.component.hooks.getSite hack
&lt;br&gt;to
&lt;br&gt;&amp;nbsp; have context inside tese functions.
&lt;br&gt;&lt;br&gt;I suggest deprecating getTotals() and CartItemTotals totally.
&lt;br&gt;They should be replaced with site-aware adapters which can access
&lt;br&gt;context data.
&lt;br&gt;&lt;br&gt;Also, when the order is create at least the following data
&lt;br&gt;should be copied to the order to make orders future proof
&lt;br&gt;&lt;br&gt;* Used taxes
&lt;br&gt;&lt;br&gt;* Item price as taxed, tax free and taxes applied to item
&lt;br&gt;&lt;br&gt;Work available
&lt;br&gt;--------------
&lt;br&gt;&lt;br&gt;2009/11: Available in getpaid.core and Products.PloneGetPaid miohtama-
&lt;br&gt;taxes branch.
&lt;br&gt;Branch is based on brandon-no-overrides branch.
&lt;br&gt;&lt;br&gt;Files touched
&lt;br&gt;&lt;br&gt;* getpaid.core.interfaces
&lt;br&gt;&lt;br&gt;* getpaid.core.cart
&lt;br&gt;&lt;br&gt;* Products.PloneGetPaid.interfaces
&lt;br&gt;&lt;br&gt;* Products.PloneGetPaid.price
&lt;br&gt;&lt;br&gt;* Products.PloneGetPaid.tests.base
&lt;br&gt;&lt;br&gt;* Products.PloneGetPaid.tests.test_taxes_and_prices
&lt;br&gt;&lt;br&gt;* Products.PloneGetPaid.browser.cart
&lt;br&gt;&lt;br&gt;*
&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt;&amp;nbsp;(overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt;&amp;nbsp;(code and issue tracker)
&lt;br&gt;You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
&lt;br&gt;To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26355990&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
&lt;br&gt;To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26355990&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
&lt;br&gt;&lt;br&gt;For more options, visit this group at
&lt;br&gt;&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Taxes-implementation-ready-to-be-merged-tp26355990p26355990.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26355889</id>
	<title>The future of GetPaid?</title>
	<published>2009-11-14T18:18:42Z</published>
	<updated>2009-11-14T18:18:42Z</updated>
	<author>
		<name>Mikko Ohtamaa</name>
	</author>
	<content type="html">Hi,
&lt;br&gt;&lt;br&gt;I participated the GetPaid sprint in Budapest. There were some worries
&lt;br&gt;among the participants for which I have ginve thoughts afterwards.
&lt;br&gt;&lt;br&gt;Many people would love to use GetPaid for creating shops, but it won't
&lt;br&gt;do it.
&lt;br&gt;Currently there are huge gaps within the code (payment processors,
&lt;br&gt;taxes, variant items, architecture limitations) which are necessities
&lt;br&gt;for a basic shop functionality. If you want to use GetPaid, be
&lt;br&gt;prepared to spent countless of hours writing everything from scratch
&lt;br&gt;and &amp;quot;fight against the framework&amp;quot;.
&lt;br&gt;&lt;br&gt;Until we have a solid working shop platform I suggest not mentioning
&lt;br&gt;&amp;quot;shop&amp;quot; on www.plonegetpaid.com and actually tell the people to seek
&lt;br&gt;help from Python shopping products.
&lt;br&gt;&lt;br&gt;Also, GetPaid future does not look very bright. Since the orignal work
&lt;br&gt;was sponsored, the orignal authors have not been very activate with
&lt;br&gt;the community. With the current state of the code it is hard to get
&lt;br&gt;anything done unless you have years of Plone experience. Most users
&lt;br&gt;who would like to use or develop GetPaid don't necessarily have this.
&lt;br&gt;They might try and get frustrated after couple of hours.
&lt;br&gt;&lt;br&gt;There is also lack of release manager or trunk maintainer. There is no
&lt;br&gt;one &amp;quot;in control&amp;quot; and people may or may not commit something into
&lt;br&gt;trunk. The vision and active maintenance is missing. There is no
&lt;br&gt;roadmap. There is no committed maintainers. This kind of organization
&lt;br&gt;may fit for small static components like most of those in Plone
&lt;br&gt;collective, but it definite doesn't seem to work with GetPaid.
&lt;br&gt;&lt;br&gt;So, should people looking for shopping products abandon GetPaid in
&lt;br&gt;favour of other solutions? There is so much good work in GetPaid, but
&lt;br&gt;it is so hard to get anything out of it.
&lt;br&gt;&lt;br&gt;-Mikko
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt;&amp;nbsp;(overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt;&amp;nbsp;(code and issue tracker)
&lt;br&gt;You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
&lt;br&gt;To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26355889&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
&lt;br&gt;To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26355889&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
&lt;br&gt;&lt;br&gt;For more options, visit this group at
&lt;br&gt;&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/The-future-of-GetPaid--tp26355889p26355889.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26355777</id>
	<title>Reviewed Brandon's work: some suggestions</title>
	<published>2009-11-14T17:59:41Z</published>
	<updated>2009-11-14T17:59:41Z</updated>
	<author>
		<name>Mikko Ohtamaa</name>
	</author>
	<content type="html">Hi,
&lt;br&gt;&lt;br&gt;I just went through Brandon's work. Looks nice to me, though there are
&lt;br&gt;some show stopping issues.
&lt;br&gt;&lt;br&gt;The offsite payment processor interface was empty. It is very
&lt;br&gt;difficult for third parties to implement payment processor unless
&lt;br&gt;interfaces are documented with the required precision.
&lt;br&gt;&lt;br&gt;If I read the core correctly there can be just one on-site payment
&lt;br&gt;processor. Also, the wizard step to choose payment processor is
&lt;br&gt;missing.
&lt;br&gt;&lt;br&gt;As is, this work is useless for many use cases, like
&lt;br&gt;&lt;br&gt;* Having a wire payment processor
&lt;br&gt;&lt;br&gt;* Choose between credit card and wire payment
&lt;br&gt;&lt;br&gt;* Choose between different on-sites processors (imagine different
&lt;br&gt;processor for different credit cards)
&lt;br&gt;&lt;br&gt;What's the status of the future of Brandon's work? In
&lt;br&gt;multiplepaymentprocessor support for these use cases exist.
&lt;br&gt;&lt;br&gt;I am willing to help to merge multiplepaymentprocessor branch with
&lt;br&gt;brandon and brandon branch with trunk if
&lt;br&gt;&lt;br&gt;1) Community &amp;quot;decision making process&amp;quot; sees this as a necessary
&lt;br&gt;requirement for the future
&lt;br&gt;&lt;br&gt;2) There is someone else willing to put hours on the issue
&lt;br&gt;&lt;br&gt;-Mikko
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt;&amp;nbsp;(overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt;&amp;nbsp;(code and issue tracker)
&lt;br&gt;You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
&lt;br&gt;To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26355777&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
&lt;br&gt;To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26355777&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
&lt;br&gt;&lt;br&gt;For more options, visit this group at
&lt;br&gt;&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Reviewed-Brandon%27s-work%3A-some-suggestions-tp26355777p26355777.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26346919</id>
	<title>Re: Alternative Session Implementation</title>
	<published>2009-11-13T19:48:43Z</published>
	<updated>2009-11-13T19:48:43Z</updated>
	<author>
		<name>Matt Halstead-3</name>
	</author>
	<content type="html">&lt;br&gt;&lt;br&gt;On Nov 13, 9:45 pm, Silvio &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26346919&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;silv...@...&lt;/a&gt;&amp;gt; wrote:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; On Fri, Nov 13, 2009 at 8:24 AM, Matt Halstead &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26346919&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;matt.halst...@...&lt;/a&gt;&amp;gt;wrote:
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt;  &amp;gt; But it should be possible replace the local persistent utility with
&lt;br&gt;&amp;gt; &amp;gt; another
&lt;br&gt;&amp;gt; &amp;gt; &amp;gt; implementation that does the loads/dumps dance internaly and saves the
&lt;br&gt;&amp;gt; &amp;gt; &amp;gt; data somewhere else.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; Can you elaborate on why session storage needed to be reimplemented?
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; I can help about this. I had a conversation with Carsten and other people at
&lt;br&gt;&amp;gt; the sprint in Budapest. My point about issue 209 is that, even if it is now
&lt;br&gt;&amp;gt; resolved, it was initially caused by a bad design decision: storing carts in
&lt;br&gt;&amp;gt; a non persistent database. This decision makes anonymous customers lose
&lt;br&gt;&amp;gt; their carts when Zope (or zeo in a zeo cluster) is restarted; site owners
&lt;br&gt;&amp;gt; never want customers to lose their carts.
&lt;/div&gt;&lt;br&gt;I'd agree with that. They will lose their carts after the session time
&lt;br&gt;out, but at least that's a constant. I have a couple of questions
&lt;br&gt;about the proposed implementation:
&lt;br&gt;&lt;br&gt;should the session data container be configured with an explicit
&lt;br&gt;pkg_id so that we can control its settings just for the shop and not
&lt;br&gt;any other use of sessions?
&lt;br&gt;&lt;br&gt;should timeout and resolution be configurable through the web?
&lt;br&gt;&lt;br&gt;we should also create an upgrade step that:
&lt;br&gt;&lt;br&gt;1) calls register_session_data_utility( self ) from the Install.py so
&lt;br&gt;people don't have to do a full product reinstall to update the session
&lt;br&gt;management
&lt;br&gt;&lt;br&gt;2) identifies unusable carts in the _sessions persistent storage and
&lt;br&gt;removes them since these will still cause problems.
&lt;br&gt;&lt;br&gt;If this is the direction people want to head, I'd be quite keen to see
&lt;br&gt;this in action in the next few weeks. I don't mind making a test
&lt;br&gt;branch if you or Carsten don't have time.
&lt;br&gt;&lt;br&gt;&amp;gt; And the storage of carts in the
&lt;br&gt;&amp;gt; temporary zodb requires the loads/dumps dance that seems to be very
&lt;br&gt;&amp;gt; error-prone and leads to hard-to-trace bugs.
&lt;br&gt;&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;           Silvio
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt;&amp;nbsp;(overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt;&amp;nbsp;(code and issue tracker)
&lt;br&gt;You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
&lt;br&gt;To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26346919&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
&lt;br&gt;To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26346919&amp;i=3&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
&lt;br&gt;&lt;br&gt;For more options, visit this group at
&lt;br&gt;&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Alternative-Session-Implementation-tp26202777p26346919.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26344696</id>
	<title>Re: Alternative Session Implementation</title>
	<published>2009-11-13T14:41:43Z</published>
	<updated>2009-11-13T14:41:43Z</updated>
	<author>
		<name>Mikko Ohtamaa</name>
	</author>
	<content type="html">&lt;br&gt;
&lt;div class=&quot;gmail_quote&quot;&gt;&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;&quot;&gt;FWIW - independent of the functional use case in discussion here -&lt;br&gt;
ZODB 3.9 has an option which can be used to prevent cross database&lt;br&gt;
references from being created in the first place.&lt;br&gt;
allow-implicit-cross-references. So that these kinds of bugs become&lt;br&gt;
trivial to trace.&lt;br&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;In the other news Plone 3 won&amp;#39;t be running on ZODB 3.9 because ZODB has been changed too much between versions. So monkey-patch is way to go.&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;&quot;&gt;

&lt;br&gt;
Here is patch that enables the same functionality for ZODB 3.8&lt;br&gt;
&lt;a href=&quot;http://code.google.com/p/getpaid/issues/detail?id=209#c52&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid/issues/detail?id=209#c52&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
--&lt;br&gt;
&lt;font color=&quot;#888888&quot;&gt;Michael Dunstan&lt;br&gt;
&lt;/font&gt;&lt;div&gt;&lt;div class=&quot;h5&quot;&gt;&lt;br&gt;
--&lt;br&gt;
GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt; (overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt; (code and issue tracker)&lt;br&gt;

You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.&lt;br&gt;
To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26344696&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;&lt;br&gt;
To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26344696&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev%2Bunsubscribe@...&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
For more options, visit this group at&lt;br&gt;
&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;br&gt;&lt;br clear=&quot;all&quot;&gt;&lt;br&gt;-- &lt;br&gt;Mikko Ohtamaa&lt;br&gt;Managing director, Red Innovation Ltd.&lt;br&gt;+358 40 743 9707&lt;br&gt;&lt;a href=&quot;http://www.redinnovation.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;www.redinnovation.com&lt;/a&gt;&lt;br&gt;Every problem is solvable if you can throw enough energy drinks at it&lt;br&gt;

&lt;p&gt;&lt;/p&gt;

-- &lt;br /&gt;
GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt; (overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt; (code and issue tracker)&lt;br /&gt;
You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.&lt;br /&gt;
To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26344696&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;&lt;br /&gt;
To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26344696&amp;i=3&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;&lt;br /&gt;
&amp;nbsp;&lt;br /&gt;
For more options, visit this group at&lt;br /&gt;
&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Alternative-Session-Implementation-tp26202777p26344696.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26343538</id>
	<title>Re: Alternative Session Implementation</title>
	<published>2009-11-13T13:05:25Z</published>
	<updated>2009-11-13T13:05:25Z</updated>
	<author>
		<name>Michael Dunstan</name>
	</author>
	<content type="html">On Fri, Nov 13, 2009 at 9:45 PM, Silvio &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26343538&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;silviot@...&lt;/a&gt;&amp;gt; wrote:
&lt;br&gt;&amp;gt; And the storage of carts in the
&lt;br&gt;&amp;gt; temporary zodb requires the loads/dumps dance that seems to be very
&lt;br&gt;&amp;gt; error-prone and leads to hard-to-trace bugs.
&lt;br&gt;&lt;br&gt;FWIW - independent of the functional use case in discussion here -
&lt;br&gt;ZODB 3.9 has an option which can be used to prevent cross database
&lt;br&gt;references from being created in the first place.
&lt;br&gt;allow-implicit-cross-references. So that these kinds of bugs become
&lt;br&gt;trivial to trace.
&lt;br&gt;&lt;br&gt;Here is patch that enables the same functionality for ZODB 3.8
&lt;br&gt;&lt;a href=&quot;http://code.google.com/p/getpaid/issues/detail?id=209#c52&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid/issues/detail?id=209#c52&lt;/a&gt;&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;Michael Dunstan
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt;&amp;nbsp;(overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt;&amp;nbsp;(code and issue tracker)
&lt;br&gt;You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
&lt;br&gt;To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26343538&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
&lt;br&gt;To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26343538&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
&lt;br&gt;&lt;br&gt;For more options, visit this group at
&lt;br&gt;&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Alternative-Session-Implementation-tp26202777p26343538.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26333194</id>
	<title>Re: Alternative Session Implementation</title>
	<published>2009-11-13T00:45:54Z</published>
	<updated>2009-11-13T00:45:54Z</updated>
	<author>
		<name>silviot</name>
	</author>
	<content type="html">&lt;div class=&quot;gmail_quote&quot;&gt;On Fri, Nov 13, 2009 at 8:24 AM, Matt Halstead &lt;span dir=&quot;ltr&quot;&gt;&amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26333194&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;matt.halstead@...&lt;/a&gt;&amp;gt;&lt;/span&gt; wrote:&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex&quot;&gt;


&lt;div&gt;
&amp;gt; But it should be possible replace the local persistent utility with another&lt;br&gt;
&amp;gt; implementation that does the loads/dumps dance internaly and saves the&lt;br&gt;
&amp;gt; data somewhere else.&lt;br&gt;
&lt;br&gt;
&lt;/div&gt;Can you elaborate on why session storage needed to be reimplemented?&lt;/blockquote&gt;&lt;div&gt;I can help about this. I had a conversation with Carsten and other people at the sprint in Budapest. My point about issue 209 is that, even if it is now resolved, it was initially caused by a bad design decision: storing carts in a non persistent database. This decision makes anonymous customers lose their carts when Zope (or zeo in a zeo cluster) is restarted; site owners never want customers to lose their carts. And the storage of carts in the temporary zodb requires the loads/dumps dance that seems to be very error-prone and leads to hard-to-trace bugs. &lt;/div&gt;

&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;          Silvio&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

-- &lt;br /&gt;
GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt; (overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt; (code and issue tracker)&lt;br /&gt;
You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.&lt;br /&gt;
To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26333194&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;&lt;br /&gt;
To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26333194&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;&lt;br /&gt;
&amp;nbsp;&lt;br /&gt;
For more options, visit this group at&lt;br /&gt;
&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Alternative-Session-Implementation-tp26202777p26333194.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26332410</id>
	<title>Re: Alternative Session Implementation</title>
	<published>2009-11-12T23:24:00Z</published>
	<updated>2009-11-12T23:24:00Z</updated>
	<author>
		<name>Matt Halstead-3</name>
	</author>
	<content type="html">Hi Carsten,
&lt;br&gt;&lt;br&gt;On Nov 4, 12:22 pm, Carsten Senger &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26332410&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;sen...@...&lt;/a&gt;&amp;gt; wrote:
&lt;br&gt;&amp;gt; Hi all,
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; I had been joining the GetPaid sprint at the Plone conference in Budapest
&lt;br&gt;&amp;gt; for one day and we shortly discussed the session implementation. If I see
&lt;br&gt;&amp;gt; it correctly the problems of ticket 209 are resolved (except of broken
&lt;br&gt;&amp;gt; ZODBs maybe).
&lt;br&gt;&lt;br&gt;I just committed the patch the michael dunstan provided - it was
&lt;br&gt;previously not committed, that does seem to resolve the source of the
&lt;br&gt;issue for non-broken _session storages.
&lt;br&gt;&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; We could not come up with a completely sessionless cart implementation, I
&lt;br&gt;&amp;gt; think mainly because nobody knew the GetPaid design well enough. Anyway I
&lt;br&gt;&amp;gt; have implemented the session based approach using zope.app.session. It
&lt;br&gt;&amp;gt; consists of an ISession utility and an ISessionData local persistent
&lt;br&gt;&amp;gt; utility to store the data. This means that sessions (in our case those of
&lt;br&gt;&amp;gt; anonymous users) are written to the ZODB the portal is saved in. This can
&lt;br&gt;&amp;gt; give you performance problems, depending on the number of anonymous
&lt;br&gt;&amp;gt; shopping cart users. I don't know if there are bigger GetPaid installations.
&lt;br&gt;&amp;gt; But it should be possible replace the local persistent utility with another
&lt;br&gt;&amp;gt; implementation that does the loads/dumps dance internaly and saves the
&lt;br&gt;&amp;gt; data somewhere else.
&lt;/div&gt;&lt;br&gt;Can you elaborate on why session storage needed to be reimplemented?
&lt;br&gt;&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; Attached you find a patch converting the implementation and the tests to
&lt;br&gt;&amp;gt; use zope.app.session. The functional anon cart tests are failing atm, but I
&lt;br&gt;&amp;gt; did not have time to look at them nor do I know if they failed before
&lt;br&gt;&amp;gt; already.
&lt;br&gt;&lt;br&gt;It would be great if you could create a branch with your changes and
&lt;br&gt;fix the tests to work.
&lt;br&gt;&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; ..Carsten
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;  Products.PloneGetPaid.session.patch
&lt;br&gt;&amp;gt; 13KViewDownload
&lt;br&gt;&lt;br&gt;cheers
&lt;br&gt;Matt
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt;&amp;nbsp;(overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt;&amp;nbsp;(code and issue tracker)
&lt;br&gt;You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
&lt;br&gt;To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26332410&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
&lt;br&gt;To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26332410&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
&lt;br&gt;&lt;br&gt;For more options, visit this group at
&lt;br&gt;&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Alternative-Session-Implementation-tp26202777p26332410.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26236494</id>
	<title>Re: pcommerce.core</title>
	<published>2009-11-06T10:28:48Z</published>
	<updated>2009-11-06T10:28:48Z</updated>
	<author>
		<name>rafael-54</name>
	</author>
	<content type="html">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot;&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;meta content=&quot;text/html;charset=ISO-8859-1&quot; http-equiv=&quot;Content-Type&quot;&gt;
&lt;/head&gt;
&lt;body bgcolor=&quot;#ffffff&quot; text=&quot;#000000&quot;&gt;
Hi,&lt;br&gt;
&amp;nbsp;&lt;br&gt;
&amp;nbsp; I hadn't time yet to take a deep look at the code. It is much lighter
than getpaid's. It seems only to implement cart, checkout and product
variations. No reports, inventory management, UPS. (features I think
not many people use...)&lt;br&gt;
&amp;nbsp; I am not also a very skilled coder, but I could help trying to
implement in Getpaid the idea of product variations presented there..&lt;br&gt;
&amp;nbsp; The project owner is Simon Kaeser and theirs homepage is
&lt;a class=&quot;moz-txt-link-freetext&quot; href=&quot;http://endlessx.com/&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://endlessx.com/&lt;/a&gt; .&lt;br&gt;
&amp;nbsp; I cannot speak in the name of getpaid community, but maybe someone
more representative could get in touch with them and see how we could
maybe join forces for interoperability..&lt;br&gt;
&lt;br&gt;
Cheers,&lt;br&gt;
Rafael&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
Christopher Johnson escreveu:
&lt;blockquote cite=&quot;mid:7393c80911051712o5160f4a6lc0dca177d2381ddb@mail.gmail.com&quot; type=&quot;cite&quot;&gt;Hi Rafael,&lt;br&gt;
  &lt;br&gt;
Thanks for pointing that out! I heard something mentioned of it at the
conference, but wasn't at the open space on broader ecommerce to learn
more. Have you checked it out?&amp;nbsp; Do you know who developed it?&lt;br&gt;
  &lt;br&gt;
Also, are any of their interfaces able to work with GetPaid packages?
Would be great to evolve towards shareable code (payment processors and
other functionality). &lt;br&gt;
  &lt;br&gt;
Cheers,&lt;br&gt;
Chris&lt;br&gt;
  &lt;br&gt;
  &lt;div class=&quot;gmail_quote&quot;&gt;On Thu, Nov 5, 2009 at 11:04 AM, rafael &lt;span dir=&quot;ltr&quot;&gt;&amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26236494&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rafaelcrocha@...&lt;/a&gt;&amp;gt;&lt;/span&gt;
wrote:&lt;br&gt;
  &lt;blockquote class=&quot;gmail_quote&quot; style=&quot;border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;&quot;&gt;
    &lt;div bgcolor=&quot;#ffffff&quot; text=&quot;#000000&quot;&gt;&lt;br&gt;
    &lt;div style=&quot;font-family: -moz-fixed; font-size: 12px;&quot; lang=&quot;x-western&quot;&gt;
    &lt;pre&gt;Hi,

  I see it was recently released a new product for commerce in Plone,
pcommerce.core .

   Has anyone taken a look in the code? I saw there is a functionality
for product variation, something there should also exist in getpaid.
Maybe we could use some ideas from there?

Rafael
    &lt;/pre&gt;
    &lt;/div&gt;
    &lt;br&gt;
    &lt;/div&gt;
    &lt;br&gt;
  &lt;/blockquote&gt;
  &lt;/div&gt;
  &lt;br&gt;
  &lt;br clear=&quot;all&quot;&gt;
  &lt;br&gt;
-- &lt;br&gt;
Cofounder and CEO&lt;br&gt;
ifPeople - Innovation for People&lt;br&gt;
  &lt;a moz-do-not-send=&quot;true&quot; href=&quot;http://www.ifpeople.net&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;www.ifpeople.net&lt;/a&gt;&lt;br&gt;
t: 678-608-3408&lt;br&gt;
130 Boulevard NE, #6&lt;br&gt;
Atlanta, GA 30312&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  &lt;/p&gt;
&lt;/blockquote&gt;
&lt;br&gt;
&lt;br&gt;
--~--~---------~--~----~------------~-------~--~----~&lt;br&gt;
GetPaid for Plone: http://www.plonegetpaid.com (overview info) | http://code.google.com/p/getpaid (code and issue tracker)
 &lt;br&gt; You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
 &lt;br&gt; To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26236494&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
 &lt;br&gt; To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26236494&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
 &lt;br&gt; &lt;p&gt;For more options, visit this group at
 &lt;br&gt; http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;br&gt;
-~----------~----~----~----~------~----~------~--~---&lt;br&gt;
&lt;/body&gt;
&lt;/html&gt;
&lt;br&gt;
</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/pcommerce.core-tp26217492p26236494.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26225302</id>
	<title>Re: pcommerce.core</title>
	<published>2009-11-05T17:12:45Z</published>
	<updated>2009-11-05T17:12:45Z</updated>
	<author>
		<name>Christopher Johnson-7</name>
	</author>
	<content type="html">Hi Rafael,&lt;br&gt;&lt;br&gt;Thanks for pointing that out! I heard something mentioned of it at the conference, but wasn&amp;#39;t at the open space on broader ecommerce to learn more. Have you checked it out?  Do you know who developed it?&lt;br&gt;
&lt;br&gt;Also, are any of their interfaces able to work with GetPaid packages? Would be great to evolve towards shareable code (payment processors and other functionality). &lt;br&gt;&lt;br&gt;Cheers,&lt;br&gt;Chris&lt;br&gt;&lt;br&gt;&lt;div class=&quot;gmail_quote&quot;&gt;
On Thu, Nov 5, 2009 at 11:04 AM, rafael &lt;span dir=&quot;ltr&quot;&gt;&amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26225302&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rafaelcrocha@...&lt;/a&gt;&amp;gt;&lt;/span&gt; wrote:&lt;br&gt;&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;&quot;&gt;




&lt;div bgcolor=&quot;#ffffff&quot; text=&quot;#000000&quot;&gt;
&lt;br&gt;
&lt;div style=&quot;font-family: -moz-fixed; font-size: 12px;&quot; lang=&quot;x-western&quot;&gt;
&lt;pre&gt;Hi,

  I see it was recently released a new product for commerce in Plone,
pcommerce.core .

   Has anyone taken a look in the code? I saw there is a functionality
for product variation, something there should also exist in getpaid.
Maybe we could use some ideas from there?

Rafael
&lt;/pre&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;/p&gt;&lt;/div&gt;

&lt;br&gt;
&lt;/blockquote&gt;&lt;/div&gt;&lt;br&gt;&lt;br clear=&quot;all&quot;&gt;&lt;br&gt;-- &lt;br&gt;Cofounder and CEO&lt;br&gt;ifPeople - Innovation for People&lt;br&gt;&lt;a href=&quot;http://www.ifpeople.net&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;www.ifpeople.net&lt;/a&gt;&lt;br&gt;t: 678-608-3408&lt;br&gt;130 Boulevard NE, #6&lt;br&gt;Atlanta, GA 30312&lt;br&gt;

&lt;br&gt;
--~--~---------~--~----~------------~-------~--~----~&lt;br&gt;
GetPaid for Plone: http://www.plonegetpaid.com (overview info) | http://code.google.com/p/getpaid (code and issue tracker)
 &lt;br&gt; You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
 &lt;br&gt; To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26225302&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
 &lt;br&gt; To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26225302&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
 &lt;br&gt; &lt;p&gt;For more options, visit this group at
 &lt;br&gt; http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;br&gt;
-~----------~----~----~----~------~----~------~--~---&lt;br&gt;
&lt;br&gt;
</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/pcommerce.core-tp26217492p26225302.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26217492</id>
	<title>pcommerce.core</title>
	<published>2009-11-05T08:04:22Z</published>
	<updated>2009-11-05T08:04:22Z</updated>
	<author>
		<name>rafael-54</name>
	</author>
	<content type="html">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot;&gt;
&lt;html&gt;
&lt;head&gt;
&lt;/head&gt;
&lt;body bgcolor=&quot;#ffffff&quot; text=&quot;#000000&quot;&gt;
&lt;br&gt;
&lt;div class=&quot;moz-text-plain&quot; wrap=&quot;true&quot; graphical-quote=&quot;true&quot; style=&quot;font-family: -moz-fixed; font-size: 12px;&quot; lang=&quot;x-western&quot;&gt;
&lt;pre wrap=&quot;&quot;&gt;Hi,

  I see it was recently released a new product for commerce in Plone,
pcommerce.core .

   Has anyone taken a look in the code? I saw there is a functionality
for product variation, something there should also exist in getpaid.
Maybe we could use some ideas from there?

Rafael
&lt;/pre&gt;
&lt;/div&gt;
&lt;br&gt;
--~--~---------~--~----~------------~-------~--~----~&lt;br&gt;
GetPaid for Plone: http://www.plonegetpaid.com (overview info) | http://code.google.com/p/getpaid (code and issue tracker)
 &lt;br&gt; You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
 &lt;br&gt; To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26217492&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
 &lt;br&gt; To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26217492&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
 &lt;br&gt; &lt;p&gt;For more options, visit this group at
 &lt;br&gt; http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;br&gt;
-~----------~----~----~----~------~----~------~--~---&lt;br&gt;
&lt;/body&gt;
&lt;/html&gt;
&lt;br&gt;
</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/pcommerce.core-tp26217492p26217492.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26204293</id>
	<title>Re: Alternative Session Implementation</title>
	<published>2009-11-04T12:42:27Z</published>
	<updated>2009-11-04T12:42:27Z</updated>
	<author>
		<name>rafael-54</name>
	</author>
	<content type="html">&lt;br&gt;&lt;br&gt;&amp;gt; Hi all,
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; I had been joining the GetPaid sprint at the Plone conference in Budapest
&lt;br&gt;&amp;gt; for one day and we shortly discussed the session implementation. If I see
&lt;br&gt;&amp;gt; it correctly the problems of ticket 209 are resolved (except of broken
&lt;br&gt;&amp;gt; ZODBs maybe).
&lt;br&gt;&amp;gt; &amp;nbsp; 
&lt;br&gt;Hi,
&lt;br&gt;I still get this bug triggered every 2 days. Maybe my zodb is corrupted,
&lt;br&gt;but my workaround for that bug is reinstalling getpaid... I tried using
&lt;br&gt;the script to fix it, but did not work...
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; We could not come up with a completely sessionless cart implementation, I
&lt;br&gt;&amp;gt; think mainly because nobody knew the GetPaid design well enough. Anyway I
&lt;br&gt;&amp;gt; have implemented the session based approach using zope.app.session. It
&lt;br&gt;&amp;gt; consists of an ISession utility and an ISessionData local persistent
&lt;br&gt;&amp;gt; utility to store the data. This means that sessions (in our case those of
&lt;br&gt;&amp;gt; anonymous users) are written to the ZODB the portal is saved in. This can
&lt;br&gt;&amp;gt; give you performance problems, depending on the number of anonymous
&lt;br&gt;&amp;gt; shopping cart users. I don't know if there are bigger GetPaid installations.
&lt;br&gt;&amp;gt; But it should be possible replace the local persistent utility with another
&lt;br&gt;&amp;gt; implementation that does the loads/dumps dance internaly and saves the
&lt;br&gt;&amp;gt; data somewhere else.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; Attached you find a patch converting the implementation and the tests to
&lt;br&gt;&amp;gt; use zope.app.session. The functional anon cart tests are failing atm, but I
&lt;br&gt;&amp;gt; did not have time to look at them nor do I know if they failed before
&lt;br&gt;&amp;gt; already.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; ..Carsten
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;nbsp; 
&lt;/div&gt;&lt;br&gt;&lt;br&gt;--~--~---------~--~----~------------~-------~--~----~
&lt;br&gt;GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt;&amp;nbsp;(overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt;&amp;nbsp;(code and issue tracker)
&lt;br&gt;You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
&lt;br&gt;To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26204293&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
&lt;br&gt;To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26204293&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
&lt;br&gt;&lt;br&gt;For more options, visit this group at
&lt;br&gt;&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;-~----------~----~----~----~------~----~------~--~---
&lt;br&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Alternative-Session-Implementation-tp26202779p26204293.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26202777</id>
	<title>Alternative Session Implementation</title>
	<published>2009-11-03T15:22:07Z</published>
	<updated>2009-11-03T15:22:07Z</updated>
	<author>
		<name>Carsten Senger-3</name>
	</author>
	<content type="html">Hi all,
&lt;br&gt;&lt;br&gt;I had been joining the GetPaid sprint at the Plone conference in Budapest
&lt;br&gt;for one day and we shortly discussed the session implementation. If I see
&lt;br&gt;it correctly the problems of ticket 209 are resolved (except of broken
&lt;br&gt;ZODBs maybe).
&lt;br&gt;We could not come up with a completely sessionless cart implementation, I
&lt;br&gt;think mainly because nobody knew the GetPaid design well enough. Anyway I
&lt;br&gt;have implemented the session based approach using zope.app.session. It
&lt;br&gt;consists of an ISession utility and an ISessionData local persistent
&lt;br&gt;utility to store the data. This means that sessions (in our case those of
&lt;br&gt;anonymous users) are written to the ZODB the portal is saved in. This can
&lt;br&gt;give you performance problems, depending on the number of anonymous
&lt;br&gt;shopping cart users. I don't know if there are bigger GetPaid installations.
&lt;br&gt;But it should be possible replace the local persistent utility with another
&lt;br&gt;implementation that does the loads/dumps dance internaly and saves the
&lt;br&gt;data somewhere else.
&lt;br&gt;&lt;br&gt;Attached you find a patch converting the implementation and the tests to
&lt;br&gt;use zope.app.session. The functional anon cart tests are failing atm, but I
&lt;br&gt;did not have time to look at them nor do I know if they failed before
&lt;br&gt;already.
&lt;br&gt;&lt;br&gt;..Carsten
&lt;br&gt;&lt;br&gt;--~--~---------~--~----~------------~-------~--~----~
&lt;br&gt;GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt;&amp;nbsp;(overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt;&amp;nbsp;(code and issue tracker)
&lt;br&gt;You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
&lt;br&gt;To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26202777&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
&lt;br&gt;To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26202777&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
&lt;br&gt;&lt;br&gt;For more options, visit this group at
&lt;br&gt;&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;-~----------~----~----~----~------~----~------~--~---
&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;hr align=&quot;left&quot; width=&quot;300&quot; /&gt;&lt;tt&gt;Index: Products/PloneGetPaid/configure.zcml
&lt;br&gt;===================================================================
&lt;br&gt;--- Products/PloneGetPaid/configure.zcml	(Revision 3169)
&lt;br&gt;+++ Products/PloneGetPaid/configure.zcml	(Arbeitskopie)
&lt;br&gt;@@ -222,11 +222,58 @@
&lt;br&gt;&amp;nbsp; &amp;nbsp; /&amp;gt;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;+&amp;lt;!-- zope.app.session for shopping carts --&amp;gt;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-&amp;lt;subscriber
&lt;br&gt;- &amp;nbsp; &amp;nbsp;for=&amp;quot;*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; getpaid.core.interfaces.IPayableCreationEvent&amp;quot;
&lt;br&gt;- &amp;nbsp; &amp;nbsp;handler=&amp;quot;.events.payable_created&amp;quot;
&lt;br&gt;- &amp;nbsp; &amp;nbsp;/&amp;gt;
&lt;br&gt;- 
&lt;br&gt;+
&lt;br&gt;+&amp;lt;adapter factory=&amp;quot;.cart.ClientId&amp;quot; 
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; permission=&amp;quot;zope.Public&amp;quot; /&amp;gt; &amp;nbsp; &amp;nbsp;
&lt;br&gt;+
&lt;br&gt;+&amp;lt;configure package=&amp;quot;zope.app.session&amp;quot;&amp;gt;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;
&lt;br&gt;+ &amp;nbsp;&amp;lt;adapter
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;factory=&amp;quot;.session.Session&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;provides=&amp;quot;zope.app.session.interfaces.ISession&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;permission=&amp;quot;zope.Public&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;/&amp;gt;
&lt;br&gt;+ &amp;nbsp;
&lt;br&gt;+ &amp;nbsp;&amp;lt;adapter
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;factory=&amp;quot;.session.Session&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;provides=&amp;quot;zope.traversing.interfaces.IPathAdapter&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;name=&amp;quot;session&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;/&amp;gt;
&lt;br&gt;+ &amp;nbsp;
&lt;br&gt;+ &amp;nbsp;&amp;lt;class class=&amp;quot;.session.Session&amp;quot;&amp;gt;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;&amp;lt;allow interface=&amp;quot;.interfaces.ISession&amp;quot; /&amp;gt;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;&amp;lt;implements interface=&amp;quot;zope.traversing.interfaces.IPathAdapter&amp;quot; /&amp;gt;
&lt;br&gt;+ &amp;nbsp;&amp;lt;/class&amp;gt;
&lt;br&gt;+ &amp;nbsp;
&lt;br&gt;+ &amp;nbsp;
&lt;br&gt;+ &amp;nbsp;&amp;lt;class class=&amp;quot;.session.PersistentSessionDataContainer&amp;quot;&amp;gt;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;&amp;lt;require
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;interface=&amp;quot;.interfaces.ISessionDataContainer&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;permission=&amp;quot;zope.Public&amp;quot; /&amp;gt;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;&amp;lt;!-- &amp;nbsp; &amp;nbsp; &amp;lt;require --&amp;gt;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;&amp;lt;!-- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; set_schema=&amp;quot;.interfaces.ISessionDataContainer&amp;quot; --&amp;gt;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;&amp;lt;!-- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; permission=&amp;quot;zope.ManageServices&amp;quot; /&amp;gt; --&amp;gt;
&lt;br&gt;+ &amp;nbsp;&amp;lt;/class&amp;gt;
&lt;br&gt;+
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp;&amp;lt;class class=&amp;quot;.session.SessionData&amp;quot;&amp;gt;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;&amp;lt;allow interface=&amp;quot;.interfaces.ISessionData&amp;quot; /&amp;gt;
&lt;br&gt;+ &amp;nbsp;&amp;lt;/class&amp;gt;
&lt;br&gt;+ &amp;nbsp;
&lt;br&gt;+ &amp;nbsp;&amp;lt;class class=&amp;quot;.session.SessionPkgData&amp;quot;&amp;gt;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;&amp;lt;allow interface=&amp;quot;.interfaces.ISessionPkgData&amp;quot; /&amp;gt;
&lt;br&gt;+ &amp;nbsp;&amp;lt;/class&amp;gt;
&lt;br&gt;+ &amp;nbsp;
&lt;br&gt;+ &amp;nbsp;&amp;lt;subscriber
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;for=&amp;quot;zope.app.appsetup.IDatabaseOpenedEvent&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;handler=&amp;quot;.bootstrap.bootStrapSubscriber&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;/&amp;gt;
&lt;br&gt;+ &amp;nbsp;
&lt;br&gt;+ &amp;nbsp;&amp;lt;subscriber
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;for=&amp;quot;zope.publisher.interfaces.http.IHTTPVirtualHostChangedEvent&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;handler=&amp;quot;.http.notifyVirtualHostChanged&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;/&amp;gt;
&lt;br&gt;&amp;nbsp;&amp;lt;/configure&amp;gt;
&lt;br&gt;+&amp;lt;/configure&amp;gt;
&lt;br&gt;\ No newline at end of file
&lt;br&gt;Index: Products/PloneGetPaid/config.py
&lt;br&gt;===================================================================
&lt;br&gt;--- Products/PloneGetPaid/config.py	(Revision 3169)
&lt;br&gt;+++ Products/PloneGetPaid/config.py	(Arbeitskopie)
&lt;br&gt;@@ -4,3 +4,6 @@
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;PLONE3 = True
&lt;br&gt;&amp;nbsp;except ImportError:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;PLONE3 = False
&lt;br&gt;+
&lt;br&gt;+SESSION_KEY = 'PloneGetPaid'
&lt;br&gt;+CART_KEY = 'getpaid.cart'
&lt;br&gt;Index: Products/PloneGetPaid/tests/test_cart.py
&lt;br&gt;===================================================================
&lt;br&gt;--- Products/PloneGetPaid/tests/test_cart.py	(Revision 3169)
&lt;br&gt;+++ Products/PloneGetPaid/tests/test_cart.py	(Arbeitskopie)
&lt;br&gt;@@ -5,6 +5,7 @@
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;from zope.component import getUtility
&lt;br&gt;&amp;nbsp;from Testing.ZopeTestCase import ZopeDocTestSuite
&lt;br&gt;+from Testing.ZopeTestCase.utils import setupCoreSessions
&lt;br&gt;&amp;nbsp;from Products.Five.utilities.marker import mark
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;from utils import optionflags
&lt;br&gt;@@ -13,8 +14,24 @@
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid import interfaces
&lt;br&gt;&amp;nbsp;from getpaid.core.interfaces import IShoppingCartUtility
&lt;br&gt;&amp;nbsp;
&lt;br&gt;+
&lt;br&gt;+class DummySessionAndBrowserIdManager:
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;__test_browser_id__ = 'funkyTestBrowserId'
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;def getBrowserIdManager(self):
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return self
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;def getBrowserId(self):
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return self.__test_browser_id__
&lt;br&gt;+
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;class TestCart(PloneGetPaidTestCase):
&lt;br&gt;&amp;nbsp;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;def afterSetUp(self):
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;super(TestCart, self).afterSetUp()
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;setattr(self.app.REQUEST, 'SESSION', DummySessionAndBrowserIdManager())
&lt;br&gt;+
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def mySetup(self):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;self.setRoles(('Manager',))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;id = self.portal.invokeFactory('Document', 'doc')
&lt;br&gt;@@ -161,18 +178,18 @@
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;...
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ValueError: Malformed key: example:malformed:key
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;&amp;quot;&amp;quot;
&lt;br&gt;-
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def pauseBrowserSession(self):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;&amp;quot;&amp;quot;Utility that disables the current session. The session can
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;be resumed using resumeBrowserSession.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;&amp;quot;&amp;quot;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;self._paused_browser_id = self.portal.REQUEST.browser_id_
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;self.portal.REQUEST.browser_id_ = None
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;self._paused_browser_id = self.portal.REQUEST.SESSION.__test_browser_id__
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;self.portal.REQUEST.SESSION.__test_browser_id__ = None
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def resumeBrowserSession(self):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;&amp;quot;&amp;quot;Utility to restore the previous session.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;&amp;quot;&amp;quot;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;self.portal.REQUEST.browser_id_ = self._paused_browser_id
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;self.portal.REQUEST.SESSION.__test_browser_id__ = self._paused_browser_id
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;def test_suite():
&lt;br&gt;Index: Products/PloneGetPaid/setuphandlers.py
&lt;br&gt;===================================================================
&lt;br&gt;--- Products/PloneGetPaid/setuphandlers.py	(Revision 3169)
&lt;br&gt;+++ Products/PloneGetPaid/setuphandlers.py	(Arbeitskopie)
&lt;br&gt;@@ -14,11 +14,11 @@
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid.Extensions.install import install_plone3_portlets
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid.Extensions.install import setup_payment_options
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid.Extensions.install import register_shopping_cart_utility
&lt;br&gt;-
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid.Extensions.install import setup_addressbook
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid.Extensions.install import setup_named_orders
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid.Extensions.install import setup_settings
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid.Extensions.install import register_shopping_cart_utility
&lt;br&gt;+from Products.PloneGetPaid.Extensions.install import register_session_data_utility
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid.config import PLONE3
&lt;br&gt;&amp;nbsp;
&lt;br&gt;@@ -82,6 +82,9 @@
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;print &amp;gt;&amp;gt; out, &amp;quot;Registering shopping cart utility&amp;quot;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;register_shopping_cart_utility(site)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;print &amp;gt;&amp;gt; out, &amp;quot;Registering session data utility&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;register_session_data_utility(site)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;print &amp;gt;&amp;gt; out, &amp;quot;Notifying Installation&amp;quot;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;notify_install( site )
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;
&lt;br&gt;Index: Products/PloneGetPaid/cart.py
&lt;br&gt;===================================================================
&lt;br&gt;--- Products/PloneGetPaid/cart.py	(Revision 3169)
&lt;br&gt;+++ Products/PloneGetPaid/cart.py	(Arbeitskopie)
&lt;br&gt;@@ -3,16 +3,21 @@
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;$Id$
&lt;br&gt;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;
&lt;br&gt;-from zope.component import getUtility
&lt;br&gt;+from zope.app.session.interfaces import IClientId
&lt;br&gt;+from zope.app.session.interfaces import ISession
&lt;br&gt;+from zope.component import adapts, getUtility
&lt;br&gt;&amp;nbsp;from zope.interface import implements
&lt;br&gt;+from zope.publisher.interfaces import IRequest
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;from getpaid.core.cart import ShoppingCart
&lt;br&gt;&amp;nbsp;from getpaid.core.interfaces import IShoppingCartUtility
&lt;br&gt;&amp;nbsp;from Products.CMFCore.utils import getToolByName
&lt;br&gt;+from Products.PloneGetPaid.config import CART_KEY, SESSION_KEY
&lt;br&gt;&amp;nbsp;from persistent import Persistent
&lt;br&gt;&amp;nbsp;from BTrees.OOBTree import OOBTree
&lt;br&gt;&amp;nbsp;from AccessControl import getSecurityManager
&lt;br&gt;&amp;nbsp;
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;class ShoppingCartUtility(Persistent):
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;implements(IShoppingCartUtility)
&lt;br&gt;@@ -73,40 +78,30 @@
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;self._sessions[uid] = cart
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return cart
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def _getCartForSession(self, context, create=False, browser_id=None):
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session_manager = getToolByName(context, 'session_data_manager')
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if browser_id is None:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if not session_manager.hasSessionData() and not create:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session = session_manager.getSessionData()
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;else:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session = session_manager.getSessionDataByKey(browser_id)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if session is None:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if not session.has_key('getpaid.cart'):
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if create:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session['getpaid.cart'] = cart = ShoppingCart()
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;else:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return None
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return session['getpaid.cart']
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session = ISession(context.REQUEST)
&lt;br&gt;&amp;nbsp;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if browser_id is not None:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# we overwrite the client_id that was set during the ISession
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# initialization
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session.client_id = browser_id
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sessiondata = session[SESSION_KEY]
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;cart = sessiondata.get(CART_KEY, None)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if create and cart is None:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sessiondata[CART_KEY] = cart = ShoppingCart()
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return cart
&lt;br&gt;+
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def _getDisposableCart(self, context, browser_id=None):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return ShoppingCart()
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def _getMultiShotCart(self, context, cart_id=None):
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session_manager = getToolByName(context, 'session_data_manager')
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sessiondata = ISession(context.REQUEST)[SESSION_KEY]
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;key = &amp;quot;%s.%s&amp;quot; % (CART_KEY, cart_id)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if not sessiondata.has_key(key):
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sessiondata[key] = ShoppingCart()
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return sessiondata[key]
&lt;br&gt;&amp;nbsp;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;key = &amp;quot;getpaid.cart.%s&amp;quot; % cart_id
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session = session_manager.getSessionData()
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if not session.has_key(key):
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session[key] = cart = ShoppingCart()
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return session[key]
&lt;br&gt;-
&lt;br&gt;-
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def destroy(self, context, key=None):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;&amp;quot;&amp;quot; Destroy the cart.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;&amp;quot;&amp;quot;
&lt;br&gt;@@ -125,37 +120,26 @@
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;else:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return self._destroyCartForSession(context)
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def _destroyCartForUser(self, context, uid):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if self._sessions.has_key(uid):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;del self._sessions[uid]
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def _destroyCartForSession(self, context, browser_id=None):
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session_manager = getToolByName(context, 'session_data_manager')
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if browser_id is None:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if not session_manager.hasSessionData(): #nothing to destroy
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return None
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session = session_manager.getSessionData()
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;else:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session = session_manager.getSessionDataByKey(browser_id)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if session is None:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if not session.has_key('getpaid.cart'):
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;del session['getpaid.cart']
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session = ISession(context.REQUEST)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if browser_id is not None:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# overwrite the client_id that was set
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# during initialization
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session.client_id = browser_id
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sessiondata = session[SESSION_KEY]
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if sessiondata.has_key(CART_KEY):
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;del sessiondata[CART_KEY]
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def _destroyMultiShotCart(self, context, cart_id=None):
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session_manager = getToolByName(context, 'session_data_manager')
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sessiondata = ISession(context.REQUEST)[SESSION_KEY]
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;key = &amp;quot;%s.%s&amp;quot; % (CART_KEY, cart_id)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if sessiondata.has_key(key):
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;del session[key]
&lt;br&gt;&amp;nbsp;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;key = &amp;quot;getpaid.cart.%s&amp;quot; % cart_id
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session = session_manager.getSessionData()
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if not session.has_key(key):
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;del session[key]
&lt;br&gt;-
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def getKey(self, context):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;&amp;quot;&amp;quot;Return key that can be used to recover the cart for the
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;current user or session.
&lt;br&gt;@@ -164,15 +148,12 @@
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if uid is not None:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return 'user:%s' % uid
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;else:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session_manager = getToolByName(context, 'session_data_manager')
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if not session_manager.hasSessionData():
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session = ISession(context.REQUEST)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sessiondata = session[SESSION_KEY]
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if not sessiondata.has_key(CART_KEY):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return None
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session = session_manager.getSessionData()
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if not session.has_key('getpaid.cart'):
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return None
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return 'session:%s' % session.token
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return 'session:%s' % session.client_id
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def _decodeKey(self, key):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;try:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;name, value = key.split(':', 1)
&lt;br&gt;@@ -185,3 +166,19 @@
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def manage_fixupOwnershipAfterAdd(self):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;pass
&lt;br&gt;+
&lt;br&gt;+
&lt;br&gt;+class ClientId(str):
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;&amp;quot;&amp;quot;&amp;quot;See zope.app.interfaces.utilities.session.IClientId
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;An IClientId Utility that uses Zope2's browser_id_manager
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;implementation.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;&amp;quot;&amp;quot;&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;implements(IClientId)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;adapts(IRequest)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;def __new__(cls, request):
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return str.__new__(
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;cls, request.SESSION.getBrowserIdManager().getBrowserId()
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;
&lt;br&gt;Index: Products/PloneGetPaid/Extensions/install.py
&lt;br&gt;===================================================================
&lt;br&gt;--- Products/PloneGetPaid/Extensions/install.py	(Revision 3169)
&lt;br&gt;+++ Products/PloneGetPaid/Extensions/install.py	(Arbeitskopie)
&lt;br&gt;@@ -12,6 +12,9 @@
&lt;br&gt;&amp;nbsp;from zope.event import notify
&lt;br&gt;&amp;nbsp;from zope.app.component.hooks import setSite
&lt;br&gt;&amp;nbsp;from zope.app.component.interfaces import ISite
&lt;br&gt;+from zope.app.session.interfaces import ISessionDataContainer
&lt;br&gt;+from zope.app.session.session import PersistentSessionDataContainer
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid import generations, preferences, addressbook, namedorder
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid.interfaces import IGetPaidManagementOptions, IAddressBookUtility, INamedOrderUtility
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid.config import PLONE3
&lt;br&gt;@@ -61,6 +64,21 @@
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# BBB for Zope 2.9
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sm.registerUtility(interface=IOrderManager, utility=manager)
&lt;br&gt;&amp;nbsp;
&lt;br&gt;+def register_session_data_utility( self ):
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;portal = getToolByName( self, 'portal_url').getPortalObject()
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;sm = portal.getSiteManager()
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;is_already_registered = [u for u in sm.getUtilitiesFor(ISessionDataContainer)]
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;if not len(is_already_registered):
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session_data = PersistentSessionDataContainer()
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session_data.timeout = 604800 # 7 days
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session_data.resolution = 100
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sm.registerUtility(session_data, ISessionDataContainer)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;try:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sm.registerUtility(component=session_data, provided=ISessionDataContainer)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;except TypeError:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# BBB for Zope 2.9
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sm.registerUtility(interface=ISessionDataContainer, utility=session_data)
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;def setup_intid( self ):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;portal = getToolByName(self, 'portal_url').getPortalObject()
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;try:
&lt;br&gt;&lt;/tt&gt;&lt;hr align=&quot;left&quot; width=&quot;300&quot; /&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Alternative-Session-Implementation-tp26202777p26202777.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26202779</id>
	<title>Alternative Session Implementation</title>
	<published>2009-11-03T15:17:56Z</published>
	<updated>2009-11-03T15:17:56Z</updated>
	<author>
		<name>Carsten Senger-3</name>
	</author>
	<content type="html">Hi all,
&lt;br&gt;&lt;br&gt;I had been joining the GetPaid sprint at the Plone conference in Budapest
&lt;br&gt;for one day and we shortly discussed the session implementation. If I see
&lt;br&gt;it correctly the problems of ticket 209 are resolved (except of broken
&lt;br&gt;ZODBs maybe).
&lt;br&gt;We could not come up with a completely sessionless cart implementation, I
&lt;br&gt;think mainly because nobody knew the GetPaid design well enough. Anyway I
&lt;br&gt;have implemented the session based approach using zope.app.session. It
&lt;br&gt;consists of an ISession utility and an ISessionData local persistent
&lt;br&gt;utility to store the data. This means that sessions (in our case those of
&lt;br&gt;anonymous users) are written to the ZODB the portal is saved in. This can
&lt;br&gt;give you performance problems, depending on the number of anonymous
&lt;br&gt;shopping cart users. I don't know if there are bigger GetPaid installations.
&lt;br&gt;But it should be possible replace the local persistent utility with another
&lt;br&gt;implementation that does the loads/dumps dance internaly and saves the
&lt;br&gt;data somewhere else.
&lt;br&gt;&lt;br&gt;Attached you find a patch converting the implementation and the tests to
&lt;br&gt;use zope.app.session. The functional anon cart tests are failing atm, but I
&lt;br&gt;did not have time to look at them nor do I know if they failed before
&lt;br&gt;already.
&lt;br&gt;&lt;br&gt;..Carsten
&lt;br&gt;&lt;br&gt;--~--~---------~--~----~------------~-------~--~----~
&lt;br&gt;GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt;&amp;nbsp;(overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt;&amp;nbsp;(code and issue tracker)
&lt;br&gt;You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
&lt;br&gt;To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26202779&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
&lt;br&gt;To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26202779&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
&lt;br&gt;&lt;br&gt;For more options, visit this group at
&lt;br&gt;&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;-~----------~----~----~----~------~----~------~--~---
&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;hr align=&quot;left&quot; width=&quot;300&quot; /&gt;&lt;tt&gt;Index: Products/PloneGetPaid/configure.zcml
&lt;br&gt;===================================================================
&lt;br&gt;--- Products/PloneGetPaid/configure.zcml	(Revision 3169)
&lt;br&gt;+++ Products/PloneGetPaid/configure.zcml	(Arbeitskopie)
&lt;br&gt;@@ -222,11 +222,58 @@
&lt;br&gt;&amp;nbsp; &amp;nbsp; /&amp;gt;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;+&amp;lt;!-- zope.app.session for shopping carts --&amp;gt;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-&amp;lt;subscriber
&lt;br&gt;- &amp;nbsp; &amp;nbsp;for=&amp;quot;*
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; getpaid.core.interfaces.IPayableCreationEvent&amp;quot;
&lt;br&gt;- &amp;nbsp; &amp;nbsp;handler=&amp;quot;.events.payable_created&amp;quot;
&lt;br&gt;- &amp;nbsp; &amp;nbsp;/&amp;gt;
&lt;br&gt;- 
&lt;br&gt;+
&lt;br&gt;+&amp;lt;adapter factory=&amp;quot;.cart.ClientId&amp;quot; 
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; permission=&amp;quot;zope.Public&amp;quot; /&amp;gt; &amp;nbsp; &amp;nbsp;
&lt;br&gt;+
&lt;br&gt;+&amp;lt;configure package=&amp;quot;zope.app.session&amp;quot;&amp;gt;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;
&lt;br&gt;+ &amp;nbsp;&amp;lt;adapter
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;factory=&amp;quot;.session.Session&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;provides=&amp;quot;zope.app.session.interfaces.ISession&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;permission=&amp;quot;zope.Public&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;/&amp;gt;
&lt;br&gt;+ &amp;nbsp;
&lt;br&gt;+ &amp;nbsp;&amp;lt;adapter
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;factory=&amp;quot;.session.Session&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;provides=&amp;quot;zope.traversing.interfaces.IPathAdapter&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;name=&amp;quot;session&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;/&amp;gt;
&lt;br&gt;+ &amp;nbsp;
&lt;br&gt;+ &amp;nbsp;&amp;lt;class class=&amp;quot;.session.Session&amp;quot;&amp;gt;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;&amp;lt;allow interface=&amp;quot;.interfaces.ISession&amp;quot; /&amp;gt;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;&amp;lt;implements interface=&amp;quot;zope.traversing.interfaces.IPathAdapter&amp;quot; /&amp;gt;
&lt;br&gt;+ &amp;nbsp;&amp;lt;/class&amp;gt;
&lt;br&gt;+ &amp;nbsp;
&lt;br&gt;+ &amp;nbsp;
&lt;br&gt;+ &amp;nbsp;&amp;lt;class class=&amp;quot;.session.PersistentSessionDataContainer&amp;quot;&amp;gt;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;&amp;lt;require
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;interface=&amp;quot;.interfaces.ISessionDataContainer&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;permission=&amp;quot;zope.Public&amp;quot; /&amp;gt;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;&amp;lt;!-- &amp;nbsp; &amp;nbsp; &amp;lt;require --&amp;gt;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;&amp;lt;!-- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; set_schema=&amp;quot;.interfaces.ISessionDataContainer&amp;quot; --&amp;gt;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;&amp;lt;!-- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; permission=&amp;quot;zope.ManageServices&amp;quot; /&amp;gt; --&amp;gt;
&lt;br&gt;+ &amp;nbsp;&amp;lt;/class&amp;gt;
&lt;br&gt;+
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp;&amp;lt;class class=&amp;quot;.session.SessionData&amp;quot;&amp;gt;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;&amp;lt;allow interface=&amp;quot;.interfaces.ISessionData&amp;quot; /&amp;gt;
&lt;br&gt;+ &amp;nbsp;&amp;lt;/class&amp;gt;
&lt;br&gt;+ &amp;nbsp;
&lt;br&gt;+ &amp;nbsp;&amp;lt;class class=&amp;quot;.session.SessionPkgData&amp;quot;&amp;gt;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;&amp;lt;allow interface=&amp;quot;.interfaces.ISessionPkgData&amp;quot; /&amp;gt;
&lt;br&gt;+ &amp;nbsp;&amp;lt;/class&amp;gt;
&lt;br&gt;+ &amp;nbsp;
&lt;br&gt;+ &amp;nbsp;&amp;lt;subscriber
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;for=&amp;quot;zope.app.appsetup.IDatabaseOpenedEvent&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;handler=&amp;quot;.bootstrap.bootStrapSubscriber&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;/&amp;gt;
&lt;br&gt;+ &amp;nbsp;
&lt;br&gt;+ &amp;nbsp;&amp;lt;subscriber
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;for=&amp;quot;zope.publisher.interfaces.http.IHTTPVirtualHostChangedEvent&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;handler=&amp;quot;.http.notifyVirtualHostChanged&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;/&amp;gt;
&lt;br&gt;&amp;nbsp;&amp;lt;/configure&amp;gt;
&lt;br&gt;+&amp;lt;/configure&amp;gt;
&lt;br&gt;\ No newline at end of file
&lt;br&gt;Index: Products/PloneGetPaid/config.py
&lt;br&gt;===================================================================
&lt;br&gt;--- Products/PloneGetPaid/config.py	(Revision 3169)
&lt;br&gt;+++ Products/PloneGetPaid/config.py	(Arbeitskopie)
&lt;br&gt;@@ -4,3 +4,6 @@
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;PLONE3 = True
&lt;br&gt;&amp;nbsp;except ImportError:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;PLONE3 = False
&lt;br&gt;+
&lt;br&gt;+SESSION_KEY = 'PloneGetPaid'
&lt;br&gt;+CART_KEY = 'getpaid.cart'
&lt;br&gt;Index: Products/PloneGetPaid/tests/test_cart.py
&lt;br&gt;===================================================================
&lt;br&gt;--- Products/PloneGetPaid/tests/test_cart.py	(Revision 3169)
&lt;br&gt;+++ Products/PloneGetPaid/tests/test_cart.py	(Arbeitskopie)
&lt;br&gt;@@ -5,6 +5,7 @@
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;from zope.component import getUtility
&lt;br&gt;&amp;nbsp;from Testing.ZopeTestCase import ZopeDocTestSuite
&lt;br&gt;+from Testing.ZopeTestCase.utils import setupCoreSessions
&lt;br&gt;&amp;nbsp;from Products.Five.utilities.marker import mark
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;from utils import optionflags
&lt;br&gt;@@ -13,8 +14,24 @@
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid import interfaces
&lt;br&gt;&amp;nbsp;from getpaid.core.interfaces import IShoppingCartUtility
&lt;br&gt;&amp;nbsp;
&lt;br&gt;+
&lt;br&gt;+class DummySessionAndBrowserIdManager:
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;__test_browser_id__ = 'funkyTestBrowserId'
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;def getBrowserIdManager(self):
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return self
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;def getBrowserId(self):
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return self.__test_browser_id__
&lt;br&gt;+
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;class TestCart(PloneGetPaidTestCase):
&lt;br&gt;&amp;nbsp;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;def afterSetUp(self):
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;super(TestCart, self).afterSetUp()
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;setattr(self.app.REQUEST, 'SESSION', DummySessionAndBrowserIdManager())
&lt;br&gt;+
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def mySetup(self):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;self.setRoles(('Manager',))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;id = self.portal.invokeFactory('Document', 'doc')
&lt;br&gt;@@ -161,18 +178,18 @@
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;...
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ValueError: Malformed key: example:malformed:key
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;&amp;quot;&amp;quot;
&lt;br&gt;-
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def pauseBrowserSession(self):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;&amp;quot;&amp;quot;Utility that disables the current session. The session can
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;be resumed using resumeBrowserSession.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;&amp;quot;&amp;quot;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;self._paused_browser_id = self.portal.REQUEST.browser_id_
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;self.portal.REQUEST.browser_id_ = None
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;self._paused_browser_id = self.portal.REQUEST.SESSION.__test_browser_id__
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;self.portal.REQUEST.SESSION.__test_browser_id__ = None
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def resumeBrowserSession(self):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;&amp;quot;&amp;quot;Utility to restore the previous session.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;&amp;quot;&amp;quot;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;self.portal.REQUEST.browser_id_ = self._paused_browser_id
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;self.portal.REQUEST.SESSION.__test_browser_id__ = self._paused_browser_id
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;def test_suite():
&lt;br&gt;Index: Products/PloneGetPaid/setuphandlers.py
&lt;br&gt;===================================================================
&lt;br&gt;--- Products/PloneGetPaid/setuphandlers.py	(Revision 3169)
&lt;br&gt;+++ Products/PloneGetPaid/setuphandlers.py	(Arbeitskopie)
&lt;br&gt;@@ -14,11 +14,11 @@
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid.Extensions.install import install_plone3_portlets
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid.Extensions.install import setup_payment_options
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid.Extensions.install import register_shopping_cart_utility
&lt;br&gt;-
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid.Extensions.install import setup_addressbook
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid.Extensions.install import setup_named_orders
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid.Extensions.install import setup_settings
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid.Extensions.install import register_shopping_cart_utility
&lt;br&gt;+from Products.PloneGetPaid.Extensions.install import register_session_data_utility
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid.config import PLONE3
&lt;br&gt;&amp;nbsp;
&lt;br&gt;@@ -82,6 +82,9 @@
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;print &amp;gt;&amp;gt; out, &amp;quot;Registering shopping cart utility&amp;quot;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;register_shopping_cart_utility(site)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;print &amp;gt;&amp;gt; out, &amp;quot;Registering session data utility&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;register_session_data_utility(site)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;print &amp;gt;&amp;gt; out, &amp;quot;Notifying Installation&amp;quot;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;notify_install( site )
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;
&lt;br&gt;Index: Products/PloneGetPaid/cart.py
&lt;br&gt;===================================================================
&lt;br&gt;--- Products/PloneGetPaid/cart.py	(Revision 3169)
&lt;br&gt;+++ Products/PloneGetPaid/cart.py	(Arbeitskopie)
&lt;br&gt;@@ -3,16 +3,21 @@
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;$Id$
&lt;br&gt;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;
&lt;br&gt;-from zope.component import getUtility
&lt;br&gt;+from zope.app.session.interfaces import IClientId
&lt;br&gt;+from zope.app.session.interfaces import ISession
&lt;br&gt;+from zope.component import adapts, getUtility
&lt;br&gt;&amp;nbsp;from zope.interface import implements
&lt;br&gt;+from zope.publisher.interfaces import IRequest
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;from getpaid.core.cart import ShoppingCart
&lt;br&gt;&amp;nbsp;from getpaid.core.interfaces import IShoppingCartUtility
&lt;br&gt;&amp;nbsp;from Products.CMFCore.utils import getToolByName
&lt;br&gt;+from Products.PloneGetPaid.config import CART_KEY, SESSION_KEY
&lt;br&gt;&amp;nbsp;from persistent import Persistent
&lt;br&gt;&amp;nbsp;from BTrees.OOBTree import OOBTree
&lt;br&gt;&amp;nbsp;from AccessControl import getSecurityManager
&lt;br&gt;&amp;nbsp;
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;class ShoppingCartUtility(Persistent):
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;implements(IShoppingCartUtility)
&lt;br&gt;@@ -73,40 +78,30 @@
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;self._sessions[uid] = cart
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return cart
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def _getCartForSession(self, context, create=False, browser_id=None):
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session_manager = getToolByName(context, 'session_data_manager')
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if browser_id is None:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if not session_manager.hasSessionData() and not create:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session = session_manager.getSessionData()
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;else:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session = session_manager.getSessionDataByKey(browser_id)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if session is None:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if not session.has_key('getpaid.cart'):
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if create:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session['getpaid.cart'] = cart = ShoppingCart()
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;else:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return None
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return session['getpaid.cart']
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session = ISession(context.REQUEST)
&lt;br&gt;&amp;nbsp;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if browser_id is not None:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# we overwrite the client_id that was set during the ISession
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# initialization
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session.client_id = browser_id
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sessiondata = session[SESSION_KEY]
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;cart = sessiondata.get(CART_KEY, None)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if create and cart is None:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sessiondata[CART_KEY] = cart = ShoppingCart()
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return cart
&lt;br&gt;+
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def _getDisposableCart(self, context, browser_id=None):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return ShoppingCart()
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def _getMultiShotCart(self, context, cart_id=None):
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session_manager = getToolByName(context, 'session_data_manager')
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sessiondata = ISession(context.REQUEST)[SESSION_KEY]
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;key = &amp;quot;%s.%s&amp;quot; % (CART_KEY, cart_id)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if not sessiondata.has_key(key):
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sessiondata[key] = ShoppingCart()
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return sessiondata[key]
&lt;br&gt;&amp;nbsp;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;key = &amp;quot;getpaid.cart.%s&amp;quot; % cart_id
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session = session_manager.getSessionData()
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if not session.has_key(key):
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session[key] = cart = ShoppingCart()
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return session[key]
&lt;br&gt;-
&lt;br&gt;-
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def destroy(self, context, key=None):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;&amp;quot;&amp;quot; Destroy the cart.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;&amp;quot;&amp;quot;
&lt;br&gt;@@ -125,37 +120,26 @@
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;else:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return self._destroyCartForSession(context)
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def _destroyCartForUser(self, context, uid):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if self._sessions.has_key(uid):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;del self._sessions[uid]
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def _destroyCartForSession(self, context, browser_id=None):
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session_manager = getToolByName(context, 'session_data_manager')
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if browser_id is None:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if not session_manager.hasSessionData(): #nothing to destroy
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return None
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session = session_manager.getSessionData()
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;else:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session = session_manager.getSessionDataByKey(browser_id)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if session is None:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if not session.has_key('getpaid.cart'):
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;del session['getpaid.cart']
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session = ISession(context.REQUEST)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if browser_id is not None:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# overwrite the client_id that was set
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# during initialization
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session.client_id = browser_id
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sessiondata = session[SESSION_KEY]
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if sessiondata.has_key(CART_KEY):
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;del sessiondata[CART_KEY]
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def _destroyMultiShotCart(self, context, cart_id=None):
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session_manager = getToolByName(context, 'session_data_manager')
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sessiondata = ISession(context.REQUEST)[SESSION_KEY]
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;key = &amp;quot;%s.%s&amp;quot; % (CART_KEY, cart_id)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if sessiondata.has_key(key):
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;del session[key]
&lt;br&gt;&amp;nbsp;
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;key = &amp;quot;getpaid.cart.%s&amp;quot; % cart_id
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session = session_manager.getSessionData()
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if not session.has_key(key):
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return
&lt;br&gt;-
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;del session[key]
&lt;br&gt;-
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def getKey(self, context):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;&amp;quot;&amp;quot;Return key that can be used to recover the cart for the
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;current user or session.
&lt;br&gt;@@ -164,15 +148,12 @@
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if uid is not None:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return 'user:%s' % uid
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;else:
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session_manager = getToolByName(context, 'session_data_manager')
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if not session_manager.hasSessionData():
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session = ISession(context.REQUEST)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sessiondata = session[SESSION_KEY]
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if not sessiondata.has_key(CART_KEY):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return None
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session = session_manager.getSessionData()
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if not session.has_key('getpaid.cart'):
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return None
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return 'session:%s' % session.token
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return 'session:%s' % session.client_id
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def _decodeKey(self, key):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;try:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;name, value = key.split(':', 1)
&lt;br&gt;@@ -185,3 +166,19 @@
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;def manage_fixupOwnershipAfterAdd(self):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;pass
&lt;br&gt;+
&lt;br&gt;+
&lt;br&gt;+class ClientId(str):
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;&amp;quot;&amp;quot;&amp;quot;See zope.app.interfaces.utilities.session.IClientId
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;An IClientId Utility that uses Zope2's browser_id_manager
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;implementation.
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;&amp;quot;&amp;quot;&amp;quot;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;implements(IClientId)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;adapts(IRequest)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;def __new__(cls, request):
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return str.__new__(
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;cls, request.SESSION.getBrowserIdManager().getBrowserId()
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;
&lt;br&gt;Index: Products/PloneGetPaid/Extensions/install.py
&lt;br&gt;===================================================================
&lt;br&gt;--- Products/PloneGetPaid/Extensions/install.py	(Revision 3169)
&lt;br&gt;+++ Products/PloneGetPaid/Extensions/install.py	(Arbeitskopie)
&lt;br&gt;@@ -12,6 +12,9 @@
&lt;br&gt;&amp;nbsp;from zope.event import notify
&lt;br&gt;&amp;nbsp;from zope.app.component.hooks import setSite
&lt;br&gt;&amp;nbsp;from zope.app.component.interfaces import ISite
&lt;br&gt;+from zope.app.session.interfaces import ISessionDataContainer
&lt;br&gt;+from zope.app.session.session import PersistentSessionDataContainer
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid import generations, preferences, addressbook, namedorder
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid.interfaces import IGetPaidManagementOptions, IAddressBookUtility, INamedOrderUtility
&lt;br&gt;&amp;nbsp;from Products.PloneGetPaid.config import PLONE3
&lt;br&gt;@@ -61,6 +64,21 @@
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# BBB for Zope 2.9
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sm.registerUtility(interface=IOrderManager, utility=manager)
&lt;br&gt;&amp;nbsp;
&lt;br&gt;+def register_session_data_utility( self ):
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;portal = getToolByName( self, 'portal_url').getPortalObject()
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;sm = portal.getSiteManager()
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;is_already_registered = [u for u in sm.getUtilitiesFor(ISessionDataContainer)]
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;if not len(is_already_registered):
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session_data = PersistentSessionDataContainer()
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session_data.timeout = 604800 # 7 days
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;session_data.resolution = 100
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sm.registerUtility(session_data, ISessionDataContainer)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;try:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sm.registerUtility(component=session_data, provided=ISessionDataContainer)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;except TypeError:
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# BBB for Zope 2.9
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sm.registerUtility(interface=ISessionDataContainer, utility=session_data)
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;def setup_intid( self ):
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;portal = getToolByName(self, 'portal_url').getPortalObject()
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;try:
&lt;br&gt;&lt;/tt&gt;&lt;hr align=&quot;left&quot; width=&quot;300&quot; /&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Alternative-Session-Implementation-tp26202779p26202779.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26157984</id>
	<title>Re: Sprinting on GetPaid: a plan</title>
	<published>2009-11-01T19:31:13Z</published>
	<updated>2009-11-01T19:31:13Z</updated>
	<author>
		<name>Michael Dunstan</name>
	</author>
	<content type="html">&lt;br&gt;On Mon, Nov 2, 2009 at 1:48 AM, Brandon Craig Rhodes
&lt;br&gt;&amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26157984&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;brandon@...&lt;/a&gt;&amp;gt; wrote:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; Michael Dunstan &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26157984&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;michael.dunstan@...&lt;/a&gt;&amp;gt; writes:
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt; The Google Checkout processor tests fabricate the incoming signals
&lt;br&gt;&amp;gt;&amp;gt; from the checkout server...
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; Well, that's an interesting idea!  At first it sounds like an
&lt;br&gt;&amp;gt; unconvincing test, but I guess if the XML you injected in the test was
&lt;br&gt;&amp;gt; actual real XML from Google that you'd captured during a by-hand test of
&lt;br&gt;&amp;gt; the callback, then you are indeed testing against real data and real
&lt;br&gt;&amp;gt; Google behavior.  I like the approach enough to be comfortable with it!
&lt;br&gt;&amp;gt; If the sprinters want to kick off a callback from PayPal, capture the
&lt;br&gt;&amp;gt; steps, and replay them in their test, I think that will be a huge step
&lt;br&gt;&amp;gt; forward.  Thanks for this simplification!
&lt;/div&gt;&lt;br&gt;Yeah - that's the same XML that would have come from Google Checkout.
&lt;br&gt;&lt;br&gt;Obviously if the XML from Google Checkout changes then the tests would
&lt;br&gt;need to be updated.
&lt;br&gt;&lt;br&gt;There are some traceback supplements in the getpaid.googlecheckout
&lt;br&gt;processor which log the received XML in the case of an error in the
&lt;br&gt;wild. See TracebackSupplement and NotifyTracebackSupplement of
&lt;br&gt;&lt;a href=&quot;http://code.google.com/p/getpaid/source/browse/getpaid.googlecheckout/trunk/src/getpaid/googlecheckout/googlecheckout.py&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid/source/browse/getpaid.googlecheckout/trunk/src/getpaid/googlecheckout/googlecheckout.py&lt;/a&gt;&lt;br&gt;&lt;br&gt;That should help with the process of updating the tests if there is a
&lt;br&gt;significant change in the XML from Google Checkout. Well - needs to be
&lt;br&gt;a fatal enough error to cause an exception to be thrown.
&lt;br&gt;&lt;br&gt;(Unfortunately I don't see any tests for those traceback supplements.)
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;Michael Dunstan
&lt;br&gt;&lt;br&gt;--~--~---------~--~----~------------~-------~--~----~
&lt;br&gt;GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt;&amp;nbsp;(overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt;&amp;nbsp;(code and issue tracker)
&lt;br&gt;You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
&lt;br&gt;To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26157984&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
&lt;br&gt;To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26157984&amp;i=3&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
&lt;br&gt;&lt;br&gt;For more options, visit this group at
&lt;br&gt;&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;-~----------~----~----~----~------~----~------~--~---
&lt;br&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Sprinting-on-GetPaid%3A-a-plan-tp26135182p26157984.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26156789</id>
	<title>Re: paypal payment processor</title>
	<published>2009-11-01T16:45:44Z</published>
	<updated>2009-11-01T16:45:44Z</updated>
	<author>
		<name>Juan Pablo Giménez-2</name>
	</author>
	<content type="html">&lt;div class=&quot;gmail_quote&quot;&gt;2009/10/31 Silvio &lt;span dir=&quot;ltr&quot;&gt;&amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26156789&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;silviot@...&lt;/a&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;&quot;&gt;
Hi,&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;while writing tests for the getpaid.paypal module this came to my mind:&lt;/div&gt;&lt;div&gt;the approach currently is that we don&amp;#39;t create an order if it&amp;#39;s not paid, but we instead create it after the paypal process is over and an IPN comes.&lt;/div&gt;


&lt;div&gt;Customer data is also collected on the paypal site.&lt;/div&gt;&lt;div&gt;Some customers are propably going to place an order and for some reasons (computer crash or phone call etc) wait some time before paying it, or lose their browser session.&lt;/div&gt;


&lt;div&gt;I really think we should create the order object and destroy the cart before the customer is sent to paypal, collecting data on the getpaid-enabled site as well.&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br&gt;+1, a &amp;quot;review your order&amp;quot; page should be handy to create the order without the need of js, but adds an extra click...&lt;br&gt;
&lt;br&gt;BTW, while implementing getpaid.nmi I faced another orders workflow problem. There is a subcriber to the IWorkflowTransitionEvent than when the workflow triggers to charging state tries to found the processor and call capture to get the transaction result,&lt;br&gt;
&lt;br&gt;        processor = component.getAdapter( context,&lt;br&gt;                                          interfaces.IPaymentProcessor,&lt;br&gt;                                          self.order.processor_id )&lt;br&gt;&lt;br&gt;        result = processor.capture( self.order, self.order.getTotalPrice() )&lt;br&gt;
   &lt;br&gt;        if result == interfaces.keys.results_async:&lt;br&gt;            return&lt;br&gt;        elif result == interfaces.keys.results_success:&lt;br&gt;            self.order.finance_workflow.fireTransition(&amp;#39;charge-charging&amp;#39;)&lt;br&gt;
        else:&lt;br&gt;            self.order.finance_workflow.fireTransition(&amp;#39;decline-charging&amp;#39;, comment=result)&lt;br&gt; &lt;br&gt;But we&amp;#39;re not implementing an IPaymentProcessor, so this fails and we can&amp;#39;t move the order over the wf... a real pain because without it we only have orders in the &amp;quot;REVIEWING&amp;quot; state.&lt;br&gt;
&lt;br&gt;My first fix was a change on payment.DefaultFinanceProcessorIntegration than caused some problems to Brandon.&lt;br&gt;&lt;br&gt;So after some testing I ended up with this solution,&lt;br&gt;&lt;br&gt;First I created a new Orded class inheretied from getpaid one...&lt;br&gt;
&lt;div style=&quot;margin-left: 40px;&quot;&gt;class INMIOrder(interfaces.IOrder):&lt;br&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;br&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;br&gt;    &lt;br&gt;class Order(BaseOrder):&lt;br&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;br&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;br&gt;    implements(INMIOrder)&lt;br&gt;
&lt;/div&gt;&lt;br&gt;Now the processor implements an orderid method,&lt;br&gt;&lt;div style=&quot;margin-left: 40px;&quot;&gt;    def orderid(self):&lt;br&gt;        cartutil=getUtility(IShoppingCartUtility)&lt;br&gt;        cart=cartutil.get(getSite())&lt;br&gt;        # we&amp;#39;ll get the order_manager, create the new order, and store it.&lt;br&gt;
        order_manager = getUtility(IOrderManager)&lt;br&gt;        new_order_id = order_manager.newOrderId()&lt;br&gt;        order = Order()&lt;br&gt;        &lt;br&gt;        # register the payment processor name to make the workflow handlers happy&lt;br&gt;
        order.processor_id = &amp;#39;getpaid.nmi.processor&amp;#39;&lt;br&gt;&lt;br&gt;        # FIXME: registering an empty contact information list for now - need to populate this from user&lt;br&gt;        # if possible&lt;br&gt;        order.contact_information = payment.ContactInformation()&lt;br&gt;
        order.billing_address = payment.BillingAddress()&lt;br&gt;        order.shipping_address = payment.ShippingAddress()&lt;br&gt;&lt;br&gt;        order.order_id = new_order_id&lt;br&gt;        &lt;br&gt;        # make cart safe for persistence by using pickling&lt;br&gt;
        order.shopping_cart = loads(dumps(cart))&lt;br&gt;        order.user_id = getSecurityManager().getUser().getId()&lt;br&gt;&lt;br&gt;        order.finance_workflow.fireTransition(&amp;#39;create&amp;#39;)&lt;br&gt;        order.finance_workflow.fireTransition(&amp;#39;authorize&amp;#39;)&lt;br&gt;
        &lt;br&gt;        order_manager.store(order)&lt;br&gt;&lt;br&gt;        return order.order_id&lt;br&gt;&lt;/div&gt;&lt;br&gt;To get this working I needed my own FinanceProcessorIntegrator,&lt;br&gt;&lt;div style=&quot;margin-left: 40px;&quot;&gt;class FinanceProcessorIntegration(payment.DefaultFinanceProcessorIntegration):&lt;br&gt;
&lt;br&gt;    def __call__( self, event ):&lt;br&gt;        # NMI processor is async, so just return&lt;br&gt;        return  &lt;br&gt;&lt;/div&gt;and register it,&lt;br&gt;&lt;div style=&quot;margin-left: 40px;&quot;&gt;  &amp;lt;adapter&lt;br&gt;     for=&amp;quot;.nmi.INMIOrder&lt;br&gt;          getpaid.core.interfaces.IDefaultFinanceWorkflow&amp;quot;&lt;br&gt;
     provides=&amp;quot;getpaid.core.interfaces.IWorkflowPaymentProcessorIntegration&amp;quot;&lt;br&gt;     factory=&amp;quot;.nmi.FinanceProcessorIntegration&amp;quot;&lt;br&gt;     /&amp;gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;And thats all... now I have a working orders workflow for my offsite processor...&lt;br&gt;
IMHO this could be moved to getpaid.core.processors, so offsite processors don&amp;#39;t need to worry about order creation, wf states and events, only aprove or decline orders based on external response...&lt;br&gt;&lt;br&gt;&lt;/div&gt;&lt;/div&gt;
Regards,&lt;br&gt;Juan Pablo&lt;br&gt;&lt;br&gt;
--~--~---------~--~----~------------~-------~--~----~&lt;br&gt;
GetPaid for Plone: http://www.plonegetpaid.com (overview info) | http://code.google.com/p/getpaid (code and issue tracker)
 &lt;br&gt; You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
 &lt;br&gt; To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26156789&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
 &lt;br&gt; To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26156789&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
 &lt;br&gt; &lt;p&gt;For more options, visit this group at
 &lt;br&gt; http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;br&gt;
-~----------~----~----~----~------~----~------~--~---&lt;br&gt;
&lt;br&gt;
</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/paypal-payment-processor-tp26147466p26156789.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26153480</id>
	<title>Re: paypal payment processor</title>
	<published>2009-11-01T10:29:52Z</published>
	<updated>2009-11-01T10:29:52Z</updated>
	<author>
		<name>silviot</name>
	</author>
	<content type="html">Two more things I forgot to mention:&lt;div&gt;The proposed workflow is intended to provide a sane user experience allowing the site manager to mix &lt;/div&gt;&lt;div&gt;cash on delivery, onsite payments as well as offsite payments with a similar process.&lt;/div&gt;

&lt;div&gt;I think they don&amp;#39;t mix well in the current implementation.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;         Silvio&lt;/div&gt;&lt;br&gt;
--~--~---------~--~----~------------~-------~--~----~&lt;br&gt;
GetPaid for Plone: http://www.plonegetpaid.com (overview info) | http://code.google.com/p/getpaid (code and issue tracker)
 &lt;br&gt; You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
 &lt;br&gt; To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26153480&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
 &lt;br&gt; To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26153480&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
 &lt;br&gt; &lt;p&gt;For more options, visit this group at
 &lt;br&gt; http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;br&gt;
-~----------~----~----~----~------~----~------~--~---&lt;br&gt;
&lt;br&gt;
</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/paypal-payment-processor-tp26147466p26153480.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26152187</id>
	<title>specifying version of five.intid</title>
	<published>2009-11-01T07:54:30Z</published>
	<updated>2009-11-01T07:54:30Z</updated>
	<author>
		<name>sunew-2</name>
	</author>
	<content type="html">&lt;br&gt;Hey everybody,
&lt;br&gt;&lt;br&gt;Just thought I would share how to override the versions specified in
&lt;br&gt;getpaid.recipe.release. If an egg is specified directly in the part of
&lt;br&gt;the recipe, the version can be overridden/unpinned.
&lt;br&gt;&lt;br&gt;If the recipe is used like this:
&lt;br&gt;&lt;br&gt;[getpaid]
&lt;br&gt;recipe = getpaid.recipe.release
&lt;br&gt;eggs =
&lt;br&gt;&amp;nbsp; &amp;nbsp; five.intid
&lt;br&gt;&lt;br&gt;&lt;br&gt;five.intid will be unpinned.
&lt;br&gt;&lt;br&gt;You can then, if needed, specify another version to pin in the
&lt;br&gt;[versions]-section of your buildout.
&lt;br&gt;&lt;br&gt;Thanks to Maurits van Rees for writing about this in his blog here:
&lt;br&gt;&lt;a href=&quot;http://maurits.vanrees.org/weblog/archive/2008/01/easily-creating-repeatable-buildouts&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://maurits.vanrees.org/weblog/archive/2008/01/easily-creating-repeatable-buildouts&lt;/a&gt;&lt;br&gt;&lt;br&gt;Happy sprinting,
&lt;br&gt;Sune B. Wøller
&lt;br&gt;&lt;br&gt;--~--~---------~--~----~------------~-------~--~----~
&lt;br&gt;GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt;&amp;nbsp;(overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt;&amp;nbsp;(code and issue tracker)
&lt;br&gt;You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
&lt;br&gt;To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26152187&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
&lt;br&gt;To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26152187&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
&lt;br&gt;&lt;br&gt;For more options, visit this group at
&lt;br&gt;&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;-~----------~----~----~----~------~----~------~--~---
&lt;br&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/specifying-version-of-five.intid-tp26152187p26152187.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26151983</id>
	<title>Re: paypal payment processor</title>
	<published>2009-11-01T07:34:40Z</published>
	<updated>2009-11-01T07:34:40Z</updated>
	<author>
		<name>silviot</name>
	</author>
	<content type="html">&lt;div class=&quot;gmail_quote&quot;&gt;On Sun, Nov 1, 2009 at 2:23 PM, Brandon Craig Rhodes &lt;span dir=&quot;ltr&quot;&gt;&amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26151983&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;brandon@...&lt;/a&gt;&amp;gt;&lt;/span&gt; wrote:&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;&quot;&gt;

First:&lt;br&gt;
&lt;br&gt;
I am &amp;quot;-1&amp;quot; on destroying the cart. &lt;br&gt;&lt;/blockquote&gt;&lt;div&gt;I probably was not clear enough. This morning Lee Joramo drew a very useful diagram that shows what my proposal looks like.&lt;/div&gt;&lt;div&gt;I just uploaded it to Google wiki, together with the email where I expose my ideas. Check it out at &lt;/div&gt;

&lt;div&gt;&lt;a href=&quot;http://code.google.com/p/getpaid/wiki/NewOrderWorkflowProposal&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid/wiki/NewOrderWorkflowProposal&lt;/a&gt; &lt;/div&gt;&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;&quot;&gt;


So, again, we should not destroy the cart until we know the customer has&lt;br&gt;
succeeded in paying; and, second, when we do get payment notification we&lt;br&gt;
shouldn&amp;#39;t &amp;quot;destroy&amp;quot; the cart, we should just remove from it whichever&lt;br&gt;
items were actually paid for, using the little list of items that PayPal&lt;br&gt;
will send us back in their IPN message.&lt;/blockquote&gt;&lt;div&gt;I&amp;#39;m -1 about this because it doesn&amp;#39;t fit my usecases (but I am aware I&amp;#39;m biased here) and because it seems harder to implement than necessary.&lt;/div&gt;&lt;div&gt;

&lt;br&gt;&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;&quot;&gt; &lt;/blockquote&gt;&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;&quot;&gt;


Second:&lt;br&gt;
&lt;br&gt;
I have a less strong opinion on creating an Order before they actually&lt;br&gt;
leave the site.  The issues would seem to be:&lt;br&gt;
&lt;br&gt;
Con&lt;br&gt;
&lt;br&gt;
* Orders are designed to hold information, but in this case there&amp;#39;s&lt;br&gt;
  nothing to store except the fact that the user pressed &amp;quot;Checkout&amp;quot; and&lt;br&gt;
  left the site.  You&amp;#39;d have all these orders sitting around with&lt;br&gt;
  nothing but an order number and a copy of a cart inside of them,&lt;br&gt;
  because the user reached PayPal and was annoyed with its interface and&lt;br&gt;
  decided not to check out after all.&lt;br&gt;&lt;/blockquote&gt;&lt;div&gt;I meant to ask for user info on our site before the payment, and have the paypal forms automatically filled with the data provided to us. &lt;/div&gt;&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;&quot;&gt;


&lt;br&gt; (I don&amp;#39;t know many store owners, I must admit, but rumor has it&lt;br&gt;
  that they tend to like customers to be as few clicks away from&lt;br&gt;
  finishing paying as possible!).&lt;/blockquote&gt;&lt;div&gt;This is why we should trat anonymous (no user/password) checkout as a first class citizen.&lt;/div&gt;&lt;div&gt;In my experience, at least for the Italian users I&amp;#39;m used to and the kind of business I developed for, asking for a username/password is a thing that I need to avoid as much as possible.&lt;/div&gt;

&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;&quot;&gt;
But, it seems to me that this mechanism uses space, time, and additional&lt;br&gt;
complexity, in order to accomplish something that the off-site service&lt;br&gt;
does anyway.&lt;br&gt;&lt;/blockquote&gt;&lt;div&gt;It does use space. I think store owners might be happy with the extra space requirements if it translates to a better user experience.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;&quot;&gt;


But, I&amp;#39;m not an actual Store Owner, so I&amp;#39;m quite open to changing my&lt;br&gt;
opinion here based on actual GetPaid users if they (or you) would like&lt;br&gt;
to share more about how they actually use the service in practice.&lt;/blockquote&gt;&lt;div&gt;I&amp;#39;d like to hear more opinions about this too. What do you all think on this ML?&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;&quot;&gt;

&lt;div class=&quot;im&quot;&gt;
&amp;gt; We could then provide the &amp;quot;pay with paypal&amp;quot; button on the order&lt;br&gt;
&amp;gt; summary page.&lt;br&gt;
&lt;br&gt;
&lt;/div&gt;Ah!  I see!  You are not advocating JavaScript, you&amp;#39;re advocating&lt;br&gt;
two-step checkout process: the person sees their cart and presses&lt;br&gt;
&amp;quot;Checkout&amp;quot;, then is shown their cart *again* and has to press &amp;quot;PayPal&lt;br&gt;
Checkout&amp;quot; to actually go off-site.&lt;br&gt;&lt;/blockquote&gt;&lt;div&gt;Yes, I&amp;#39;m really positive this is not an issue. I never had the impression any of my users (I use the described approach in production, and it works well) had anything to complain about.  &lt;/div&gt;

&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;&quot;&gt;&lt;div class=&quot;im&quot;&gt;&amp;gt; BTW, we should also fix the personal details form and separate &amp;quot;first&lt;br&gt;
&amp;gt; name&amp;quot; from &amp;quot;surname&amp;quot;: we can&amp;#39;t programmatically split &amp;quot;Full name&amp;quot; when&lt;br&gt;
&amp;gt; we pass it to paypal.&lt;br&gt;
&lt;br&gt;
&lt;/div&gt;I&amp;#39;m certainly not an expert on this area, but two objections immediately&lt;br&gt;
occur to me:&lt;br&gt;
&lt;br&gt;
1. Isn&amp;#39;t the personal details page something that&amp;#39;s a Plone-wide&lt;br&gt;
   standard and that we can&amp;#39;t change?  Surely we don&amp;#39;t want that form to&lt;br&gt;
   change on the day that someone adds GetPaid to a site that&amp;#39;s been&lt;br&gt;
   maybe running for years, and have to go back through and add two&lt;br&gt;
   names to all of their users before proceeding?&lt;br&gt;
&lt;br&gt;
2. The first+last formula doesn&amp;#39;t work everywhere in the world - nor&lt;br&gt;
   even with everyone in a large university.  I think that&amp;#39;s why Plone&lt;br&gt;
   has a free-form field.&lt;br&gt;
&lt;br&gt;
If PayPal needs first and last, I suspect that we will just have to do&lt;br&gt;
our best using .split() and so forth with the normal Plone name field.&lt;br&gt;
But, again, I could easily be wrong here!&lt;/blockquote&gt;&lt;div&gt;-1000: programmatically splitting name and surname can lead to weird results. I would never ever do that. &lt;/div&gt;&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;&quot;&gt;

 &lt;/blockquote&gt;&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;&quot;&gt;&lt;div class=&quot;im&quot;&gt;
&amp;gt; One more issue: anonymous users can&amp;#39;t see their own orders, so they&lt;br&gt;
&amp;gt; wouldn&amp;#39;t be able to pay with the described setup.&lt;br&gt;
&lt;br&gt;
&lt;/div&gt;Can they pay with my proposed setup?  They would just click &amp;quot;Check out&lt;br&gt;
with PayPal&amp;quot; and be immediately whisked off-site?&lt;br&gt;&lt;/blockquote&gt;&lt;div&gt;I&amp;#39;m actually proposing to change that, and ask for name/address before sending them to paypal. &lt;/div&gt;&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;&quot;&gt;


&lt;div class=&quot;im&quot;&gt;&lt;br&gt;
&amp;gt; We could solve this providing a token in the emails we send after the&lt;br&gt;
&amp;gt; order is created; the token could be the md5 hash of the date and time&lt;br&gt;
&lt;/div&gt;&amp;gt; of the order. ... What do you think?&lt;br&gt;
&lt;br&gt;
A strongly random UUID, not the date and time, is what is needed here&lt;br&gt;
for each Order; but, aside from that, your idea is a very good one!&lt;br&gt;
It&amp;#39;s just like the Tracking links that lots of sites send out: because&lt;br&gt;
no one else can guess a 30-character random string, the URL is&lt;br&gt;
essentially private to whomever reads the email.  That would be a nice&lt;br&gt;
way for people (at least who type their emails correctly) to have a way&lt;br&gt;
back to their Order.  Plus, on the final Order page itself we could say&lt;br&gt;
&amp;quot;to visit this later, bookmark...&amp;quot; and have the link there too.&lt;br&gt;&lt;/blockquote&gt;&lt;div&gt;Good, that should be some attribute on the order, randomly generated on order creation.&lt;/div&gt;&lt;div&gt;This also leaves room for some improvement: in case we need the order url to expire, we could store an expiration date with the token and let the user ask for a new url in case it&amp;#39;s expired, providing their email address.&lt;/div&gt;

&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;   Silvio&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;/div&gt;&lt;br&gt;
--~--~---------~--~----~------------~-------~--~----~&lt;br&gt;
GetPaid for Plone: http://www.plonegetpaid.com (overview info) | http://code.google.com/p/getpaid (code and issue tracker)
 &lt;br&gt; You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
 &lt;br&gt; To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26151983&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
 &lt;br&gt; To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26151983&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
 &lt;br&gt; &lt;p&gt;For more options, visit this group at
 &lt;br&gt; http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;br&gt;
-~----------~----~----~----~------~----~------~--~---&lt;br&gt;
&lt;br&gt;
</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/paypal-payment-processor-tp26147466p26151983.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26150829</id>
	<title>Re: paypal payment processor</title>
	<published>2009-11-01T05:23:13Z</published>
	<updated>2009-11-01T05:23:13Z</updated>
	<author>
		<name>Brandon Craig Rhodes</name>
	</author>
	<content type="html">&lt;br&gt;Silvio &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26150829&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;silviot@...&lt;/a&gt;&amp;gt; writes:
&lt;br&gt;&lt;br&gt;&amp;gt; I really think we should create the order object and destroy the cart
&lt;br&gt;&amp;gt; before the customer is sent to paypal, collecting data on the
&lt;br&gt;&amp;gt; getpaid-enabled site as well.
&lt;br&gt;&lt;br&gt;First:
&lt;br&gt;&lt;br&gt;I am &amp;quot;-1&amp;quot; on destroying the cart. &amp;nbsp;If the HTTP forwarding to PayPal
&lt;br&gt;fails - if, say, there is a DNS glitch or their Internet connection goes
&lt;br&gt;down for a moment - then the user will have to return to the store to
&lt;br&gt;press &amp;quot;Checkout&amp;quot; again, but all the hard work to fill their cart will be
&lt;br&gt;gone. &amp;nbsp;They'll have to go all over the site again, refilling their cart,
&lt;br&gt;and then maybe find that their link to PayPal is down *again* when they
&lt;br&gt;finish and hit &amp;quot;Checkout&amp;quot; the second time - and now, again, their cart
&lt;br&gt;is destroyed and gone. &amp;nbsp;This is not an acceptable customer experience.
&lt;br&gt;&lt;br&gt;In crafting the customer experience, in fact, I'm going to consistently
&lt;br&gt;argue that we should be acting as much like Amazon as possible, because
&lt;br&gt;I think that their approach works extremely well. &amp;nbsp;It looks like neither
&lt;br&gt;GetPaid nor Satchmo has spent enough time looking at corner cases that
&lt;br&gt;Amazon handles well and trying to emulate them. &amp;nbsp;For example: it is
&lt;br&gt;actually irresponsible to empty the cart upon payment, because the user,
&lt;br&gt;in another browser tab, might have already added new items to their
&lt;br&gt;shopping cart that are not line items in the order they're checking out
&lt;br&gt;with. &amp;nbsp;Amazon handles this entirely correctly: if I put A and B in my
&lt;br&gt;shopping cart, then press &amp;quot;Checkout&amp;quot;, then while waiting for one of the
&lt;br&gt;checkout screens to process I open another tab and put C in my cart - so
&lt;br&gt;that my cart now has A, B, and C, in it - then when the payment goes
&lt;br&gt;through only A and B disappear from my cart and C is still there,
&lt;br&gt;waiting for me to start a new purchase.
&lt;br&gt;&lt;br&gt;So, again, we should not destroy the cart until we know the customer has
&lt;br&gt;succeeded in paying; and, second, when we do get payment notification we
&lt;br&gt;shouldn't &amp;quot;destroy&amp;quot; the cart, we should just remove from it whichever
&lt;br&gt;items were actually paid for, using the little list of items that PayPal
&lt;br&gt;will send us back in their IPN message.
&lt;br&gt;&lt;br&gt;Second:
&lt;br&gt;&lt;br&gt;I have a less strong opinion on creating an Order before they actually
&lt;br&gt;leave the site. &amp;nbsp;The issues would seem to be:
&lt;br&gt;&lt;br&gt;Con
&lt;br&gt;&lt;br&gt;* Orders are designed to hold information, but in this case there's
&lt;br&gt;&amp;nbsp; nothing to store except the fact that the user pressed &amp;quot;Checkout&amp;quot; and
&lt;br&gt;&amp;nbsp; left the site. &amp;nbsp;You'd have all these orders sitting around with
&lt;br&gt;&amp;nbsp; nothing but an order number and a copy of a cart inside of them,
&lt;br&gt;&amp;nbsp; because the user reached PayPal and was annoyed with its interface and
&lt;br&gt;&amp;nbsp; decided not to check out after all.
&lt;br&gt;&lt;br&gt;* It requires a JavaScript trick: the &amp;quot;PayPal&amp;quot; button actually has to
&lt;br&gt;&amp;nbsp; redirect to an internal page that creates the order and then uses
&lt;br&gt;&amp;nbsp; JavaScript to press the &amp;quot;Submit&amp;quot; button on the actual form that POSTs
&lt;br&gt;&amp;nbsp; to PayPal. &amp;nbsp;If the JavaScript doesn't work with their browser, then
&lt;br&gt;&amp;nbsp; the &amp;quot;PayPal checkout&amp;quot; button will just have taken them to a screen
&lt;br&gt;&amp;nbsp; with another PayPal checkout button, and making users click twice to
&lt;br&gt;&amp;nbsp; leave the site is something that lots of store owners might want to
&lt;br&gt;&amp;nbsp; avoid (I don't know many store owners, I must admit, but rumor has it
&lt;br&gt;&amp;nbsp; that they tend to like customers to be as few clicks away from
&lt;br&gt;&amp;nbsp; finishing paying as possible!).
&lt;br&gt;&lt;br&gt;Pro
&lt;br&gt;&lt;br&gt;* Using the user IDs and timestamps on all of those empty Order objects,
&lt;br&gt;&amp;nbsp; you could see how many visitors filled their cart then pressed
&lt;br&gt;&amp;nbsp; &amp;quot;Checkout&amp;quot; without completing the process.
&lt;br&gt;&lt;br&gt;Please add any more Pro and Con here that you can think of!
&lt;br&gt;&lt;br&gt;But, it seems to me that this mechanism uses space, time, and additional
&lt;br&gt;complexity, in order to accomplish something that the off-site service
&lt;br&gt;does anyway. &amp;nbsp;I mean, the off-site service has several steps in its
&lt;br&gt;checkout process, and if you want analytics on checkout process
&lt;br&gt;abandonment you've got to go check out whatever stats PayPal keeps for
&lt;br&gt;you, to see who left the process and quit at which stages in the
&lt;br&gt;checkout. &amp;nbsp;And, since you have to use PayPal to get complete analytics
&lt;br&gt;anyway, why invest in extra complexity on our end just to keep a
&lt;br&gt;duplicate copy of one of the several numbers?
&lt;br&gt;&lt;br&gt;But, I'm not an actual Store Owner, so I'm quite open to changing my
&lt;br&gt;opinion here based on actual GetPaid users if they (or you) would like
&lt;br&gt;to share more about how they actually use the service in practice.
&lt;br&gt;&lt;br&gt;&amp;gt; We could then provide the &amp;quot;pay with paypal&amp;quot; button on the order
&lt;br&gt;&amp;gt; summary page.
&lt;br&gt;&lt;br&gt;Ah! &amp;nbsp;I see! &amp;nbsp;You are not advocating JavaScript, you're advocating
&lt;br&gt;two-step checkout process: the person sees their cart and presses
&lt;br&gt;&amp;quot;Checkout&amp;quot;, then is shown their cart *again* and has to press &amp;quot;PayPal
&lt;br&gt;Checkout&amp;quot; to actually go off-site. &amp;nbsp;
&lt;br&gt;&lt;br&gt;&amp;gt; It would also simplify the solution of a bug with the current
&lt;br&gt;&amp;gt; implementation; the function order_id of the view
&lt;br&gt;&amp;gt; getpaid.paypal.views.PayPalCheckoutButton is:
&lt;br&gt;&amp;gt; &amp;nbsp;30 &amp;nbsp; &amp;nbsp; def order_id(self):
&lt;br&gt;&amp;gt; &amp;nbsp;31 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 'PUT ORDER ID HERE'
&lt;br&gt;&amp;gt; and it would be handy to have the actual order id available when we
&lt;br&gt;&amp;gt; create the button.
&lt;br&gt;&lt;br&gt;My proposal, which I entirely forgot to mention in the sprint docs, is
&lt;br&gt;that every time we generate the &amp;quot;PayPal&amp;quot; form - which might be dozens of
&lt;br&gt;times, at least, during each person's shopping experience - we generate
&lt;br&gt;a fake &amp;quot;Order Id&amp;quot; that embeds the user's Plone ID somewhere secretly
&lt;br&gt;inside of it. &amp;nbsp;That way, when we later get an IPN message for that Order
&lt;br&gt;and see that it doesn't exist yet, we can create it and auto-associate
&lt;br&gt;it with the right cart owner using their embedded Plone Id.
&lt;br&gt;&lt;br&gt;But before coding this I wanted to have everyone else think through
&lt;br&gt;whether this would raise any security concerns (I can't see any myself)
&lt;br&gt;and I wanted opinions on whether it should be explicit, where the user
&lt;br&gt;themselves (if they check) could see that the order number is
&lt;br&gt;&amp;quot;69391959632-brhodes&amp;quot;, or whether we should encode it somehow as part of
&lt;br&gt;the order number so that it looks like numbers or hex codes too.
&lt;br&gt;&lt;br&gt;&amp;gt; BTW, we should also fix the personal details form and separate &amp;quot;first
&lt;br&gt;&amp;gt; name&amp;quot; from &amp;quot;surname&amp;quot;: we can't programmatically split &amp;quot;Full name&amp;quot; when
&lt;br&gt;&amp;gt; we pass it to paypal.
&lt;br&gt;&lt;br&gt;I'm certainly not an expert on this area, but two objections immediately
&lt;br&gt;occur to me:
&lt;br&gt;&lt;br&gt;1. Isn't the personal details page something that's a Plone-wide
&lt;br&gt;&amp;nbsp; &amp;nbsp;standard and that we can't change? &amp;nbsp;Surely we don't want that form to
&lt;br&gt;&amp;nbsp; &amp;nbsp;change on the day that someone adds GetPaid to a site that's been
&lt;br&gt;&amp;nbsp; &amp;nbsp;maybe running for years, and have to go back through and add two
&lt;br&gt;&amp;nbsp; &amp;nbsp;names to all of their users before proceeding?
&lt;br&gt;&lt;br&gt;2. The first+last formula doesn't work everywhere in the world - nor
&lt;br&gt;&amp;nbsp; &amp;nbsp;even with everyone in a large university. &amp;nbsp;I think that's why Plone
&lt;br&gt;&amp;nbsp; &amp;nbsp;has a free-form field.
&lt;br&gt;&lt;br&gt;If PayPal needs first and last, I suspect that we will just have to do
&lt;br&gt;our best using .split() and so forth with the normal Plone name field.
&lt;br&gt;But, again, I could easily be wrong here!
&lt;br&gt;&lt;br&gt;&amp;gt; One more issue: anonymous users can't see their own orders, so they
&lt;br&gt;&amp;gt; wouldn't be able to pay with the described setup.
&lt;br&gt;&lt;br&gt;Can they pay with my proposed setup? &amp;nbsp;They would just click &amp;quot;Check out
&lt;br&gt;with PayPal&amp;quot; and be immediately whisked off-site?
&lt;br&gt;&lt;br&gt;&amp;gt; We could solve this providing a token in the emails we send after the
&lt;br&gt;&amp;gt; order is created; the token could be the md5 hash of the date and time
&lt;br&gt;&amp;gt; of the order. ... What do you think?
&lt;br&gt;&lt;br&gt;A strongly random UUID, not the date and time, is what is needed here
&lt;br&gt;for each Order; but, aside from that, your idea is a very good one!
&lt;br&gt;It's just like the Tracking links that lots of sites send out: because
&lt;br&gt;no one else can guess a 30-character random string, the URL is
&lt;br&gt;essentially private to whomever reads the email. &amp;nbsp;That would be a nice
&lt;br&gt;way for people (at least who type their emails correctly) to have a way
&lt;br&gt;back to their Order. &amp;nbsp;Plus, on the final Order page itself we could say
&lt;br&gt;&amp;quot;to visit this later, bookmark...&amp;quot; and have the link there too.
&lt;br&gt;&lt;br&gt;Anyway, please feel free to provide ideas, thoughts, and counter-objects
&lt;br&gt;to anything above!
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;Brandon Craig Rhodes &amp;nbsp; &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26150829&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;brandon@...&lt;/a&gt; &amp;nbsp; &lt;a href=&quot;http://rhodesmill.org/brandon&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://rhodesmill.org/brandon&lt;/a&gt;&lt;br&gt;&lt;br&gt;--~--~---------~--~----~------------~-------~--~----~
&lt;br&gt;GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt;&amp;nbsp;(overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt;&amp;nbsp;(code and issue tracker)
&lt;br&gt;You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
&lt;br&gt;To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26150829&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
&lt;br&gt;To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26150829&amp;i=3&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
&lt;br&gt;&lt;br&gt;For more options, visit this group at
&lt;br&gt;&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;-~----------~----~----~----~------~----~------~--~---
&lt;br&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/paypal-payment-processor-tp26147466p26150829.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26150573</id>
	<title>Re: Sprinting on GetPaid: a plan</title>
	<published>2009-11-01T04:48:21Z</published>
	<updated>2009-11-01T04:48:21Z</updated>
	<author>
		<name>Brandon Craig Rhodes</name>
	</author>
	<content type="html">&lt;br&gt;Michael Dunstan &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26150573&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;michael.dunstan@...&lt;/a&gt;&amp;gt; writes:
&lt;br&gt;&lt;br&gt;&amp;gt; The Google Checkout processor tests fabricate the incoming signals
&lt;br&gt;&amp;gt; from the checkout server...
&lt;br&gt;&lt;br&gt;Well, that's an interesting idea! &amp;nbsp;At first it sounds like an
&lt;br&gt;unconvincing test, but I guess if the XML you injected in the test was
&lt;br&gt;actual real XML from Google that you'd captured during a by-hand test of
&lt;br&gt;the callback, then you are indeed testing against real data and real
&lt;br&gt;Google behavior. &amp;nbsp;I like the approach enough to be comfortable with it!
&lt;br&gt;If the sprinters want to kick off a callback from PayPal, capture the
&lt;br&gt;steps, and replay them in their test, I think that will be a huge step
&lt;br&gt;forward. &amp;nbsp;Thanks for this simplification!
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;Brandon Craig Rhodes &amp;nbsp; &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26150573&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;brandon@...&lt;/a&gt; &amp;nbsp; &lt;a href=&quot;http://rhodesmill.org/brandon&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://rhodesmill.org/brandon&lt;/a&gt;&lt;br&gt;&lt;br&gt;--~--~---------~--~----~------------~-------~--~----~
&lt;br&gt;GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt;&amp;nbsp;(overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt;&amp;nbsp;(code and issue tracker)
&lt;br&gt;You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
&lt;br&gt;To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26150573&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
&lt;br&gt;To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26150573&amp;i=3&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
&lt;br&gt;&lt;br&gt;For more options, visit this group at
&lt;br&gt;&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;-~----------~----~----~----~------~----~------~--~---
&lt;br&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Sprinting-on-GetPaid%3A-a-plan-tp26135182p26150573.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26147466</id>
	<title>paypal payment processor</title>
	<published>2009-10-31T17:46:49Z</published>
	<updated>2009-10-31T17:46:49Z</updated>
	<author>
		<name>silviot</name>
	</author>
	<content type="html">Hi,&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;while writing tests for the getpaid.paypal module this came to my mind:&lt;/div&gt;&lt;div&gt;the approach currently is that we don&amp;#39;t create an order if it&amp;#39;s not paid, but we instead create it after the paypal process is over and an IPN comes.&lt;/div&gt;

&lt;div&gt;Customer data is also collected on the paypal site.&lt;/div&gt;&lt;div&gt;Some customers are propably going to place an order and for some reasons (computer crash or phone call etc) wait some time before paying it, or lose their browser session.&lt;/div&gt;

&lt;div&gt;I really think we should create the order object and destroy the cart before the customer is sent to paypal, collecting data on the getpaid-enabled site as well.&lt;/div&gt;&lt;div&gt;We could then provide the &amp;quot;pay with paypal&amp;quot; button on the order summary page. This would allow orders to be paid after they have been taken.&lt;/div&gt;

&lt;div&gt;It would also simplify the solution of a bug with the current implementation; the function order_id of the view getpaid.paypal.views.PayPalCheckoutButton is:&lt;/div&gt;&lt;div&gt;&lt;div&gt; 30     def order_id(self):&lt;/div&gt;&lt;div&gt; 31         return &amp;#39;PUT ORDER ID HERE&amp;#39;&lt;/div&gt;

&lt;div&gt;and it would be handy to have the actual order id available when we create the button.&lt;/div&gt;&lt;div&gt;BTW, we should also fix the personal details form and separate &amp;quot;first name&amp;quot; from &amp;quot;surname&amp;quot;: we can&amp;#39;t programmatically split &amp;quot;Full name&amp;quot; when we pass it to paypal.&lt;/div&gt;

&lt;div&gt;One more issue: anonymous users can&amp;#39;t see their own orders, so they wouldn&amp;#39;t be able to pay with the described setup.&lt;/div&gt;&lt;div&gt;We could solve this providing a token in the emails we send after the order is created; the token could be the md5 hash of the date and time of the order.&lt;/div&gt;

&lt;div&gt;Would this be secure enough? It would prevent a random person from collecting personal data of users, would it?&lt;/div&gt;&lt;div&gt;I currently use this approach in production and, at least for me, it has worked well; but I&amp;#39;m not sure it&amp;#39;s secure enough. Anyway, users like *a lot* not to be forced to remember username/password pairs. This would also allow them to email the link to the order details page to a friend, and he could see only that particular order. This could be useful for gifts if the recipient wants to check the shipping status.&lt;/div&gt;

&lt;div&gt;What do you think?&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;         Silvio&lt;/div&gt;&lt;/div&gt;&lt;br&gt;
--~--~---------~--~----~------------~-------~--~----~&lt;br&gt;
GetPaid for Plone: http://www.plonegetpaid.com (overview info) | http://code.google.com/p/getpaid (code and issue tracker)
 &lt;br&gt; You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
 &lt;br&gt; To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26147466&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
 &lt;br&gt; To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26147466&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
 &lt;br&gt; &lt;p&gt;For more options, visit this group at
 &lt;br&gt; http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;br&gt;
-~----------~----~----~----~------~----~------~--~---&lt;br&gt;
&lt;br&gt;
</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/paypal-payment-processor-tp26147466p26147466.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26143144</id>
	<title>Re: Sprinting on GetPaid: a plan</title>
	<published>2009-10-31T08:09:28Z</published>
	<updated>2009-10-31T08:09:28Z</updated>
	<author>
		<name>Mikko Ohtamaa</name>
	</author>
	<content type="html">&lt;br&gt;&amp;gt;&amp;gt; &amp;gt; My vote would be against a default &amp;quot;buildout.cfg&amp;quot; in Subversion if we're
&lt;br&gt;&amp;gt;&amp;gt; &amp;gt; going to support multiple versions of Plone; it just makes it too
&lt;br&gt;&amp;gt;&amp;gt; &amp;gt; dangerous, in my opinion, for people working on some other version.  If
&lt;br&gt;&amp;gt;&amp;gt; &amp;gt; you run &amp;quot;buildout&amp;quot; without choosing a version, that error message is
&lt;br&gt;&amp;gt;&amp;gt; &amp;gt; necessary to remind you that the choice must be made.
&lt;br&gt;&amp;gt;&amp;gt;
&lt;br&gt;&lt;br&gt;Extending buildout is much better way than having a default buildout
&lt;br&gt;for each version. buildourt.cfg might be different depending on
&lt;br&gt;installer and OS - we do not want to support that variation. If you
&lt;br&gt;want to see the heacache check out buildout.cfg in Windows installer.
&lt;br&gt;Instead we could provide different extension for each Plone version if
&lt;br&gt;version soup is a problem.
&lt;br&gt;&lt;br&gt;I suggest we use combination of extends and  [versions] to deal with
&lt;br&gt;versioning problems.
&lt;br&gt;E.g.
&lt;br&gt;[buildout]
&lt;br&gt;extends = &lt;a href=&quot;http://dist.plone.org/release/3.3/versions.cfg&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://dist.plone.org/release/3.3/versions.cfg&lt;/a&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;a href=&quot;http://svn.plone.org/svn/collective/getpaid.buildout/getpaid_for_3.3.cfg&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://svn.plone.org/svn/collective/getpaid.buildout/getpaid_for_3.3.cfg&lt;/a&gt;&lt;br&gt;&lt;br&gt;getpaid_for_3.3.cfg contains
&lt;br&gt;&lt;br&gt;[versions]
&lt;br&gt;Products.PloneGetPaid=0.8
&lt;br&gt;getpaid.somepackage=0.7
&lt;br&gt;...
&lt;br&gt;&lt;br&gt;vs.
&lt;br&gt;&lt;br&gt;[buildout]
&lt;br&gt;extends = &lt;a href=&quot;http://dist.plone.org/release/4.0/versions.cfg&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://dist.plone.org/release/4.0/versions.cfg&lt;/a&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;a href=&quot;http://svn.plone.org/svn/collective/getpaid.buildout/getpaid_for_4.0.cfg&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://svn.plone.org/svn/collective/getpaid.buildout/getpaid_for_4.0.cfg&lt;/a&gt;&lt;br&gt;&lt;br&gt;-Mikko
&lt;br&gt;&lt;br&gt;--~--~---------~--~----~------------~-------~--~----~
&lt;br&gt;GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt;&amp;nbsp;(overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt;&amp;nbsp;(code and issue tracker)
&lt;br&gt;You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
&lt;br&gt;To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26143144&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
&lt;br&gt;To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26143144&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
&lt;br&gt;&lt;br&gt;For more options, visit this group at
&lt;br&gt;&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;-~----------~----~----~----~------~----~------~--~---
&lt;br&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Sprinting-on-GetPaid%3A-a-plan-tp26135182p26143144.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26141927</id>
	<title>Re: Sprinting on GetPaid: a plan</title>
	<published>2009-10-31T05:14:20Z</published>
	<updated>2009-10-31T05:14:20Z</updated>
	<author>
		<name>silviot</name>
	</author>
	<content type="html">&lt;div class=&quot;gmail_quote&quot;&gt;2009/10/31 Juan Pablo Giménez &lt;span dir=&quot;ltr&quot;&gt;&amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26141927&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;jpg@...&lt;/a&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;&quot;&gt;

&lt;br&gt;
El vie, 30-10-2009 a las 19:21 -0400, Brandon Craig Rhodes escribió:&lt;br&gt;
&lt;div class=&quot;im&quot;&gt;&amp;gt; Silvio &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26141927&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;silviot@...&lt;/a&gt;&amp;gt; writes:&lt;br&gt;
&amp;gt;&lt;br&gt;
&amp;gt; &amp;gt; I forgot to specify the cfg file here (as I don&amp;#39;t usually do) and it&lt;br&gt;
&amp;gt; &amp;gt; didn&amp;#39;t work.  So I added a buildout.cfg that loads 316.cfg to be used&lt;br&gt;
&amp;gt; &amp;gt; as a default for the latest supported version.&lt;br&gt;
&amp;gt;&lt;br&gt;
&amp;gt; The &amp;quot;buildout.cfg&amp;quot; used to be the one for Plone 2.5.5, which was never&lt;br&gt;
&amp;gt; the version I wanted, and I got tired of ruining my buildout every time&lt;br&gt;
&amp;gt; that I forgot and re-ran &amp;quot;buildout&amp;quot; without any arguments. :-)&lt;br&gt;
&amp;gt;&lt;br&gt;
&amp;gt; My vote would be against a default &amp;quot;buildout.cfg&amp;quot; in Subversion if we&amp;#39;re&lt;br&gt;
&amp;gt; going to support multiple versions of Plone; it just makes it too&lt;br&gt;
&amp;gt; dangerous, in my opinion, for people working on some other version.  If&lt;br&gt;
&amp;gt; you run &amp;quot;buildout&amp;quot; without choosing a version, that error message is&lt;br&gt;
&amp;gt; necessary to remind you that the choice must be made.&lt;br&gt;
&lt;br&gt;
&lt;/div&gt;+1&lt;/blockquote&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Ok, sorry for committing that change without asking: I didn&amp;#39;t think the choice of not having a buildout.cfg was intentional.&lt;/div&gt;&lt;div&gt;I stay however on my point that we should have a sensible default buildout.cfg that actually extends the buildout for the latest supported Plone.&lt;/div&gt;

&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;       Silvio&lt;/div&gt;&lt;/div&gt;&lt;br&gt;
--~--~---------~--~----~------------~-------~--~----~&lt;br&gt;
GetPaid for Plone: http://www.plonegetpaid.com (overview info) | http://code.google.com/p/getpaid (code and issue tracker)
 &lt;br&gt; You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
 &lt;br&gt; To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26141927&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
 &lt;br&gt; To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26141927&amp;i=3&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
 &lt;br&gt; &lt;p&gt;For more options, visit this group at
 &lt;br&gt; http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;br&gt;
-~----------~----~----~----~------~----~------~--~---&lt;br&gt;
&lt;br&gt;
</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Sprinting-on-GetPaid%3A-a-plan-tp26135182p26141927.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26141835</id>
	<title>Re: Sprinting on GetPaid: a plan</title>
	<published>2009-10-31T05:12:11Z</published>
	<updated>2009-10-31T05:12:11Z</updated>
	<author>
		<name>Brandon Craig Rhodes</name>
	</author>
	<content type="html">&lt;br&gt;Juan Pablo Giménez &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26141835&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;jpg@...&lt;/a&gt;&amp;gt; writes:
&lt;br&gt;&lt;br&gt;&amp;gt; I'm not using orders workflow because
&lt;br&gt;&amp;gt; DefaultFinanceProcessorIntegration is tied to IPaymentProcessor and we
&lt;br&gt;&amp;gt; are implementing IOffsitePaymentProcessor, that was what I changed on
&lt;br&gt;&amp;gt; getpaid.core.payment and you reverted (brandon)...
&lt;br&gt;&lt;br&gt;I reverted the change because it broke GetPaid for me and I couldn't
&lt;br&gt;understand why it was there. &amp;nbsp;Let me go take a look now while the sprint
&lt;br&gt;is going on!
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;Brandon Craig Rhodes &amp;nbsp; &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26141835&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;brandon@...&lt;/a&gt; &amp;nbsp; &lt;a href=&quot;http://rhodesmill.org/brandon&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://rhodesmill.org/brandon&lt;/a&gt;&lt;br&gt;&lt;br&gt;--~--~---------~--~----~------------~-------~--~----~
&lt;br&gt;GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt;&amp;nbsp;(overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt;&amp;nbsp;(code and issue tracker)
&lt;br&gt;You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
&lt;br&gt;To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26141835&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
&lt;br&gt;To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26141835&amp;i=3&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
&lt;br&gt;&lt;br&gt;For more options, visit this group at
&lt;br&gt;&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;-~----------~----~----~----~------~----~------~--~---
&lt;br&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Sprinting-on-GetPaid%3A-a-plan-tp26135182p26141835.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26140862</id>
	<title>Re: Sprinting on GetPaid: a plan</title>
	<published>2009-10-31T02:20:19Z</published>
	<updated>2009-10-31T02:20:19Z</updated>
	<author>
		<name>Mikko Ohtamaa</name>
	</author>
	<content type="html">&lt;div&gt;&lt;br&gt;&lt;/div&gt;Hi all,&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Brandon, thanks for the great work!&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Unfortunately I will be participating document spring, so I cannot help you here. Also my work laptop said BOOOM so I cannot work on the code in any case.&lt;/div&gt;
&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;If you need help with Mr. Developer or you have questions about getpaid.atshop I am here to answer to questions. I might or might not get to IRC.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;-Mikko&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;
&lt;br&gt;&lt;div class=&quot;gmail_quote&quot;&gt;On Fri, Oct 30, 2009 at 8:47 PM, Brandon Craig Rhodes &lt;span dir=&quot;ltr&quot;&gt;&amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26140862&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;brandon@...&lt;/a&gt;&amp;gt;&lt;/span&gt; wrote:&lt;br&gt;&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;&quot;&gt;
&lt;br&gt;
I have an important outstanding branch of GetPaid which needs to be&lt;br&gt;
merged, but I would like some help with it before merging.&lt;br&gt;
&lt;br&gt;
Christopher Johnson asked me to describe the tasks that need to be&lt;br&gt;
completed, in a format convenient for sprinters.  Hence this email!  If&lt;br&gt;
you are sprinting on GetPaid, try reading through this whole email, then&lt;br&gt;
seeing whether one of the issues is one within your range of competence&lt;br&gt;
to tackle!&lt;br&gt;
&lt;br&gt;
Briefly, here is the process to get started on if you are a sprinter:&lt;br&gt;
&lt;br&gt;
 1. Build out my &amp;quot;no-overrides&amp;quot; branch.&lt;br&gt;
 2. Verify that buttons now appear and disappear.&lt;br&gt;
 3. Practice running tests.&lt;br&gt;
 4. Choose a task.&lt;br&gt;
 5. Sprint!&lt;br&gt;
&lt;br&gt;
For each of these five items, I&amp;#39;ve written an extended explanation&lt;br&gt;
below.  Read through it carefully, and let me know if you have any&lt;br&gt;
questions!&lt;br&gt;
&lt;br&gt;
Build out my &amp;quot;no-overrides&amp;quot; branch&lt;br&gt;
----------------------------------&lt;br&gt;
&lt;br&gt;
Unlike the main GetPaid buildout, which pulls in the official version of&lt;br&gt;
each GetPaid package, my buildout pulls in the branches from SVN where I&lt;br&gt;
have been working on the new functionality.  You will need Python 2.4 to&lt;br&gt;
work on it; if you do not have that version of Python on your system and&lt;br&gt;
are unsure how to install it, please ask a more experienced sprinter how!&lt;br&gt;
&lt;br&gt;
Here are the commands for creating your own copy of my buildout; there&lt;br&gt;
are only four of them, but they can take quite a while to run.  I have&lt;br&gt;
shown the amount of time that they take on my own laptop, but I think my&lt;br&gt;
laptop already has many packages installed that the buildout needed; if&lt;br&gt;
these packages need to be downloaded for the first time on your own&lt;br&gt;
computer, then the times below could run much longer:&lt;br&gt;
&lt;br&gt;
 (5 minutes)&lt;br&gt;
 svn co &lt;a href=&quot;https://getpaid.googlecode.com/svn/getpaid.buildout/branches/brandon-no-overrides&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;https://getpaid.googlecode.com/svn/getpaid.buildout/branches/brandon-no-overrides&lt;/a&gt; no-overrides&lt;br&gt;
&lt;br&gt;
 (Immediate)&lt;br&gt;
 cd no-overrides&lt;br&gt;
&lt;br&gt;
 (10 seconds)&lt;br&gt;
 python2.4 bootstrap.py -c 316.cfg&lt;br&gt;
&lt;br&gt;
 (4 minutes)&lt;br&gt;
 bin/buildout -c 316.cfg -v&lt;br&gt;
&lt;br&gt;
Once these commands have finished, you should then be able to run a&lt;br&gt;
Plone instance very simply:&lt;br&gt;
&lt;br&gt;
 bin/instance fg&lt;br&gt;
&lt;br&gt;
You *might* at this point receive the error &amp;quot;ImportError: No module&lt;br&gt;
named PIL&amp;quot;.  If you do, simply ask someone more experienced how to&lt;br&gt;
install the Python Imaging Library for Python 2.4 on your system.  Once&lt;br&gt;
it is installed, you should be able to run the above command successfully.&lt;br&gt;
&lt;br&gt;
Once the instance is up and running:&lt;br&gt;
&lt;br&gt;
* Visit the URL:&lt;br&gt;
&lt;br&gt;
   &lt;a href=&quot;http://localhost:8080/manage_main&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://localhost:8080/manage_main&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
  and log in as &amp;quot;admin&amp;quot; with the password &amp;quot;admin&amp;quot;.  Then select &amp;quot;Plone&lt;br&gt;
  site&amp;quot; from the pull-down menu next to &amp;quot;Add&amp;quot;, press Enter, give it the&lt;br&gt;
  Id &amp;quot;Plone&amp;quot; and select &amp;quot;PloneGetPaid&amp;quot; from the &amp;quot;Extension Profiles&amp;quot;&lt;br&gt;
  down at the bottom, and press &amp;quot;Add Plone Site&amp;quot;.  You should now be&lt;br&gt;
  able to visit your new Plone site at:&lt;br&gt;
&lt;br&gt;
   &lt;a href=&quot;http://localhost:8080/Plone&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://localhost:8080/Plone&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
* Make a &amp;quot;Page&amp;quot; a buyable type by visiting the following URL and moving&lt;br&gt;
  &amp;quot;Page&amp;quot; into the right column at the top and clicking &amp;quot;Apply&amp;quot;:&lt;br&gt;
&lt;br&gt;
   &lt;a href=&quot;http://localhost:8080/Plone/@@manage-getpaid-content-types&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://localhost:8080/Plone/@@manage-getpaid-content-types&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
* Create a buyable Page by returning to your home page:&lt;br&gt;
&lt;br&gt;
   &lt;a href=&quot;http://localhost:8080/Plone/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://localhost:8080/Plone/&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
  and selecting &amp;quot;Add new…&amp;quot; &amp;quot;Page&amp;quot;.  Give it a title of &amp;quot;Sweater&amp;quot; and&lt;br&gt;
  click &amp;quot;Save&amp;quot;.  Then select &amp;quot;Actions…&amp;quot; &amp;quot;Make buyable&amp;quot;, give it a&lt;br&gt;
  product code of &amp;quot;1001&amp;quot; and a price of &amp;quot;59.95&amp;quot;, and click &amp;quot;Activate&amp;quot;.&lt;br&gt;
&lt;br&gt;
* Add the page to your shopping cart by finding the &amp;quot;Product details&amp;quot;&lt;br&gt;
  portlet in the lower-right of the Sweater page and clicking &amp;quot;Add to&lt;br&gt;
  Cart&amp;quot;.&lt;br&gt;
&lt;br&gt;
Verify that buttons now appear and disappear&lt;br&gt;
--------------------------------------------&lt;br&gt;
&lt;br&gt;
After following the instructions above, and with your Plone instance&lt;br&gt;
running, you are ready to check out the new features of my branch.  It&lt;br&gt;
is designed to allow multiple off-site payment processors to live&lt;br&gt;
happily together on the screen at the same time, and also to allow&lt;br&gt;
on-site payment processing to be an option that can be turned on or off.&lt;br&gt;
Here is how to try out my new features:&lt;br&gt;
&lt;br&gt;
* Visit your shopping cart at:&lt;br&gt;
&lt;br&gt;
   &lt;a href=&quot;http://localhost:8080/Plone/@@getpaid-cart&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://localhost:8080/Plone/@@getpaid-cart&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
  The cart should have a single checkout button, beneath the &amp;quot;Continue&lt;br&gt;
  Shopping&amp;quot; button, and it should be labeled &amp;quot;Checkout&amp;quot;.  Try clicking&lt;br&gt;
  on it; it should send you to the first page of the built-in checkout&lt;br&gt;
  process.&lt;br&gt;
&lt;br&gt;
* The first feature of my branch that you should try out is that onsite&lt;br&gt;
  checkout can now be enabled or disabled, separately from the offsite&lt;br&gt;
  payment options.  To see this, visit:&lt;br&gt;
&lt;br&gt;
   &lt;a href=&quot;http://localhost:8080/Plone/@@manage-getpaid-payment-options&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://localhost:8080/Plone/@@manage-getpaid-payment-options&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
  and un-check the &amp;quot;Activate On-site Payment&amp;quot; button and click &amp;quot;apply&amp;quot;.&lt;br&gt;
  Now return to and re-load your shopping cart page.  You should note&lt;br&gt;
  that no &amp;quot;Checkout&amp;quot; button now appears.&lt;br&gt;
&lt;br&gt;
* The next feature you should try out is the fact that off-site payment&lt;br&gt;
  buttons can be made to appear.  Return to the payment options screen&lt;br&gt;
  and move &amp;quot;Google Checkout&amp;quot; into the right column and press &amp;quot;Apply&amp;quot;.&lt;br&gt;
  Re-load your cart and you should now see a Google Checkout button&lt;br&gt;
  appear.  Now return to the payment options screen and add the &amp;quot;PayPal&amp;quot;&lt;br&gt;
  processor to the list on the right as well; now, your cart should show&lt;br&gt;
  two checkout buttons.  Now return to the payment options and turn the&lt;br&gt;
  &amp;quot;Activate On-site Payment&amp;quot; check box back on; your cart should now&lt;br&gt;
  show all three buttons for the user to choose from.&lt;br&gt;
&lt;br&gt;
There; that&amp;#39;s, essentially, what the branch accomplishes.  Rather than&lt;br&gt;
require every off-site payment solution to perform messy ZCML overrides&lt;br&gt;
to hijack the main GetPaid checkout button, my branch lets them each&lt;br&gt;
cleanly offer their own button that appears or disappears under the&lt;br&gt;
control of the site owner, not the programmer.&lt;br&gt;
&lt;br&gt;
Actually, there&amp;#39;s another effect that you can observe - the Payment&lt;br&gt;
Processor options page at:&lt;br&gt;
&lt;br&gt;
 &lt;a href=&quot;http://localhost:8080/Plone/@@manage-getpaid-payment-processor&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://localhost:8080/Plone/@@manage-getpaid-payment-processor&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
provides a block of options for each active payment processor, but makes&lt;br&gt;
them disappear if the payment processor is turned off.  Isn&amp;#39;t that cool?&lt;br&gt;
&lt;br&gt;
Practice running tests&lt;br&gt;
----------------------&lt;br&gt;
&lt;br&gt;
Good programmers always try to include comprehensive unit and&lt;br&gt;
integration tests as part of a package.  Test can verify, as we keep&lt;br&gt;
&amp;quot;improving&amp;quot; our products, that all of their old features actually keep&lt;br&gt;
working even as we are busy adding new ones.&lt;br&gt;
&lt;br&gt;
Most of the work I have done has been in four packages.  Here is the&lt;br&gt;
status of their tests:&lt;br&gt;
&lt;br&gt;
* Products.PloneGetPaid - Working&lt;br&gt;
* getpaid.core - Working&lt;br&gt;
* getpaid.paypal - Broken!&lt;br&gt;
* getpaid.googlecheckout - Broken (package might not even completely work)!&lt;br&gt;
&lt;br&gt;
As you can guess, those last two statuses have a lot to do with what I&lt;br&gt;
would like to see accomplished during the sprint. :-)&lt;br&gt;
&lt;br&gt;
Here is how to run the two working sets of tests, so that you can see&lt;br&gt;
that they indeed succeed - and so that you can also learn the pattern,&lt;br&gt;
in case the sprint task you choose involves running the tests for any of&lt;br&gt;
the other GetPaid packages:&lt;br&gt;
&lt;br&gt;
 bin/instance test --package Products.PloneGetPaid&lt;br&gt;
 bin/instance test --package getpaid.core&lt;br&gt;
&lt;br&gt;
You should see lots of crazy warning and deprecation messages scroll&lt;br&gt;
past (ah, Plone!) then the dots &amp;quot;....&amp;quot; that are printed as each test&lt;br&gt;
runs.  Once the ordeal is over, you should receive a report telling you&lt;br&gt;
that, despite all of those scary messages, the tests actually passed:&lt;br&gt;
&lt;br&gt;
   Ran 147 tests with 0 failures and 0 errors in 96.076 seconds.&lt;br&gt;
&lt;br&gt;
If they pass, then your buildout is a safe place for you to begin work.&lt;br&gt;
&lt;br&gt;
Look at all you&amp;#39;ve accomplished!  You now have a working development&lt;br&gt;
instance of GetPaid, you can run its Plone, you can explore its&lt;br&gt;
features, and you can run its tests.  It&amp;#39;s now about time to choose a&lt;br&gt;
task and start sprinting!&lt;br&gt;
&lt;br&gt;
Choose a task&lt;br&gt;
-------------&lt;br&gt;
&lt;br&gt;
If you are new to Plone development, there is one issue that might not&lt;br&gt;
have been thought about ahead of time: establishing your legal ability&lt;br&gt;
to contribute code back to GetPaid.  I know that contributing to Plone&lt;br&gt;
requires signing and returning a form to the foundation, but you should&lt;br&gt;
talk to Christopher Johnson as you get started on this sprint to make&lt;br&gt;
sure that code or patches you generate can indeed be legally contributed&lt;br&gt;
back to the effort.&lt;br&gt;
&lt;br&gt;
So, how can you choose a task?&lt;br&gt;
&lt;br&gt;
What I would like to see the sprint accomplish is to get both the PayPal&lt;br&gt;
and the GoogleCheckout mechanisms working great with my new branch.&lt;br&gt;
That would bring about two great results:&lt;br&gt;
&lt;br&gt;
1. Just the fact that everyone would have worked with and tried out my&lt;br&gt;
   branch for hours and hours would hopefully make us all comfortable&lt;br&gt;
   that my &amp;quot;Products.PloneGetPaid&amp;quot; and &amp;quot;getpaid.core&amp;quot; innovates can now&lt;br&gt;
   be merged back into trunk.&lt;br&gt;
&lt;br&gt;
2. Instead of my new feature appearing for the first time in trunk with&lt;br&gt;
   its &amp;quot;Offsite Payment Processors&amp;quot; setup option blank, we could now&lt;br&gt;
   include both PayPal and GoogleCheckout in the default GetPaid build.&lt;br&gt;
&lt;br&gt;
To help people communicate during this sprint, I will here invent a&lt;br&gt;
little rating system for GetPaid off-site payment processors:&lt;br&gt;
&lt;br&gt;
&amp;quot;Tin&amp;quot; - the off-site payment processor does not even use my new plug-in&lt;br&gt;
    mechanism, but relies on an &amp;quot;overrides.zcml&amp;quot; file instead.&lt;br&gt;
&lt;br&gt;
&amp;quot;Bronze&amp;quot; - the processor has been rewritten to use my new plug-in&lt;br&gt;
    mechanism and can therefore live peacefully with other off-site&lt;br&gt;
    payment processors.&lt;br&gt;
&lt;br&gt;
&amp;quot;Silver&amp;quot; - the processor&amp;#39;s tests have been re-written (or written for&lt;br&gt;
   the first time, if it lacked them before) to demonstrate that it&lt;br&gt;
   plugs in fine with my new mechanism.&lt;br&gt;
&lt;br&gt;
&amp;quot;Gold&amp;quot; - the processor supports a callback mechanism that lets the&lt;br&gt;
   off-site payment solution report back to Plone about which orders&lt;br&gt;
   users actually carried through with.&lt;br&gt;
&lt;br&gt;
&amp;quot;Platinum&amp;quot; - tests are written, and work, for the callback mechanism.&lt;br&gt;
&lt;br&gt;
Given the above ratings, here is now I would rate the two payment&lt;br&gt;
processors I have touched:&lt;br&gt;
&lt;br&gt;
PayPal - Bronze&lt;br&gt;
GoogleCheckout - on the way to Bronze&lt;br&gt;
&lt;br&gt;
The goal that I would suggest for the sprint is to work on these two&lt;br&gt;
change processors to get them both at least to &amp;quot;Silver&amp;quot;, because that is&lt;br&gt;
a tolerable working state: while shop owners can&amp;#39;t use &amp;quot;Silver&amp;quot;-level&lt;br&gt;
processors and expect to be able to manage orders on their Plone site,&lt;br&gt;
many won&amp;#39;t need to because they can do their management on PayPal or&lt;br&gt;
Google Checkout&amp;#39;s own site.  Of course, if sprinters are available to&lt;br&gt;
start working on going Gold, then please do so!&lt;br&gt;
&lt;br&gt;
So, having given that background, what are the available projects for&lt;br&gt;
the sprint?  Here are some projects that I think could be divvied up&lt;br&gt;
among you.&lt;br&gt;
&lt;br&gt;
Easy Tasks - require only basic knowledge of Plone&lt;br&gt;
..................................................&lt;br&gt;
&lt;br&gt;
* Add &amp;quot;Available&amp;quot; and &amp;quot;Selected&amp;quot; headings to the &amp;quot;Off-site Payment&lt;br&gt;
  Processors&amp;quot; controller on the @@manage-getpaid-payment-options page.&lt;br&gt;
&lt;br&gt;
    Take a look at the @@manage-getpaid-payment-options page; do you see&lt;br&gt;
    something funny about the off-site selection boxes up at the top?&lt;br&gt;
    That&amp;#39;s right!  They contain absolutely no indication of which box is&lt;br&gt;
    for the ones you *do* want to use, and which box is for the ones you&lt;br&gt;
    *don&amp;#39;t*. :-)&lt;br&gt;
&lt;br&gt;
    That&amp;#39;s because I couldn&amp;#39;t figure out how to label them, and after&lt;br&gt;
    one or two tries I ran out of time and had to turn to other things.&lt;br&gt;
&lt;br&gt;
    The odd thing is that the &amp;quot;Accepted Credit Cards&amp;quot; setting just below&lt;br&gt;
    it on the same page *does* have headings; but I couldn&amp;#39;t figure out&lt;br&gt;
    what the difference was!&lt;br&gt;
&lt;br&gt;
    This whole form is powered by the &amp;quot;IGetPaidManagementPaymentOptions&amp;quot;&lt;br&gt;
    interface in:&lt;br&gt;
&lt;br&gt;
     Products.PloneGetPaid/Products/PloneGetPaid/interfaces.py&lt;br&gt;
&lt;br&gt;
    Somehow there&amp;#39;s a way to turn those little headings on; go find it!&lt;br&gt;
    If you&amp;#39;re new to Plone, this should be a great little project.&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
* Fix the fact that checkout buttons are too close to each other.&lt;br&gt;
&lt;br&gt;
    You probably noticed this already: the checkout buttons run right up&lt;br&gt;
    against each other (in Firefox, at least) where they are sitting&lt;br&gt;
    beneath the shopping cart.  If you know a little HTML and CSS, then&lt;br&gt;
    please consider jumping in and fixing this!  I am probably just&lt;br&gt;
    failing to put a &amp;lt;div&amp;gt; around them with the right class to tell the&lt;br&gt;
    default Plone stylesheets that they&amp;#39;re buttons and need some room&lt;br&gt;
    around them.&lt;br&gt;
&lt;br&gt;
    The (admittedly primitive) template that I use for the stack of&lt;br&gt;
    buttons is here:&lt;br&gt;
&lt;br&gt;
     Products.PloneGetPaid/Products/PloneGetPaid/browser/templates/&lt;a href=&quot;http://checkout-buttons.pt&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;checkout-buttons.pt&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
    What am I doing wrong?  You will want to compare my HTML to other&lt;br&gt;
    buttons around the Plone site, that are presumably done the &amp;quot;right&amp;quot;&lt;br&gt;
    and &amp;quot;standard&amp;quot; way, and then try modifying the above template until&lt;br&gt;
    things look better.&lt;br&gt;
&lt;br&gt;
    It&amp;#39;s annoying that the checkout buttons are different sizes, isn&amp;#39;t&lt;br&gt;
    it?  But we have to use the logos for user recognition of these&lt;br&gt;
    common services, right?  You might also think about whether there&amp;#39;s&lt;br&gt;
    any way to improve the appearance when the Google button is so much&lt;br&gt;
    bigger than the PayPal one!&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
* Disable the checkout process if &amp;quot;Activate On-site Payment&amp;quot; is&lt;br&gt;
  unchecked.&lt;br&gt;
&lt;br&gt;
    Okay, you might have noticed something of a flaw in my design: if&lt;br&gt;
    the store owner un-checks the &amp;quot;Activate On-site Payment&amp;quot; box at&lt;br&gt;
&lt;br&gt;
     &lt;a href=&quot;http://localhost:8080/Plone/@@manage-getpaid-payment-options&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://localhost:8080/Plone/@@manage-getpaid-payment-options&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
    then, as planned, the normal &amp;quot;Checkout&amp;quot; button disappears.  But,&lt;br&gt;
    behind the scenes, the view is still there and ready to let the user&lt;br&gt;
    check out!  It should really be disabled.  To be more exact, if the&lt;br&gt;
    &amp;quot;Activate On-site Payment&amp;quot; box is unchecked by the store owner, then&lt;br&gt;
    any attempt to access:&lt;br&gt;
&lt;br&gt;
     &lt;a href=&quot;http://localhost:8080/Plone/@@getpaid-checkout-wizard&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://localhost:8080/Plone/@@getpaid-checkout-wizard&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
    (whether by a user who knows GetPaid, or because an old link to the&lt;br&gt;
    checkout has been left in a site template somewhere) should be met&lt;br&gt;
    with some sort of refusal.  Maybe it should redirect back to the&lt;br&gt;
    main cart view?  Or should it show an error and provide a link back&lt;br&gt;
    to the rest of the site?  First, write the logic.  Then you can&lt;br&gt;
    debate with other GetPaid people about what action the logic should&lt;br&gt;
    trigger.&lt;br&gt;
&lt;br&gt;
    You will probably accomplish this by finding the class that runs the&lt;br&gt;
    &amp;quot;getpaid-checkout-wizard&amp;quot; view (look through the ZCML to find the&lt;br&gt;
    module and class that run that view), and putting an &amp;quot;if&amp;quot; statement&lt;br&gt;
    inside of it somewhere that grabs the GetPaid global options (you&lt;br&gt;
    can find the pattern for this in several places; look for the portal&lt;br&gt;
    root being adapted to an options interface from getpaid.core!) and&lt;br&gt;
    then looks to make sure that onsite checkout is enabled.&lt;br&gt;
&lt;br&gt;
Intermediate Tasks&lt;br&gt;
..................&lt;br&gt;
&lt;br&gt;
* Write tests for PayPal&lt;br&gt;
&lt;br&gt;
    The PayPal processor in &amp;quot;trunk&amp;quot; lacks tests entirely, from what I&lt;br&gt;
    can see, and it needs some!  You can verify that it works by hand by&lt;br&gt;
    creating a PayPal sandbox account and entering its username into&lt;br&gt;
    your PayPal Processor Options (if PayPal is turned on!) at:&lt;br&gt;
&lt;br&gt;
     &lt;a href=&quot;http://localhost:8080/Plone/@@manage-getpaid-payment-processor&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://localhost:8080/Plone/@@manage-getpaid-payment-processor&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
    By &amp;quot;works&amp;quot;, I mean that you&amp;#39;ll indeed be forwarded to PayPal which&lt;br&gt;
    will display the total of your shopping cart, and if you click on&lt;br&gt;
    the pull-down arrow on the margin just below the total you&amp;#39;ll see&lt;br&gt;
    all of the &amp;quot;line items&amp;quot; appear that detail the objects that were in&lt;br&gt;
    your shopping cart.  This all demonstrates that information is&lt;br&gt;
    making it through from GetPaid to PayPal correctly.&lt;br&gt;
&lt;br&gt;
    But this is the world of Python, and testing things by hand is not&lt;br&gt;
    enough for us!  The PayPal change processor needs tests.  How can&lt;br&gt;
    you add them?&lt;br&gt;
&lt;br&gt;
    First, look at the trunk of &amp;quot;getpaid.googlecheckout&amp;quot;:&lt;br&gt;
&lt;br&gt;
     &lt;a href=&quot;http://code.google.com/p/getpaid/source/browse#svn/getpaid.googlecheckout/trunk/src/getpaid/googlecheckout/tests&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid/source/browse#svn/getpaid.googlecheckout/trunk/src/getpaid/googlecheckout/tests&lt;/a&gt;&lt;br&gt;

&lt;br&gt;
    You will see that its tests.test_suite() function runs two doctests&lt;br&gt;
    that you&amp;#39;ll find one level up, outside the test directory: one test&lt;br&gt;
    just named &amp;quot;googlecheckout.txt&amp;quot; and another that is named&lt;br&gt;
    &amp;quot;googlecheckout-browser.txt&amp;quot;.  If you checked out the project trunk&lt;br&gt;
    and ran these tests, you&amp;#39;d even see that they pass!&lt;br&gt;
&lt;br&gt;
    To give PayPal tests, copy these tests as an example and adapt them&lt;br&gt;
    to PayPal: have them create some purchasable objects,&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
* Get the Google Checkout button working.&lt;br&gt;
&lt;br&gt;
    Though the Google Checkout button will appear when that payment&lt;br&gt;
    processor is activated, the form that surrounds the button is pretty&lt;br&gt;
    much empty.  Unlike the PayPal checkout button, which I&amp;#39;ve been able&lt;br&gt;
    to spend more time on, the Google Checkout button is pretty much&lt;br&gt;
    blank.&lt;br&gt;
&lt;br&gt;
    It needs someone to go in and add all of the hidden fields that will&lt;br&gt;
    make it an effective button.  If you choose to tackle this problem,&lt;br&gt;
    you will have the advantage of having the PayPal branch to work off&lt;br&gt;
    of: it will show you how an effective form can be generated that is&lt;br&gt;
    full of information about the current shopping cart.&lt;br&gt;
&lt;br&gt;
    You will have succeeded if, when you are done, the Google Checkout&lt;br&gt;
    button - like the PayPal button - actually takes the person clicking&lt;br&gt;
    it off-site and if, upon arrival, Google Checkout knows what items&lt;br&gt;
    were in their cart.  Expect to need to bring up the Google Checkout&lt;br&gt;
    docs to complete this task; but use the PayPal branch to see&lt;br&gt;
    examples of how to get to the information (like payment processor&lt;br&gt;
    settings and cart contents) that you&amp;#39;ll need to fill out the form.&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
* BONUS: Tests for Google Checkout.&lt;br&gt;
&lt;br&gt;
    If the previous item is actually accomplished, and the Google&lt;br&gt;
    Checkout button becomes useful, then write working tests for it -&lt;br&gt;
    check out the instructions in the first item in this Intermediate&lt;br&gt;
    section for thoughts on testing.&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
Advanced Tasks&lt;br&gt;
..............&lt;br&gt;
&lt;br&gt;
* Get PayPal notification working.&lt;br&gt;
* Get Google Checkout notification working.&lt;br&gt;
&lt;br&gt;
    Okay, here is a real challenge in case some serious Plone hackers&lt;br&gt;
    show up and the above items don&amp;#39;t provide enough entertainment.&lt;br&gt;
&lt;br&gt;
    Your task is to write tests - I have no idea how - that verify that&lt;br&gt;
    either the PayPal or Google Checkout payment processor, after&lt;br&gt;
    sending the user off-site, correctly receives back the messages&lt;br&gt;
    telling them that the buyer is progressing through checkout.&lt;br&gt;
&lt;br&gt;
    There are two challenges here that are actually a bit steep for me,&lt;br&gt;
    as a developer, to tackle (which is why I&amp;#39;ve not even attempted to&lt;br&gt;
    tackle them):&lt;br&gt;
&lt;br&gt;
    1. No &amp;quot;Order&amp;quot; object exists yet when the user leaves the site.  How,&lt;br&gt;
       then, will the return messages from PayPal or Google Checkout -&lt;br&gt;
       that refer to the order number - be associated with the correct&lt;br&gt;
       user, and result in an order being created for them?  My guess is&lt;br&gt;
       that the buttons that send users off-site should generate&lt;br&gt;
       one-time disposable order numbers that have the user&amp;#39;s username&lt;br&gt;
       encoded inside of them.  When the notification comes back, if no&lt;br&gt;
       order of that number exists yet, then the username can be decoded&lt;br&gt;
       to figure out what user to create the order for.  And when the&lt;br&gt;
       order is finalized and purchased, you can even empty that user&amp;#39;s&lt;br&gt;
       shopping cart.  For bonus points, only empty it of the items that&lt;br&gt;
       have actually been purchased, leaving items inside that were not&lt;br&gt;
       included in the order the user just paid for. :-)&lt;br&gt;
&lt;br&gt;
    2. How can a Plone test - whether a doctest or normal unit test -&lt;br&gt;
       submit a form to an off-site service and at the same time already&lt;br&gt;
       be ready to receive a signal back?  There are two parts to this&lt;br&gt;
       question: first, since the test will often be running on a&lt;br&gt;
       computer behind a firewall, the test will have to be given the&lt;br&gt;
       name of an SSH account it can log into with an &amp;quot;-R&amp;quot; option so&lt;br&gt;
       that &amp;quot;http://wherever.it.is:PORT/&amp;quot; becomes a location that the&lt;br&gt;
       remote service can POST to and have it actually be received by&lt;br&gt;
       the test on whatever port it opens.  And, second, how can the&lt;br&gt;
       test break into two threads to do the actual HTTP handling?&lt;br&gt;
&lt;br&gt;
    These, again, are quite advanced challenges, and are actually a bit&lt;br&gt;
    beyond my own knowledge at this point; you should only seize them if&lt;br&gt;
    you are among the Great Among Plone, and happen to be wanting to&lt;br&gt;
    sprint upon GetPaid.  If we are so honored.&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
Sprint!&lt;br&gt;
-------&lt;br&gt;
&lt;br&gt;
Finally, after choosing a task from the above: get started!&lt;br&gt;
&lt;br&gt;
I&amp;#39;ll try to be on IRC, and helpful GetPaid folks should be somewhere&lt;br&gt;
nearby to help.  I have tried to be clear in everything above, and I&amp;#39;ll&lt;br&gt;
apologize ahead of time if any inaccuracies in what I&amp;#39;ve written waste&lt;br&gt;
your time; I&amp;#39;ve taken part in several sprints before, and I know how&lt;br&gt;
frustrating it can be just getting set up, much less trying to&lt;br&gt;
accomplish anything!&lt;br&gt;
&lt;br&gt;
If you could, use the mailing list to let us know what you&amp;#39;re working&lt;br&gt;
on, so that everyone has a record of who has grabbed what task.  When&lt;br&gt;
the sprint is over, send a reply to your message telling what happened,&lt;br&gt;
where things stand, and including your patch or improvement if you&lt;br&gt;
generated one but weren&amp;#39;t in a position to commit it.&lt;br&gt;
&lt;br&gt;
And, most of all, have fun. :-)  I look forward to hearing your reports!&lt;br&gt;
&lt;br&gt;
--&lt;br&gt;
Brandon Craig Rhodes   &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26140862&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;brandon@...&lt;/a&gt;   &lt;a href=&quot;http://rhodesmill.org/brandon&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://rhodesmill.org/brandon&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/blockquote&gt;&lt;/div&gt;&lt;br&gt;&lt;br clear=&quot;all&quot;&gt;&lt;br&gt;-- &lt;br&gt;Mikko Ohtamaa&lt;br&gt;Managing director, Red Innovation Ltd.&lt;br&gt;+358 40 743 9707&lt;br&gt;&lt;a href=&quot;http://www.redinnovation.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;www.redinnovation.com&lt;/a&gt;&lt;br&gt;Every problem is solvable if you can throw enough energy drinks at it&lt;br&gt;

&lt;/div&gt;
&lt;br&gt;
--~--~---------~--~----~------------~-------~--~----~&lt;br&gt;
GetPaid for Plone: http://www.plonegetpaid.com (overview info) | http://code.google.com/p/getpaid (code and issue tracker)
 &lt;br&gt; You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
 &lt;br&gt; To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26140862&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
 &lt;br&gt; To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26140862&amp;i=3&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
 &lt;br&gt; &lt;p&gt;For more options, visit this group at
 &lt;br&gt; http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;br&gt;
-~----------~----~----~----~------~----~------~--~---&lt;br&gt;
&lt;br&gt;
</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Sprinting-on-GetPaid%3A-a-plan-tp26135182p26140862.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26141654</id>
	<title>Re: Sprinting on GetPaid: a plan</title>
	<published>2009-10-31T00:36:25Z</published>
	<updated>2009-10-31T00:36:25Z</updated>
	<author>
		<name>Juan Pablo Giménez-2</name>
	</author>
	<content type="html">&lt;br&gt;El vie, 30-10-2009 a las 14:47 -0400, Brandon Craig Rhodes escribió:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; I have an important outstanding branch of GetPaid which needs to be
&lt;br&gt;&amp;gt; merged, but I would like some help with it before merging.
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; Christopher Johnson asked me to describe the tasks that need to be
&lt;br&gt;&amp;gt; completed, in a format convenient for sprinters. &amp;nbsp;Hence this email! &amp;nbsp;If
&lt;br&gt;&amp;gt; you are sprinting on GetPaid, try reading through this whole email, then
&lt;br&gt;&amp;gt; seeing whether one of the issues is one within your range of competence
&lt;br&gt;&amp;gt; to tackle!
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; Briefly, here is the process to get started on if you are a sprinter:
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; &amp;nbsp;1. Build out my &amp;quot;no-overrides&amp;quot; branch.
&lt;br&gt;&amp;gt; &amp;nbsp;2. Verify that buttons now appear and disappear.
&lt;br&gt;&amp;gt; &amp;nbsp;3. Practice running tests.
&lt;br&gt;&amp;gt; &amp;nbsp;4. Choose a task.
&lt;br&gt;&amp;gt; &amp;nbsp;5. Sprint!
&lt;/div&gt;&lt;br&gt;FYI, getpaid.nmi processor is working again! and have a running test
&lt;br&gt;suite,
&lt;br&gt;&lt;br&gt;./bin/instance test -s getpaid.nmi
&lt;br&gt;...
&lt;br&gt;Installing PloneGetPaid ... done (0.052s)
&lt;br&gt;Running Products.PloneTestCase.layer.PloneSite tests:
&lt;br&gt;&amp;nbsp; Set up Products.PloneTestCase.layer.PloneSite in 0.009 seconds.
&lt;br&gt;&amp;nbsp; Running:
&lt;br&gt;...Installing Five ... done (0.040s)
&lt;br&gt;2009-10-31 04:04:06 WARNING plone.z3cform Monkey patching
&lt;br&gt;z3c.form.term.ChoiceTerms to correctly bind fields
&lt;br&gt;.............
&lt;br&gt;&amp;nbsp; Ran 16 tests with 0 failures and 0 errors in 10.508 seconds.
&lt;br&gt;Tearing down left over layers:
&lt;br&gt;&amp;nbsp; Tear down Products.PloneTestCase.layer.PloneSite in 0.544 seconds.
&lt;br&gt;&amp;nbsp; Tear down Products.PloneTestCase.layer.ZCML in 0.006 seconds.
&lt;br&gt;Testrunner took: 11.792 seconds. &amp;nbsp;
&lt;br&gt;&lt;br&gt;I'm not using orders workflow because DefaultFinanceProcessorIntegration
&lt;br&gt;is tied to IPaymentProcessor and we are implementing
&lt;br&gt;IOffsitePaymentProcessor, that was what I changed on
&lt;br&gt;getpaid.core.payment and you reverted (brandon)... but its ok, maybe we
&lt;br&gt;shouldn't change DefaultFinanceProcessorIntegration but &amp;quot;overrides&amp;quot; the
&lt;br&gt;adapter (not actually overrides, but find a way to wire another class)
&lt;br&gt;or define a full new workflow for offsite processors... I'm not sure
&lt;br&gt;what is better (and is too late here... :))
&lt;br&gt;&lt;br&gt;Regards,
&lt;br&gt;Juan Pablo
&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;--~--~---------~--~----~------------~-------~--~----~
&lt;br&gt;GetPaid for Plone: &lt;a href=&quot;http://www.plonegetpaid.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.plonegetpaid.com&lt;/a&gt;&amp;nbsp;(overview info) | &lt;a href=&quot;http://code.google.com/p/getpaid&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://code.google.com/p/getpaid&lt;/a&gt;&amp;nbsp;(code and issue tracker)
&lt;br&gt;You received this message because you are subscribed to the Google Groups &amp;quot;getpaid-dev&amp;quot; group.
&lt;br&gt;To post to this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26141654&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev@...&lt;/a&gt;
&lt;br&gt;To unsubscribe from this group, send email to &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26141654&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;getpaid-dev+unsubscribe@...&lt;/a&gt;
&lt;br&gt;&lt;br&gt;For more options, visit this group at
&lt;br&gt;&lt;a href=&quot;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://groups.google.com/group/getpaid-dev?hl=en?hl=en&lt;/a&gt;&lt;br&gt;-~----------~----~----~----~------~----~------~--~---
&lt;br&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Sprinting-on-GetPaid%3A-a-plan-tp26135182p26141654.html" />
</entry>

</feed>
