· 7 years ago · Nov 21, 2018, 04:10 PM
1<?php
2/*
3Plugin Name: CCAvenue Payment Gateway Advanced for WooCommerce
4Plugin URI: http://www.aheadzen.com
5Description: Extends WooCommerce with ccavenue Indian payment gateway with iFrame. Collect card credentials and accept payments on your checkout page using our secure iFrame. Reduce payment hops and allow customers to make secure payments without leaving your web page for a seamless brand experience.
6Version: 1.0.4
7Author: Aheadzen Team
8Author URI: http://www.aheadzen.com/
9
10Copyright: © 2014-2015 aheadzen.com
11License: GNU General Public License v3.0
12License URI: http://www.gnu.org/licenses/gpl-3.0.html
13*/
14 if ( ! defined( 'ABSPATH' ) )
15 exit;
16 add_action('plugins_loaded', 'woocommerce_aheadzen_ccave_init', 0);
17
18 function woocommerce_aheadzen_ccave_init() {
19
20 if ( !class_exists( 'WC_Payment_Gateway' ) ) return;
21
22 /**
23 * Gateway class
24 */
25 class WC_aheadzen_Ccave extends WC_Payment_Gateway {
26 public function __construct(){
27
28 // Go wild in here
29 $this -> id = 'ccavenue';
30 $this -> method_title = __('CCAvenue Advanced', 'aheadzen');
31 $this -> icon = plugins_url( 'images/logo.gif' , __FILE__ );
32 $this -> has_fields = true;
33
34 $this -> init_form_fields();
35 $this -> init_settings();
36
37 $this -> title = $this -> settings['title'];
38 $this -> description = $this -> settings['description'];
39 $this -> merchant_id = $this -> settings['merchant_id'];
40 $this -> working_key = $this -> settings['working_key'];
41 $this -> access_code = $this -> settings['access_code'];
42 $this -> sandbox = $this -> settings['sandbox'];
43 $this -> iframemode = $this -> settings['iframemode'];
44 $this -> hideccavenuelogo = $this -> settings['hideccavenuelogo'];
45 $this -> enable_currency_conversion = $this -> settings['enable_currency_conversion'];
46
47 $this -> default_add1 = $this -> settings['default_add1'];
48 $this -> default_country = $this -> settings['default_country'];
49 $this -> default_state = $this -> settings['default_state'];
50 $this -> default_city = $this -> settings['default_city'];
51 $this -> default_zip = $this -> settings['default_zip'];
52 $this -> default_phone = $this -> settings['default_phone'];
53
54 if($this -> hideccavenuelogo=='yes')
55 {
56 $this -> icon = '';
57 }
58
59 if($this->sandbox=='yes'){
60 $this->liveurlonly = "https://test.ccavenue.com/transaction/transaction.do";
61 }else{
62 $this->liveurlonly = "https://secure.ccavenue.com/transaction/transaction.do";
63 }
64
65 $this->liveurl = $this->liveurlonly.'?command=initiateTransaction';
66 $this->notify_url = str_replace( 'https:', 'http:', home_url( '/wc-api/WC_aheadzen_Ccave' ) );
67
68 $this -> msg['message'] = "";
69 $this -> msg['class'] = "";
70
71 $this -> payment_option = $_POST['payment_option'];
72 $this -> card_type = $_POST['card_type'];
73 $this -> card_name = $_POST['card_name'];
74 $this -> data_accept = $_POST['data_accept'];
75 $this -> card_number = $_POST['card_number'];
76 $this -> expiry_month = $_POST['expiry_month'];
77 $this -> expiry_year = $_POST['expiry_year'];
78 $this -> cvv_number = $_POST['cvv_number'];
79 $this -> issuing_bank = $_POST['issuing_bank'];
80
81 //add_action('init', array(&$this, 'check_ccavenue_response'));
82 //update for woocommerce >2.0
83 add_action( 'woocommerce_api_wc_aheadzen_ccave', array( $this, 'check_ccavenue_response' ) );
84 add_action('valid-ccavenue-request', array($this, 'successful_request'));
85 if ( version_compare( WOOCOMMERCE_VERSION, '2.0.0', '>=' ) ) {
86 add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
87 } else {
88 add_action( 'woocommerce_update_options_payment_gateways', array( &$this, 'process_admin_options' ) );
89 }
90 add_action('woocommerce_receipt_ccavenue', array($this, 'receipt_page'));
91 add_action('woocommerce_thankyou_ccavenue',array($this, 'thankyou_page'));
92 }
93
94 function init_form_fields(){
95
96 $countries = WC()->countries->countries;
97
98 $this -> form_fields = array(
99 'enabled' => array(
100 'title' => __('Enable/Disable', 'aheadzen'),
101 'type' => 'checkbox',
102 'label' => __('Enable CCAvenue Payment Module.', 'aheadzen'),
103 'default' => 'no'),
104
105 'sandbox' => array(
106 'title' => __('Enable Sandbox?', 'aheadzen'),
107 'type' => 'checkbox',
108 'label' => __('Enable Sandbox CCAvenue Payment.', 'aheadzen'),
109 'default' => 'no'),
110
111 'iframemode' => array(
112 'title' => __('Iframe/Redirect Payment', 'aheadzen'),
113 'type' => 'checkbox',
114 'label' => __('Enable Iframe method and do not want customer to redirect on CCAvenue site.', 'aheadzen'),
115 'default' => 'no'),
116
117 'enable_currency_conversion' => array(
118 'title' => __('Currency Conversion to INR?', 'aheadzen'),
119 'type' => 'checkbox',
120 'label' => __('Enable Currency Conversion to INR.', 'aheadzen'),
121 'default' => 'no'),
122
123
124 'hideccavenuelogo' => array(
125 'title' => __('Show/Hide Logo', 'aheadzen'),
126 'type' => 'checkbox',
127 'label' => __('Hide CCAvenue logo on checkout page.', 'aheadzen'),
128 'default' => 'no'),
129
130 'title' => array(
131 'title' => __('Title:', 'aheadzen'),
132 'type'=> 'text',
133 'description' => __('This controls the title which the user sees during checkout.', 'aheadzen'),
134 'default' => __('CCAvenue', 'aheadzen')),
135 'description' => array(
136 'title' => __('Description:', 'aheadzen'),
137 'type' => 'textarea',
138 'description' => __('This controls the description which the user sees during checkout.', 'aheadzen'),
139 'default' => __('Pay securely by Credit or Debit card or internet banking through CCAvenue Secure Servers.', 'aheadzen')),
140 'merchant_id' => array(
141 'title' => __('Merchant ID', 'aheadzen'),
142 'type' => 'text',
143 'description' => __('This id(USER ID) available at "Generate Working Key" of "Settings and Options at CCAvenue."')),
144 'working_key' => array(
145 'title' => __('Working Key', 'aheadzen'),
146 'type' => 'text',
147 'description' => __('Given to Merchant by CCAvenue', 'aheadzen'),
148 ),
149 'access_code' => array(
150 'title' => __('Access Code', 'aheadzen'),
151 'type' => 'text',
152 'description' => __('Given to Merchant by CCAvenue', 'aheadzen'),
153 ),
154 'default_add1' => array(
155 'title' => __('Default Address', 'aheadzen'),
156 'type' => 'text',
157 'description' => __('Enter Address in case of user address not selected while checkout. eg: 123 Green Acres,
158West Eden', 'aheadzen'),
159 ),
160 'default_city' => array(
161 'title' => __('Default City', 'aheadzen'),
162 'type' => 'text',
163 'description' => __('Enter City in case of user city not selected while checkout. eg: Estberry', 'aheadzen'),
164 ),
165 'default_state' => array(
166 'title' => __('Default State', 'aheadzen'),
167 'type' => 'text',
168 'description' => __('Enter State in case of user state not selected while checkout. eg: Wales', 'aheadzen'),
169 ),
170 'default_zip' => array(
171 'title' => __('Default Zip', 'aheadzen'),
172 'type' => 'text',
173 'description' => __('Enter Zip in case of user zip not selected while checkout. eg: 12345', 'aheadzen'),
174 ),
175 'default_country' => array(
176 'title' => __('Default Country', 'aheadzen'),
177 'type' => 'select',
178 'options' => $countries,
179 'description' => __('Select Country in case of user country not selected while checkout. eg: UK', 'aheadzen'),
180 ),
181 'default_phone' => array(
182 'title' => __('Default Phone Number', 'aheadzen'),
183 'type' => 'text',
184 'description' => __('Enter Phone Number in case of user phone number not selected while checkout. eg: 41-345-345678', 'aheadzen'),
185 ),
186 );
187
188 }
189 /**
190 * Admin Panel Options
191 * - Options for bits like 'title' and availability on a country-by-country basis
192 **/
193 public function admin_options(){
194 echo '<h3>'.__('CCAvenue Payment Gateway Advanced', 'aheadzen').'</h3>';
195 echo '<p>'.__('CCAvenue is most popular payment gateway for online shopping in India').'</p>';
196 echo '<table class="form-table">';
197 $this -> generate_settings_html();
198 echo '</table>';
199
200 }
201 /**
202 * There are no payment fields for CCAvenue, but we want to show the description if set.
203 **/
204 function payment_fields(){
205 if($this -> description) echo wpautop(wptexturize($this -> description));
206 }
207 /**
208 * Receipt Page
209 **/
210 function receipt_page($order){
211 // echo '<p>'.__('Thank you for your order, please click the button below to pay with CCAvenue.', 'aheadzen').'</p>';
212 echo $this -> generate_ccavenue_form($order);
213 }
214
215 /**
216 * Thankyou Page
217 **/
218 function thankyou_page($order){
219 if (!empty($this->instructions))
220 echo wpautop( wptexturize( $this->instructions ) );
221
222 }
223 /**
224 * Process the payment and return the result
225 **/
226 function process_payment($order_id){
227 $order = new WC_Order($order_id);
228 update_post_meta($order_id,'_post_data',$_POST);
229 return array('result' => 'success', 'redirect' => $order->get_checkout_payment_url( true ));
230
231 }
232 /**
233 * Check for valid CCAvenue server callback
234 **/
235 function check_ccavenue_response(){
236 global $woocommerce;
237
238 $msg['class'] = 'error';
239 $msg['message'] = "Thank you for shopping with us. However, the transaction has been declined.";
240
241 if(isset($_REQUEST['encResp'])){
242
243 $encResponse = $_REQUEST["encResp"];
244 $rcvdString = decrypt($encResponse,$this -> working_key);
245
246 $decryptValues = array();
247
248 parse_str( $rcvdString, $decryptValues );
249 $order_id_time = $decryptValues['order_id'];
250 $order_id = explode('_', $decryptValues['order_id']);
251 $order_id = (int)$order_id[0];
252
253 if($order_id != ''){
254 try{
255 $order = new WC_Order($order_id);
256 $order_status = $decryptValues['order_status'];
257 $transauthorised = false;
258 if($order -> status !=='completed'){
259 if($order_status=="Success")
260 {
261 $transauthorised = true;
262 $msg['message'] = "Thank you for shopping with us. Your account has been charged and your transaction is successful. We will be shipping your order to you soon.";
263 $msg['class'] = 'success';
264 if($order -> status != 'processing'){
265 $order -> payment_complete();
266 $order -> add_order_note('CCAvenue payment successful<br/>Bank Ref Number: '.$decryptValues['bank_ref_no']);
267 $woocommerce -> cart -> empty_cart();
268
269 }
270
271 }
272 else if($order_status==="Aborted")
273 {
274 $admin_email = get_option('admin_email');
275 $msg['message'] = 'Oh! Something went wrong. Payment was cancelled. Have any questions? Please email to <a href="mailto:'.$admin_email.'">'.$admin_email.'</a>';
276 $msg['class'] = 'error';
277
278 }
279 else if($order_status==="Failure")
280 {
281 $msg['class'] = 'error';
282 $msg['message'] = "Thank you for shopping with us. However, the transaction has been declined.";
283 }
284 else
285 {
286 $msg['class'] = 'error';
287 $msg['message'] = "Thank you for shopping with us. However, the transaction has been declined.";
288 }
289
290 if($transauthorised==false){
291 $order -> update_status('failed');
292 $order -> add_order_note('Failed');
293 $order -> add_order_note($this->msg['message']);
294 }
295
296 }
297 }catch(Exception $e){
298
299 $msg['class'] = 'error';
300 $msg['message'] = "Thank you for shopping with us. However, the transaction has been declined.";
301
302 }
303
304 }
305
306 }
307
308 if ( function_exists( 'wc_add_notice' ) )
309 {
310 wc_add_notice( $msg['message'], $msg['class'] );
311
312 }
313 else
314 {
315 if($msg['class']=='success'){
316 $woocommerce->add_message( $msg['message']);
317 }else{
318 $woocommerce->add_error( $msg['message'] );
319
320 }
321 $woocommerce->set_messages();
322 }
323 $redirect_url = $this->get_return_url( $order );
324 //$redirect_url = get_permalink(woocommerce_get_page_id('myaccount'));
325 wp_redirect( $redirect_url );
326 exit;
327
328}
329 /*
330 //Removed For WooCommerce 2.0
331 function showMessage($content){
332 return '<div class="box '.$this -> msg['class'].'-box">'.$this -> msg['message'].'</div>'.$content;
333 }*/
334 /**
335 * Generate CCAvenue button link
336 **/
337 public function generate_ccavenue_form($order_id){
338 global $woocommerce;
339 $order = new WC_Order($order_id);
340 $order_id = $order_id.'_'.date("ymds");
341
342 $post_data = get_post_meta($order_id,'_post_data',true);
343 update_post_meta($order_id,'_post_data',array());
344
345 if($order -> billing_address_1 && $order -> billing_country && $order -> billing_state && $order -> billing_city && $order -> billing_postcode)
346 {
347 $country = wc()->countries -> countries [$order -> billing_country];
348 $state = $order -> billing_state;
349 $city = $order -> billing_city;
350 $zip = $order -> billing_postcode;
351 $phone = $order->billing_phone;
352 $billing_address_1 = trim($order -> billing_address_1, ',');
353 }else{
354 $billing_address_1 = $this->default_add1;
355 $country = $this->default_country;
356 $state = $this->default_state;
357 $city = $this->default_city;
358 $zip = $this->default_zip;
359 $phone = $this->default_phone;
360 }
361
362
363 $the_currency = get_woocommerce_currency();
364 $the_order_total = $order->order_total;
365 if($this->enable_currency_conversion=='yes')
366 {
367 if($the_currency!='INR' && class_exists('WC_Aelia_CurrencySwitcher')){
368 $all_currency = WC_Aelia_CurrencySwitcher::settings()->get_enabled_currencies();
369 if(in_array('INR',$all_currency)){
370 $the_order_total = WC_Aelia_CurrencySwitcher::instance()->convert($the_order_total,$the_currency,'INR');
371 $the_currency = 'INR';
372 $the_display_msg = "<small> $the_currency has been converted to equivalent amount in INR for faster payment processing.</small><br />";
373 }
374
375 }
376 }
377 $ccavenue_args = array(
378 'merchant_id' => $this -> merchant_id,
379 'amount' => $the_order_total,
380 'order_id' => $order_id,
381 'redirect_url' => $this->notify_url,
382 'cancel_url' => $this->notify_url,
383 'billing_name' => $order -> billing_first_name .' '. $order -> billing_last_name,
384 'billing_address' => $billing_address_1,
385 'billing_country' => $country,
386 'billing_state' => $state,
387 'billing_city' => $city,
388 'billing_zip' => $zip,
389 'billing_tel' => $phone,
390 'billing_email' => $order -> billing_email,
391 'delivery_name' => $order -> shipping_first_name .' '. $order -> shipping_last_name,
392 'delivery_address' => $order -> shipping_address_1,
393 'delivery_country' => $order -> shipping_country,
394 'delivery_state' => $order -> shipping_state,
395 'delivery_tel' => '',
396 'delivery_city' => $order -> shipping_city,
397 'delivery_zip' => $order -> shipping_postcode,
398 'language' => 'EN',
399 'currency' => $the_currency,
400
401 'payment_option' => $post_data['payment_option'],
402 'card_type' => $post_data['card_type'],
403 'card_name' => $post_data['card_name'],
404 'data_accept' => $post_data['data_accept'],
405 'card_number' => $post_data['card_number'],
406 'expiry_month' => $post_data['expiry_month'],
407 'expiry_year' => $post_data['expiry_year'],
408 'cvv_number' => $post_data['cvv_number'],
409 'issuing_bank' => $post_data['issuing_bank'],
410 );
411
412 if($this -> iframemode=='yes') //Iframe mode
413 {
414 $ccavenue_args['integration_type'] = 'iframe_normal';
415 }
416
417 foreach($ccavenue_args as $param => $value) {
418 $paramsJoined[] = "$param=$value";
419 }
420 $merchant_data = implode('&', $paramsJoined);
421
422 //echo $merchant_data;
423 $encrypted_data = encrypt($merchant_data, $this -> working_key);
424
425 $form = '';
426 if($this -> iframemode=='yes') //Iframe mode
427 {
428 $production_url = $this -> liveurl.'&encRequest='.$encrypted_data.'&access_code='.$this->access_code;
429
430 //echo 'DATA VALUE:'.$merchant_data;
431 //echo '<br><br><br>';
432 //echo 'URL TO CCAvenue : '.$production_url;
433
434 $form .= $the_display_msg.'<iframe src="'.$production_url.'" id="paymentFrame" name="paymentFrame" height="2000" width="600" frameborder="0" scrolling="No" ></iframe>
435
436 <script type="text/javascript">
437 jQuery(document).ready(function(){
438 window.addEventListener(\'message\', function(e) {
439 jQuery("#paymentFrame").css("height",e.data[\'newHeight\']+\'px\');
440 }, false);
441
442 });
443 </script>';
444 /*if(!$_POST)
445 {
446 wc_enqueue_js( 'jQuery("#ccavenue_payment_form").submit();');
447
448 }
449 $targetto = 'target="paymentFrame"';*/
450
451 }else{ //redirect to CCAvenue site
452 wc_enqueue_js( '
453 $.blockUI({
454 message: "' . esc_js( __( 'Thank you for your order. We are now redirecting you to CcAvenue to make payment.', 'woocommerce' ) ) . '",
455 baseZ: 99999,
456 overlayCSS:
457 {
458 background: "#fff",
459 opacity: 0.6
460 },
461 css: {
462 padding: "20px",
463 zindex: "9999999",
464 textAlign: "center",
465 color: "#555",
466 border: "3px solid #aaa",
467 backgroundColor:"#fff",
468 cursor: "wait",
469 lineHeight: "24px",
470 }
471 });
472 jQuery("#submit_ccavenue_payment_form").click();
473 ' );
474 $targetto = 'target="_top"';
475
476 //===================================
477
478 $ccavenue_args_array = array();
479 $ccavenue_args_array[] = "<input type='hidden' name='encRequest' value='$encrypted_data'/>";
480 $ccavenue_args_array[] = "<input type='hidden' name='access_code' value='{$this->access_code}'/>";
481
482 $form .= '<form action="' . esc_url( $this -> liveurl ) . '" method="post" id="ccavenue_payment_form" '.$targetto.'>
483 ' . implode( '', $ccavenue_args_array ) . '
484 <!-- Button Fallback -->
485 <div class="payment_buttons">
486 <input type="submit" class="button alt" id="submit_ccavenue_payment_form" value="' . __( 'Pay via CCAvenue', 'woocommerce' ) . '" /> <a class="button cancel" href="' . esc_url( $order->get_cancel_order_url() ) . '">' . __( 'Cancel order & restore cart', 'woocommerce' ) . '</a>
487 </div>
488 <script type="text/javascript">
489 jQuery(".payment_buttons").hide();
490 </script>
491 </form>';
492 }
493 return $form;
494}
495
496// get all pages
497function get_pages($title = false, $indent = true) {
498 $wp_pages = get_pages('sort_column=menu_order');
499 $page_list = array();
500 if ($title) $page_list[] = $title;
501 foreach ($wp_pages as $page) {
502 $prefix = '';
503 // show indented child pages?
504 if ($indent) {
505 $has_parent = $page->post_parent;
506 while($has_parent) {
507 $prefix .= ' - ';
508 $next_page = get_page($has_parent);
509 $has_parent = $next_page->post_parent;
510 }
511 }
512 // add to page list array array
513 $page_list[$page->ID] = $prefix . $page->post_title;
514 }
515 return $page_list;
516}
517
518}
519
520 /**
521 * Add the Gateway to WooCommerce
522 **/
523 function woocommerce_add_aheadzen_ccave_gateway($methods) {
524 $methods[] = 'WC_aheadzen_Ccave';
525
526 return $methods;
527 }
528
529 add_filter('woocommerce_payment_gateways', 'woocommerce_add_aheadzen_ccave_gateway' );
530}
531
532/*
533ccavenue functions
534 */
535
536function encrypt($plainText,$key)
537{
538 $secretKey = hextobin(md5($key));
539 $initVector = pack("C*", 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f);
540 $openMode = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '','cbc', '');
541 $blockSize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, 'cbc');
542 $plainPad = pkcs5_pad($plainText, $blockSize);
543 if (mcrypt_generic_init($openMode, $secretKey, $initVector) != -1)
544 {
545 $encryptedText = mcrypt_generic($openMode, $plainPad);
546 mcrypt_generic_deinit($openMode);
547
548 }
549 return bin2hex($encryptedText);
550}
551
552function decrypt($encryptedText,$key)
553{
554 $secretKey = hextobin(md5($key));
555 $initVector = pack("C*", 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f);
556 $encryptedText=hextobin($encryptedText);
557 $openMode = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '','cbc', '');
558 mcrypt_generic_init($openMode, $secretKey, $initVector);
559 $decryptedText = mdecrypt_generic($openMode, $encryptedText);
560 $decryptedText = rtrim($decryptedText, "\0");
561 mcrypt_generic_deinit($openMode);
562 return $decryptedText;
563
564}
565 //*********** Padding Function *********************
566
567function pkcs5_pad ($plainText, $blockSize)
568{
569 $pad = $blockSize - (strlen($plainText) % $blockSize);
570 return $plainText . str_repeat(chr($pad), $pad);
571}
572
573 //********** Hexadecimal to Binary function for php 4.0 version ********
574
575function hextobin($hexString)
576{
577 $length = strlen($hexString);
578 $binString="";
579 $count=0;
580 while($count<$length)
581 {
582 $subString =substr($hexString,$count,2);
583 $packedString = pack("H*",$subString);
584 if ($count==0)
585 {
586 $binString=$packedString;
587 }
588
589 else
590 {
591 $binString.=$packedString;
592 }
593
594 $count+=2;
595 }
596 return $binString;
597}
598function aheadzen_debug($what){
599 echo '<pre>';
600 print_r($what);
601 echo '</pre>';
602}
603?>