@@ -31,38 +31,46 @@ public function __construct()
3131 /**
3232 * Send an SMS message (static convenience method).
3333 *
34- * @param string $to Recipient phone number (8 digits)
35- * @param string $text Message text (max 160 characters)
36- * @param string|null $from Optional sender ID (8 characters), defaults to config
34+ * @param string $to Recipient phone number
35+ * @param string $text Message text
36+ * @param string|null $from Optional sender number, defaults to config
37+ * @param array $options Optional CallPro parameters
3738 *
3839 * @return array Response containing status and message ID
3940 *
4041 * @throws \Exception If API request fails
4142 */
42- public static function sendSms (string $ to , string $ text , ?string $ from = null ): array
43+ public static function sendSms (string $ to , string $ text , ?string $ from = null , array $ options = [] ): array
4344 {
4445 $ instance = new static ();
4546
46- return $ instance ->send ($ to , $ text , $ from );
47+ return $ instance ->send ($ to , $ text , $ from, $ options );
4748 }
4849
4950 /**
5051 * Send an SMS message.
5152 *
52- * @param string $to Recipient phone number (8 digits)
53- * @param string $text Message text (max 160 characters)
54- * @param string|null $from Optional sender ID (8 characters), defaults to config
53+ * @param string $to Recipient phone number
54+ * @param string $text Message text
55+ * @param string|null $from Optional sender number, defaults to config
56+ * @param array $options Optional CallPro parameters
5557 *
5658 * @return array Response containing status and message ID
5759 *
5860 * @throws \Exception If API request fails
5961 */
60- public function send (string $ to , string $ text , ?string $ from = null ): array
62+ public function send (string $ to , string $ text , ?string $ from = null , array $ options = [] ): array
6163 {
6264 $ from = $ from ?? $ this ->from ;
6365
64- // Validate parameters
6566 $ this ->validateParameters ($ to , $ text , $ from );
67+ $ payload = array_filter ([
68+ 'from ' => $ from ,
69+ 'to ' => $ to ,
70+ 'text ' => $ text ,
71+ 'brand ' => data_get ($ options , 'brand ' ),
72+ 'unique_id ' => data_get ($ options , 'unique_id ' ),
73+ ], static fn ($ value ) => $ value !== null && $ value !== '' );
6674
6775 try {
6876 Log::info ('Sending SMS via CallPro ' , [
@@ -73,31 +81,26 @@ public function send(string $to, string $text, ?string $from = null): array
7381
7482 $ response = Http::withHeaders ([
7583 'x-api-key ' => $ this ->apiKey ,
76- ])->get ("{$ this ->baseUrl }/send " , [
77- 'from ' => $ from ,
78- 'to ' => $ to ,
79- 'text ' => $ text ,
80- ]);
84+ ])->post ("{$ this ->baseUrl }/send " , $ payload );
8185
8286 $ statusCode = $ response ->status ();
8387 $ body = $ response ->json ();
8488
85- // Handle response based on status code
86- if ($ statusCode === 200 ) {
89+ if ($ statusCode === 200 && is_array ($ body ) && isset ($ body ['message_id ' ])) {
8790 Log::info ('SMS sent successfully ' , [
88- 'message_id ' => $ body ['Message ID ' ] ?? null ,
89- 'result ' => $ body ['Result ' ] ?? null ,
91+ 'message_id ' => $ body ['message_id ' ] ,
92+ 'status ' => $ body ['status ' ] ?? null ,
9093 ]);
9194
9295 return [
9396 'success ' => true ,
94- 'message_id ' => $ body ['Message ID ' ] ?? null ,
95- 'result ' => $ body ['Result ' ] ?? 'SUCCESS ' ,
97+ 'message_id ' => $ body ['message_id ' ],
98+ 'result ' => $ body ['status ' ] ?? 'queued ' ,
99+ 'status ' => $ body ['status ' ] ?? 'queued ' ,
96100 ];
97101 }
98102
99- // Handle error responses
100- $ errorMessage = $ this ->getErrorMessage ($ statusCode );
103+ $ errorMessage = $ this ->getErrorMessage ($ statusCode , $ body );
101104
102105 Log::error ('SMS sending failed ' , [
103106 'status_code ' => $ statusCode ,
@@ -131,16 +134,12 @@ protected function validateParameters(string $to, string $text, string $from): v
131134 throw new \InvalidArgumentException ('CallPro API key is not configured ' );
132135 }
133136
134- if (strlen ($ from ) !== 8 || !ctype_digit ($ from )) {
135- throw new \InvalidArgumentException ('Sender ID (from) must be exactly 8 digits ' );
136- }
137-
138- if (strlen ($ to ) !== 8 ) {
139- throw new \InvalidArgumentException ('Recipient phone number (to) must be exactly 8 characters ' );
137+ if (!preg_match ('/^\d{8}$/ ' , $ from )) {
138+ throw new \InvalidArgumentException ('Sender number (from) must be exactly 8 digits ' );
140139 }
141140
142- if (strlen ( $ text ) > 160 ) {
143- throw new \InvalidArgumentException ('Message text cannot exceed 160 characters ' );
141+ if (! $ this -> isValidRecipientNumber ( $ to ) ) {
142+ throw new \InvalidArgumentException ('Recipient phone number (to) must be an 8-digit, 976-prefixed, +976-prefixed, or international number ' );
144143 }
145144
146145 if (empty ($ text )) {
@@ -151,17 +150,40 @@ protected function validateParameters(string $to, string $text, string $from): v
151150 /**
152151 * Get error message based on status code.
153152 */
154- protected function getErrorMessage (int $ statusCode ): string
153+ protected function getErrorMessage (int $ statusCode, ? array $ body = null ): string
155154 {
155+ if (is_array ($ body )) {
156+ $ error = data_get ($ body , 'error ' ) ?? data_get ($ body , 'reason ' );
157+ if (is_string ($ error ) && !empty ($ error )) {
158+ return $ error ;
159+ }
160+
161+ $ issues = data_get ($ body , 'issues ' );
162+ if (is_array ($ issues ) && !empty ($ issues )) {
163+ return json_encode ($ issues );
164+ }
165+ }
166+
156167 return match ($ statusCode ) {
157- 402 => 'Invalid request parameters ' ,
158- 403 => 'Invalid API key (x-api-key) ' ,
159- 404 => 'Invalid sender ID or recipient phone number format ' ,
160- 503 => 'API rate limit exceeded (max 5 requests per second) ' ,
168+ 400 => 'Invalid request parameters ' ,
169+ 401 => 'Invalid or missing API key ' ,
170+ 402 => 'Payment not paid ' ,
171+ 403 => 'Blocked number ' ,
172+ 404 => 'Tenant or phone number not found ' ,
173+ 422 => 'Validation error ' ,
174+ 500 => 'CallPro server error ' ,
161175 default => "API request failed with status code: {$ statusCode }" ,
162176 };
163177 }
164178
179+ /**
180+ * Validate recipient number formats accepted by CallPro.
181+ */
182+ protected function isValidRecipientNumber (string $ to ): bool
183+ {
184+ return (bool ) preg_match ('/^(?:\d{8}|976\d{8}|\+976\d{8}|\d{9,15})$/ ' , $ to );
185+ }
186+
165187 /**
166188 * Check if the service is configured.
167189 */
0 commit comments