Order_Endpoint
Class Order Endpoint.
Source
File: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php
class Order_Endpoint implements Tribe__Documentation__Swagger__Provider_Interface { /** * The REST API endpoint path. * * @since 5.1.9 * * @var string */ protected $path = '/commerce/paypal/order'; /** * Register the actual endpoint on WP Rest API. * * @since 5.1.9 */ public function register() { $namespace = tribe( 'tickets.rest-v1.main' )->get_events_route_namespace(); $documentation = tribe( 'tickets.rest-v1.endpoints.documentation' ); register_rest_route( $namespace, $this->get_endpoint_path(), [ 'methods' => WP_REST_Server::CREATABLE, 'args' => $this->create_order_args(), 'callback' => [ $this, 'handle_create_order' ], 'permission_callback' => '__return_true', ] ); register_rest_route( $namespace, $this->get_endpoint_path() . '/(?P<order_id>[0-9a-zA-Z]+)', [ 'methods' => WP_REST_Server::CREATABLE, 'args' => $this->update_order_args(), 'callback' => [ $this, 'handle_update_order' ], 'permission_callback' => '__return_true', ] ); register_rest_route( $namespace, $this->get_endpoint_path() . '/(?P<order_id>[0-9a-zA-Z]+)', [ 'methods' => WP_REST_Server::DELETABLE, 'args' => $this->fail_order_args(), 'callback' => [ $this, 'handle_fail_order' ], 'permission_callback' => '__return_true', ] ); $documentation->register_documentation_provider( $this->get_endpoint_path(), $this ); } /** * Gets the Endpoint path for the on boarding process. * * @since 5.1.9 * * @return string */ public function get_endpoint_path() { return $this->path; } /** * Get the REST API route URL. * * @since 5.1.9 * * @return string The REST API route URL. */ public function get_route_url() { $namespace = tribe( 'tickets.rest-v1.main' )->get_events_route_namespace(); return rest_url( '/' . $namespace . $this->get_endpoint_path(), 'https' ); } /** * Handles the request that creates an order with Tickets Commerce and the PayPal gateway. * * @since 5.1.9 * * @param WP_REST_Request $request The request object. * * @return WP_Error|WP_REST_Response An array containing the data on success or a WP_Error instance on failure. */ public function handle_create_order( WP_REST_Request $request ) { $response = [ 'success' => false, ]; $messages = $this->get_error_messages(); $order = tribe( Order::class )->create_from_cart( tribe( Gateway::class ) ); $unit = [ 'reference_id' => $order->ID, 'value' => $order->total_value, 'currency' => $order->currency, 'first_name' => $order->purchaser['first_name'], 'last_name' => $order->purchaser['last_name'], 'email' => $order->purchaser['email'], ]; foreach ( $order->items as $item ) { $ticket = \Tribe__Tickets__Tickets::load_ticket_object( $item['ticket_id'] ); $unit['items'][] = [ 'name' => $ticket->name, 'unit_amount' => [ 'value' => $item['price'], 'currency_code' => $order->currency ], 'quantity' => $item['quantity'], 'item_total' => [ 'value' => $item['sub_total'], 'currency_code' => $order->currency ], 'sku' => $ticket->sku, ]; } $paypal_order = tribe( Client::class )->create_order( $unit ); if ( empty( $paypal_order['id'] ) || empty( $paypal_order['create_time'] ) ) { return new WP_Error( 'tec-tc-gateway-paypal-failed-creating-order', $messages['failed-creating-order'], $order ); } $debug_header = tribe( Client::class )->get_debug_header(); if ( ! empty( $debug_header ) ) { $paypal_order['debug_id'] = $debug_header; } $updated = tribe( Order::class )->modify_status( $order->ID, Pending::SLUG, [ 'gateway_payload' => $paypal_order, 'gateway_order_id' => $paypal_order['id'], ] ); if ( is_wp_error( $updated ) ) { return $updated; } // Respond with the ID for Paypal Usage. $response['success'] = true; $response['id'] = $paypal_order['id']; return new WP_REST_Response( $response ); } /** * Handles the request that updates an order with Tickets Commerce and the PayPal gateway. * * @since 5.1.9 * * @param WP_REST_Request $request The request object. * * @return WP_Error|WP_REST_Response An array containing the data on success or a WP_Error instance on failure. */ public function handle_update_order( WP_REST_Request $request ) { $response = [ 'success' => false, ]; $messages = $this->get_error_messages(); $paypal_order_id = $request->get_param( 'order_id' ); $order = tec_tc_orders()->by_args( [ 'status' => tribe( Pending::class )->get_wp_slug(), 'gateway_order_id' => $paypal_order_id, ] )->first(); if ( ! $order ) { return new WP_Error( 'tec-tc-gateway-paypal-nonexistent-order-id', $messages['nonexistent-order-id'], $order ); } $payer_id = $request->get_param( 'payer_id' ); $paypal_capture_response = tribe( Client::class )->capture_order( $paypal_order_id, $payer_id ); $debug_header = tribe( Client::class )->get_debug_header(); if ( ! empty( $debug_header ) ) { $paypal_capture_response['debug_id'] = $debug_header; } if ( 'UNPROCESSABLE_ENTITY' === Arr::get( $paypal_capture_response, 'name' ) ) { // Flag the order as Denied. tribe( Order::class )->modify_status( $order->ID, Denied::SLUG, [ 'gateway_payload' => $paypal_capture_response, ] ); return new WP_Error( 'tec-tc-gateway-paypal-failed-capture', $messages['failed-capture'], $paypal_capture_response ); } $paypal_capture_status = Arr::get( $paypal_capture_response, [ 'status' ] ); $status = tribe( Status::class )->convert_to_commerce_status( $paypal_capture_status ); if ( ! $status ) { return new WP_Error( 'tec-tc-gateway-paypal-invalid-capture-status', $messages['invalid-capture-status'], $paypal_capture_response ); } $updated = tribe( Order::class )->modify_status( $order->ID, $status->get_slug(), [ 'gateway_payload' => $paypal_capture_response, ] ); if ( is_wp_error( $updated ) ) { return $updated; } $response['success'] = true; $response['status'] = $status->get_slug(); $response['order_id'] = $order->ID; // When we have success we clear the cart. tribe( Cart::class )->clear_cart(); $response['redirect_url'] = add_query_arg( [ 'tc-order-id' => $paypal_order_id ], tribe( Success::class )->get_url() ); return new WP_REST_Response( $response ); } /** * Handles the request that handles failing an order with Tickets Commerce and the PayPal gateway. * * @since 5.2.0 * * @param WP_REST_Request $request The request object. * * @return WP_Error|WP_REST_Response An array containing the data on success or a WP_Error instance on failure. */ public function handle_fail_order( WP_REST_Request $request ) { $response = [ 'success' => false, ]; $paypal_order_id = $request->get_param( 'order_id' ); $order = tec_tc_orders()->by_args( [ 'status' => 'any', 'gateway_order_id' => $paypal_order_id, ] )->first(); $messages = $this->get_error_messages(); if ( ! $order ) { return new WP_Error( 'tec-tc-gateway-paypal-nonexistent-order-id', null, $order ); } $failed_reason = $request->get_param( 'failed_reason' ); $failed_status = $request->get_param( 'failed_status' ); if ( empty( $failed_status ) ) { $failed_status = 'not-completed'; } $status = tribe( Status_Handler::class )->get_by_slug( $failed_status ); if ( ! $status ) { return new WP_Error( 'tec-tc-gateway-paypal-invalid-failed-status', null, [ 'failed_status' => $failed_status, 'failed_reason' => $failed_reason ] ); } /** * @todo possible determine if we should have error code associated with the failing of this order. */ $updated = tribe( Order::class )->modify_status( $order->ID, $status->get_slug() ); if ( is_wp_error( $updated ) ) { return $updated; } $response['success'] = true; $response['status'] = $status->get_slug(); $response['order_id'] = $order->ID; $response['title'] = $messages['canceled-creating-order']; return new WP_REST_Response( $response ); } /** * Arguments used for the signup redirect. * * @since 5.1.9 * * @return array */ public function create_order_args() { return []; } /** * Arguments used for the updating order for PayPal. * * @since 5.1.9 * * @return array */ public function update_order_args() { return [ 'order_id' => [ 'description' => __( 'Order ID in PayPal', 'event-tickets' ), 'required' => true, 'type' => 'string', 'validate_callback' => static function ( $value ) { if ( ! is_string( $value ) ) { return new WP_Error( 'rest_invalid_param', 'The order ID argument must be a string.', [ 'status' => 400 ] ); } return $value; }, 'sanitize_callback' => [ $this, 'sanitize_callback' ], ], 'payer_id' => [ 'description' => __( 'Payer ID token from PayPal', 'event-tickets' ), 'required' => false, 'type' => 'string', 'validate_callback' => static function ( $value ) { if ( ! is_string( $value ) ) { return new WP_Error( 'rest_invalid_param', 'The payer ID argument must be a string.', [ 'status' => 400 ] ); } return $value; }, 'sanitize_callback' => [ $this, 'sanitize_callback' ], ], ]; } /** * Arguments used for the deleting order for PayPal. * * @since 5.2.0 * * @return array */ public function fail_order_args() { return [ 'order_id' => [ 'description' => __( 'Order ID in PayPal', 'event-tickets' ), 'required' => true, 'type' => 'string', 'validate_callback' => static function ( $value ) { if ( ! is_string( $value ) ) { return new WP_Error( 'rest_invalid_param', 'The order ID argument must be a string.', [ 'status' => 400 ] ); } return $value; }, 'sanitize_callback' => [ $this, 'sanitize_callback' ], ], 'failed_status' => [ 'description' => __( 'To which status the failing should change this order to', 'event-tickets' ), 'required' => false, 'type' => 'string', 'validate_callback' => static function ( $value ) { if ( ! is_string( $value ) ) { return new WP_Error( 'rest_invalid_param', 'The failed status argument must be a string.', [ 'status' => 400 ] ); } return $value; }, 'sanitize_callback' => [ $this, 'sanitize_callback' ], ], 'failed_reason' => [ 'description' => __( 'Why this particular order has failed.', 'event-tickets' ), 'required' => false, 'type' => 'string', 'validate_callback' => static function ( $value ) { if ( ! is_string( $value ) ) { return new WP_Error( 'rest_invalid_param', 'The failed reason argument must be a string.', [ 'status' => 400 ] ); } return $value; }, 'sanitize_callback' => [ $this, 'sanitize_callback' ], ], ]; } /** * Sanitize a request argument based on details registered to the route. * * @since 5.1.9 * * @param mixed $value Value of the 'filter' argument. * * @return string|array */ public function sanitize_callback( $value ) { if ( is_array( $value ) ) { return array_map( 'sanitize_text_field', $value ); } return sanitize_text_field( $value ); } /** * {@inheritDoc} * * @TODO We need to make sure Swagger documentation is present. * * @since 5.1.9 * * @return array */ public function get_documentation() { return []; } /** * Returns an array of error messages that are used by the API responses. * * @since 5.2.0 * * @return array $messages Array of error messages. */ public function get_error_messages() { $messages = [ 'failed-creating-order' => __( 'Creating new PayPal order failed. Please try again.', 'event-tickets' ), 'canceled-creating-order' => __( 'Your PayPal order was cancelled.', 'event-tickets' ), 'nonexistent-order-id' => __( 'Provided Order id is not valid.', 'event-tickets' ), 'failed-capture' => __( 'There was a problem while processing your payment, please try again.', 'event-tickets' ), 'invalid-capture-status' => __( 'There was a problem with the Order status change, please try again.', 'event-tickets' ), ]; /** * Filter the error messages for PayPal checkout. * * @since 5.2.0 * * @param array $messages Array of error messages. */ return apply_filters( 'tec_tickets_commerce_order_endpoint_error_messages', $messages ); } }
Changelog
Version | Description |
---|---|
5.1.9 | Introduced. |
Methods
- create_order_args — Arguments used for the signup redirect.
- fail_order_args — Arguments used for the deleting order for PayPal.
- format_order_item_name — Formats the order item name by truncating it to a specified length.
- get_documentation — {@inheritDoc}
- get_endpoint_path — Gets the Endpoint path for the on boarding process.
- get_error_messages — Returns an array of error messages that are used by the API responses.
- get_route_url — Get the REST API route URL.
- handle_create_order — Handles the request that creates an order with Tickets Commerce and the PayPal gateway.
- handle_fail_order — Handles the request that handles failing an order with Tickets Commerce and the PayPal gateway.
- handle_recheck_order — Gets the Order object again, in another request, to check for purchases possibly denied after creation.
- handle_update_order — Handles the request that updates an order with Tickets Commerce and the PayPal gateway.
- register — Register the actual endpoint on WP Rest API.
- sanitize_callback — Sanitize a request argument based on details registered to the route.
- update_order_args — Arguments used for the updating order for PayPal.