blob: 374f568f466c33b6482e0ba898d061a1028ee5a2 [file] [log] [blame]
swissChilif0cbdc32023-01-05 17:21:38 -05001<?php
2if ( ! defined( 'ABSPATH' ) ) {
3 exit;
4}
5
6if ( ! defined( 'WOOCOMMERCE_CONNECT_SERVER_URL' ) ) {
7 define( 'WOOCOMMERCE_CONNECT_SERVER_URL', 'https://api.woocommerce.com/' );
8}
9
10if ( ! 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}