PluginProbe
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 2.6.1
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v2.6.1
4.7.2 4.7.1 4.7.0 4.6.6 4.6.5 4.6.4 4.6.3 4.6.2 4.6.1 4.6.0 4.5.1 4.5.0 4.4.2 4.4.1 4.4.0 4.3.3 4.3.2 4.3.1 4.3.0 4.2.3 4.2.2 4.2.1 1.0.3 1.0.4 1.0.5 All 281 releases
← All changes | app/src/Controllers/Rest/CheckoutsController.php +107 -75 4.6.22.6.1 View file →
@@ -3,8 +3,9 @@
3 3 namespace SureCart\Controllers\Rest;
4 4
5 5 use SureCart\Models\Checkout;
6 6 use SureCart\Models\Form;
7 +use SureCart\Models\Product;
7 8 use SureCart\Models\User;
8 9 use SureCart\WordPress\Users\CustomerLinkService;
9 10 use SureCart\WordPress\RecaptchaValidationService;
10 11
@@ -27,32 +28,12 @@
27 28 *
28 29 * @return \SureCart\Models\Model|\WP_Error
29 30 */
30 31 protected function middleware( $class, \WP_REST_Request $request ) {
31 - // Set the return url.
32 - $request->set_param( 'external_url', esc_url_raw( get_home_url( null, 'surecart/redirect' ) ) );
32 + // if abandoned checkout is enabled, set the return url.
33 + $request->set_param( 'abandoned_checkout_return_url', ! empty( $request->get_param( 'abandoned_checkout_enabled' ) ) ? esc_url_raw( get_home_url( null, 'surecart/redirect' ) ) : null );
33 34
34 - // if this is an open invoice, we don't set the user.
35 - if ( 'open_invoice' === $request->get_param( 'type' ) ) {
36 - return apply_filters( 'surecart/request/model', $class, $request );
37 - }
38 -
39 - $request->set_param(
40 - 'metadata',
41 - array_merge(
42 - $request->get_param( 'metadata' ) ?? [],
43 - [
44 - // this must always be set to ensure the user cannot override the user role.
45 - 'wp_user_role' => is_user_logged_in() ? wp_get_current_user()->roles : null,
46 - ]
47 - )
48 - );
49 -
50 - // set the user.
51 - $class = $this->maybeSetUser( $class, $request );
52 -
53 - // return the class.
54 - return apply_filters( 'surecart/request/model', $class, $request );
35 + return $this->maybeSetUser( $class, $request );
55 36 }
56 37
57 38 /**
58 39 * Edit model.
@@ -185,8 +166,11 @@
185 166 $checkout = new $this->class( [ 'id' => $request['id'] ] );
186 167 $finalized = $checkout->where( $request->get_query_params() )
187 168 ->finalize( $request->get_body_params() );
188 169
170 + // validate the finalized request.
171 + $finalized = $this->validateFinalizeRequest( $finalized, $request );
172 +
189 173 // bail if error.
190 174 if ( is_wp_error( $finalized ) ) {
191 175 return $finalized;
192 176 }
@@ -277,8 +261,14 @@
277 261 */
278 262 public function validate( $args, $request ) {
279 263 $errors = new \WP_Error();
280 264
265 + // check if they are trying to sign in.
266 + // $valid_login = $this->maybeValidateLoginCreds( $request->get_param( 'email' ), $request->get_param( 'password' ) );
267 + // if ( is_wp_error( $valid_login ) ) {
268 + // $errors->add( $valid_login->get_error_code(), $valid_login->get_error_message() );
269 + // }
270 +
281 271 // Check if honeypot checkbox checked or not.
282 272 $metadata = $request->get_param( 'metadata' );
283 273 if ( $metadata && ! empty( $metadata['get_feedback'] ) ) {
284 274 $errors->add( 'invalid', __( 'Spam check failed. Please try again.', 'surecart' ) );
@@ -296,87 +286,114 @@
296 286 return apply_filters( 'surecart/checkout/validate', $errors, $args, $request );
297 287 }
298 288
299 289 /**
300 - * Cancel an checkout
290 + * Check if the user is trying to sign in.
291 + * If so, validate credentials before finalizing.
301 292 *
302 - * @param \WP_REST_Request $request Rest Request.
293 + * @param string $email Email.
294 + * @param string $password Password.
303 295 *
304 - * @return \SureCart\Models\Checkout|\WP_Error
296 + * @return true|\WP_Error
305 297 */
306 - public function cancel( \WP_REST_Request $request ) {
307 - $order = $this->middleware( new $this->class( $request['id'] ), $request );
308 - if ( is_wp_error( $order ) ) {
309 - return $order;
298 + public function maybeValidateLoginCreds( $email = '', $password = '' ) {
299 + // check if the person is signing in using a password and sign them in.
300 + if ( $password && $email ) {
301 + // user exists, try signing in with password.
302 + $user = get_user_by( 'email', $email );
303 + // if there's a user, check the username and password before we submit the order.
304 + if ( false !== $user ) {
305 + return wp_authenticate_username_password( null, $user->user_login, $password );
306 + }
310 307 }
311 - return $order->where( $request->get_query_params() )->cancel();
308 + return true;
312 309 }
313 310
314 311 /**
315 - * Offer the bump (used for analytics).
312 + * Validate the finalized request.
313 + * We do this to make sure the form is in "Test" mode
314 + * if a test payment is requested. This prevents the spamming of any
315 + * forms on your site that are not in test mode or creating access to something
316 + * with a fake test payment.
316 317 *
317 - * @param \WP_REST_Request $request Rest Request.
318 + * @param \SureCart\Models\Checkout $finalized Finalized checkout.
319 + * @param \WP_REST_Request $request The request.
318 320 *
319 - * @return \SureCart\Models\Checkout|\WP_Error
321 + * @return \WP_Error|\SureCart\Models\Checkout
320 322 */
321 - public function offerBump( \WP_REST_Request $request ) {
322 - $order = $this->middleware( new $this->class( $request['id'] ), $request );
323 - if ( is_wp_error( $order ) ) {
324 - return $order;
323 + public function validateFinalizeRequest( $finalized, $request ) {
324 + // allow this if the user can edit orders.
325 + if ( current_user_can( 'edit_sc_orders' ) ) {
326 + return $finalized;
325 327 }
326 - return $order->where( $request->get_query_params() )->offerBump( $request['bump_id'] );
328 +
329 + // make sure the form id is valid.
330 + if ( ! empty( $request['form_id'] ) ) {
331 + return $this->validateFormId( $finalized, $request );
332 + }
333 +
334 + return $this->validateProductId( $finalized, $request );
327 335 }
328 336
329 337 /**
330 - * Offer the bump (used for analytics).
338 + * Validate the product id.
331 339 *
332 - * @param \WP_REST_Request $request Rest Request.
340 + * @param \WP_REST_Request $request The rest request.
341 + * @param \SureCart\Models\Order $finalized The finalized order.
333 342 *
334 - * @return \SureCart\Models\Checkout|\WP_Error
343 + * @return \WP_Error|\SureCart\Models\Order
335 344 */
336 - public function offerUpsell( \WP_REST_Request $request ) {
337 - $order = $this->middleware( new $this->class( $request['id'] ), $request );
338 - if ( is_wp_error( $order ) ) {
339 - return $order;
345 + public function validateProductId( $finalized, $request ) {
346 + // make sure the product is valid.
347 + if ( empty( $request['product_id'] ) ) {
348 + return new \WP_Error( 'missing_parameters', 'You must pass a form id or product id in order to make this payment.', [ 'status' => 400 ] );
340 349 }
341 - return $order->where( $request->get_query_params() )->offerUpsell( $request['upsell_id'] );
342 - }
350 + // make sure the product is valid.
351 + $product = Product::find( $request['product_id'] );
352 + if ( empty( $product->id ) ) {
353 + return new \WP_Error( 'product_id_invalid', esc_html__( 'This product is invalid.', 'surecart' ), [ 'status' => 400 ] );
354 + }
343 355
344 - /**
345 - * Offer the bump (used for analytics).
346 - *
347 - * @param \WP_REST_Request $request Rest Request.
348 - *
349 - * @return \SureCart\Models\Checkout|\WP_Error
350 - */
351 - public function declineUpsell( \WP_REST_Request $request ) {
352 - $order = $this->middleware( new $this->class( $request['id'] ), $request );
353 - if ( is_wp_error( $order ) ) {
354 - return $order;
356 + // check to make sure the product buy page is enabled.
357 + if ( ! $product->buyLink()->isEnabled() ) {
358 + return new \WP_Error( 'product_buy_page_disabled', esc_html__( 'This product is not available for purchase.', 'surecart' ), [ 'status' => 400 ] );
355 359 }
356 - return $order->where( $request->get_query_params() )->declineUpsell( $request['upsell_id'] );
360 +
361 + // the mode must match.
362 + $mode = $product->buyLink()->getMode();
363 + // if the request is for test mode, but the form is not test, return an error.
364 + if ( false === $finalized->live_mode && 'test' !== $mode ) {
365 + return new \WP_Error( 'invalid_mode', 'This page is set to live mode, but the request is for test mode. Please clear any site caching and try again.', [ 'status' => 400 ] );
366 + }
367 +
368 + // At least one line item must be for this product.
369 + foreach ( $finalized->line_items->data as $line_item ) {
370 + if ( $line_item->price->product->id === $product->id ) {
371 + return $finalized;
372 + }
373 + }
374 +
375 + return new \WP_Error( 'product_buy_page_disabled', esc_html__( 'This product is not available for purchase.', 'surecart' ), [ 'status' => 400 ] );
357 376 }
358 377
359 378 /**
360 - * Check if the user is trying to sign in.
361 - * If so, validate credentials before finalizing.
379 + * Validate the form id.
362 380 *
363 - * @param string $email Email.
364 - * @param string $password Password.
381 + * @param \WP_REST_Request $request The rest request.
382 + * @param \SureCart\Models\Order $finalized The finalized order.
365 383 *
366 - * @return true|\WP_Error
384 + * @return \WP_Error|\SureCart\Models\Order
367 385 */
368 - public function maybeValidateLoginCreds( $email = '', $password = '' ) {
369 - // check if the person is signing in using a password and sign them in.
370 - if ( $password && $email ) {
371 - // user exists, try signing in with password.
372 - $user = get_user_by( 'email', $email );
373 - // if there's a user, check the username and password before we submit the order.
374 - if ( false !== $user ) {
375 - return wp_authenticate_username_password( null, $user->user_login, $password );
376 - }
386 + public function validateFormId( $finalized, $request ) {
387 + // the form's mode must be test.
388 + $mode = $this->getFormMode( (int) $request['form_id'] );
389 +
390 + // if the request is for test mode, but the form is not test, return an error.
391 + if ( false === $finalized->live_mode && 'test' !== $mode ) {
392 + return new \WP_Error( 'invalid_mode', 'The form is set to live mode, but the request is for test mode.', [ 'status' => 400 ] );
377 393 }
378 - return true;
394 +
395 + return $finalized;
379 396 }
380 397
381 398 /**
382 399 * Create or login the user.
@@ -394,6 +411,21 @@
394 411 'user_login' => $user_email,
395 412 'user_password' => $password,
396 413 ]
397 414 );
415 + }
416 +
417 + /**
418 + * Cancel an checkout
419 + *
420 + * @param \WP_REST_Request $request Rest Request.
421 + *
422 + * @return \SureCart\Models\Checkout|\WP_Error
423 + */
424 + public function cancel( \WP_REST_Request $request ) {
425 + $order = $this->middleware( new $this->class( $request['id'] ), $request );
426 + if ( is_wp_error( $order ) ) {
427 + return $order;
428 + }
429 + return $order->where( $request->get_query_params() )->cancel();
398 430 }
399 431 }