iDEAL Advance PHP Integration

iDEAL Advance PHP integration is not that tough but it will be tough when you miss documentation. Before you begin to write code, read “iDEAL_General_EN_v2.1.pdf”, Topic 3.4. Below is summery diagram.

You should be aware of general configuration part before you can begin this portion of code. Read Topic 3.3 in “iDEAL_Advanced_PHP_EN_V2.2.pdf”.

In brief it works in following way:

  1. Make directory request (Get Bank list, Issuer list is what they called)
  2. Make Transaction Request and redirected to iDEAL/bank)
  3. Make Status Request (This is after iDEAL/bank redirect to webshop)

1) Directory Request

Directory Request means you are fetching Issuer List (List of banks) from iDEAL. This is list of banks which are associated with iDEAL and making payment from these banks is possible. Below is code, how can you fetch Issuer List:

  1. $ideal_connector = new iDEALConnector();
  2. $response = $ideal_connector->GetIssuerList();
  3.  
  4. if ($response->errorMessage)
  5. {
  6.  $errorCode = $response->getErrorCode();
  7.  $errorMsg = $response->getErrorMessage();
  8.  $consumerMessage = $response->getConsumerMessage();
  9. }
  10. else
  11. {
  12.  $IssuerList =& $response->getIssuerFullList();
  13. }

If you see line number 3, I have made little bit changes. Original iDEAL document has

  1. if ( ! $response ) {,

There’s no way that $response is false on failure because $ideal_connector->GetIssuerList() returns ErrorRespose Object. So when error is returned by Get $ideal_connector->IssuerList(), you’ll encounter error in next line i.e. $response->getIssuerFullList() because ErrorResponse object do not have getIssuerFullList().

Once you fetch Issuer Lists (Banks), let end user select his/her bank. HTML code looks like below:

  1. <form method="post" action="" id="form1" name="form1">
  2. <td valign="top" class="form-label">
  3.  
  4.      <select name="bank">
  5.   <option value="">Select Your Bank</option>
  6.   <?php foreach($banks as $bank): ?>
  7.      <option value="<?php echo $bank->issuerID ?>"><?php echo $bank->issuerName ?></option>
  8.   <?php endforeach; ?>
  9.      </select>
  10.  </td>
  11.  <td>
  12.     <input class="btn" type="submit" name="submit2" value="Make Your Payment" id="submit2">
  13. </td>
  14. </form>

Note: It is suggested to save issuer list in local cache and run DirectoryRequest query once in 24 hour.

Transaction Request
End user will select banks (issuer is what they called) and submit form. Now you have to make Transaction request and redirect issuer’s website. Code looks like below

  1. $ideal_connector = new iDEALConnector();
  2. $response = $ideal_connector->RequestTransaction($issuerId,$purchaseId,$amount,$description,$entranceCode);
  3. if($response->transactionID)
  4. {
  5.  $url = $response->getIssuerAuthenticationURL();
  6.  header("Location:".$url);
  7. }

After this, end user login to his bank and make payment. On successful, iDEAL/bank redirect customer to webshop again (you have to define redirect page in config, they call it MerchantReturnURL).

Parameters for RequestTransaction():
IssuerId: the ID of the issuer the consumer has selected from the pick list
PurchaseId: the purchase number according to the online shop’s system
Amount: the amount in whole cents (no decimals; 1 Euro = 100)
Description: the description of the product
EntranceCode: a code determined by the online shop with which the purchase can be
authenticated upon redirection to the online shop (see section 4.2.2 for details).
(optional) ExpirationPeriod: if different from the configured value.
(optional) MerchantReturnURL: if different from the configured value.

Status Request
When iDEAL/bank redirect end user to webshop, it will automatically add two parameters entranceCode and TransactionId. entranceCode is hold by ec variable and TransectionId is hold by trxid variable. So, you have TransactionId (trxid) in landing page, you should make status request. If you do not make status request, payment will not be guaranteed. Following is code to make status request:

  1. $connector = new iDEALConnector();
  2. $transactionId = $_GET['trxid'];
  3. $response = $connector->RequestTransactionStatus($transactionId);
  4. if ($response->errorMessage)
  5. {
  6.  $errorCode = $response->getErrorCode();
  7.  $errorMsg = $response->getErrorMessage();
  8.  $consumerMessage = $response->getConsumerMessage();
  9. } else {
  10.  $status =& $response->getStatus();
  11.  
  12.  if ($status === IDEAL_TX_STATUS_SUCCESS )
  13.  {
  14.   $consumerName = $response->getConsumerName();
  15.   $consumerAccNumber = $response->getConsumerAccountNumber();
  16.   $consumerCity = $response->getConsumerCity();
  17.  }
  18. }

(Issue request can be made manually from iDEAL Dashboard as well).

iDEAL Basic (ING Bank) Integration

iDEAL Basic integration method is different from iDEAL Advance. Sumit Bankskota has provided code for basic integration, thanks Sumit. Below is complete code, try on your own:

  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  4. </head>
  5. <body>
  6. <FORM METHOD="post" ACTION="https://idealtest.secure-ing.com" name="frm1" id="frm1">
  7. <INPUT type="hidden" NAME="merchantID" value="xxxxxxx" />
  8. <INPUT type="hidden" NAME="subID" value="0" />
  9. <INPUT type="hidden" NAME="amount" VALUE="xxxxx" />
  10. <INPUT type="hidden" NAME="purchaseID" VALUE="xxxx" />
  11. <INPUT type="hidden" NAME="language" VALUE="nl" />
  12. <INPUT type="hidden" NAME="currency" VALUE="EUR" />
  13. <INPUT type="hidden" NAME="description" VALUE="iDEAL Basic purchase" />
  14. <INPUT type="hidden" NAME="itemNumber1" VALUE="xxxx" />
  15. <INPUT type="hidden" NAME="itemDescription1" VALUE="xxxxx" />
  16. <INPUT type="hidden" NAME="itemQuantity1" VALUE="xxxx" />
  17. <INPUT type="hidden" NAME="itemPrice1" VALUE="xxxxx" />
  18. <INPUT type="hidden" NAME="paymentType" VALUE="ideal" />
  19.  
  20. <INPUT type="hidden" NAME="validUntil" VALUE=" 2009-01-01T12:00:00:0000Z" />
  21.  
  22. <input type="hidden" name="PSPID" value="PSP-id" />
  23.  
  24. <input type="hidden" name="accepturl" value="http://www.hosturl.nl/path/accept_url.php" />
  25. <input type="hidden" name="declineurl" value="http://www.hosturl.nl/path/decline_url.php" />
  26. <input type="hidden" name="exceptionurl" value="http://www.hosturl.nl/path/exception_url.php" />
  27. <input type="hidden" name="cancelurl" value="http://www.hosturl.nl/path/cancel_url.php" />
  28. <input type="hidden" name="homeurl" value="http://www.hosturl.nl/home">
  29.  
  30. <input type="submit" value="Bevestig bestelling" id="submit2" name="submit2" />
  31. </form>
  32. </body>
  33. </html>

Parameter values in hidden control are hypothetical (dummy). So you need to replace with right values.

For iDEAL Advance, click this link.

If you have done for any other Bank or other way, let me know.

TinyMCE editor – image upload plugin (Ajax File Manager)

TinyMCE is very nice editor. But it lacks image upload functionality which drives crazy to lot of programmer as enabling image upload facility is tough. I have chance to play around with it and found actually integrating image upload facility is very easy. Among lot of plugin, I find Ajax File Manger is nice.

You can download tinyMCE with Ajax File Manager plugin from http://www.phpletter.com/DOWNLOAD, See under “Tinymce Ajax File and Image Manager”. Direct link http://www.phpletter.com/download_project_version.php?version_id=28.

A copy of demo TinyMCE with Ajax File Manager can be seen here http://demo.phpletter.com/tinymce_test.php. View Source and copy code.

Code snippet to enable Ajax File Manager in TinyMCE:

  1. tinyMCE.init({
  2.  mode : "exact",
  3.  elements : "ajaxfilemanager",
  4.  theme : "advanced",
  5.  plugins : "table,advhr,advimage,advlink,flash,paste,fullscreen,noneditable,contextmenu",
  6.  theme_advanced_buttons1_add_before : "newdocument,separator",
  7.  theme_advanced_buttons1_add : "fontselect,fontsizeselect",
  8.  theme_advanced_buttons2_add : "separator,forecolor,backcolor,liststyle",
  9.  theme_advanced_buttons2_add_before: "cut,copy,paste,pastetext,pasteword,separator,",
  10.  theme_advanced_buttons3_add_before : "tablecontrols,separator",
  11.  theme_advanced_buttons3_add : "flash,advhr,separator,fullscreen",
  12.  theme_advanced_toolbar_location : "top",
  13.  theme_advanced_toolbar_align : "left",
  14.  extended_valid_elements : "hr[class|width|size|noshade]",
  15.  file_browser_callback : "ajaxfilemanager",
  16.  paste_use_dialog : false,
  17.  theme_advanced_resizing : true,
  18.  theme_advanced_resize_horizontal : true,
  19.  apply_source_formatting : true,
  20.  force_br_newlines : true,
  21.  force_p_newlines : false,
  22.  relative_urls : true
  23. });
  24.  
  25. function ajaxfilemanager(field_name, url, type, win) {
  26.  var ajaxfilemanagerurl = "http://<host>/<path_to_ajaxfilemanage>/ajaxfilemanager/ajaxfilemanager.php?editor=tinymce";
  27.  switch (type) {
  28.   case "image":
  29.    break;
  30.   case "media":
  31.    break;
  32.   case "flash":
  33.    break;
  34.   case "file":
  35.    break;
  36.   default:
  37.    return false;
  38.  }
  39.  var fileBrowserWindow = new Array();
  40.  fileBrowserWindow["file"] = ajaxfilemanagerurl;
  41.  fileBrowserWindow["title"] = "Ajax File Manager";
  42.  fileBrowserWindow["width"] = "782";
  43.  fileBrowserWindow["height"] = "440";
  44.  fileBrowserWindow["close_previous"] = "no";
  45.  tinyMCE.openWindow(fileBrowserWindow, {
  46.    window : win,
  47.    input : field_name,
  48.    resizable : "yes",
  49.    inline : "yes",
  50.    editor_id : tinyMCE.getWindowArg("editor_id")
  51.  });
  52.  
  53.  return false;
  54. }

Analysis of code:
Line number 15:

  1. file_browser_callback : "ajaxfilemanager"

The value ‘ajaxfilemanager’ defines the name of the Javascript function which will be called every time a user clicks the browse button in one of the dialogue windows. You can see function definition start from line number 25 to 54. This function opens a new window calling a URL tailored (See line number 26).

Important Points
Don’t forget to set upload directory path in tiny_mce/plugins/ajaxfilemanager/inc/config.base.php. It should be relative path.

  1. define('CONFIG_SYS_DEFAULT_PATH', '../../../../../uploads/');
  2. define('CONFIG_SYS_ROOT_PATH', '../../../../../uploads/');

Above folder should have 777 permission. Also set 777 permission to session folder folder, tiny_mce/plugins/ajaxfilemanager/session.

Alternatively you can try following uploader

http://dustweb.ru/log/projects/tinymce_images/

Cofigure:

  1. Give class name to your editor e.g. class=”tiny”
  2. Add following
    In list of plugins, add images
    add editor_selector : “tiny”,
    In list of button, add images
  3. Change DIR_IMAGES and DIR_FILES path on tiny_mce/plugins/images/connector/php/config.php to suit your location. Upload folder should have 777 permission.

Actual configuration looks like (See images on line number 8 and 12):

  1. tinyMCE.init({
  2.  // General options
  3.  mode : "textareas",
  4.  theme : "advanced",
  5.  
  6.  //plugins : "safari,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,wordcount",
  7.  editor_selector : "tiny",
  8.  plugins : "safari,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,images,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template",
  9.  
  10.  // Theme options
  11.  theme_advanced_buttons1 : "save,newdocument,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,styleselect,formatselect,fontselect,fontsizeselect",
  12.  theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,images, cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor",
  13.  theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions,iespell,media,advhr,|,print,|,ltr,rtl,|,fullscreen",
  14.  theme_advanced_buttons4 : "insertlayer,moveforward,movebackward,absolute,|,styleprops,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,pagebreak",
  15.  theme_advanced_toolbar_location : "top",
  16.  theme_advanced_toolbar_align : "left",
  17.  theme_advanced_statusbar_location : "bottom",
  18.  theme_advanced_resizing : true,
  19.  
  20.  // Example content CSS (should be your site CSS)
  21.  content_css : "css/content.css",
  22.  
  23.  // Drop lists for link/image/media/template dialogs
  24.  template_external_list_url : "lists/template_list.js",
  25.  external_link_list_url : "lists/link_list.js",
  26.  external_image_list_url : "lists/image_list.js",
  27.  media_external_list_url : "lists/media_list.js",
  28.  
  29.  // Replace values for the template plugin
  30.  template_replace_values : {
  31.   username : "Some User",
  32.   staffid : "991234"
  33.  }
  34. });

Good luck!