March 15, 2006

Payment Modules with osCommerce

You will find other articles relevant to this document in these sections:
Cameron Manderson @ 12:21 pm

I have had a fair bit of experience now with Payment Modules under osCommerce. I have used publicly available payment modules as well as writing my own (for Australian eSec/Securepay, Westpac Webadvantage and Mastercard Internet Gateway Services - MIGS).

I have to say that a lot of the modules aren’t correctly documented and often take the quickest approach to doing a problem, without considering future maintenance or implementing good industry practices. Overall the osCommerce package has, in my opinion, in general, become more of a nightmare than a solution for anything you want to do that slightly changes from the standard package they provide.

But instead of turning this into a “I am so over osCommerce” post I am going to discuss coding up a Payment Method that will suit the requirements of your client or your site.

The Payment Module

The payment module is a way of creating a custom hook point for handling payment by a specific means, such as accepting payment via PayPal or through an Online Credit Card Gateway. It is written flexible enough to cater for 98% of situations and has frameworked multilanguage support. A payment module is formed of two files, the Payment Module Language file as well as the Payment File Class.

The payment module language files are located in

“includes/languages/[english]/modules/payment” and should to correspond to the same name as your class file. It contains series of define(); calls to setup the various language requirements that you need.

The payment module class files are located in

“includes/modules/payment” and are typically named similar to “cc_via_whatever.php” or something more descriptive. This is the file that will handle our processing.

You will need to request from your payment gateway provider an integration guide. Any payment provider will be able to provide you this information and should provide sufficient support for you to diagnose the process.

The next step is to analyse the flow of the Payment Module Class. This is extremely important for you to understand as you will need to disect your payment integration into the correct functions of your Payment Class. Ensure that you protect your clients sensitive information and never rely on hidden form fields (!).
The order in which the payment module is executed occurs similar to below:

Constructor (function cc_via_whatever): Purpose is to initialise requirements of osCommerce. The variables that it wants you to configure include:

- $this->code = (same as your class file name prepend, eg, “cc_via_whatever”)
- $this->title = (Title of the payment module, EG “Payment Via Credit Card Facilities Online”, you will see this appear on your website frontend)
- $this->description = (a more verbose explaination of the payment module)
- $this->enabled = (This is very important to set true or false. I usually check to ensure all my Admin controlled variables are set before making this module enabled)
- $this->form_action_url = (Where to submit the form contents to once hit submit)
- $this->sort_order = (The sort order of this module in correspondance to others)

function update_status: Purpose it so check whether this payment module is available during runtime with an order.
Usually this method will analyse whether the payment module is valid within this clients zone. This is usually a generic call, so you can reference other example payment modules.

First Stage, Making Selection of the Payment Module

function javascript_validation: Purpose is to check the contents of the submitted payment details when this option is selected for payment.
This is usually fairly generic between the credit card modules, but you will need to ensure that your naming of your files remain the same as well.

function selection: Purpose is to provide a set of form information when the payment module is selected. The form information is used to render the form required fields, such as Credit Card number etc. The javascript validation provided in the above javascript_validation method will work off the field names setup here. If you are using a bank hosted integration model, or one that does not require user input of credit card you can return only the id and module. Check another payment module for the syntax.
function pre_confirmation_check: Purpose is to validate the details that have been submitted for the form that we created above. This needs to be very thorough. If you are using this payment method for the validation of a Credit Card you may like to make use of the validation class cc_validation.php bundled with osCommerce. Other payment modules will help you which its use. If the form fields don’t validate, this function will redirect the user back to the payment selection screen.

Second Stage, Confirming the order

function confirm: Purpose is to confirm to the user the details that will be used to process the order. Once again this is in an array format that defines keys that will be read in on the confirmation page.

function process_button: This allows us to place in hidden form fields into the confirmation page. These are provided to you by your payment gateway. You will need to carefully analyse which fields need to be placed here - as they are parsed through the request (only) to the next process:

Third Stage, Processing the payment

function before_process: This is where all of our actions go for processing the payment (prior to the order being saved). If you are using a Bank Hosted model this is called after the user has been to the bank and is returning. You will need to validate the request (eg, $_GET/$_POST) to ensure that the bank responded with the correct details. If you are submitting to the bank directly using CURL or similar, you will perform you actions here also to determine if the order should be continued to be processed, or to divert the user back to the payment details screen. This method doesn’t return a value, instead you will need to perform your validation and redirect if necessary. Otherwise allow the function to terminate and it will continue to process the order.

function after_process: This is called after the order has been saved. I don’t usually have a need for this method.

Misc Methods required for the payment module to integrate into osCommerce

function get_error: Create an associative array to house the error. Check syntax from existing payment module

function check: Checks whether the payment has been “installed” through the admin panel. You can determine this by checking for configuration_values which get inserted into the database when the user hits “install”.

function install: Installs the configuration keys into the database. This is where you define the fields to be collected from the adminsitrator user, such as Merchant ID’s etc.

function remove: Removes the configuration keys from the database, called when they hit “remove” in the backend.

function keys: Defines an array containing the configuration key keys that are used by the payment module.

For an example for one that I contributed to osCommerce for MIGS - ANZ, Bendigo use etc checkout the link to the payment module: MIGS Payment Module

I recommend for people to indicate on their module: Proper PHPDoc tags for functions, break up the method access into accessor style methods, try to leave a much notes for future developers (even yourself) such as “//” sections that indicate what you are doing etc. Also ensure to TODO notes where you have not completed a section of the integration, and also quote any documentation versions that you have used.

Lastly to complete the Payment Module you should include correct documentation that outlines how to install via FTP etc.

Share and Enjoy:These icons link to social bookmarking sites where readers can share and discover new web pages.
  • del.icio.us
  • digg
  • Furl
  • Reddit
  • YahooMyWeb

32 Comments »

  1. HI,
    our site is basically shopping cart site…
    we are planning to implement recurring orders facility in our site(like repeating the order for “every day” or “every week” or “every month” or “Every year”).
    i had’t found this payment facility in your documents …
    Can please guide me on this issue…
    like - how do i query…. and how can i get the payment done with out user interaction except for the first transaction.

    replay ASAP . its urgent.

    Comment by vijay — April 14, 2006 @ 5:38 am

  2. Hi vijay,

    For this to be possible you will need to hold onto the credit card details, and encrypt in some form (such a PKI asymetric). You would need to store these to a database, obviously with some sort of date field for next process. You then need to be able to query the database to check if a payment is required (eg, date has parsed). You would decrypt the details, connect to your payment gateway and then process the credit card, update the database on a successful process (eg, determine next process due date) and log the payment specifics to the database (amount received, receipt number etc). This is really part of a billing system which would be seperate to your cart software per say. You will need to overcome issues of notification of failures during processing, maybe automatic notifications to you as admin, crontab to run each day automatically, protecting the database with sufficient security (as required by law), determining your security encrypt/decrypt ideas etc.

    It is quite a big topic, and really needs to be attacked in stages I would imagine. No quick answer.

    Comment by Cameron Manderson — April 18, 2006 @ 10:20 am

  3. Thanks for excelent information how the payment module works.
    I am beginner at getting to know oscommerce and I have difficulties to understand general flow of the system.
    Perhaps someone could help me probably at very easy question.

    I need prepayment or bank transfer module or whatever you like to call it.
    There are allready some available, but my need is little bit different.
    Bank Name, Account Holder, Account Number are of course needed information, but I want to add Finnish standard reference number to that information. Reference number is something unique to the bill + crc number. Simplest way would be to use order_id number, but order_id number is not probably created before order confirmation button is pressed? I assume that is the case!

    So at the next stage I would normally get Thanks for the order screen. Now I need add the payment information to that screen (or create one screen before that) and calculate that reference number. So it seems that I cannot do that with the payment module? It would be logical if I could do that, but if it is not possible in what module I need to changes. Of course that same information must be send with the order confirmation email.

    Cheers,
    Mikko

    Comment by Mikko — June 20, 2006 @ 8:36 am

  4. Hi Mikko.

    You need to have a look at writing the reference number generation into the after_process, does the user need to know it before then? You could also email it to your customer at this stage, along with the other details of the order. Otherwise you could generate a unique reference number prior to processing an order (which could be based off IP/datetime/costtotal or something) and then once the order is being processed you could assign that ID to the order in the after_process also. If the user doesn’t hit confirm then the reference number is not needed.

    Hope this helps.

    Comment by Cameron Manderson — June 20, 2006 @ 9:53 am

  5. I have been hacking my way through the osCommerce forums and have used your MIGS payment module (which I think will be great) in the hope that it will work with Bendigo Bank. I keep coming up with a Runtime Error when it gets to MasterCard.

    Just wondering if you have heard of any success with Bendigo yet?

    Comment by Kain — August 3, 2006 @ 5:57 pm

  6. Can you tell me the specific runtime error you are getting?

    The most common error is an incorrect Merchant ID. So check this. Failing that, if you are comfortable with php, do a search through the cc_via_migs.php source for “die” and you should come across Cam’s die() statement, uncomment this to print out the querystring and just check the correct data is being sent through to the gateway.

    If you’r still having trouble get back to us with the runtime and error and the printout of the querystring.

    Comment by Richard Lee — August 4, 2006 @ 12:23 pm

  7. Hi Richard, I checked the Merchant ID. Unfortunately I’m new to php…
    The runtime error I’m getting is…
    Runtime Exception E5065-08041022:
    Cheers, Kain

    Comment by Kain — August 6, 2006 @ 2:39 pm

  8. Hi Richard,
    I got the information being sent, everything looks fine except I changed vpc_anzExtendedOrderInfo to vpc_OrderInfo to match the feilds I have been given with the test pages. After this I got a new runtime exception E5065-08061416, then later relised they are just a sequential number.
    The only other thing that looked different was that the fields are in a different order but I didn’t think that would matter. Here’s the querystring (minus the hash, merchant and code, cheers.

    https://migs.mastercard.com.au/vpcpay?

    session_id=815d03dd6e38c3c6400b7b1317a5a32c&
    session_name=osCsid&
    vpc_AccessCode=XXXXXXXX&
    vpc_Amount=13000&
    vpc_Command=pay&
    vpc_Locale=en_AU&
    vpc_MerchTxnRef=test2AT20060806134519%2F1&
    vpc_Merchant=TESTBBLXXXXXXX&
    vpc_OrderInfo=test2AT20060806134519&
    vpc_ReturnURL=http%3A%2F%2Fmydomain.com.au%2Fcart%2Fcheckout_process.php&
    vpc_TicketNo=2&
    vpc_Version=1&
    vpc_anzExtendedOrderInfo=My+Name&
    vpc_SecureHash=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Comment by Kain — August 6, 2006 @ 3:38 pm

  9. I am not sure why my post didn’t come up, but I think your problem is the vpc_anzExtendedOrderInfo, disable it by commenting out the lines that draw the hidden fields in the module. You should not use any of the vpc_* variables for you custom information, like vpc_OrderInfo.. This should fix your problem. Unfortunately this additional line may be causing issues.

    Comment by Cameron Manderson — August 6, 2006 @ 4:18 pm

  10. Thanks, that got it going.

    Comment by Kain — August 7, 2006 @ 1:45 pm

  11. Glad you got it working Kain :)

    vpc_anzExtendedOrderInfo is a custom field ANZ supplied me with so I could store customer name info beside each transaction. This field isn’t part of the official MIG’s implementation and is obviously causing errors with Bendigo’s MIGs gateway… We’ll re-upload a new version of MIGS soon

    Comment by Richard Lee — August 7, 2006 @ 2:44 pm

  12. Arrrrgh,

    Hi Cameron,

    Had it going great, a long story then goes on ending with a re-install of the whole cart and starting from scratch…

    I have the osCommerce Migs contribution up and running, its deducting money from the test cards and saying transaction approved then returns to the log_in page of the site. Instead of saying transaction done and sending off a confirmation email etc.

    Please tell me this is a common and easy fix.

    cheers, Kain

    Comment by Kain — August 16, 2006 @ 4:33 pm

  13. This may be due to the OSC session ID not being parsed to or returned to the OSC installation, therefore your OSC installation can not continue with the checkout process. (Generally your web browser should use a cookie to identify an existing session ID when returning to the site).

    Once again use the diagnostic features identified above (uncomment the die field, check what is being sent to the server and look for any of the session ID’s and the correct return URL). You will also want to check the returned result (but you may not be able to get there due to the session issue).

    Good luck with diagnosing your error, please keep us posted as there may be something we can do to help.

    Cheers

    Comment by Cameron Manderson — August 17, 2006 @ 9:52 am

  14. Hi Cameron,

    Thanks for your suggestions, I appreciate the help. As you can see from the info below the session info is the same as what I had when it was operational (should it return to checkout_process.php?). I tried with force cookies on in osc,I couldn’t get two computers to operate past the osc prompt to turn cookies on by lowering security to medium (or even minimum).

    I haven’t figured out how to check the banks return info. Although going into the merchant administration site shows that the transaction is completed successfully.

    Output info….

    https://migs.mastercard.com.au/vpcpay?

    session_id=f78dde5820b731a47870c0e98a4e8ab2&
    session_name=osCsid&vpc_
    AccessCode=xxxxxxxx&vpc_
    Amount=260600&vpc_
    Command=pay&vpc_
    Locale=en_AU&vpc_
    MerchTxnRef=test2AT20060817095417%2F1&vpc_
    Merchant=TESTBBLxxxxxx&vpc_
    OrderInfo=test2AT20060817095417&vpc_
    ReturnURL=http%3A%2F%2Fmydomain.com.au%2Fcart%2Fcheckout_process.php&vpc_
    TicketNo=2&vpc_
    Version=1&vpc_
    SecureHash=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    cheers,

    Comment by Kain — August 17, 2006 @ 11:12 am

  15. Hmm that is a tough one, what modifications have you made to standard OSCommerce installation? Have any of the hosting structure changed? eg, hosting them on a local computer opposed to a live server etc..?

    It is correctly parsing the information across to the payment gateway, hence a normal looking request to the bank, which is can process correctly, but when it is getting a response back to the site- OSCommerce appears to interrupt without setting up the session again, before MIGS can resume a transaction (therefore not even getting to MIGS).

    If you have installed any additional modification they may be the cause of the interruption. I would look for any that interfere with sessions or checkout process. Maybe the osCsid identifier changing etc.

    Speak shortly,

    Comment by Cameron Manderson — August 17, 2006 @ 6:25 pm

  16. The mod’s I have included is the file_feature-.77 contribution so people can upload an image for use in the shop and product atrributes such as text, radio etc. After that I win-merged the global patch files to get the register globals going again.

    Like the last instal I had it on a live server, no changes.
    I do get to MIGS though, i can process a test credit card and it says transaction approved, here’s your receipt number, returning you to your merchant etc. Even in the banks merchant administration web site it says transaction approved.

    Maybe I should try removing the upload file mods and see what happens. The thing is, I had these 3 (file feature, global patch, migs) running last week. it was after installing a TNT shipping module it became such a mess so I started a fresh install (including SQL) without TNT.

    Arrrgh, once more.

    Comment by Kain — August 17, 2006 @ 7:12 pm

  17. Hi again Kain,

    Sounds like a very annoying situation!

    Yes the “sever” point between the application happens when migs redirects the user to a URL with the bank page. If migs has done its job correctly to this stage (with the correct merchant ID etc) you will be able to process a transaction with the bank, get the receipt number into your MA etc. The bank then attempts to send your client back to your site.

    When the client is sent back to your site, they are sent to the “return url” that is present in your initial request. OScommerce has some prepend tasks that identify the user, see whether they are allowed to process an order and then parses control using the processes outlined in the above article.

    If oscommerce doesn’t think the person should be continuing the process they will most likely be shifted back to the login process without allowing MIGS to see the request and process the response.

    Speak soon
    cam

    Comment by Cameron Manderson — August 18, 2006 @ 9:03 am

  18. […] melbourne chapter ยป Payment Modules with osCommerce (tags: oscommerce) […]

    Pingback by links for 2006-11-07 « Andy’s Blog — November 8, 2006 @ 5:33 am

  19. Hi Cameron/Richard,

    I’m having some difficulty with the “ob_get_contents()” in cc_via_migs.

    I have written a custom payment gateway to DIALECT in Java. This sits on an internal secure sever, and outputs the following after a transaction attempt:

    processingError=true

    processingErrorMessage=

    transactionApproved=

    responseCode=

    transactionNo=

    receiptNo=

    merchantTXRef=

    transactionDeclined=

    creditCardExpired=

    insufficientFunds=

    My other java apps use the buffered reader to get the Response Code(readline 8) , Transaction Number(readline 10), and Receipt No(readline 12).

    I have got the cc_via_migs module to make a successful transaction to our payment gateway, but am unable to get it to read the response, and update the DB with these values, hence the script makes a succesful payment but then diverts to payment_error.

    Please help a PHP newbie.

    Regards
    Tony.

    Comment by Tony — February 25, 2007 @ 5:54 pm

  20. ob_get_contents only buffers the output content for us to have a look at from the server. What do you mean by unable to read the response? What happens when you echo it to screen? Empty? What integration method are you using.. I am guessing merchant hosted?

    Comment by Cameron Manderson — February 28, 2007 @ 10:32 pm

  21. Great tutorial, I still have to try it.

    It was the only one I could find on the internet so it was worth a digg.

    http://digg.com/programming/Payment_Modules_with_osCommerce

    Comment by Myahya — March 4, 2007 @ 4:35 am

  22. […] “Payment Modules with osCommerce” is a good tutorial for writing payment modules for osCommerce, which I need to do as part of my graduation project. I was not able to find any other guides or tutorials for writing payment modules, and osCommerce is poorly documented. The tutorial was even worth a digg. […]

    Pingback by Developing Payment Modules with osCommerce « Mohamed Yahya — March 4, 2007 @ 4:52 am

  23. Myahya - thanks for digging this article!

    Comment by Richard Lee — March 5, 2007 @ 10:05 am

  24. Hello Richard,

    Great article and got me started. Am using with Bendigo Bank but have a problem with the total being passed on. Using order total module and have tried without but most orders are being passed on $1 less than the total amount. On larger orders this amount increases to around $2-3 per order. The lesser order I can fix up but would like to know what is causing this problem.

    Any assistance would be greatly appreciated.

    Thanks

    Damien

    Comment by Damien Tomlins — June 1, 2007 @ 4:10 pm

  25. Just an update. Larger carts, around the $2000 mark send info of 300 to the MIGS server. Any ideas what could be causing this?

    Thanks

    Damien
    Coast VoIP

    Comment by Damien Tomlins — June 1, 2007 @ 4:30 pm

  26. Very nice, I was just searching for stuff on what the different function in a payment module do, this answered that.. amongst the 500+ modules in osCommerce site noOne has done CheckCare (Alliance / AACH) yet, so I just did, if anyone like a copy please contact me at the contact form on my web page, my code isnt a true module as I did hardcode some english text for error messages in a couple of places, but anyone who likes a copy is free to get one and tweak and perhaps properlify for the world :)

    Comment by Stokkeland — June 8, 2007 @ 12:15 pm

  27. Hi,

    You mention: “Ensure that you protect your clients sensitive information and never rely on hidden form fields (!).”

    However, I notice that your module uses hidden form fields in the confirmation button.

    Could you please clarify what you mean by “never rely on hidden form fields” then?

    Comment by TLT — August 30, 2007 @ 11:29 am

  28. Hello,

    Grt document. I have an oscommerce enabled website, our payment gateway is ICICI payeal. I have configured both but now the problem is that oscommrce doesn’t keep tracks of orders. i.e. when customer buys something he got redirected to payment gateway site. that is fine now I want that when the transaction get finished customer must be redirected to checkout_process.php. so that oscommerce can keep track or can save the order. I have tried that to redirect on checkout_process.php but it is redirected to login.php please help me to resolve this issue.

    Thanks.

    Comment by jaswant — October 17, 2007 @ 6:36 pm

  29. Hi,

    I need to modify enets.php file present in the includes/modules/payment/enets.php to accept the “amex” credit card in enets. Currently it accepts only visa/master card.

    Would you please clarify how to rewrite the enets payment module.

    Thanks in advance,
    Yegeswari

    Comment by Yegeswari — December 5, 2007 @ 5:19 pm

  30. Hi,
    I am using ANZ egate merchant hosted services and they require me to put every merchant hosted orders in “verify by visa” mode. The module that you design can only be use in normal transaction but not verify by visa which ANZ said it might easy to get a charge back. Can you guide me how to modify your code in order to work with “verify by visa” mode? Thank you.

    Comment by Andy — December 17, 2007 @ 11:34 am

  31. Hi,

    I have a website where users gain points. I need the user to be able to buy stuff with these points and not some currency. Could you suggest how do I go about this.

    Thank You
    Ruchira

    Comment by Ruchira — February 13, 2008 @ 4:12 pm

  32. Hello
    As you surely see my english are not good, I am not successful to understand model of the payment, attached my code.

    I am very I would appreciate it if will be able to help me. Thank you.
    Reuben
    Jerusalem
    Israel

    Comment by Reuben Porat — May 20, 2008 @ 5:54 pm

RSS feed for comments on this post. TrackBack URI

Leave a comment