发布

PHP实现国际短信验证码发送接口的完整指南

WAP站长网 2025-9-9 22:30
0 2

PHP 快速接入国际短信 API 接口:实现国际验证码短信发送

本文将详细介绍如何使用 PHP 语言快速接入国际短信 API 接口,实现国际验证码短信的发送功能,拿来就能用,10 分钟就能完成接入

一、主要提供两大功能

  • 单条短信发送(支持黑名单等拦截错误实时返回)
  • 获取状态报告(每条短信状态仅可获取一次)

二、环境要求

  • PHP 5.6 或更高版本
  • 开启 cURL 扩展
  • 有效的 SP_ID 和密钥(开发者中心查看)

三、完整 PHP 代码实现

以下是完整的 PHP 示例代码,只需替换配置参数即可使用:

<?php
/**
 * 国际短信接口Demo
 * 适用于3yit.com的短信API
 * 只需替换下面的配置参数即可使用
 */
 
class InternationalSMS {
    // ==================== 配置区域 ====================
    private $sp_id = '908452'; // 替换为您的SP_ID
    private $raw_password = 'your_raw_password'; // 替换为您的原始密码
    private $api_send_url = 'https://api.3yit.com/api/send-sms-single';
    private $api_report_url = 'https://api.3yit.com/api/report';
    // ==================== 配置结束 ====================
    
    private $password;
    
    public function __construct() {
        // 自动将密码转换为MD5格式
        $this->password = md5($this->raw_password);
    }
    
    /**
     * 发送单条国际验证码短信
     * @param string $mobile 国际手机号(格式:国家代码+号码,如639257890123)
     * @param string $message 短信内容
     * @param string $ext 扩展号(可选)
     * @return array 返回结果
     */
    public function sendVerificationCode($mobile, $message, $ext = '') {
        // 准备请求参数
        $params = [
            'sp_id' => $this->sp_id,
            'mobile' => $mobile,
            'content' => $message,
            'password' => $this->password,
            'ext' => $ext
        ];
        
        // 发送POST请求
        $result = $this->httpPost($this->api_send_url, $params);
        
        // 解析返回的JSON
        $response = json_decode($result, true);
        
        if (!$response) {
            return [
                'success' => false,
                'message' => 'API响应解析失败',
                'raw_response' => $result
            ];
        }
        
        // 判断是否发送成功
        if ($response['code'] == 0) {
            return [
                'success' => true,
                'message' => '短信发送成功',
                'msg_id' => $response['msg_id'],
                'response' => $response
            ];
        } else {
            return [
                'success' => false,
                'message' => $this->getErrorMessage($response['code'], isset($response['data']) ? $response['data'] : ''),
                'error_code' => $response['code'],
                'response' => $response
            ];
        }
    }
    
    /**
     * 获取状态报告
     * @return array 返回状态报告数据
     */
    public function getReport() {
        // 准备请求参数
        $params = [
            'sp_id' => $this->sp_id,
            'password' => $this->password
        ];
        
        // 构建查询字符串
        $queryString = http_build_query($params);
        $url = $this->api_report_url . '?' . $queryString;
        
        // 发送GET请求
        $result = $this->httpGet($url);
        
        // 解析返回的JSON
        $response = json_decode($result, true);
        
        if (!$response) {
            return [
                'success' => false,
                'message' => 'API响应解析失败',
                'raw_response' => $result
            ];
        }
        
        // 判断是否获取成功
        if ($response['code'] == 0) {
            $reports = [];
            if (!empty($response['data'])) {
                // 解析多条报告数据
                $reportList = explode('|', $response['data']);
                foreach ($reportList as $report) {
                    $fields = explode(',', $report);
                    if (count($fields) >= 5) {
                        $reports[] = [
                            'ext' => $fields[0],
                            'msg_id' => $fields[1],
                            'mobile' => $fields[2],
                            'status' => $fields[3],
                            'time' => $fields[4],
                            'price' => isset($fields[5]) ? $fields[5] : ''
                        ];
                    }
                }
            }
            
            return [
                'success' => true,
                'message' => '获取状态报告成功',
                'reports' => $reports,
                'response' => $response
            ];
        } else {
            return [
                'success' => false,
                'message' => $this->getErrorMessage($response['code']),
                'error_code' => $response['code'],
                'response' => $response
            ];
        }
    }
    
    /**
     * 发送HTTP POST请求
     * @param string $url 请求地址
     * @param array $params 请求参数
     * @return string 响应内容
     */
    private function httpPost($url, $params) {
        $ch = curl_init();
        
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        
        $response = curl_exec($ch);
        curl_close($ch);
        
        return $response;
    }
    
    /**
     * 发送HTTP GET请求
     * @param string $url 请求地址
     * @return string 响应内容
     */
    private function httpGet($url) {
        $ch = curl_init();
        
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        
        $response = curl_exec($ch);
        curl_close($ch);
        
        return $response;
    }
    
    /**
     * 获取错误信息
     * @param int $code 错误码
     * @param string $data 错误数据
     * @return string 错误描述
     */
    private function getErrorMessage($code, $data = '') {
        $errorMessages = [
            10000 => '服务出错,请稍后再试',
            10001 => '参数错误,请确认',
            10008 => '账号被锁定,请联系管理员确认',
            10011 => '余额不足,请尽快充值',
            10100 => '签名校验失败',
            10101 => '您的ip不在白名单内,请确认',
            10102 => '密码错误,请确认',
            10200 => '产品sp_id必须填写',
            10201 => '手机号必须填写',
            10202 => '短信内容必须填写',
            10203 => '发送时间格式必须为UNIX时间戳',
            10208 => '短信进拦截,具体原因参考data字段',
            10209 => '触发防刷,请调整配置'
        ];
        
        $dataMessages = [
            'WL:MBLJ' => '短信内容匹配到了模板,并且此模板类型是拦截',
            'WL:MBSH' => '命中审核模板',
            'WL:NMLJ' => '短信内容没有匹配到模板,并且用户的模板审核方式是未匹配到就进拦截',
            'WL:NMSH' => '短信内容没有匹配到模板,并且用户的模板审核方式是未匹配到就进审核',
            'WL:KHLJ' => '命中空号,进拦截',
            'WL:QHLJ' => '命中用户签名黑名单,进拦截',
            'WL:SHLJ' => '命中用户SPID黑名单,进拦截',
            'WL:CHLJ' => '命中系统产品黑名单,进拦截',
            'WL:CWHM' => '错误号码',
            'WL:QWBB' => '签名未报备,进拦截',
            'WL:MQM' => '需要签名但没有,进拦截',
            'WL:CS' => '超过限速了',
            'WL:ZJLJ' => '不匹配任何模板,直接拦截',
            'WL:CMT' => '产品未配置相应通道,进拦截',
            'WL:CDQC' => '通道不支持该地区发送,进拦截',
            'WL:CGMT' => '产品通道池中没有相应通道,进拦截',
            'WL:CNH' => '所选的通道不健康,进拦截',
            'WL:TCLJ' => '不在发送时间段,进拦截',
            'WL:TCSH' => '不在发送时间段,进审核',
            'WL:CPL' => '超频限制'
        ];
        
        $message = isset($errorMessages[$code]) ? $errorMessages[$code] : "未知错误 (代码: {$code})";
        
        // 如果是拦截错误,添加详细原因
        if ($code == 10208 && !empty($data) && isset($dataMessages[$data])) {
            $message .= ': ' . $dataMessages[$data];
        }
        
        return $message;
    }
}
 
// ==================== 使用示例 ====================
 
// 创建短信实例
$sms = new InternationalSMS();
 
// 示例1:发送验证码短信
$mobile = '639257890123'; // 国际手机号(菲律宾示例)
$verificationCode = rand(1000, 9999); // 生成随机验证码
$message = "Your verification code is {$verificationCode}. Please use it within 10 minutes.";
 
$result = $sms->sendVerificationCode($mobile, $message);
 
if ($result['success']) {
    echo "短信发送成功!消息ID: " . $result['msg_id'] . "\n";
    // 这里应该将msg_id保存到数据库,与用户关联
} else {
    echo "短信发送失败: " . $result['message'] . "\n";
}
 
// 示例2:获取状态报告
// $reportResult = $sms->getReport();
// if ($reportResult['success']) {
//     echo "获取到 " . count($reportResult['reports']) . " 条状态报告\n";
//     foreach ($reportResult['reports'] as $report) {
//         echo "手机号: {$report['mobile']}, 状态: {$report['status']}, 时间: {$report['time']}\n";
//     }
// } else {
//     echo "获取状态报告失败: " . $reportResult['message'] . "\n";
// }
 
?>

879ed07f213c41f4b933b963d5cdd3bb

四、使用说明

  1. 配置参数
    • 将$sp_id替换为您的实际 SP_ID
    • 将$raw_password替换为您的原始密码
  2. 发送短信
    • 调用sendVerificationCode方法,传入国际手机号和短信内容
    • 国际手机号格式:国家代码 + 号码(如菲律宾:639257890123)
  3. 获取状态报告
    • 调用getReport方法获取短信发送状态
  4. 错误处理
    • 代码已包含完整的错误码解析功能
    • 发送失败时会返回详细的错误信息

五、注意事项

  • 确保服务器已开启 cURL 扩展
  • 国际手机号不需要添加 "+" 前缀
  • 每条短信的状态报告只能获取一次,获取后需要本地存储

这个 Demo 提供了完整的功能实现和错误处理,下载后只需替换配置参数即可使用。