matewa_terminal_status_install_uuid(), 'hash' => hash( 'sha256', $proof ), 'expires' => time() + 180, ), 180 ); return $proof; } } if ( ! function_exists( 'matewa_terminal_status_proof_callback' ) ) { function matewa_terminal_status_proof_callback( WP_REST_Request $request ) { $uuid = sanitize_text_field( (string) $request->get_param( 'install_uuid' ) ); $proof = sanitize_text_field( (string) $request->get_param( 'proof' ) ); $saved = get_transient( MATEWA_TERMINAL_STATUS_PROOF_TRANSIENT ); $ok = is_array( $saved ) && (int) ( $saved['expires'] ?? 0 ) >= time() && hash_equals( (string) ( $saved['uuid'] ?? '' ), $uuid ) && hash_equals( (string) ( $saved['hash'] ?? '' ), hash( 'sha256', $proof ) ); if ( ! $ok ) { return new WP_REST_Response( array( 'ok' => false ), 403 ); } delete_transient( MATEWA_TERMINAL_STATUS_PROOF_TRANSIENT ); return new WP_REST_Response( array( 'ok' => true, 'install_uuid' => $uuid, ), 200 ); } } add_action( 'rest_api_init', static function() { register_rest_route( '247chatmate/v1', '/terminal-status-proof', array( 'methods' => WP_REST_Server::READABLE, 'callback' => 'matewa_terminal_status_proof_callback', 'permission_callback' => '__return_true', ) ); } ); if ( ! function_exists( 'matewa_terminal_status_check' ) ) { function matewa_terminal_status_check( $license_meta = array() ) { $license_meta = is_array( $license_meta ) ? $license_meta : array(); $order_id = sanitize_text_field( (string) ( $license_meta['order_id'] ?? '' ) ); $order_item_id = sanitize_text_field( (string) ( $license_meta['order_item_id'] ?? '' ) ); $customer_id = sanitize_text_field( (string) ( $license_meta['customer_id'] ?? '' ) ); $product_id = sanitize_text_field( (string) ( $license_meta['product_id'] ?? '' ) ); $variant_id = sanitize_text_field( (string) ( $license_meta['variant_id'] ?? '' ) ); /* * Without a LemonSqueezy object identifier there is nothing reliable * to match server-side. Fail open here and leave the normal licence * validation result unchanged. */ if ( '' === $order_id && '' === $order_item_id && '' === $customer_id ) { return array( 'ok' => false, 'code' => 'no_match_identifiers', 'terminal' => false, ); } $proof = matewa_terminal_status_make_proof(); $payload = array( 'action' => 'entitlement_status', 'site_url' => esc_url_raw( home_url( '/' ) ), 'install_uuid' => matewa_terminal_status_install_uuid(), 'plugin_version' => defined( 'MATEWA_VERSION' ) ? (string) MATEWA_VERSION : '', 'release_channel' => defined( 'MATEWA_DISTRIBUTION_PROFILE' ) ? (string) MATEWA_DISTRIBUTION_PROFILE : 'free', 'proof_url' => esc_url_raw( rest_url( '247chatmate/v1/terminal-status-proof' ) ), 'site_proof' => $proof, 'order_id' => $order_id, 'order_item_id' => $order_item_id, 'customer_id' => $customer_id, 'product_id' => $product_id, 'variant_id' => $variant_id, ); $response = wp_remote_post( MATEWA_TERMINAL_STATUS_ENDPOINT, array( 'timeout' => 12, 'headers' => array( 'Content-Type' => 'application/json; charset=utf-8' ), 'body' => wp_json_encode( $payload, JSON_UNESCAPED_SLASHES ), ) ); if ( is_wp_error( $response ) ) { return array( 'ok' => false, 'code' => 'status_unavailable', 'terminal' => false, ); } $status_code = (int) wp_remote_retrieve_response_code( $response ); $data = json_decode( (string) wp_remote_retrieve_body( $response ), true ); if ( $status_code < 200 || $status_code >= 300 || ! is_array( $data ) ) { return array( 'ok' => false, 'code' => 'invalid_status_response', 'terminal' => false, ); } return array( 'ok' => ! empty( $data['ok'] ), 'code' => sanitize_key( (string) ( $data['code'] ?? '' ) ), 'terminal' => ! empty( $data['terminal'] ), 'stored_status' => sanitize_key( (string) ( $data['stored_status'] ?? '' ) ), 'subscription_status' => sanitize_key( (string) ( $data['subscription_status'] ?? '' ) ), 'last_event' => sanitize_key( (string) ( $data['last_event'] ?? '' ) ), ); } }