diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8462f08a..91c9af7e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## unreleased
 
+### Added
+
+- `HasPayload::with_payload_mut` function ([#189][pr189])
+
+[pr189]: https://github.com/teloxide/teloxide-core/pull/189
+
 ## 0.4.3 - 2022-03-08
 
 ### Added
diff --git a/src/requests/has_payload.rs b/src/requests/has_payload.rs
index 870bc50c..d7d12100 100644
--- a/src/requests/has_payload.rs
+++ b/src/requests/has_payload.rs
@@ -28,6 +28,16 @@ pub trait HasPayload {
 
     /// Gain immutable access to the underlying payload.
     fn payload_ref(&self) -> &Self::Payload;
+
+    /// Update payload with a function
+    fn with_payload_mut<F>(mut self, f: F) -> Self
+    where
+        Self: Sized,
+        F: FnOnce(&mut Self::Payload),
+    {
+        f(self.payload_mut());
+        self
+    }
 }
 
 impl<P> HasPayload for P