diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/montnets/config/MontnetsConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/montnets/config/MontnetsConfig.java
new file mode 100644
index 00000000..068a30a2
--- /dev/null
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/montnets/config/MontnetsConfig.java
@@ -0,0 +1,41 @@
+package org.dromara.sms4j.montnets.config;
+
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.dromara.sms4j.comm.constant.SupplierConstant;
+import org.dromara.sms4j.provider.config.BaseConfig;
+
+/**
+ * @author SU
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class MontnetsConfig extends BaseConfig {
+
+ /**
+ * 请求地址
+ */
+ private String url;
+ /**
+ * 接口名称
+ */
+ private String api;
+ /**
+ * 模板code
+ */
+ private String templateId;
+ /**
+ * 模板变量名称
+ */
+ private String templateParam;
+
+ /**
+ * 获取供应商
+ */
+ @Override
+ public String getSupplier() {
+ return SupplierConstant.MONTNETS;
+ }
+
+}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/montnets/config/MontnetsFactory.java b/sms4j-provider/src/main/java/org/dromara/sms4j/montnets/config/MontnetsFactory.java
new file mode 100644
index 00000000..1d7708ab
--- /dev/null
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/montnets/config/MontnetsFactory.java
@@ -0,0 +1,48 @@
+package org.dromara.sms4j.montnets.config;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.dromara.sms4j.comm.constant.SupplierConstant;
+import org.dromara.sms4j.montnets.service.MontnetsSmsImpl;
+import org.dromara.sms4j.provider.factory.AbstractProviderFactory;
+
+
+/**
+ * MontnetsSmsConfig
+ *
梦网对象建造者
+ *
+ * @author :SU
+ * 2025/4/23 10:32
+ **/
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class MontnetsFactory extends AbstractProviderFactory {
+
+ private static final MontnetsFactory INSTANCE = new MontnetsFactory();
+
+ /**
+ * 获取建造者实例
+ * @return 建造者实例
+ */
+ public static MontnetsFactory instance() {
+ return INSTANCE;
+ }
+
+ /**
+ * 创建短信实现对象
+ * @param montnetsConfig 短信配置对象
+ * @return 短信实现对象
+ */
+ @Override
+ public MontnetsSmsImpl createSms(MontnetsConfig montnetsConfig) {
+ return new MontnetsSmsImpl(montnetsConfig);
+ }
+
+ /**
+ * 获取供应商
+ * @return 供应商
+ */
+ @Override
+ public String getSupplier() {
+ return SupplierConstant.MONTNETS;
+ }
+}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/montnets/service/MontnetsSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/montnets/service/MontnetsSmsImpl.java
new file mode 100644
index 00000000..2f067996
--- /dev/null
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/montnets/service/MontnetsSmsImpl.java
@@ -0,0 +1,152 @@
+package org.dromara.sms4j.montnets.service;
+
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.net.URLDecoder;
+import cn.hutool.core.net.URLEncodeUtil;
+import cn.hutool.json.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.sms4j.api.entity.SmsResponse;
+import org.dromara.sms4j.api.utils.SmsRespUtils;
+import org.dromara.sms4j.comm.constant.Constant;
+import org.dromara.sms4j.comm.constant.SupplierConstant;
+import org.dromara.sms4j.comm.delayedTime.DelayedTime;
+import org.dromara.sms4j.comm.exception.SmsBlendException;
+import org.dromara.sms4j.comm.utils.SmsUtils;
+import org.dromara.sms4j.montnets.config.MontnetsConfig;
+import org.dromara.sms4j.montnets.utils.MontnetsUtils;
+import org.dromara.sms4j.provider.service.AbstractSmsBlend;
+
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+import java.util.concurrent.Executor;
+
+/**
+ * 类名: MontnetsSmsImpl
+ *
说明: 梦网短信实现
+ *
+ * @author :SU
+ * 2025/4/23 10:32
+ **/
+@Slf4j
+public class MontnetsSmsImpl extends AbstractSmsBlend {
+
+ private int retry = 0;
+
+ /**
+ * MontnetsSmsImpl
+ * 构造器,用于构造短信实现模块
+ */
+ public MontnetsSmsImpl(MontnetsConfig config, Executor pool, DelayedTime delayedTime) {
+ super(config, pool, delayedTime);
+ }
+
+ /**
+ * MontnetsSmsImpl
+ *
构造器,用于构造短信实现模块
+ */
+ public MontnetsSmsImpl(MontnetsConfig config) {
+ super(config);
+ }
+
+ @Override
+ public String getSupplier() {
+ return SupplierConstant.MONTNETS;
+ }
+
+ @Override
+ public SmsResponse sendMessage(String phone, String message) {
+ LinkedHashMap map = new LinkedHashMap<>(1);
+ map.put(getConfig().getTemplateParam(), message);
+ return sendMessage(phone, this.getConfig().getTemplateId(), map);
+ }
+
+ @Override
+ public SmsResponse sendMessage(String phone, LinkedHashMap messages) {
+ if (Objects.isNull(messages)) {
+ messages = new LinkedHashMap<>();
+ }
+ return sendMessage(phone, getConfig().getTemplateId(), messages);
+ }
+
+ @Override
+ public SmsResponse sendMessage(String phone, String templateId, LinkedHashMap messages) {
+ if (Objects.isNull(messages)) {
+ messages = new LinkedHashMap<>();
+ }
+ String messageStr = formatMessage(messages);
+ return getSmsResponse(phone, messageStr, templateId);
+ }
+
+
+ @Override
+ public SmsResponse massTexting(List phones, String message) {
+ LinkedHashMap map = new LinkedHashMap<>();
+ map.put(getConfig().getTemplateParam(), message);
+ return massTexting(phones, getConfig().getTemplateId(), map);
+ }
+
+
+ @Override
+ public SmsResponse massTexting(List phones, String templateId, LinkedHashMap messages) {
+ if (Objects.isNull(messages)) {
+ messages = new LinkedHashMap<>();
+ }
+ String messageStr = formatMessage(messages);
+ return getSmsResponse(SmsUtils.addCodePrefixIfNot(phones), messageStr, templateId);
+ }
+
+ private SmsResponse getSmsResponse(String phone, String message, String templateId) {
+ String requestUrl;
+ String paramStr;
+ try {
+ requestUrl = MontnetsUtils.generateSendSmsRequestUrl(this.getConfig());
+ paramStr = MontnetsUtils.generateParamBody(this.getConfig(), phone, message, templateId);
+ } catch (Exception e) {
+ log.error("montnets send message error", e);
+ throw new SmsBlendException(e.getMessage());
+ }
+
+ log.debug("requestUrl {}", requestUrl);
+ Map headers = MapUtil.newHashMap(1, true);
+ headers.put(Constant.CONTENT_TYPE, Constant.APPLICATION_JSON_UTF8);
+
+ SmsResponse smsResponse;
+ try {
+ smsResponse = this.getResponse(this.http.postJson(requestUrl, headers, paramStr));
+ } catch (SmsBlendException e) {
+ smsResponse = this.errorResp(e.message);
+ }
+
+ if (!smsResponse.isSuccess() && this.retry != this.getConfig().getMaxRetries()) {
+ return this.requestRetry(phone, message, templateId);
+ } else {
+ this.retry = 0;
+ return smsResponse;
+ }
+ }
+
+ private SmsResponse requestRetry(String phone, String message, String templateId) {
+ this.http.safeSleep(this.getConfig().getRetryInterval());
+ ++this.retry;
+ log.warn("短信第 {} 次重新发送", this.retry);
+ return this.getSmsResponse(phone, message, templateId);
+ }
+
+ private SmsResponse getResponse(JSONObject resJson) {
+ return SmsRespUtils.resp(URLDecoder.decode(resJson.getStr("desc"), StandardCharsets.UTF_8), "0".equals(resJson.getStr("result")), getConfigId());
+ }
+
+ /**
+ * 说明:格式化消息
+ *
+ * @param messages 模板参数key-value集合
+ * @return 格式化后的消息 key1=urlEncode(value1)&key2=urlEncode(value2)
+ */
+ private String formatMessage(LinkedHashMap messages) {
+ StringJoiner joiner = new StringJoiner("&");
+ for (Map.Entry entry : messages.entrySet()) {
+ joiner.add(entry.getKey() + "=" + URLEncodeUtil.encode(entry.getValue(), StandardCharsets.UTF_8));
+ }
+ return URLEncodeUtil.encode(joiner.toString());
+ }
+}
diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/montnets/utils/MontnetsUtils.java b/sms4j-provider/src/main/java/org/dromara/sms4j/montnets/utils/MontnetsUtils.java
new file mode 100644
index 00000000..8e8d3930
--- /dev/null
+++ b/sms4j-provider/src/main/java/org/dromara/sms4j/montnets/utils/MontnetsUtils.java
@@ -0,0 +1,62 @@
+package org.dromara.sms4j.montnets.utils;
+
+import cn.hutool.crypto.digest.DigestUtil;
+import cn.hutool.json.JSONUtil;
+import org.dromara.sms4j.comm.utils.SmsDateUtils;
+import org.dromara.sms4j.montnets.config.MontnetsConfig;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * @author SU
+ * 2025/4/23 10:32
+ */
+public class MontnetsUtils {
+
+ public static String generateSendSmsRequestUrl(MontnetsConfig montnetsConfig) {
+ String url = montnetsConfig.getUrl();
+ String api = montnetsConfig.getApi();
+ return url + api;
+ }
+
+ /**
+ * 生成请求body参数
+ *
+ * @param montnetsConfig 短信配置
+ * @param phone 手机号
+ * @param message 短信内容
+ * @param templateId 模板ID
+ */
+ public static Map generateParamMap(MontnetsConfig montnetsConfig, String phone, String message, String templateId) {
+ Map paramMap = new HashMap<>();
+
+ String accessKeyId = montnetsConfig.getAccessKeyId();
+ String accessKeySecret = montnetsConfig.getAccessKeySecret();
+ String timeStamp = SmsDateUtils.formatDateToStr(new Date(), "MMddHHmmss", SmsDateUtils.gmt8());
+
+ paramMap.put("userid", accessKeyId);
+ paramMap.put("pwd", DigestUtil.md5Hex(accessKeyId.toUpperCase(Locale.ENGLISH) + "00000000" + accessKeySecret + timeStamp));
+ paramMap.put("timestamp", timeStamp);
+ paramMap.put("mobile", phone);
+ paramMap.put("content", message);
+ paramMap.put("tmplid", templateId);
+
+ return paramMap;
+ }
+
+ /**
+ * 生成请求参数body字符串
+ *
+ * @param montnetsConfig 短信配置
+ * @param phone 手机号
+ * @param message 短信内容
+ * @param templateId 模板ID
+ */
+ public static String generateParamBody(MontnetsConfig montnetsConfig, String phone, String message, String templateId) {
+ Map paramMap = generateParamMap(montnetsConfig, phone, message, templateId);
+ return JSONUtil.toJsonStr(paramMap);
+ }
+}
\ No newline at end of file