Forum OpenACS Q&A: Want to make a new callback registry, details below...
The item type could be numeric (as in, an object ID to a description of the item) or a string... and either of these would be a parameter to the callback register proc.
How is this normally done? Is there an example of this kind of thing I could pick apart?
ecommerce calls the payment-gateway service when an order is made. The payment-gateway interfaces with the specific gateway packages.
Depending on your trigger strategy, take a look at ecommerce/tcl/ecommerce-scheduled-procs.tcl or ecommerce/tcl/ecommerce-credit-procs.tcl
What I need to have happen is a specific objeect is created, called a certivicate...
on my side (of the app authorship), the cert grants usage permission to certain pages for a length of time specified in the cert, and would be specified when the ec_item is sold.
From what I understand of ecommerce, it takes care of the payment side and possibly causes stuff to be shipped. For my case, instead of shipping something, all I need is for it to create an object.
I'm fairly certain ecommerce has the basis of this use-case built in.
Each product is assigned shippable_p. 0 means item is a service or downloadable item.
Each item purchased is assigned a unique id in ec_items. For example, if quantity 5 of an item is purchased, there will be 5 items created in ec_items.
Parameter CartMaxToAdd sets the upper limit for quantities added to the shopping basket --helps prevent service interruptions when a large quantity is added to a cart.
A simplified case should be possible without assigning a certificate, given ec_items id mapping and custom attributes handled via ec_custom_product_fields and ec_custom_product_fields_values. If the certificate number is important, look at adding the package ec-serial-numbers which assigns and tracks serial numbers to specific items in an order --I don't have any experience with ec-serial-numbers.
I ended up making these cert things as part of my app, and they're tested: they allow access starting at a certain timestamp, and begin denying access at another. Works great, getting ecommerce to create the cert is the last step.
I feel I have a coupla choices, one, is I would add code specific to my app that just creates the cert... the problems here being that nothing else could benefit,
The other choice would be a more general solution as outlined in my original message, the only problem I see is I don't know yet how to do it.
First cut on my thoughts on it... two levels of callbacks, one fires any time an ec_item is created, and that in turn fires a callback to "clients" who register for a specific type of ec_item (maybe product id?), then I register as a client of the second callback for the type of item represented by my app.
Bottom line: I need for ecommerce to create the cert object.
Take a look at the ecommerce doc page: /doc/ecommerce/ecommerce-operation
There are multiple ways to handle this.
I wouldn't worry too much about a general solution. Ecommerce package is very much web 1.0 technology. A new version is in development --been going on what.. 10 years now? Anyway.. when it's beta, a message will be posted in the forum here. cheers!
To all: I'm still looking for something general I can apply to any package or table, that looks like:
- an insert or update trigger identifies the insert or update, such that a list of ID column values, is seen in a plpgsql trigger func
- this list of IDs and an indication of what happened about them (insert? or update?) made available thru a tcl callback
and the way I would apply that, is an insert trigger on ec_items for a specific product_id would cause an object in my app, an object completely independent from ecommerce -- once created, access to pages in my app are granted according to terms stored in the object.
Right now the (sub)problem I want to solve is how I can get an indication when a product of a specific type is pu8rchased, either in a tcl func or a db stored proc.
ec_update_state_to_authorized updates ec_items on a newly authorized order, so that shippable items are to_be_shipped.
At the same time, one could query the order for ec_items where shippable_p == 'f', and mark some independent lookup table that the object ID is readable for the user of the order_id for N units of time (or time_expires).
No callbacks are needed.
Callbacks are indicated when the user is waiting for a displayed response, and a procedure takes an unspecified amount of time (usually seconds or more).
ec_update_state_to_authorized is executed as a scheduled procedure, so a callback is unnecessary.
Using this proc means that the credit card has been processed for nonshippable items, so it's time to provide access via procs called from it.
A schema might be defined with these minimums:
The object_id could be a subsite, a content_item etc
The particulars would be handled by your custom procs.
Ben, I have the table you;re talking about when you say my_app_certificates. I was thinking that ecommerce could make one (by whatever mechanism) when an ec_item of the appropriate kind becomes shippable, and I thought what you're calling my_app_certificates.object_id could point at the ec_item.
The reason I wanted to do it as a callback, is so that my app-specific code would not go into ecommerce, what would go there is a callback setup so that anyone who wants to could run custom code that doesn't necessarily have anything to do with user interface and that is triggered by the purchase of a specific item. Such custom code would register itself with a proc I write, one of its parameters being the ec_item type. Then, when an item of that type is sold, the callback would fire.
There are a bunch of custom features in the ecommerce package. Basically, if a feature is unimplemented, the code does not trigger any related activity.
Creating a callback might be a practice that works for other locations.
For ecommerce, you might find it more consistent to just add the code and have it not trigger when the feature is unimplemented --consistent with existing code strategy.
Each product_id is an acs object_id, so a product_id / certificate map table should be all that is needed to create triggering code.
If you want to integrate the code further, you could create a product_category_id for the certificates and identify the category_id via a parameter or something.. again, where the code doesn't trigger activity if the feature is not implemented for a particular installation.
Anyway, I'm confident you (will) have something that works well.