Splitting Payment from Satchmo

52 views
Skip to first unread message

Bruce Kroeze

unread,
Sep 17, 2009, 7:24:55 PM9/17/09
to satchmo-developers
It is premature to mention this, but I'm quite excited.

After talking with Chris at DjangoCon, I decided to tackle one of the
biggest, most obvious refactoring opportunities available in Satchmo,
the Payment system. It is our opinion that making the Satchmo Payment
modules available via a generic interface would be a massive help to
many other projects. Sort of like Ruby's "active-merchant", but with
a different approach and a Python/Django feel.

To that end, I've spent far too many hours over the last few days
working on the split. I'm calling it "Bursar", and I'm developing it
with these guidelines:

- No reliance on any part of Satchmo. Not even keyedcache or
livesettings. Hopefully no external dependencies at all.
- It just handles authorizations and payments, nothing else.
- It requires little-to-no changes to existing Satchmo code, other
than the payment module itself.
- Every processor needs its own tests, and documentation about the
prerequisites (dev keys, etc) needed to run the tests.
- No cruft. I'm removing all Python 2.3 compatibility, and simplifying the API.

The existing Satchmo payment modules are all split into two parts for
Bursar. The views, config, and urls remain in Satchmo. The processor
itself goes to Bursar. To add a new payment module, one would develop
the processor in Bursar, and a "Satchmofied" interface for it in
satchmo.payment.

After days of work, I've finally gotten the "dummy" processor to work
and to pass all the new tests I've written for it. I think the
remaining processors should go quickly now that I've gotten that one
done. I've also cured a few Satchmo bugs while I was at it.
Refactoring (while painful and slow) makes bugs far more obvious.

I'm working off of a large fork of Satchmo at the moment. For obvious
reasons, I'm not going to check that in until the split is complete
and solid. If you are an adventurous sort, send me an email and I'll
send you a link where you can download the fork.

If you just want to see what is going on so far, the code is available
at: http://bitbucket.org/bkroeze/django-bursar

I've adopted a moderately strict formal refactoring process for this
project. The first step is to replicate functionality with as few
changes to existing Satchmo processes as possible. When that is done,
I hope to simplify and document with the aim of making it easy to add
new processors in the future. I am no documentation expert, so I will
really need help with that part. I'm open to discussion, wishlists,
and random comments about the project.

--
Bruce Kroeze
http://www.ecomsmith.com
It's time to hammer your site into shape.

Josh VanderLinden

unread,
Sep 17, 2009, 7:28:48 PM9/17/09
to satchmo-d...@googlegroups.com
This is fantastic news Bruce! I applaud your efforts, and I can't
wait to see the results! Unfortunately, I probably won't be doing
much more with with Satchmo on a regular basis, and I'm in the process
of moving. Otherwise I would volunteer to help you move things along!

Simon

unread,
Sep 18, 2009, 3:43:47 AM9/18/09
to satchmo-d...@googlegroups.com
I also applaud your efforts. Afraid I won't be up for much more then testing at merge time.

What are the chances of swapping out the Paypal module for
http://github.com/dcramer/django-paypal
I only suggest this because I thought it would be good for a part or Satchmo to have more eyes on it.

Simon


Juanjo

unread,
Sep 18, 2009, 6:03:02 AM9/18/09
to Satchmo developers
I like it!

I hope to be able to help testing the SERMEPA module in a few weeks.

On Sep 18, 9:43 am, Simon <si...@luijk.co.uk> wrote:
> I also applaud your efforts. Afraid I won't be up for much more then testing
> at merge time.
>
> What are the chances of swapping out the Paypal module forhttp://github.com/dcramer/django-paypal

mihau

unread,
Oct 8, 2009, 10:50:24 AM10/8/09
to Satchmo developers
Hi Bruce,

I had a short break from developing Satchmo itself, but now I'm going
to spend next few days on your code. New requirements from my customer
came up recently and I'll try to shift as much of my work into public
space within Satchmo. My two key items are:

1. Refunds: Some of the payment gateways handle refunds and also some
of them do them automatically if there are some problems with credit
cards (reported frauds, etc.) At least PayPal is konwn to do it and to
send IPN message to notify the shop about refunded orders.
The objective is to have some way of notifying the shop software about
refunded payments, in order to deal with the affected Order (change
status, cancel, etc.). Perhaps some signal would be useful here, to
allow developers to define custom response -- I suppose that every
show would want to react in different way.

2. Additional data recording: My customer asked me to have IP address
stored together with a payment. However, just saving it into DB is not
a good thing, as it may possibly cause security/legal issues somewhere
for someone.
My idea here is to have another signal, called upon payment
initiation, which takes Order, Request and perhaps the original Cart
(which together allow to access any customer data), which fills a
dictionary of payment details. The dictionary is saved with the
Payment then (sth. like ItemDetails for OrderItem).

These are just rough ideas, without having read your new code. If
anyone has some ideas/suggestions, please let me know :)

--
michal

Bruce Kroeze

unread,
Oct 8, 2009, 2:16:39 PM10/8/09
to satchmo-d...@googlegroups.com
Hi Michael, thanks for your interest.

I've separately sent you my Satchmo fork which uses Bursar.

On Thu, Oct 8, 2009 at 7:50 AM, mihau <michal....@gmail.com> wrote:
>
> 1. Refunds: Some of the payment gateways handle refunds and also some
> of them do them automatically if there are some problems with credit
> cards (reported frauds, etc.) At least PayPal is konwn to do it and to
> send IPN message to notify the shop about refunded orders.
> The objective is to have some way of notifying the shop software about
> refunded payments, in order to deal with the affected Order (change
> status, cancel, etc.). Perhaps some signal would be useful here, to
> allow developers to define custom response -- I suppose that every
> show would want to react in different way.

So, if the payment system "hears about" a forced refund, it should
signal. Satchmo could pick up the signal and make the appropriate
change to the order record.

> 2. Additional data recording: My customer asked me to have IP address
> stored together with a payment. However, just saving it into DB is not
> a good thing, as it may possibly cause security/legal issues somewhere
> for someone.
> My idea here is to have another signal, called upon payment
> initiation, which takes Order, Request and perhaps the original Cart
> (which together allow to access any customer data), which fills a
> dictionary of payment details. The dictionary is saved with the
> Payment then (sth. like ItemDetails for OrderItem).
>

That's pretty much what I'm doing in Bursar. The Bursar models keep a
separate record of everything charged. The API just accepts a list of
items and quantities to be charged, along with their costs and saves
that. Optionally, it can just take shipping/tax/total and charge with
no details. It also takes a separate snapshot of the contact (after
all, it could change over time, so we need the at-the-moment
information) and associates it to the Payment.

Adding more information to the Payment record is a good idea. We
could just use simple name/value pairs, and let different processors
capture more information if they so desire.

Alex Hayes

unread,
Oct 11, 2009, 8:39:53 AM10/11/09
to Satchmo developers
Hi Bruce,

I'm interested in these changes also, because I need to handle refunds
and pre-authorisations using Satchmo:

- Refunds - basically my clients need to issue refunds and most
gateways seem to support this functionality. This differs slightly
from Michal's scenario as rather than the gateway initiating the
refund the refund is initiated by someone with privilege to do so at
the store.
- Pre-Auths - for a client of mine I'm using Satchmo in a Rental
situation, where a pre-auth is used as "insurance" for the item being
rented (basically a short lived bond). Basically this means two
transactions, one for the pre-auth and one for the actual purchase of
the item. I imagine that this is not a common scenario however I would
be interested in contributing this back to the Satchmo community, some
guidance about how you would prefer it to be approached would be nice.
More details can be found at http://groups.google.com/group/satchmo-users/browse_thread/thread/84659c96ee1a1712#

I also have a payment processor to contribute for an Australian
gateway provider, NetRegistry, which would need switching over to use
the django-bursar api when its stable.

Thanks
Alex


On Oct 9, 5:16 am, Bruce Kroeze <bkro...@gmail.com> wrote:
> Hi Michael, thanks for your interest.
>
> I've separately sent you my Satchmo fork which uses Bursar.
>
> Bruce Kroezehttp://www.ecomsmith.com

Bruce Kroeze

unread,
Oct 11, 2009, 12:40:00 PM10/11/09
to satchmo-d...@googlegroups.com
On Sun, Oct 11, 2009 at 5:39 AM, Alex Hayes <al...@alution.com> wrote:
>
> Hi Bruce,
>
> I'm interested in these changes also, because I need to handle refunds
> and pre-authorisations using Satchmo:
>
>  - Refunds - basically my clients need to issue refunds and most
> gateways seem to support this functionality. This differs slightly
> from Michal's scenario as rather than the gateway initiating the
> refund the refund is initiated by someone with privilege to do so at
> the store.

Actually, the base processor object can already do refunds, just not
gateway-initiated ones. IIRC, the only processor which currently
implements the refund method is Authorizenet.

We definitely need some sort of admin screen to do
store-owner-initated refunds, but that should be pretty
straightforward.

>  - Pre-Auths - for a client of mine I'm using Satchmo in a Rental
> situation, where a pre-auth is used as "insurance" for the item being
> rented (basically a short lived bond). Basically this means two
> transactions, one for the pre-auth and one for the actual purchase of
> the item. I imagine that this is not a common scenario however I would
> be interested in contributing this back to the Satchmo community, some
> guidance about how you would prefer it to be approached would be nice.
> More details can be found at http://groups.google.com/group/satchmo-users/browse_thread/thread/84659c96ee1a1712#

Authorizenet can do this as well. In fact, it is the default way it
operates if you don't check the "capture payment immediately" button.
An AUTH is made on the order, which is then captured when the order is
marked complete.

> I also have a payment processor to contribute for an Australian
> gateway provider, NetRegistry, which would need switching over to use
> the django-bursar api when its stable.

Great, we can always use more.

--
Bruce Kroeze

Alex Hayes

unread,
Oct 15, 2009, 10:15:27 AM10/15/09
to Satchmo developers
> >  - Pre-Auths - for a client of mine I'm using Satchmo in a Rental
> > situation, where a pre-auth is used as "insurance" for the item being
> > rented (basically a short lived bond). Basically this means two
> > transactions, one for the pre-auth and one for the actual purchase of
> > the item. I imagine that this is not a common scenario however I would
> > be interested in contributing this back to the Satchmo community, some
> > guidance about how you would prefer it to be approached would be nice.
> > More details can be found athttp://groups.google.com/group/satchmo-users/browse_thread/thread/846...
>
> Authorizenet can do this as well.  In fact, it is the default way it
> operates if you don't check the "capture payment immediately" button.
> An AUTH is made on the order, which is then captured when the order is
> marked complete.
>

Hi Bruce, the issue I have is that I really need to perform two
transactions, in the one step, one which performs a real transaction
and another which performs a pre-auth.

So, for a Product, lets say its a Car, you might have an actual
payment of $75 and a preauth of $500. Preferably the user only has to
enter the users card details once and these duel transactions are
performed at the same time.

I've looked at various approaches to implementing this but I as yet
haven't been able to come up with a good approach (mainly because I
don't know the internals of Satchmo well enough yet).

I was wondering if perhaps you can point me in the right direction?
Note I know how to do the pre-auth, that is not an issue, the issue is
combining the two transactions into one process.

Thanks
Alex

Alex Hayes

unread,
Oct 15, 2009, 10:43:02 AM10/15/09
to Satchmo developers
To elaborate, the best approach I have been able to come up with thus
far is to place the logic to perform the two two transactions into a
custom confirm_info() for my own custom payment module. The issue with
this of course is that it then only works for this custom payment
module, I can't test say for instance with the dummy payment module or
process real payments with any of the other modules.

This of course wouldn't be much of an issue right now if the gateway
actually had a real test interface, but they don't.

Thanks
Alex

Bruce Kroeze

unread,
Oct 15, 2009, 11:51:06 AM10/15/09
to satchmo-d...@googlegroups.com
On Thu, Oct 15, 2009 at 7:43 AM, Alex Hayes <al...@alution.com> wrote:
>
> To elaborate, the best approach I have been able to come up with thus
> far is to place the logic to perform the two two transactions into a
> custom confirm_info() for my own custom payment module. The issue with
> this of course is that it then only works for this custom payment
> module, I can't test say for instance with the dummy payment module or
> process real payments with any of the other modules.
>
> This of course wouldn't be much of an issue right now if the gateway
> actually had a real test interface, but they don't.

They do have test interfaces in django-bursar, which is the name I've
given to the payment system split from Satchmo. I think the ability
to test outside of a Satchmo environment is critical for reliability
and flexibility.

In the meantime, it will require some custom programming, but if you
notice, you can auth for whatever you want. When you capture, the
processor can request a specific amount to capture, instead of the
full amount of the auth. That hasn't been completely tested, but it
was the idea, and it is already built-in.

Alex Hayes

unread,
Oct 15, 2009, 2:00:17 PM10/15/09
to Satchmo developers
Hi Bruce,

Well I managed to get it going using a custom confirm which has the
following logic:

items = self.order.orderitem_set.filter
(product__productattribute__name='is_authorization')
authorization_amount = Decimal(0)
for item in items:
authorization_amount = authorization_amount +
item.product.get_qty_price(1)
authorization_result = self.processor.authorize_payment
(force=True, amount=authorization_amount)
if authorization_result.success:
# continue on with the rest of the process

Now, this works however I'm wondering if there is a better way to get
sum of the products in the cart that have the product attribute
is_authorization. Also I'm thinking that this is probably not the
place to do this, or rather, perhaps I need a custom product which has
a different payment process? I'm not even sure if that is possible.

I wanted to do this as a separate product for several reasons, namely
the hire product has a price for daily hire, whereas they only need to
pay one preauth for the entirety of the hire. For instance, I might
hire a car for 30 days at $30 per day, but I only need to pay for one
pre-auth for that entire 30 days.

I'll have a look into processing this in bursar when I straighten it
out in satchmo to start with.

Thanks for all your help and great work Bruce!
Alex

On Oct 16, 2:51 am, Bruce Kroeze <bkro...@gmail.com> wrote:
> Bruce Kroezehttp://www.ecomsmith.com
Reply all
Reply to author
Forward
0 new messages