使用INFOBIP发送SMS返回200但未收到短信问题求助
问题背景
调用Infobip短信API后返回HTTP 200状态码,但目标手机号未收到短信。API返回的状态为PENDING_ACCEPTED,而非预期的DELIVERED_TO_HANDSET。
实现代码
try { // Create the connection to the Infobip API. URL url = new URL(BASE_URL + "/sms/2/text/advanced"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setRequestProperty("Authorization", "App " + API_KEY); connection.setRequestProperty("Content-Type", "application/json"); connection.setRequestProperty("Accept", "application/json"); // connection.setRequestProperty("User-Agent", "Mozilla/4.76"); connection.setDoOutput(true); // Create the SMS message JSON payload. String payload = String.format("{\"messages\":[{\"from\":\"%s\",\"destinations\":[{\"to\":\"%s\"}],\"text\":\"%s\"}]}", SENDER, RECIPIENT, MESSAGE_TEXT ); // Write the payload to the request. try (OutputStream os = connection.getOutputStream()) { byte[] input = payload.getBytes("utf-8"); os.write(input, 0, input.length); } // Get the response from the API. int responseCode = connection.getResponseCode(); System.out.println("Response Code: " + responseCode); if (responseCode == HttpURLConnection.HTTP_OK) { try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { String line; StringBuilder response = new StringBuilder(); while ((line = reader.readLine()) != null) { response.append(line); } System.out.println("Message sent successfully. Response Content: " + response.toString()); } } else { // Print the response content for error requests. // Similar to the success case, adjust the parsing and print the full response content. try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()))) { String line; StringBuilder response = new StringBuilder(); while ((line = reader.readLine()) != null) { response.append(line); } System.out.println("Error sending message. Response Content: " + response.toString()); } } } catch (Exception e) { e.printStackTrace(); }
API返回内容
Message sent successfully. Response Content: {"messages":[{"messageId":"3915723960824335774697","status":{"description":"Message sent to next instance","groupId":1,"groupName":"PENDING","id":26,"name":"PENDING_ACCEPTED"},"to":"970597086266"}]}
预期送达状态
groupId: 3 groupName: DELIVERED id: 5 name: DELIVERED_TO_HANDSET description: Message delivered to handset action: null
原因分析
- 200 OK仅代表请求被接收:Infobip返回200只是确认你的请求已被系统接受并进入处理队列,
PENDING_ACCEPTED状态说明消息还在路由到运营商的环节,并非最终送达状态。 - 号码格式问题:目标号码未使用E.164标准格式(如缺少
+前缀),部分运营商会拒绝非标准格式的号码。 - Sender ID不合规:发送方签名未在Infobip备案,或不符合目标国家的监管要求(比如部分国家要求Sender ID为数字短码),导致运营商拦截消息。
- 内容合规问题:短信内容包含敏感词、违规链接或违反当地通信法规,被Infobip或运营商过滤。
- 运营商延迟或拦截:消息已到达运营商,但因网络拥堵、号码异常(如停机、拉黑)等原因未送达。
解决方案
1. 查询实时消息状态
用返回的messageId调用Infobip的短信状态查询API,获取最新流转状态,定位卡壳环节。示例代码:
try { URL url = new URL(BASE_URL + "/sms/2/reports?messageId=" + MESSAGE_ID); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setRequestProperty("Authorization", "App " + API_KEY); connection.setRequestProperty("Accept", "application/json"); int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { String line; StringBuilder response = new StringBuilder(); while ((line = reader.readLine()) != null) { response.append(line); } System.out.println("Message status: " + response.toString()); } } } catch (Exception e) { e.printStackTrace(); }
2. 验证号码格式
确保目标号码是E.164标准格式(如+970597086266),检查代码中RECIPIENT变量是否包含正确前缀。
3. 检查Sender ID合规性
登录Infobip后台确认Sender ID已完成备案,且符合目标地区的短信发送规则(比如部分国家禁止字母Sender ID)。
4. 测试内容合规性
发送一条无敏感内容的测试短信(如"Test message from Infobip"),验证是否能正常送达,排除内容过滤问题。
5. 开启状态回调
在发送请求的payload中添加notifyUrl参数,让Infobip在消息状态变更时主动通知你的服务,实时获取送达状态:
String payload = String.format("{\"messages\":[{\"from\":\"%s\",\"destinations\":[{\"to\":\"%s\"}],\"text\":\"%s\",\"notifyUrl\":\"https://your-server.com/webhook/sms-status\"}]}", SENDER, RECIPIENT, MESSAGE_TEXT );
你的服务需要提供一个可访问的接口,接收Infobip的POST回调请求,解析状态变更信息。
6. 查看Infobip控制台日志
登录Infobip管理后台,进入消息日志页面,查看详细的状态流转记录,包括是否被运营商拒绝、延迟原因等。
内容的提问来源于stack exchange,提问作者Hasan Isleem

