logger = $logger; } private function request( string $url, array $args ) : array|\WP_Error { $args = wp_parse_args( $args, array( 'timeout' => 20, 'redirection' => 0, 'sslverify' => true ) ); $response = wp_remote_request( esc_url_raw( $url ), $args ); if ( is_wp_error( $response ) ) { return $response; } $code = wp_remote_retrieve_response_code( $response ); $body = wp_remote_retrieve_body( $response ); $json = json_decode( $body, true ); if ( $code < 200 || $code > 299 ) { return new \WP_Error( 'authkey_http', sprintf( 'Authkey returned HTTP %d.', $code ), array( 'body' => $body ) ); } return is_array( $json ) ? $json : array( 'raw' => $body ); } /** Make a JSON POST request to an Authkey console endpoint. */ private function json_post( string $url, array $body ) : array|\WP_Error { return $this->request( $url, array( 'method' => 'POST', 'headers' => array( 'Content-Type' => 'application/json', 'Accept' => 'application/json' ), 'body' => wp_json_encode( $body ), ) ); } public function login( string $username, string $password ) : array|\WP_Error { $result = $this->json_post( 'https://console.authkey.io/api/login1.php', array( 'username' => $username, 'password' => $password ) ); if ( is_wp_error( $result ) || empty( $result['success'] ) || empty( $result['token'] ) ) { if ( is_wp_error( $result ) ) { return $result; } $message = sanitize_text_field( (string) ( $result['message'] ?? $result['error'] ?? __( 'Login failed. Check your credentials.', 'authkey' ) ) ); return new \WP_Error( 'authkey_login', $message ); } $user_id = absint( $result['user']['userId'] ?? $result['user_id'] ?? 0 ); update_option( 'authkey_token', sanitize_text_field( $result['token'] ), false ); update_option( 'authkey_user_id', $user_id, false ); $this->save_profile( $result ); $profile = $this->profile(); if ( ! is_wp_error( $profile ) ) { $this->save_profile( $profile ); } return $result; } public function profile() : array|\WP_Error { $c = Settings::credentials(); return $this->json_post( 'https://console.authkey.io/api/profile.php', array( 'user_id' => $c['user_id'], 'method' => 'retrieve', 'token' => $c['token'] ) ); } /** Store profile fields regardless of the response wrapper or field casing. */ private function save_profile( array $profile ) : void { $values = $this->flatten_profile( $profile ); // Authkey's profile endpoint uses `currency` for the available balance // and `country_currency` for its currency code (for example, INR). if ( isset( $values['currency'] ) && '' !== (string) $values['currency'] ) { update_option( 'authkey_balance', sanitize_text_field( (string) $values['currency'] ), false ); } if ( isset( $values['country_currency'] ) && '' !== (string) $values['country_currency'] ) { update_option( 'authkey_currency', sanitize_text_field( (string) $values['country_currency'] ), false ); } $fields = array( 'authkey' => array( 'authkey', 'auth_key', 'api_key' ), 'user_name' => array( 'user_name', 'username', 'name' ), 'balance' => array( 'balance', 'wallet_balance', 'currency' ), 'currency' => array( 'country_currency', 'currency_code' ), ); foreach ( $fields as $option => $aliases ) { foreach ( $aliases as $alias ) { if ( isset( $values[ $alias ] ) && '' !== (string) $values[ $alias ] ) { update_option( 'authkey_' . $option, sanitize_text_field( (string) $values[ $alias ] ), false ); break; } } } } private function flatten_profile( array $data ) : array { $flat = array(); foreach ( $data as $key => $value ) { if ( is_array( $value ) ) { $flat = array_merge( $flat, $this->flatten_profile( $value ) ); } elseif ( is_scalar( $value ) ) { $flat[ strtolower( (string) $key ) ] = $value; } } return $flat; } public function templates( bool $refresh = false ) : array|\WP_Error { $key = 'authkey_templates'; if ( ! $refresh ) { $cached = get_transient( $key ); if ( is_array( $cached ) ) { return $cached; } } $c = Settings::credentials(); if ( '' === $c['authkey'] ) { return new \WP_Error( 'authkey_missing', __( 'Connect your Authkey account first.', 'authkey' ) ); } $result = $this->request( 'https://console.authkey.io/restapi/getAllTemplate.php', array( 'method' => 'POST', 'headers' => array( 'Authorization' => 'Basic ' . $c['authkey'], 'Content-Type' => 'application/json', 'Accept' => 'application/json' ), 'body' => wp_json_encode( array( 'channel' => 'whatsapp' ) ) ) ); if ( ! is_wp_error( $result ) ) { set_transient( $key, $result, HOUR_IN_SECONDS ); } return $result; } /** Sanitize scalar template values before they are sent to the external API. */ private function sanitize_template_values( array $values ) : array { $sanitized = array(); foreach ( $values as $key => $value ) { $key = sanitize_key( (string) $key ); if ( '' === $key || ! is_scalar( $value ) ) { continue; } $sanitized[ $key ] = sanitize_text_field( (string) $value ); } return $sanitized; } public function send( string $mobile, int $wid, array $values ) : array|\WP_Error { $c = Settings::credentials(); if ( '' === $c['authkey'] ) { return new \WP_Error( 'authkey_missing', __( 'Authkey account is not connected.', 'authkey' ) ); } $mobile = preg_replace( '/[^0-9]/', '', $mobile ); if ( strlen( $mobile ) < 7 ) { return new \WP_Error( 'authkey_mobile', __( 'A valid recipient mobile number is required.', 'authkey' ) ); } if ( $wid <= 0 ) { return new \WP_Error( 'authkey_wid', __( 'The selected WhatsApp template has no valid template ID.', 'authkey' ) ); } $params = array( 'authkey' => $c['authkey'], 'mobile' => $mobile, 'country_code' => '91', 'wid' => $wid ); foreach ( $this->sanitize_template_values( $values ) as $key => $value ) { $params[ $key ] = $value; } return $this->request( add_query_arg( $params, 'https://api.authkey.io/request' ), array( 'method' => 'GET' ) ); } /** Add a WooCommerce customer contact to an Authkey contact list. */ public function add_list_contact( string $list_name, string $country_code, string $mobile, string $billing ) : array|\WP_Error { $c = Settings::credentials(); if ( '' === $c['authkey'] ) { return new \WP_Error( 'authkey_missing', __( 'Authkey account is not connected.', 'authkey' ) ); } $list_name = sanitize_text_field( $list_name ); $country_code = preg_replace( '/[^0-9]/', '', $country_code ); $mobile = preg_replace( '/[^0-9]/', '', $mobile ); if ( '' === $list_name ) { return new \WP_Error( 'authkey_list_name', __( 'A contact list name is required.', 'authkey' ) ); } if ( '' === $country_code ) { return new \WP_Error( 'authkey_country_code', __( 'A valid country code is required.', 'authkey' ) ); } if ( strlen( $mobile ) < 7 ) { return new \WP_Error( 'authkey_mobile', __( 'A valid billing mobile number is required.', 'authkey' ) ); } return $this->json_post( 'https://console.authkey.io/restapi/addlistdata.php', array( 'authkey' => $c['authkey'], 'list_name' => $list_name, 'country_code' => $country_code, 'mobile' => $mobile, 'billing' => sanitize_text_field( $billing ), ) ); } }