WC_Gateway_Paypal_PDT_Handler

Handle PDT Responses from PayPal.

Defined (1)

The class is defined in the following location(s).

/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php  
  1. class WC_Gateway_Paypal_PDT_Handler extends WC_Gateway_Paypal_Response { 
  2.  
  3. /** @var string identity_token for PDT support */ 
  4. protected $identity_token; 
  5.  
  6. /** 
  7. * Constructor. 
  8. * @param bool $sandbox 
  9. * @param string $identity_token 
  10. */ 
  11. public function __construct( $sandbox = false, $identity_token = '' ) { 
  12. add_action( 'woocommerce_thankyou_paypal', array( $this, 'check_response' ) ); 
  13.  
  14. $this->identity_token = $identity_token; 
  15. $this->sandbox = $sandbox; 
  16.  
  17. /** 
  18. * Validate a PDT transaction to ensure its authentic. 
  19. * @param string $transaction 
  20. * @return bool|array False or result array 
  21. */ 
  22. protected function validate_transaction( $transaction ) { 
  23. $pdt = array( 
  24. 'body' => array( 
  25. 'cmd' => '_notify-synch',  
  26. 'tx' => $transaction,  
  27. 'at' => $this->identity_token,  
  28. ),  
  29. 'timeout' => 60,  
  30. 'httpversion' => '1.1',  
  31. 'user-agent' => 'WooCommerce/' . WC_VERSION,  
  32. ); 
  33.  
  34. // Post back to get a response. 
  35. $response = wp_safe_remote_post( $this->sandbox ? 'https://www.sandbox.paypal.com/cgi-bin/webscr' : 'https://www.paypal.com/cgi-bin/webscr', $pdt ); 
  36.  
  37. if ( is_wp_error( $response ) || ! strpos( $response['body'], "SUCCESS" ) === 0 ) { 
  38. return false; 
  39.  
  40. // Parse transaction result data 
  41. $transaction_result = array_map( 'wc_clean', array_map( 'urldecode', explode( "\n", $response['body'] ) ) ); 
  42. $transaction_results = array(); 
  43.  
  44. foreach ( $transaction_result as $line ) { 
  45. $line = explode( "=", $line ); 
  46. $transaction_results[ $line[0] ] = isset( $line[1] ) ? $line[1] : ''; 
  47.  
  48. if ( ! empty( $transaction_results['charset'] ) && function_exists( 'iconv' ) ) { 
  49. foreach ( $transaction_results as $key => $value ) { 
  50. $transaction_results[ $key ] = iconv( $transaction_results['charset'], 'utf-8', $value ); 
  51.  
  52. return $transaction_results; 
  53.  
  54. /** 
  55. * Check Response for PDT. 
  56. */ 
  57. public function check_response() { 
  58. if ( empty( $_REQUEST['cm'] ) || empty( $_REQUEST['tx'] ) || empty( $_REQUEST['st'] ) ) { 
  59. return; 
  60.  
  61. $order_id = wc_clean( stripslashes( $_REQUEST['cm'] ) ); 
  62. $status = wc_clean( strtolower( stripslashes( $_REQUEST['st'] ) ) ); 
  63. $amount = wc_clean( stripslashes( $_REQUEST['amt'] ) ); 
  64. $transaction = wc_clean( stripslashes( $_REQUEST['tx'] ) ); 
  65.  
  66. if ( ! ( $order = $this->get_paypal_order( $order_id ) ) || ! $order->has_status( 'pending' ) ) { 
  67. return false; 
  68.  
  69. $transaction_result = $this->validate_transaction( $transaction ); 
  70.  
  71. WC_Gateway_Paypal::log( 'PDT Transaction Result: ' . wc_print_r( $transaction_result, true ) ); 
  72.  
  73. update_post_meta( $order->get_id(), '_paypal_status', $status ); 
  74. update_post_meta( $order->get_id(), '_transaction_id', $transaction ); 
  75.  
  76. if ( $transaction_result ) { 
  77. if ( 'completed' === $status ) { 
  78. if ( $order->get_total() != $amount ) { 
  79. WC_Gateway_Paypal::log( 'Payment error: Amounts do not match (amt ' . $amount . ')', 'error' ); 
  80. $this->payment_on_hold( $order, sprintf( __( 'Validation error: PayPal amounts do not match (amt %s).', 'woocommerce' ), $amount ) ); 
  81. } else { 
  82. $this->payment_complete( $order, $transaction, __( 'PDT payment completed', 'woocommerce' ) ); 
  83.  
  84. // Log paypal transaction fee and other meta data. 
  85. if ( ! empty( $transaction_result['mc_fee'] ) ) { 
  86. update_post_meta( $order->get_id(), 'PayPal Transaction Fee', $transaction_result['mc_fee'] ); 
  87. if ( ! empty( $transaction_result['payer_email'] ) ) { 
  88. update_post_meta( $order->get_id(), 'Payer PayPal address', $transaction_result['payer_email'] ); 
  89. if ( ! empty( $transaction_result['first_name'] ) ) { 
  90. update_post_meta( $order->get_id(), 'Payer first name', $transaction_result['first_name'] ); 
  91. if ( ! empty( $transaction_result['last_name'] ) ) { 
  92. update_post_meta( $order->get_id(), 'Payer last name', $transaction_result['last_name'] ); 
  93. if ( ! empty( $transaction_result['payment_type'] ) ) { 
  94. update_post_meta( $order->get_id(), 'Payment type', $transaction_result['payment_type'] ); 
  95. } else { 
  96. if ( 'authorization' === $transaction_result['pending_reason'] ) { 
  97. $this->payment_on_hold( $order, __( 'Payment authorized. Change payment status to processing or complete to capture funds.', 'woocommerce' ) ); 
  98. } else { 
  99. $this->payment_on_hold( $order, sprintf( __( 'Payment pending (%s).', 'woocommerce' ), $transaction_result['pending_reason'] ) );