uc_cmcic.module 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. <?php
  2. /**
  3. * @file
  4. * Written by Henri MEDOT <henri.medot[AT]absyx[DOT]fr>
  5. * http://www.absyx.fr
  6. */
  7. require_once dirname(__FILE__) .'/uc_cmcic.inc';
  8. define('UC_CMCIC_URL_CM_TEST', 'https://paiement.creditmutuel.fr/test/paiement.cgi');
  9. /*******************************************************************************
  10. * Drupal Hooks
  11. ******************************************************************************/
  12. /**
  13. * Implementation of hook_menu().
  14. */
  15. function uc_cmcic_menu() {
  16. $items['cart/cmcic/response'] = array(
  17. 'title' => 'CM-CIC p@iement response',
  18. 'page callback' => 'uc_cmcic_response',
  19. 'access callback' => 'uc_cmcic_response_access',
  20. 'type' => MENU_CALLBACK,
  21. );
  22. $items['cart/cmcic/success'] = array(
  23. 'title' => 'CM-CIC p@iement payment success',
  24. 'page callback' => 'uc_cmcic_success',
  25. 'access arguments' => array('access content'),
  26. 'type' => MENU_CALLBACK,
  27. );
  28. $items['cart/cmcic/cancel'] = array(
  29. 'title' => 'CM-CIC p@iement payment cancelled',
  30. 'page callback' => 'uc_cmcic_cancel',
  31. 'access arguments' => array('access content'),
  32. 'type' => MENU_CALLBACK,
  33. );
  34. $items['cart/cmcic/return'] = array(
  35. 'title' => 'CM-CIC p@iement payment return',
  36. 'page callback' => 'uc_cmcic_return',
  37. 'access arguments' => array('access content'),
  38. 'type' => MENU_CALLBACK,
  39. );
  40. return $items;
  41. }
  42. // Make sure CM-CIC p@iement always has access to send responses.
  43. function uc_cmcic_response_access() {
  44. return TRUE;
  45. }
  46. /*******************************************************************************
  47. * Ubercart Hooks
  48. ******************************************************************************/
  49. /**
  50. * Implementation of hook_uc_payment_method().
  51. */
  52. function uc_cmcic_uc_payment_method() {
  53. $title = variable_get('uc_cmcic_method_title', t('Credit card with CM-CIC p@iement'))
  54. .'<br />'. theme('image', array('path' => drupal_get_path('module', 'uc_cmcic') .'/images/logo_cm-paiement-pt.jpg'));
  55. $methods['cmcic'] = array(
  56. 'name' => t('CM-CIC p@iement'),
  57. 'title' => $title,
  58. 'desc' => t('Redirect users to submit payments through CM-CIC p@iement.'),
  59. 'callback' => 'uc_payment_method_cmcic',
  60. 'redirect' => 'uc_cmcic_form',
  61. 'weight' => 3,
  62. 'checkout' => TRUE,
  63. 'no_gateway' => TRUE,
  64. );
  65. return $methods;
  66. }
  67. /*******************************************************************************
  68. * Callback and Helper Functions
  69. ******************************************************************************/
  70. /**
  71. * Add CM-CIC p@iement settings to the payment method settings form.
  72. */
  73. function uc_payment_method_cmcic($op, &$arg1) {
  74. switch ($op) {
  75. case 'settings':
  76. $form['uc_cmcic_url'] = array(
  77. '#type' => 'textfield',
  78. '#title' => t('CM-CIC p@iement URL'),
  79. '#description' => t('The URL to the CM-CIC p@iement payment platform.'),
  80. '#default_value' => variable_get('uc_cmcic_url', UC_CMCIC_URL_CM_TEST),
  81. );
  82. $form['uc_cmcic_tpe'] = array(
  83. '#type' => 'textfield',
  84. '#title' => t('POS terminal number'),
  85. '#description' => t('The 7-character virtual POS terminal number your site was assigned when subscribing to CM-CIC p@iement.'),
  86. '#default_value' => variable_get('uc_cmcic_tpe', ''),
  87. '#size' => 10,
  88. '#maxlength' => 7,
  89. );
  90. $form['uc_cmcic_key'] = array(
  91. '#type' => 'textfield',
  92. '#title' => t('Merchant security key'),
  93. '#description' => t('The 40-character key your site was assigned when subscribing to CM-CIC p@iement.'),
  94. '#default_value' => variable_get('uc_cmcic_key', ''),
  95. '#maxlength' => 40,
  96. );
  97. $form['uc_cmcic_site_code'] = array(
  98. '#type' => 'textfield',
  99. '#title' => t('Site code'),
  100. '#description' => t('The 20-character code your site was assigned when subscribing to CM-CIC p@iement.'),
  101. '#default_value' => variable_get('uc_cmcic_site_code', ''),
  102. '#size' => 25,
  103. '#maxlength' => 20,
  104. );
  105. $form['uc_cmcic_response_url'] = array(
  106. '#type' => 'item',
  107. '#title' => t('Return interface URL'),
  108. '#markup' => url('cart/cmcic/response', array('absolute' => TRUE)),
  109. '#description' => 'You have to provide your bank with this URL for CM-CIC p@iement to function properly.',
  110. );
  111. return $form;
  112. }
  113. }
  114. /**
  115. * Form to build the submission to CM-CIC p@iement.
  116. */
  117. function uc_cmcic_form($form, &$form_state, $order) {
  118. global $language;
  119. $fields = array(
  120. 'TPE' => variable_get('uc_cmcic_tpe', ''),
  121. 'date' => date('d/m/Y:H:i:s', time()),
  122. 'montant' => round($order->order_total, 2) . variable_get('uc_currency_code', 'USD'),
  123. 'reference' => $order->order_id,
  124. 'texte-libre' => md5(uniqid(rand(), TRUE)),
  125. 'mail' => $order->primary_email,
  126. 'lgue' => in_array(strtoupper($language->language), uc_cmcic_languages()) ? strtoupper($language->language) : 'EN',
  127. 'societe' => variable_get('uc_cmcic_site_code', ''),
  128. 'url_retour' => url('cart/cmcic/cancel', array('absolute' => TRUE)),
  129. 'url_retour_ok' => url('cart/cmcic/success', array('absolute' => TRUE)),
  130. 'url_retour_err' => url('cart/cmcic/return', array('absolute' => TRUE)),
  131. );
  132. $fields = uc_cmcic_complete_request(variable_get('uc_cmcic_key', ''), $fields);
  133. // Add the transaction ID to the order's data array.
  134. $order->data['cmcic']['texte-libre'] = $fields['texte-libre'];
  135. // Save the updated data array to the database.
  136. uc_cmcic_save_order_data($order);
  137. $form['#action'] = variable_get('uc_cmcic_url', UC_CMCIC_URL_CM_TEST);
  138. foreach ($fields as $name => $value) {
  139. $form[$name] = array('#type' => 'hidden', '#value' => $value);
  140. }
  141. $form['submit'] = array(
  142. '#type' => 'submit',
  143. '#value' => t('Submit order'),
  144. );
  145. return $form;
  146. }
  147. /**
  148. * Save order's updated data array to the database.
  149. */
  150. function uc_cmcic_save_order_data($order) {
  151. db_update('uc_orders')
  152. ->fields(array('data' => serialize($order->data)))
  153. ->condition('order_id', $order->order_id)
  154. ->execute();
  155. }
  156. /**
  157. * Handle an incoming payment.
  158. */
  159. function uc_cmcic_response() {
  160. if (empty($_POST)) {
  161. watchdog('uc_cmcic', 'Response attempted without any POST data.', array(), WATCHDOG_WARNING);
  162. return;
  163. }
  164. unset($mac_ok);
  165. $order = uc_cmcic_get_order($mac_ok);
  166. if (!$order) {
  167. watchdog('uc_cmcic', 'Invalid response.', array(), WATCHDOG_ERROR);
  168. uc_cmcic_receipt_exit($mac_ok);
  169. }
  170. $order_id = $order->order_id;
  171. if (($_POST['code-retour'] != 'paiement') && ($_POST['code-retour'] != 'payetest')) {
  172. uc_order_comment_save($order_id, 0, t("The customer's attempted payment from a bank account may have failed. Authorisation result is @result.", array('@result' => $_POST['motifrefus'])), 'admin');
  173. uc_cmcic_receipt_exit(TRUE);
  174. }
  175. $amount = substr($_POST['montant'], 0, -3);
  176. $currency = substr($_POST['montant'], -3);
  177. $comment = t('CM-CIC p@iement authorisation #: @number', array('@number' => $_POST['numauto']));
  178. uc_payment_enter($order_id, 'cmcic', $amount, $order->uid, $_POST, $comment);
  179. uc_cart_complete_sale($order);
  180. uc_order_comment_save($order_id, 0, t('Payment of @amount @currency submitted through CM-CIC p@iement.', array('@amount' => uc_currency_format($amount, FALSE), '@currency' => $currency)), 'order', 'payment_received');
  181. uc_order_comment_save($order_id, 0, t('CM-CIC p@iement response reported a payment of @amount @currency.', array('@amount' => uc_currency_format($amount, FALSE), '@currency' => $currency)));
  182. uc_cmcic_receipt_exit(TRUE);
  183. }
  184. // Return the receipt to the bank then exit cleanly.
  185. function uc_cmcic_receipt_exit($mac_ok) {
  186. print uc_cmcic_receipt($mac_ok);
  187. module_invoke_all('exit');
  188. exit;
  189. }
  190. /**
  191. * Handle a successful payment.
  192. */
  193. function uc_cmcic_success() {
  194. if (empty($_SESSION['cart_order'])) {
  195. drupal_goto('cart');
  196. }
  197. // This lets us know it's a legitimate access of the complete page.
  198. $_SESSION['uc_checkout'][$_SESSION['cart_order']]['do_complete'] = TRUE;
  199. drupal_goto('cart/checkout/complete');
  200. }
  201. /**
  202. * Handle a cancelled payment.
  203. */
  204. function uc_cmcic_cancel() {
  205. unset($_SESSION['cart_order']);
  206. drupal_set_message(t('Your payment was cancelled. Please feel free to continue shopping or contact us for assistance.'));
  207. drupal_goto('cart');
  208. }
  209. /**
  210. * Handle an unsuccessful payment.
  211. */
  212. function uc_cmcic_return() {
  213. unset($_SESSION['cart_order']);
  214. drupal_set_message(t('Sorry, your payment could not be processed. Please try again or contact us for assistance.'));
  215. drupal_goto('cart');
  216. }
  217. function uc_cmcic_get_order(&$mac_ok) {
  218. $mac_ok = FALSE;
  219. if (!uc_cmcic_validate_response(variable_get('uc_cmcic_key', ''), $_POST)) {
  220. return FALSE;
  221. }
  222. $mac_ok = TRUE;
  223. if (isset($_POST['reference']) && ($order = uc_order_load(intval($_POST['reference'])))) {
  224. if (isset($order->data['cmcic']['texte-libre']) && ($_POST['texte-libre'] == $order->data['cmcic']['texte-libre'])) {
  225. return $order;
  226. }
  227. }
  228. return FALSE;
  229. }