2012-05-26 16:25:07 +00:00
< ? php
/**
2015-11-03 13:31:20 +00:00
* PayPal Standard Payment Gateway .
2012-08-10 13:09:02 +00:00
*
2012-05-26 16:25:07 +00:00
* Provides a PayPal Standard Payment Gateway .
*
2015-03-12 20:39:47 +00:00
* @ class WC_Gateway_Paypal
* @ extends WC_Payment_Gateway
2014-10-21 21:31:37 +00:00
* @ version 2.3 . 0
2012-08-15 18:15:06 +00:00
* @ package WooCommerce / Classes / Payment
* @ author WooThemes
2012-05-26 16:25:07 +00:00
*/
2016-01-05 05:23:01 +00:00
if ( ! defined ( 'ABSPATH' ) ) {
exit ;
}
/**
* WC_Gateway_Paypal Class .
*/
2012-12-31 18:25:09 +00:00
class WC_Gateway_Paypal extends WC_Payment_Gateway {
2012-11-27 16:22:47 +00:00
2016-01-05 19:19:12 +00:00
/** @var bool Whether or not logging is enabled */
2015-04-09 11:00:42 +00:00
public static $log_enabled = false ;
/** @var WC_Logger Logger instance */
public static $log = false ;
2013-12-31 12:45:02 +00:00
/**
* Constructor for the gateway .
*/
2012-08-10 13:09:02 +00:00
public function __construct () {
2014-10-23 13:27:24 +00:00
$this -> id = 'paypal' ;
$this -> has_fields = false ;
$this -> order_button_text = __ ( 'Proceed to PayPal' , 'woocommerce' );
$this -> method_title = __ ( 'PayPal' , 'woocommerce' );
2016-10-27 17:36:24 +00:00
$this -> method_description = sprintf ( __ ( 'PayPal Standard sends customers to PayPal to enter their payment information. PayPal IPN requires fsockopen/cURL support to update order statuses after payment. Check the <a href="%s">system status</a> page for more details.' , 'woocommerce' ), admin_url ( 'admin.php?page=wc-status' ) );
2014-10-23 13:27:24 +00:00
$this -> supports = array (
2014-07-07 10:44:15 +00:00
'products' ,
2016-08-27 02:08:49 +00:00
'refunds' ,
2014-07-07 10:44:15 +00:00
);
2012-08-10 13:09:02 +00:00
2012-05-26 16:25:07 +00:00
// Load the settings.
2013-01-02 13:38:33 +00:00
$this -> init_form_fields ();
2012-05-26 16:25:07 +00:00
$this -> init_settings ();
2012-08-10 13:09:02 +00:00
2016-01-05 05:23:01 +00:00
// Define user set variables.
2015-03-13 09:38:09 +00:00
$this -> title = $this -> get_option ( 'title' );
$this -> description = $this -> get_option ( 'description' );
$this -> testmode = 'yes' === $this -> get_option ( 'testmode' , 'no' );
$this -> debug = 'yes' === $this -> get_option ( 'debug' , 'no' );
$this -> email = $this -> get_option ( 'email' );
$this -> receiver_email = $this -> get_option ( 'receiver_email' , $this -> email );
$this -> identity_token = $this -> get_option ( 'identity_token' );
2012-08-10 13:09:02 +00:00
2015-04-09 11:00:42 +00:00
self :: $log_enabled = $this -> debug ;
2012-12-31 18:25:09 +00:00
add_action ( 'woocommerce_update_options_payment_gateways_' . $this -> id , array ( $this , 'process_admin_options' ) );
2016-07-27 12:48:10 +00:00
add_action ( 'woocommerce_order_status_on-hold_to_processing' , array ( $this , 'capture_payment' ) );
add_action ( 'woocommerce_order_status_on-hold_to_completed' , array ( $this , 'capture_payment' ) );
2012-08-10 13:09:02 +00:00
2013-12-31 12:53:55 +00:00
if ( ! $this -> is_valid_for_use () ) {
2014-09-29 10:08:19 +00:00
$this -> enabled = 'no' ;
2014-11-19 14:34:34 +00:00
} else {
2016-07-27 10:58:43 +00:00
include_once ( dirname ( __FILE__ ) . '/includes/class-wc-gateway-paypal-ipn-handler.php' );
2015-02-03 16:24:01 +00:00
new WC_Gateway_Paypal_IPN_Handler ( $this -> testmode , $this -> receiver_email );
2015-01-28 17:06:59 +00:00
if ( $this -> identity_token ) {
2016-07-27 10:58:43 +00:00
include_once ( dirname ( __FILE__ ) . '/includes/class-wc-gateway-paypal-pdt-handler.php' );
2015-02-03 16:24:01 +00:00
new WC_Gateway_Paypal_PDT_Handler ( $this -> testmode , $this -> identity_token );
2014-11-19 14:34:34 +00:00
}
2013-12-31 12:53:55 +00:00
}
2013-12-31 12:45:02 +00:00
}
2012-08-10 13:09:02 +00:00
2014-11-18 12:39:56 +00:00
/**
2015-11-03 13:31:20 +00:00
* Logging method .
2016-11-21 19:04:59 +00:00
*
* @ param string $message Log message .
* @ param string $level Optional . Default 'info' .
* emergency | alert | critical | error | warning | notice | info | debug
2014-11-18 12:39:56 +00:00
*/
2016-11-21 19:04:59 +00:00
public static function log ( $message , $level = 'info' ) {
2015-04-09 11:00:42 +00:00
if ( self :: $log_enabled ) {
if ( empty ( self :: $log ) ) {
2016-08-08 12:59:23 +00:00
self :: $log = wc_get_logger ();
2014-11-18 12:39:56 +00:00
}
2016-12-21 19:15:19 +00:00
self :: $log -> log ( $level , $message , array ( 'source' => 'paypal' ) );
2014-11-18 12:39:56 +00:00
}
}
2014-09-19 15:55:14 +00:00
/**
2016-01-05 19:19:12 +00:00
* Get gateway icon .
2014-09-19 15:55:14 +00:00
* @ return string
*/
public function get_icon () {
2014-11-19 14:34:34 +00:00
$icon_html = '' ;
$icon = ( array ) $this -> get_icon_image ( WC () -> countries -> get_base_country () );
foreach ( $icon as $i ) {
2016-10-12 10:16:30 +00:00
$icon_html .= '<img src="' . esc_attr ( $i ) . '" alt="' . esc_attr__ ( 'PayPal acceptance mark' , 'woocommerce' ) . '" />' ;
2014-11-19 14:34:34 +00:00
}
2014-11-18 12:47:40 +00:00
2016-11-04 15:40:15 +00:00
$icon_html .= sprintf ( '<a href="%1$s" class="about_paypal" onclick="javascript:window.open(\'%1$s\',\'WIPaypal\',\'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=1060, height=700\'); return false;">' . esc_attr__ ( 'What is PayPal?' , 'woocommerce' ) . '</a>' , esc_url ( $this -> get_icon_url ( WC () -> countries -> get_base_country () ) ) );
2014-11-19 14:34:34 +00:00
return apply_filters ( 'woocommerce_gateway_icon' , $icon_html , $this -> id );
}
/**
2015-11-03 13:31:20 +00:00
* Get the link for an icon based on country .
2014-11-19 14:34:34 +00:00
* @ param string $country
* @ return string
*/
2015-03-19 18:26:28 +00:00
protected function get_icon_url ( $country ) {
2016-01-21 21:28:14 +00:00
$url = 'https://www.paypal.com/' . strtolower ( $country );
2017-09-27 15:14:26 +00:00
$home_counties = array ( 'BE' , 'CZ' , 'DK' , 'HU' , 'IT' , 'JP' , 'NL' , 'NO' , 'ES' , 'SE' , 'TR' , 'IN' );
$countries = array ( 'DZ' , 'AU' , 'BH' , 'BQ' , 'BW' , 'CA' , 'CN' , 'CW' , 'FI' , 'FR' , 'DE' , 'GR' , 'HK' , 'ID' , 'JO' , 'KE' , 'KW' , 'LU' , 'MY' , 'MA' , 'OM' , 'PH' , 'PL' , 'PT' , 'QA' , 'IE' , 'RU' , 'BL' , 'SX' , 'MF' , 'SA' , 'SG' , 'SK' , 'KR' , 'SS' , 'TW' , 'TH' , 'AE' , 'GB' , 'US' , 'VN' );
2015-05-27 16:23:21 +00:00
2016-01-16 05:15:42 +00:00
if ( in_array ( $country , $home_counties ) ) {
2016-01-21 21:28:14 +00:00
return $url . '/webapps/mpp/home' ;
2016-09-01 20:50:14 +00:00
} elseif ( in_array ( $country , $countries ) ) {
2016-01-21 21:28:14 +00:00
return $url . '/webapps/mpp/paypal-popup' ;
} else {
return $url . '/cgi-bin/webscr?cmd=xpt/Marketing/general/WIPaypal-outside' ;
2014-11-19 14:34:34 +00:00
}
}
/**
2015-11-03 13:31:20 +00:00
* Get PayPal images for a country .
2017-09-27 15:14:26 +00:00
*
* @ param string $country Country code .
2014-11-19 14:34:34 +00:00
* @ return array of image URLs
*/
2015-03-19 18:26:28 +00:00
protected function get_icon_image ( $country ) {
2014-11-19 14:34:34 +00:00
switch ( $country ) {
2014-09-19 15:55:14 +00:00
case 'US' :
case 'NZ' :
case 'CZ' :
case 'HU' :
case 'MY' :
$icon = 'https://www.paypalobjects.com/webstatic/mktg/logo/AM_mc_vs_dc_ae.jpg' ;
break ;
case 'TR' :
$icon = 'https://www.paypalobjects.com/webstatic/mktg/logo-center/logo_paypal_odeme_secenekleri.jpg' ;
break ;
case 'GB' :
$icon = 'https://www.paypalobjects.com/webstatic/mktg/Logo/AM_mc_vs_ms_ae_UK.png' ;
break ;
case 'MX' :
$icon = array (
'https://www.paypal.com/es_XC/Marketing/i/banner/paypal_visa_mastercard_amex.png' ,
2016-08-27 02:08:49 +00:00
'https://www.paypal.com/es_XC/Marketing/i/banner/paypal_debit_card_275x60.gif' ,
2014-09-19 15:55:14 +00:00
);
break ;
case 'FR' :
$icon = 'https://www.paypalobjects.com/webstatic/mktg/logo-center/logo_paypal_moyens_paiement_fr.jpg' ;
break ;
case 'AU' :
$icon = 'https://www.paypalobjects.com/webstatic/en_AU/mktg/logo/Solutions-graphics-1-184x80.jpg' ;
break ;
case 'DK' :
$icon = 'https://www.paypalobjects.com/webstatic/mktg/logo-center/logo_PayPal_betalingsmuligheder_dk.jpg' ;
break ;
case 'RU' :
$icon = 'https://www.paypalobjects.com/webstatic/ru_RU/mktg/business/pages/logo-center/AM_mc_vs_dc_ae.jpg' ;
break ;
case 'NO' :
$icon = 'https://www.paypalobjects.com/webstatic/mktg/logo-center/banner_pl_just_pp_319x110.jpg' ;
break ;
case 'CA' :
$icon = 'https://www.paypalobjects.com/webstatic/en_CA/mktg/logo-image/AM_mc_vs_dc_ae.jpg' ;
break ;
case 'HK' :
$icon = 'https://www.paypalobjects.com/webstatic/en_HK/mktg/logo/AM_mc_vs_dc_ae.jpg' ;
break ;
case 'SG' :
$icon = 'https://www.paypalobjects.com/webstatic/en_SG/mktg/Logos/AM_mc_vs_dc_ae.jpg' ;
break ;
case 'TW' :
$icon = 'https://www.paypalobjects.com/webstatic/en_TW/mktg/logos/AM_mc_vs_dc_ae.jpg' ;
break ;
case 'TH' :
$icon = 'https://www.paypalobjects.com/webstatic/en_TH/mktg/Logos/AM_mc_vs_dc_ae.jpg' ;
break ;
2015-05-06 21:17:19 +00:00
case 'JP' :
$icon = 'https://www.paypal.com/ja_JP/JP/i/bnr/horizontal_solution_4_jcb.gif' ;
break ;
2017-09-27 15:14:26 +00:00
case 'IN' :
$icon = 'https://www.paypalobjects.com/webstatic/mktg/logo/AM_mc_vs_dc_ae.jpg' ;
break ;
2014-09-19 15:55:14 +00:00
default :
$icon = WC_HTTPS :: force_https_url ( WC () -> plugin_url () . '/includes/gateways/paypal/assets/images/paypal.png' );
break ;
}
2014-11-19 14:34:34 +00:00
return apply_filters ( 'woocommerce_paypal_icon' , $icon );
2014-09-19 15:55:14 +00:00
}
2013-12-31 12:45:02 +00:00
/**
2015-11-03 13:31:20 +00:00
* Check if this gateway is enabled and available in the user ' s country .
2013-12-31 12:45:02 +00:00
* @ return bool
*/
2014-11-18 13:46:49 +00:00
public function is_valid_for_use () {
2017-09-27 15:14:26 +00:00
return in_array ( get_woocommerce_currency (), apply_filters ( 'woocommerce_paypal_supported_currencies' , array ( 'AUD' , 'BRL' , 'CAD' , 'MXN' , 'NZD' , 'HKD' , 'SGD' , 'USD' , 'EUR' , 'JPY' , 'TRY' , 'NOK' , 'CZK' , 'DKK' , 'HUF' , 'ILS' , 'MYR' , 'PHP' , 'PLN' , 'SEK' , 'CHF' , 'TWD' , 'THB' , 'GBP' , 'RMB' , 'RUB' , 'INR' ) ) );
2013-12-31 12:45:02 +00:00
}
2012-08-10 13:09:02 +00:00
2012-05-26 16:25:07 +00:00
/**
2015-11-03 13:31:20 +00:00
* Admin Panel Options .
* - Options for bits like 'title' and availability on a country - by - country basis .
2012-05-26 16:25:07 +00:00
*
* @ since 1.0 . 0
*/
public function admin_options () {
2014-07-31 05:57:13 +00:00
if ( $this -> is_valid_for_use () ) {
parent :: admin_options ();
} else {
2012-12-31 12:07:43 +00:00
?>
2016-10-12 10:16:30 +00:00
< div class = " inline error " >< p >< strong >< ? php _e ( 'Gateway disabled' , 'woocommerce' ); ?> </strong>: <?php _e( 'PayPal does not support your store currency.', 'woocommerce' ); ?></p></div>
2014-07-31 05:57:13 +00:00
< ? php
}
2012-12-27 10:44:58 +00:00
}
2012-08-10 13:09:02 +00:00
2013-12-31 12:45:02 +00:00
/**
2015-11-03 13:31:20 +00:00
* Initialise Gateway Settings Form Fields .
2013-12-31 12:45:02 +00:00
*/
2014-07-07 10:44:15 +00:00
public function init_form_fields () {
2014-11-18 12:43:23 +00:00
$this -> form_fields = include ( 'includes/settings-paypal.php' );
2013-12-31 12:45:02 +00:00
}
2012-08-10 13:09:02 +00:00
2014-02-24 14:49:01 +00:00
/**
2014-11-19 14:34:34 +00:00
* Get the transaction URL .
2014-11-18 13:46:49 +00:00
* @ param WC_Order $order
2014-11-19 14:34:34 +00:00
* @ return string
2014-11-18 13:46:49 +00:00
*/
2014-11-19 14:34:34 +00:00
public function get_transaction_url ( $order ) {
if ( $this -> testmode ) {
$this -> view_transaction_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_view-a-trans&id=%s' ;
} else {
$this -> view_transaction_url = 'https://www.paypal.com/cgi-bin/webscr?cmd=_view-a-trans&id=%s' ;
2014-11-18 13:46:49 +00:00
}
2014-11-19 14:34:34 +00:00
return parent :: get_transaction_url ( $order );
2012-05-26 16:25:07 +00:00
}
2013-12-31 12:45:02 +00:00
/**
2015-11-03 13:31:20 +00:00
* Process the payment and return the result .
2016-01-05 05:23:01 +00:00
* @ param int $order_id
2013-12-31 12:45:02 +00:00
* @ return array
*/
2014-07-07 10:44:15 +00:00
public function process_payment ( $order_id ) {
2016-07-27 10:58:43 +00:00
include_once ( dirname ( __FILE__ ) . '/includes/class-wc-gateway-paypal-request.php' );
2014-07-07 10:44:15 +00:00
2014-11-19 14:34:34 +00:00
$order = wc_get_order ( $order_id );
$paypal_request = new WC_Gateway_Paypal_Request ( $this );
2014-07-07 10:44:15 +00:00
return array (
2014-11-19 14:34:34 +00:00
'result' => 'success' ,
2016-08-27 01:46:45 +00:00
'redirect' => $paypal_request -> get_request_url ( $order , $this -> testmode ),
2014-07-07 10:44:15 +00:00
);
}
2012-08-10 13:09:02 +00:00
2014-11-18 16:52:55 +00:00
/**
2015-03-12 20:39:47 +00:00
* Can the order be refunded via PayPal ?
2014-11-18 16:52:55 +00:00
* @ param WC_Order $order
* @ return bool
*/
public function can_refund_order ( $order ) {
2014-11-19 14:34:34 +00:00
return $order && $order -> get_transaction_id ();
2014-11-18 16:52:55 +00:00
}
2016-07-27 12:48:10 +00:00
/**
* Init the API class and set the username / password etc .
*/
protected function init_api () {
include_once ( dirname ( __FILE__ ) . '/includes/class-wc-gateway-paypal-api-handler.php' );
WC_Gateway_Paypal_API_Handler :: $api_username = $this -> get_option ( 'api_username' );
WC_Gateway_Paypal_API_Handler :: $api_password = $this -> get_option ( 'api_password' );
WC_Gateway_Paypal_API_Handler :: $api_signature = $this -> get_option ( 'api_signature' );
2016-07-27 15:55:42 +00:00
WC_Gateway_Paypal_API_Handler :: $sandbox = $this -> testmode ;
2016-07-27 12:48:10 +00:00
}
2014-07-07 10:44:15 +00:00
/**
2015-11-03 13:31:20 +00:00
* Process a refund if supported .
2016-01-05 05:23:01 +00:00
* @ param int $order_id
* @ param float $amount
2014-08-07 18:57:29 +00:00
* @ param string $reason
2017-05-15 11:50:52 +00:00
* @ return bool | WP_Error
2014-07-07 10:44:15 +00:00
*/
2014-08-11 13:07:09 +00:00
public function process_refund ( $order_id , $amount = null , $reason = '' ) {
2014-08-15 12:29:21 +00:00
$order = wc_get_order ( $order_id );
2012-08-10 13:09:02 +00:00
2014-11-18 16:52:55 +00:00
if ( ! $this -> can_refund_order ( $order ) ) {
2016-11-21 19:18:42 +00:00
$this -> log ( 'Refund Failed: No transaction ID' , 'error' );
2016-10-12 10:16:30 +00:00
return new WP_Error ( 'error' , __ ( 'Refund failed: No transaction ID' , 'woocommerce' ) );
2014-07-07 10:44:15 +00:00
}
2012-08-10 13:09:02 +00:00
2016-07-27 12:48:10 +00:00
$this -> init_api ();
2012-08-10 13:09:02 +00:00
2016-07-27 15:55:42 +00:00
$result = WC_Gateway_Paypal_API_Handler :: refund_transaction ( $order , $amount , $reason );
2012-08-10 13:09:02 +00:00
2014-11-19 14:34:34 +00:00
if ( is_wp_error ( $result ) ) {
2016-11-21 19:18:42 +00:00
$this -> log ( 'Refund Failed: ' . $result -> get_error_message (), 'error' );
2015-10-06 13:32:18 +00:00
return new WP_Error ( 'error' , $result -> get_error_message () );
2014-07-07 10:44:15 +00:00
}
2012-08-10 13:09:02 +00:00
2016-12-16 21:51:20 +00:00
$this -> log ( 'Refund Result: ' . wc_print_r ( $result , true ) );
2014-11-20 15:03:42 +00:00
2016-07-27 15:55:42 +00:00
switch ( strtolower ( $result -> ACK ) ) {
2014-07-07 10:44:15 +00:00
case 'success' :
case 'successwithwarning' :
2016-09-01 20:50:14 +00:00
$order -> add_order_note ( sprintf ( __ ( 'Refunded %1$s - Refund ID: %2$s' , 'woocommerce' ), $result -> GROSSREFUNDAMT , $result -> REFUNDTRANSACTIONID ) );
2014-07-07 10:44:15 +00:00
return true ;
break ;
2012-05-26 16:25:07 +00:00
}
2012-08-10 13:09:02 +00:00
2016-07-27 15:55:42 +00:00
return isset ( $result -> L_LONGMESSAGE0 ) ? new WP_Error ( 'error' , $result -> L_LONGMESSAGE0 ) : false ;
2012-05-26 16:25:07 +00:00
}
2016-07-27 12:48:10 +00:00
/**
* Capture payment when the order is changed from on - hold to complete or processing
*
* @ param int $order_id
*/
public function capture_payment ( $order_id ) {
$order = wc_get_order ( $order_id );
2016-08-05 15:04:41 +00:00
if ( 'paypal' === $order -> get_payment_method () && 'pending' === get_post_meta ( $order -> get_id (), '_paypal_status' , true ) && $order -> get_transaction_id () ) {
2016-07-27 12:48:10 +00:00
$this -> init_api ();
2016-07-27 15:55:42 +00:00
$result = WC_Gateway_Paypal_API_Handler :: do_capture ( $order );
if ( is_wp_error ( $result ) ) {
2016-11-21 19:18:42 +00:00
$this -> log ( 'Capture Failed: ' . $result -> get_error_message (), 'error' );
2016-07-27 15:55:42 +00:00
$order -> add_order_note ( sprintf ( __ ( 'Payment could not captured: %s' , 'woocommerce' ), $result -> get_error_message () ) );
return ;
}
2016-12-16 21:51:20 +00:00
$this -> log ( 'Capture Result: ' . wc_print_r ( $result , true ) );
2016-07-27 15:55:42 +00:00
if ( ! empty ( $result -> PAYMENTSTATUS ) ) {
switch ( $result -> PAYMENTSTATUS ) {
case 'Completed' :
2016-09-01 20:50:14 +00:00
$order -> add_order_note ( sprintf ( __ ( 'Payment of %1$s was captured - Auth ID: %2$s, Transaction ID: %3$s' , 'woocommerce' ), $result -> AMT , $result -> AUTHORIZATIONID , $result -> TRANSACTIONID ) );
2016-08-05 14:56:23 +00:00
update_post_meta ( $order -> get_id (), '_paypal_status' , $result -> PAYMENTSTATUS );
update_post_meta ( $order -> get_id (), '_transaction_id' , $result -> TRANSACTIONID );
2016-07-27 15:55:42 +00:00
break ;
default :
2016-09-01 20:50:14 +00:00
$order -> add_order_note ( sprintf ( __ ( 'Payment could not captured - Auth ID: %1$s, Status: %2$s' , 'woocommerce' ), $result -> AUTHORIZATIONID , $result -> PAYMENTSTATUS ) );
2016-07-27 15:55:42 +00:00
break ;
}
}
2016-07-27 12:48:10 +00:00
}
}
2013-09-23 12:36:04 +00:00
}