diff --git a/src/controller/mod.rs b/src/controller/mod.rs
index 146d98d9d20190b7254b0ca6bc52211b79225459..4aad5143f0c71fff7c9ca9defa9a8f9511e2a138 100644
--- a/src/controller/mod.rs
+++ b/src/controller/mod.rs
@@ -12,7 +12,8 @@ pub fn route_stage() -> AdHoc {
                     product::create,
                     product::list,
                     product::read,
-                    product::delete
+                    product::delete,
+                    product::publish,
                 ],
             )
             .mount(
diff --git a/src/controller/product.rs b/src/controller/product.rs
index 1cc538419d9a5a7f6b73e520417c04426fefbb3b..0855a6c6aa21a964fb2d6165614effc5d073e1aa 100644
--- a/src/controller/product.rs
+++ b/src/controller/product.rs
@@ -1,16 +1,15 @@
 use rocket::response::status::Created;
 use rocket::serde::json::Json;
 
-use bambangshop::Result;
 use crate::model::product::Product;
 use crate::service::product::ProductService;
-
+use bambangshop::Result;
 
 #[post("/", data = "<product>")]
 pub fn create(product: Json<Product>) -> Result<Created<Json<Product>>> {
     return match ProductService::create(product.into_inner()) {
         Ok(f) => Ok(Created::new("/").body(Json::from(f))),
-        Err(e) => Err(e)
+        Err(e) => Err(e),
     };
 }
 
@@ -18,7 +17,7 @@ pub fn create(product: Json<Product>) -> Result<Created<Json<Product>>> {
 pub fn list() -> Result<Json<Vec<Product>>> {
     return match ProductService::list() {
         Ok(f) => Ok(Json::from(f)),
-        Err(e) => Err(e)
+        Err(e) => Err(e),
     };
 }
 
@@ -26,7 +25,7 @@ pub fn list() -> Result<Json<Vec<Product>>> {
 pub fn read(id: usize) -> Result<Json<Product>> {
     return match ProductService::read(id) {
         Ok(f) => Ok(Json::from(f)),
-        Err(e) => Err(e)
+        Err(e) => Err(e),
     };
 }
 
@@ -34,6 +33,14 @@ pub fn read(id: usize) -> Result<Json<Product>> {
 pub fn delete(id: usize) -> Result<Json<Product>> {
     return match ProductService::delete(id) {
         Ok(f) => Ok(Json::from(f)),
-        Err(e) => Err(e)
+        Err(e) => Err(e),
+    };
+}
+
+#[post("/<id>/publish")]
+pub fn publish(id: usize) -> Result<Json<Product>> {
+    return match ProductService::publish(id) {
+        Ok(f) => Ok(Json::from(f)),
+        Err(e) => Err(e),
     };
 }
diff --git a/src/service/product.rs b/src/service/product.rs
index 775bf09d1d171391547c61071a0f17c976131036..d4dff9aedf03e3f1d58878826eed8158fbe39f8e 100644
--- a/src/service/product.rs
+++ b/src/service/product.rs
@@ -1,9 +1,9 @@
-use rocket::http::Status;
-use rocket::serde::json::Json;
-
-use bambangshop::{Result, compose_error_response};
 use crate::model::product::Product;
 use crate::repository::product::ProductRepository;
+use crate::service::notification::NotificationService;
+use bambangshop::{compose_error_response, Result};
+use rocket::http::Status;
+use rocket::serde::json::Json;
 
 pub struct ProductService;
 
@@ -24,7 +24,7 @@ impl ProductService {
         if product_opt.is_none() {
             return Err(compose_error_response(
                 Status::NotFound,
-                String::from("Product not found.")
+                String::from("Product not found."),
             ));
         }
         return Ok(product_opt.unwrap());
@@ -35,11 +35,25 @@ impl ProductService {
         if product_opt.is_none() {
             return Err(compose_error_response(
                 Status::NotFound,
-                String::from("Product not found.")
+                String::from("Product not found."),
             ));
         }
         let product: Product = product_opt.unwrap();
 
         return Ok(Json::from(product));
     }
+
+    pub fn publish(id: usize) -> Result<Product> {
+        let product_opt: Option<Product> = ProductRepository::get_by_id(id);
+        if product_opt.is_none() {
+            return Err(compose_error_response(
+                Status::NotFound,
+                String::from("Product not found."),
+            ));
+        }
+        let product: Product = product_opt.unwrap();
+
+        NotificationService.notify(&product.product_type, "PROMOTION", product.clone());
+        return Ok(product);
+    }
 }