'POST', 'callback' => 'orderping_rest_ping', // Authentication is the signature check inside the callback. 'permission_callback' => '__return_true', ) ); register_rest_route( 'orderping/v1', '/kick', array( 'methods' => 'POST', 'callback' => 'orderping_rest_kick', // Authentication is the HMAC token inside the callback (outbox.php). 'permission_callback' => '__return_true', ) ); register_rest_route( 'orderping/v1', '/confirmation', array( 'methods' => 'POST', 'callback' => 'orderping_rest_confirmation', // Authentication is the signature check inside the callback. 'permission_callback' => '__return_true', ) ); register_rest_route( 'orderping/v1', '/cancel', array( 'methods' => 'POST', 'callback' => 'orderping_rest_cancel', // Authentication is the signature check inside the callback. 'permission_callback' => '__return_true', ) ); register_rest_route( 'orderping/v1', '/order-state', array( 'methods' => 'POST', 'callback' => 'orderping_rest_order_state', // Authentication is the signature check inside the callback. 'permission_callback' => '__return_true', ) ); register_rest_route( 'orderping/v1', '/prepay-link', array( 'methods' => 'POST', 'callback' => 'orderping_rest_prepay_link', // Authentication is the signature check inside the callback. 'permission_callback' => '__return_true', ) ); register_rest_route( 'orderping/v1', '/prepay-writeback', array( 'methods' => 'POST', 'callback' => 'orderping_rest_prepay_writeback', // Authentication is the signature check inside the callback. 'permission_callback' => '__return_true', ) ); register_rest_route( 'orderping/v1', '/disconnect', array( 'methods' => 'POST', 'callback' => 'orderping_rest_disconnect', // Authentication is the signature check inside the callback. 'permission_callback' => '__return_true', ) ); } ); } /** * Handles a backend ping. Rejects anything not signed for this connection. * * @param WP_REST_Request $request Request. * @return WP_REST_Response|WP_Error */ function orderping_rest_ping( WP_REST_Request $request ) { $conn = orderping_connection(); if ( null === $conn || $conn['id'] !== (string) $request->get_header( 'x_op_connection' ) ) { return new WP_Error( 'orderping_unauthorized', 'Unauthorized', array( 'status' => 401 ) ); } $body = $request->get_body(); $verdict = orderping_verify( $conn['secret'], 'cp-to-site', 'POST', ORDERPING_PING_PATH, (string) $request->get_header( 'x_op_timestamp' ), (string) $request->get_header( 'x_op_nonce' ), (string) $request->get_header( 'x_op_signature' ), $body, time() ); if ( true !== $verdict ) { return new WP_Error( 'orderping_unauthorized', 'Unauthorized', array( 'status' => 401 ) ); } // Claim the nonce only after the signature is valid. if ( ! orderping_claim_nonce( (string) $request->get_header( 'x_op_nonce' ) ) ) { return new WP_Error( 'orderping_replayed', 'Unauthorized', array( 'status' => 401 ) ); } $data = json_decode( $body, true ); if ( ! is_array( $data ) || ( $data['type'] ?? '' ) !== 'ping' ) { return new WP_Error( 'orderping_invalid', 'Invalid event', array( 'status' => 400 ) ); } return new WP_REST_Response( array( 'status' => 'ok', 'plugin_version' => ORDERPING_VERSION, 'contract_version' => ORDERPING_CONTRACT_VERSION, ), 200 ); }