swissChili | f0cbdc3 | 2023-01-05 17:21:38 -0500 | [diff] [blame] | 1 | <?php |
| 2 | if ( ! defined( 'ABSPATH' ) ) { |
| 3 | exit; |
| 4 | } |
| 5 | |
| 6 | if ( ! defined( 'WOOCOMMERCE_CONNECT_SERVER_URL' ) ) { |
| 7 | define( 'WOOCOMMERCE_CONNECT_SERVER_URL', 'https://api.woocommerce.com/' ); |
| 8 | } |
| 9 | |
| 10 | if ( ! class_exists( 'WC_Stripe_Connect_API' ) ) { |
| 11 | /** |
| 12 | * Stripe Connect API class. |
| 13 | */ |
| 14 | class WC_Stripe_Connect_API { |
| 15 | |
| 16 | const WOOCOMMERCE_CONNECT_SERVER_API_VERSION = '3'; |
| 17 | |
| 18 | /** |
| 19 | * Send request to Connect Server to initiate Stripe OAuth |
| 20 | * |
| 21 | * @param string $return_url return address. |
| 22 | * |
| 23 | * @return array |
| 24 | */ |
| 25 | public function get_stripe_oauth_init( $return_url ) { |
| 26 | |
| 27 | $current_user = wp_get_current_user(); |
| 28 | $business_data = []; |
| 29 | $business_data['url'] = get_site_url(); |
| 30 | $business_data['business_name'] = html_entity_decode( get_bloginfo( 'name' ), ENT_QUOTES ); |
| 31 | $business_data['first_name'] = $current_user->user_firstname; |
| 32 | $business_data['last_name'] = $current_user->user_lastname; |
| 33 | $business_data['phone'] = ''; |
| 34 | $business_data['currency'] = get_woocommerce_currency(); |
| 35 | |
| 36 | $wc_countries = WC()->countries; |
| 37 | |
| 38 | if ( method_exists( $wc_countries, 'get_base_address' ) ) { |
| 39 | $business_data['country'] = $wc_countries->get_base_country(); |
| 40 | $business_data['street_address'] = $wc_countries->get_base_address(); |
| 41 | $business_data['city'] = $wc_countries->get_base_city(); |
| 42 | $business_data['state'] = $wc_countries->get_base_state(); |
| 43 | $business_data['zip'] = $wc_countries->get_base_postcode(); |
| 44 | } else { |
| 45 | $base_location = wc_get_base_location(); |
| 46 | $business_data['country'] = $base_location['country']; |
| 47 | $business_data['street_address'] = ''; |
| 48 | $business_data['city'] = ''; |
| 49 | $business_data['state'] = $base_location['state']; |
| 50 | $business_data['zip'] = ''; |
| 51 | } |
| 52 | |
| 53 | $request = [ |
| 54 | 'returnUrl' => $return_url, |
| 55 | 'businessData' => $business_data, |
| 56 | ]; |
| 57 | |
| 58 | return $this->request( 'POST', '/stripe/oauth-init', $request ); |
| 59 | } |
| 60 | |
| 61 | /** |
| 62 | * Send request to Connect Server for Stripe keys |
| 63 | * |
| 64 | * @param string $code OAuth server code. |
| 65 | * |
| 66 | * @return array |
| 67 | */ |
| 68 | public function get_stripe_oauth_keys( $code ) { |
| 69 | |
| 70 | $request = [ 'code' => $code ]; |
| 71 | |
| 72 | return $this->request( 'POST', '/stripe/oauth-keys', $request ); |
| 73 | } |
| 74 | |
| 75 | /** |
| 76 | * General OAuth request method. |
| 77 | * |
| 78 | * @param string $method request method. |
| 79 | * @param string $path path for request. |
| 80 | * @param array $body request body. |
| 81 | * |
| 82 | * @return array|WP_Error |
| 83 | */ |
| 84 | protected function request( $method, $path, $body = [] ) { |
| 85 | |
| 86 | if ( ! is_array( $body ) ) { |
| 87 | return new WP_Error( |
| 88 | 'request_body_should_be_array', |
| 89 | __( 'Unable to send request to WooCommerce Connect server. Body must be an array.', 'woocommerce-gateway-stripe' ) |
| 90 | ); |
| 91 | } |
| 92 | |
| 93 | $url = trailingslashit( WOOCOMMERCE_CONNECT_SERVER_URL ); |
| 94 | $url = apply_filters( 'wc_connect_server_url', $url ); |
| 95 | $url = trailingslashit( $url ) . ltrim( $path, '/' ); |
| 96 | |
| 97 | // Add useful system information to requests that contain bodies. |
| 98 | if ( in_array( $method, [ 'POST', 'PUT' ], true ) ) { |
| 99 | $body = $this->request_body( $body ); |
| 100 | $body = wp_json_encode( apply_filters( 'wc_connect_api_client_body', $body ) ); |
| 101 | |
| 102 | if ( ! $body ) { |
| 103 | return new WP_Error( |
| 104 | 'unable_to_json_encode_body', |
| 105 | __( 'Unable to encode body for request to WooCommerce Connect server.', 'woocommerce-gateway-stripe' ) |
| 106 | ); |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | $headers = $this->request_headers(); |
| 111 | if ( is_wp_error( $headers ) ) { |
| 112 | return $headers; |
| 113 | } |
| 114 | |
| 115 | $http_timeout = 60; // 1 minute |
| 116 | wc_set_time_limit( $http_timeout + 10 ); |
| 117 | $args = [ |
| 118 | 'headers' => $headers, |
| 119 | 'method' => $method, |
| 120 | 'body' => $body, |
| 121 | 'redirection' => 0, |
| 122 | 'compress' => true, |
| 123 | 'timeout' => $http_timeout, |
| 124 | ]; |
| 125 | |
| 126 | $args = apply_filters( 'wc_connect_request_args', $args ); |
| 127 | $response = wp_remote_request( $url, $args ); |
| 128 | $response_code = wp_remote_retrieve_response_code( $response ); |
| 129 | $content_type = wp_remote_retrieve_header( $response, 'content-type' ); |
| 130 | |
| 131 | if ( false === strpos( $content_type, 'application/json' ) ) { |
| 132 | if ( 200 !== $response_code ) { |
| 133 | return new WP_Error( |
| 134 | 'wcc_server_error', |
| 135 | sprintf( |
| 136 | // Translators: HTTP error code. |
| 137 | __( 'Error: The WooCommerce Connect server returned HTTP code: %d', 'woocommerce-gateway-stripe' ), |
| 138 | $response_code |
| 139 | ) |
| 140 | ); |
| 141 | } else { |
| 142 | return new WP_Error( |
| 143 | 'wcc_server_error_content_type', |
| 144 | sprintf( |
| 145 | // Translators: content-type error code. |
| 146 | __( 'Error: The WooCommerce Connect server returned an invalid content-type: %s.', 'woocommerce-gateway-stripe' ), |
| 147 | $content_type |
| 148 | ) |
| 149 | ); |
| 150 | } |
| 151 | } |
| 152 | |
| 153 | $response_body = wp_remote_retrieve_body( $response ); |
| 154 | if ( ! empty( $response_body ) ) { |
| 155 | $response_body = json_decode( $response_body ); |
| 156 | } |
| 157 | |
| 158 | if ( 200 !== $response_code ) { |
| 159 | if ( empty( $response_body ) ) { |
| 160 | return new WP_Error( |
| 161 | 'wcc_server_empty_response', |
| 162 | sprintf( |
| 163 | // Translators: HTTP error code. |
| 164 | __( 'Error: The WooCommerce Connect server returned ( %d ) and an empty response body.', 'woocommerce-gateway-stripe' ), |
| 165 | $response_code |
| 166 | ) |
| 167 | ); |
| 168 | } |
| 169 | |
| 170 | $error = property_exists( $response_body, 'error' ) ? $response_body->error : ''; |
| 171 | $message = property_exists( $response_body, 'message' ) ? $response_body->message : ''; |
| 172 | $data = property_exists( $response_body, 'data' ) ? $response_body->data : ''; |
| 173 | |
| 174 | return new WP_Error( |
| 175 | 'wcc_server_error_response', |
| 176 | sprintf( |
| 177 | /* translators: %1$s: error code, %2$s: error message, %3$d: HTTP response code */ |
| 178 | __( 'Error: The WooCommerce Connect server returned: %1$s %2$s ( %3$d )', 'woocommerce-gateway-stripe' ), |
| 179 | $error, |
| 180 | $message, |
| 181 | $response_code |
| 182 | ), |
| 183 | $data |
| 184 | ); |
| 185 | } |
| 186 | |
| 187 | return $response_body; |
| 188 | } |
| 189 | |
| 190 | /** |
| 191 | * Adds useful WP/WC/WCC information to request bodies. |
| 192 | * |
| 193 | * @param array $initial_body body of initial request. |
| 194 | * |
| 195 | * @return array |
| 196 | */ |
| 197 | protected function request_body( $initial_body = [] ) { |
| 198 | |
| 199 | $default_body = [ |
| 200 | 'settings' => [], |
| 201 | ]; |
| 202 | |
| 203 | $body = array_merge( $default_body, $initial_body ); |
| 204 | |
| 205 | // Add interesting fields to the body of each request. |
| 206 | $body['settings'] = wp_parse_args( |
| 207 | $body['settings'], |
| 208 | [ |
| 209 | 'base_city' => WC()->countries->get_base_city(), |
| 210 | 'base_country' => WC()->countries->get_base_country(), |
| 211 | 'base_state' => WC()->countries->get_base_state(), |
| 212 | 'base_postcode' => WC()->countries->get_base_postcode(), |
| 213 | 'currency' => get_woocommerce_currency(), |
| 214 | 'stripe_version' => WC_STRIPE_VERSION, |
| 215 | 'wc_version' => WC()->version, |
| 216 | 'wp_version' => get_bloginfo( 'version' ), |
| 217 | ] |
| 218 | ); |
| 219 | |
| 220 | return $body; |
| 221 | } |
| 222 | |
| 223 | /** |
| 224 | * Generates headers for request to the WooCommerce Connect Server. |
| 225 | * |
| 226 | * @return array|WP_Error |
| 227 | */ |
| 228 | protected function request_headers() { |
| 229 | |
| 230 | $headers = []; |
| 231 | $locale = strtolower( str_replace( '_', '-', get_locale() ) ); |
| 232 | $locale_elements = explode( '-', $locale ); |
| 233 | $lang = $locale_elements[0]; |
| 234 | $headers['Accept-Language'] = $locale . ',' . $lang; |
| 235 | $headers['Content-Type'] = 'application/json; charset=utf-8'; |
| 236 | $headers['Accept'] = 'application/vnd.woocommerce-connect.v' . self::WOOCOMMERCE_CONNECT_SERVER_API_VERSION; |
| 237 | |
| 238 | return $headers; |
| 239 | } |
| 240 | } |
| 241 | } |