My code currently supports only buy now links, which are suitable for my purposes as I just want to charge a single calculated amount at a time.
Before I start committing this package to the cvs tree, I wanted to get a bit of feedback on my implementation approach. You can browse the (undocumented) code on my cvs server:
openacs/packages/ paypal-support is the paypal package, pump-invoicing is a simple package using paypal-support.
The overall idea is this:
pump-invoicing uses an api-call from paypal-support to generate the paypal "buy now" link (actually a form snippet):
db_multirow -extend { buy_now } invoice_list invoice_list {
select invoice_id, description, total, notes
from invoices
where organization_id = :organization
and deleted = 'f';
} {
set buy_now [paypal::buy_now \
-item_name $description \
-amount $total \
-no_shipping \
-invoice_id $invoice_id \
-return_url $return_url \
-callback_impl [invoicing::package_key]]
}
When the customer completes the paypal transaction, PayPal will post the IPN to /paypal-support/ipn-callback - see openacs/packages/paypal-support/www/ipn-callback.tcl
(Prepare yourself for a confusion of the word callback - sorry about that, but PayPal does a callback on us, and we do a tcl callback internally...)After verifying the IPN, the paypal-support package (optionally) uses the callback mechanism to pass the IPN info back to the client package. In our example, pump-invoicing, here is the callback implementation:
ad_proc -callback paypal::ipn::callback -impl pump-invoicing {
-ipn_ns_set:required
} {
Implementation of the ipn callback provided by paypal-support
} {
ns_log Notice "pump-invoicing: recieved an ipn callback for invoice [ns_set get $ipn_ns_set invoice]"
return 1
}
I think that's nice and simple. There are a few nuances - some dealt with, some still to be - with how we need to interact with PayPal, but that's about it.I'd appreciate it if anyone interested in Paypal could take a look at the code and give me some feedback.
The reason I am using an ns_set to pass in the IPN info is so if paypal add extra info fields, the callback interface won't have to change.
I am planning to add some helper procs to paypal-support to interrogate the ns_set for standard pieces of information to provide abstraction for the common pieces of information - oh for method calls on ns_sets :)
Request notifications