Нет описания

class-wc-gateway-paypal-api-handler.php 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. <?php
  2. /**
  3. * Class WC_Gateway_Paypal_API_Handler file.
  4. *
  5. * @package WooCommerce\Gateways
  6. */
  7. if ( ! defined( 'ABSPATH' ) ) {
  8. exit;
  9. }
  10. /**
  11. * Handles Refunds and other API requests such as capture.
  12. *
  13. * @since 3.0.0
  14. */
  15. class WC_Gateway_Paypal_API_Handler {
  16. /**
  17. * API Username
  18. *
  19. * @var string
  20. */
  21. public static $api_username;
  22. /**
  23. * API Password
  24. *
  25. * @var string
  26. */
  27. public static $api_password;
  28. /**
  29. * API Signature
  30. *
  31. * @var string
  32. */
  33. public static $api_signature;
  34. /**
  35. * Sandbox
  36. *
  37. * @var bool
  38. */
  39. public static $sandbox = false;
  40. /**
  41. * Get capture request args.
  42. * See https://developer.paypal.com/docs/classic/api/merchant/DoCapture_API_Operation_NVP/.
  43. *
  44. * @param WC_Order $order Order object.
  45. * @param float $amount Amount.
  46. * @return array
  47. */
  48. public static function get_capture_request( $order, $amount = null ) {
  49. $request = array(
  50. 'VERSION' => '84.0',
  51. 'SIGNATURE' => self::$api_signature,
  52. 'USER' => self::$api_username,
  53. 'PWD' => self::$api_password,
  54. 'METHOD' => 'DoCapture',
  55. 'AUTHORIZATIONID' => $order->get_transaction_id(),
  56. 'AMT' => number_format( is_null( $amount ) ? $order->get_total() : $amount, 2, '.', '' ),
  57. 'CURRENCYCODE' => $order->get_currency(),
  58. 'COMPLETETYPE' => 'Complete',
  59. );
  60. return apply_filters( 'woocommerce_paypal_capture_request', $request, $order, $amount );
  61. }
  62. /**
  63. * Get refund request args.
  64. *
  65. * @param WC_Order $order Order object.
  66. * @param float $amount Refund amount.
  67. * @param string $reason Refund reason.
  68. * @return array
  69. */
  70. public static function get_refund_request( $order, $amount = null, $reason = '' ) {
  71. $request = array(
  72. 'VERSION' => '84.0',
  73. 'SIGNATURE' => self::$api_signature,
  74. 'USER' => self::$api_username,
  75. 'PWD' => self::$api_password,
  76. 'METHOD' => 'RefundTransaction',
  77. 'TRANSACTIONID' => $order->get_transaction_id(),
  78. 'NOTE' => html_entity_decode( wc_trim_string( $reason, 255 ), ENT_NOQUOTES, 'UTF-8' ),
  79. 'REFUNDTYPE' => 'Full',
  80. );
  81. if ( ! is_null( $amount ) ) {
  82. $request['AMT'] = number_format( $amount, 2, '.', '' );
  83. $request['CURRENCYCODE'] = $order->get_currency();
  84. $request['REFUNDTYPE'] = 'Partial';
  85. }
  86. return apply_filters( 'woocommerce_paypal_refund_request', $request, $order, $amount, $reason );
  87. }
  88. /**
  89. * Capture an authorization.
  90. *
  91. * @param WC_Order $order Order object.
  92. * @param float $amount Amount.
  93. * @return object Either an object of name value pairs for a success, or a WP_ERROR object.
  94. */
  95. public static function do_capture( $order, $amount = null ) {
  96. $raw_response = wp_safe_remote_post(
  97. self::$sandbox ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp',
  98. array(
  99. 'method' => 'POST',
  100. 'body' => self::get_capture_request( $order, $amount ),
  101. 'timeout' => 70,
  102. 'user-agent' => 'WooCommerce/' . WC()->version,
  103. 'httpversion' => '1.1',
  104. )
  105. );
  106. WC_Gateway_Paypal::log( 'DoCapture Response: ' . wc_print_r( $raw_response, true ) );
  107. if ( is_wp_error( $raw_response ) ) {
  108. return $raw_response;
  109. } elseif ( empty( $raw_response['body'] ) ) {
  110. return new WP_Error( 'paypal-api', 'Empty Response' );
  111. }
  112. parse_str( $raw_response['body'], $response );
  113. return (object) $response;
  114. }
  115. /**
  116. * Refund an order via PayPal.
  117. *
  118. * @param WC_Order $order Order object.
  119. * @param float $amount Refund amount.
  120. * @param string $reason Refund reason.
  121. * @return object Either an object of name value pairs for a success, or a WP_ERROR object.
  122. */
  123. public static function refund_transaction( $order, $amount = null, $reason = '' ) {
  124. $raw_response = wp_safe_remote_post(
  125. self::$sandbox ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp',
  126. array(
  127. 'method' => 'POST',
  128. 'body' => self::get_refund_request( $order, $amount, $reason ),
  129. 'timeout' => 70,
  130. 'user-agent' => 'WooCommerce/' . WC()->version,
  131. 'httpversion' => '1.1',
  132. )
  133. );
  134. WC_Gateway_Paypal::log( 'Refund Response: ' . wc_print_r( $raw_response, true ) );
  135. if ( is_wp_error( $raw_response ) ) {
  136. return $raw_response;
  137. } elseif ( empty( $raw_response['body'] ) ) {
  138. return new WP_Error( 'paypal-api', 'Empty Response' );
  139. }
  140. parse_str( $raw_response['body'], $response );
  141. return (object) $response;
  142. }
  143. }
  144. /**
  145. * Here for backwards compatibility.
  146. *
  147. * @since 3.0.0
  148. */
  149. class WC_Gateway_Paypal_Refund extends WC_Gateway_Paypal_API_Handler {
  150. /**
  151. * Get refund request args. Proxy to WC_Gateway_Paypal_API_Handler::get_refund_request().
  152. *
  153. * @param WC_Order $order Order object.
  154. * @param float $amount Refund amount.
  155. * @param string $reason Refund reason.
  156. *
  157. * @return array
  158. */
  159. public static function get_request( $order, $amount = null, $reason = '' ) {
  160. return self::get_refund_request( $order, $amount, $reason );
  161. }
  162. /**
  163. * Process an order refund.
  164. *
  165. * @param WC_Order $order Order object.
  166. * @param float $amount Refund amount.
  167. * @param string $reason Refund reason.
  168. * @param bool $sandbox Whether to use sandbox mode or not.
  169. * @return object Either an object of name value pairs for a success, or a WP_ERROR object.
  170. */
  171. public static function refund_order( $order, $amount = null, $reason = '', $sandbox = false ) {
  172. if ( $sandbox ) {
  173. self::$sandbox = $sandbox;
  174. }
  175. $result = self::refund_transaction( $order, $amount, $reason );
  176. if ( is_wp_error( $result ) ) {
  177. return $result;
  178. } else {
  179. return (array) $result;
  180. }
  181. }
  182. }