WordPress REST Api get posts by ID

You’re getting that mismatched values because you’re using the wrong argument for the post ID in your $args array (i.e. the query args for WP_Query). And the correct argument is p (lowercase P) and not id:

$args = [
//  'id' => $request['id'], // wrong argument name - 'id'
    'p' => $request['id'],  // and the correct one is 'p'
    'post_type' => 'payment',
];

And in addition to that main issue, another one I noticed is the $post_id = $post->ID; whereby that $post is an array and not object. So did you mean to use $post_id = $post[0]->ID; ?

Also, why do you have to use get_posts()? Why not just use get_post()$post = get_post( $request['id'] ); ? That way, the above $post_id = $post->ID; would be valid. So for example, this is how your code would look like when using get_post():

if ( ! $post = get_post( $request['id'] ) ) {
    return new WP_Error( 'your_error_code_here', 'Please define a valid post ID.' );
}

$metas = get_post_meta( $request['id'] );
$post_id = $post->ID;

$response[ $post_id ]['response'] = $post;