About This is a Python framework to integrate with Protx VSP Form credit card payment service. It was created to fill the gap because Protx doesn't have a kit Python. It is build as a Zope product. It can be used in Plone or other Zope systems. You can also take pieces of it and use in other Python-based web servers. What is Protx? Read more on "www.protx.com":http://www.protx.com. Basically it is like PayPal. Allows you to gather payments from credit cards without necessity of building super secure system to store users data. Why then use Protx instead of PayPal? This is a marketing question and it is not my role to answer it. But the big advantage for our UK customer is that they transfer money within 3 days. PayPal needs 30-60 days. This is called **cash flow**. But I wouldn't bet my bottom dollar. Installation 1. Unpack, copy to Zope 'Products' directory and restart the instance. 2. Add 'Protx Tool' in ZMI from 'Add' list. It has default id 'protx_tool'. 3. Select storage plugin you want to use: default is ZODB storage, You can change it to SQL storage. 4. If you are using relational database create table defined in *ZProtx/sql/Tables.sql* 5. If you have Protx account change Properties: Protx login/Vendor name, Protx password, Protx form action url. If not, use values provided but they will only work for VSPSimulator. ZMI Management Test Simple page that allows quickly to check if this tool is working. After installation step go here and fill test form. Submit it and you will see step 2. It is necessary. Here we created form that will be send to Protx with encrypted data and some parameters. For debug purpose I'm showing all this hidden fields. Press *Submit* and you will be redirected to VSPSimulator (if you haven't changed anything). Follow the instructions on the screen and at the end you can select result status. You can choose 'OK' or one of possible errors. After that Protx redirects to our tool and calls given 'SuccessURL' or 'FailureURL'. Here they are simple pages that will show all fields send from Protx. Go to 'Transactions' tab and on the top there is your last operation. Plugins What is a plugin? Plugin is a set of scripts or sql files in *ZProtx/plugins* folder. Every plugin is a separate subfolder there. When you load a new plugin all scripts stored in tool will be removed and new files from given folder loaded. Currently there are only two plugins *zodb* and *sql*. Using this page you can see what plugin is used and change it. ZODB plugin Storage that uses 'PersistentMapping'. All data is stored as simple dictionary with transaction id as key. It was impossible to implement this using only Python Scripts so I've implemented a little supporting class 'ZODBStorage'. Scripts are calling methods from it. SQL plugin Uses table 'transactions' to store data. Table is very simple and should work on all databases. It was tested with PostgeSQL 8.2. The only thing required in Zope is working Database Connection. Tool uses first connection returned by 'Products.ZSQLMethods.SQL.SQLConnectionIDs'. Plugin's structure Each plugin contains 5 Python scripts: * 'addTransaction' - method called each time new transaction is created, * 'deleteTransactions' - method used to remove transaction, * 'editTransaction' - used every time to update transaction data, * 'getTransaction' - method used to obtain transaction from storage, * 'getTransactions' - gets all transactions. What they do is obvious. But the idea behind is quite comlpicated. Because we want to have multiple data storages I need to have different functionalities which common API. That is why I've created plugins. Each plugin MUST have those methods which are called inside tool. All access to storage is done by those scripts. They are objects but inside tools they are treated like ordinary methods. ZODB plugin has only those scripts and they are using ZODBStorage API to access data. SQL storage has also ZSQL Methods that write to and read from database. All storage specific functionality is hide inside them and we don't need to change anything in Python code whenever we change plugin (or add new one in the future). Transactions List of all stored transactions. List looks the same whatever plugin we use. Each transaction is a record of all fields sent to and from Protx. Transaction that went to Protx but never return has filled fields till 'DeliveryPostCode'. If Protx send a response we update fields from 'AddressResult' to 'CAVV' which all possible data. See **References** section to learn more about each column. Contents Standard view of Zope's folder. Here are placed scripts and ZSQL Methods added from plugin. It is possible to change them and add new if one want to change standard behaviour. **WARNING**. If you add/change something and reload/change plugin all your changes will be lost. Properties Standard Zope's properties tab with some crucial configuration: * 'Protx login/Vendor name' - your Vendor Name (unique login) from Protx * 'Protx vendor email (optional)' - your email where transaction inforamtions are send * 'Protx password' - XOR encryption key obtained from Protx * 'Protx form action url' - URL when transaction form is send. There are 3 possibilities: 1 - Simulator website, 2 - Test website, 3 - live. Read on Protx website how to obtain accounts on each of them. * 'Protx protocol number' - Protocol number used to communicate. Currently supported 2.22 (V.2007) * 'Method/page for success url' - method/template where Protx sends Request when transaction is successful. This is only method name that must be implemented/added inside tool. Before sending tool adds the whole url to itself before this value. * 'Method/page for failure url' - method/template where Protx sends Request when transaction is failed. This is only method name that must be implemented/added inside tool. Before sending tool adds the whole url to itself before this value. * 'Currency (ISO code)' - Currency code used in transactions. We can select from list of few predefined/commonly used. Protx supports only UK banks so maybe only GBP is enough? * 'Form fields removed from REQUEST before send to Protx' - we can have many other information inside form in our real application. We may do whatever we want with them but we **MUST NOT** send them to Protx. It will break the communication. Add here all field names that were added or aren't required. * 'Current plugin' - read only name of current plugin. Integration Process flow This is complicated part :). I can't use images so I'll try to describe process using text. There are nice images in Protx manuals which is nice to read. Of course this tool aims to relieve you from reading and implementing something from scratch. So this is what happens: 1. User fills the order form. You can build form with fields required by your application but you have to add mandatory fields, either visible or hidden: 'SuccessURL', 'FailureURL', 'Amount', 'Currency', 'Description'. 2. After submit we construct summary form. The action of this form is an URL to Protx system. The summary should have information readable by user like list of all products and total price. But for Protx we need to provide another data (hidden inputs in form): 'VPSProtocol', 'TxType', 'Vendor', 'Crypt'. First 3 fields are defined in tool and 'Crypt' is generated by method 'here.startTransaction(request)'. This methods add transaction information to storage and returns it as crypted string which must then be send to Protx. You don't need to worry about unique id - it is generated in the system automatically. 3. Now we are on Protx website. We have to provide our credit card data and pay for shopping. If we are using simulator or test we just pretending doing this. After transaction is done we are redirected to our website again. 4. Tool receives crypted field 'crypt'. Inside there is information about transaction. We encrypt it and update transaction record inside storage. Received data contain our transaction id so we know which transaction to update. In example both success and failure urls are templates. Inside them we call 'processSuccess/Failure' methods with 'REQUEST' as argument. Those methods encrypt data and update transaction record with received information. Then we show those fields but in reality we will show page that confirms payment or explains error. You can integrate your application with Protx Tool in two ways. All of them require some changes in described process. Using scripts in ZMI This is simpler case. If you don't need much changes you can use this tool almost straight away. This will happen if you have simple application and don't need special actions when products are bought. 1. You can create your own shopping cart templates using required fields/methods described above. In template that summarize order call 'startTransaction(request)'. This will add new transaction to storage using 'addTransaction' script. 2. You probably have your own database/storage with products or you want to store more information about each sale. Nothing difficult. You can update plugin scripts either in file system or ZMI. You can also add your own scripts, SQL Methods or even External Methods to provide advanced processing. 3. Each time transaction is added, edited, deleted it will call plugin methods with your changes providing business logic required by your application. 4. In template/method that is called when transaction is successful call 'processSuccess(request)' and when failed call 'processFailure(request)'. Those methods call 'editTransaction' script to update transaction. 5. Examples: - Add script:: data['Status'] = '' data['add_date'] = DateTime().strftime("%Y-%m-%d %H:%M:%S") context.addZODBTransaction(data) #your code context.doSoemthingClever(data) return True - Edit script:: context.editZODBTransaction(data) #your code context.doSoemthingMoreClever(data) Deep level integration If you think that above functionality is not enough for you there is few other possible ways: - Use this tool and its API methods in your code. Do whatever you want with input/output data, add additional validation or fraud detection. - You don't have to use its own storages, you can implement your own. You can integrate with some existing solutions that store data somewhere else that RDBMS or ZODB (flat files, xml, MS Access, XML-RPC etc) - Implement your own solution inheriting from classes from 'ZProtx'. The most important is class 'Protx' which contain methods required by Protx and used in their kits. Unit tests Go to 'tests' directory and if you are using Windows edit 'runone.bat' and 'runall.bat' and set path to Python executable in your Zope installation folder. On Linux edit 'runone.sh' and 'runall.sh' and do the same. Or don't worry if you have this path defined in system. To execute all tests:: runall.bat (Windows) ./runall.sh (Linux) To execute tests for one class:: runone.bat (Windows) ./runone.sh (Linux) Known problems If you see this error on Linux:: from ImplPython import RestrictedDTML, SecurityManager, ZopeSecurityPolicy ImportError: No module named ImplPython That means that you are using wrong 'python' version interpreter. You must change 'PYTHON' variable in shell script to use version that Zope uses. References * "Protx: VSP Form Custom Integration":http://techsupport.protx.com/vspformcustom.asp * "Protx: Downloads":http://techsupport.protx.com/downloads.asp License This is **FREE** and **OPEN SOURCE** product. You can use anywhere for free and change it whatever you like. For details see *LICENSE.txt*. Author * "Lukasz Lakomy":mailto:lukasz@llakomy.com