This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 8cb56be3a4c4 CAMEL-22814: Support for Telegram Bot Payments API 
(#20695)
8cb56be3a4c4 is described below

commit 8cb56be3a4c4ee9bcdd1c767b6e28e3dd8800b8e
Author: Kirill Byvshev <[email protected]>
AuthorDate: Tue Jan 6 22:40:47 2026 +0400

    CAMEL-22814: Support for Telegram Bot Payments API (#20695)
---
 .../src/main/docs/telegram-component.adoc          |   4 +
 .../{TelegramService.java => TelegramMessage.java} |  18 +-
 .../camel/component/telegram/TelegramProducer.java |  40 ++-
 .../camel/component/telegram/TelegramService.java  |  10 +-
 .../component/telegram/model/IncomingMessage.java  |  13 +
 .../telegram/model/InlineKeyboardButton.java       |  32 +-
 .../telegram/model/MessageResultString.java        |  48 +++
 .../component/telegram/model/OutgoingMessage.java  |   9 +-
 .../camel/component/telegram/model/Update.java     |  26 ++
 .../payments/AnswerPreCheckoutQueryMessage.java    |  89 +++++
 .../model/payments/AnswerShippingQueryMessage.java | 105 ++++++
 .../model/payments/CreateInvoiceLinkMessage.java   | 308 +++++++++++++++++
 .../telegram/model/payments/LabeledPrice.java      |  70 ++++
 .../telegram/model/payments/OrderInfo.java         |  99 ++++++
 .../telegram/model/payments/PreCheckoutQuery.java  | 125 +++++++
 .../model/payments/SendInvoiceMessage.java         | 368 +++++++++++++++++++++
 .../telegram/model/payments/ShippingAddress.java   | 127 +++++++
 .../telegram/model/payments/ShippingOption.java    |  82 +++++
 .../telegram/model/payments/ShippingQuery.java     |  90 +++++
 .../telegram/model/payments/SuccessfulPayment.java | 181 ++++++++++
 .../telegram/service/OutgoingMessageHandler.java   |  89 +----
 .../TelegramApiClient.java}                        |  21 +-
 .../telegram/service/TelegramHandlerRegistry.java  |  95 ++++++
 ...ageHandler.java => TelegramMessageHandler.java} |  28 +-
 .../service/TelegramServiceRestBotAPIAdapter.java  | 134 +++-----
 .../telegram/util/TelegramMessageHelper.java       |   4 +
 .../TelegramConsumerPreCheckoutQueryTest.java      |  81 +++++
 .../TelegramConsumerShippingQueryTest.java         |  89 +++++
 .../TelegramConsumerSuccessfulPaymentTest.java     | 102 ++++++
 .../telegram/TelegramProducerInvoiceTest.java      | 250 ++++++++++++++
 .../messages/answer-pre-checkout-query.json        |   4 +
 .../resources/messages/answer-shipping-query.json  |   4 +
 .../resources/messages/create-invoice-link.json    |   4 +
 .../src/test/resources/messages/send-invoice.json  |  26 ++
 .../messages/updates-pre-checkout-query.json       |  19 ++
 .../resources/messages/updates-shipping-query.json |  25 ++
 .../messages/updates-successful-payment.json       |  44 +++
 37 files changed, 2618 insertions(+), 245 deletions(-)

diff --git a/components/camel-telegram/src/main/docs/telegram-component.adoc 
b/components/camel-telegram/src/main/docs/telegram-component.adoc
index 761f25da8d57..0629c6ac0ab4 100644
--- a/components/camel-telegram/src/main/docs/telegram-component.adoc
+++ b/components/camel-telegram/src/main/docs/telegram-component.adoc
@@ -110,6 +110,10 @@ The following message bodies are allowed for a producer 
endpoint (messages of ty
 | `EditMessageLiveLocationMessage` | To send changes to a live location 
(editMessageLiveLocation)
 | `StopMessageLiveLocationMessage` | To stop updating a live location message 
sent by the bot or via the bot (for inline bots) before live_period expires 
(stopMessageLiveLocation)
 | `SendVenueMessage` | To send information about a venue (sendVenue)
+| `SendInvoiceMessage` | To send an invoice for payment (sendInvoice)
+| `CreateInvoiceLinkMessage` | To create a link for an invoice 
(createInvoiceLink)
+| `AnswerShippingQueryMessage` | To reply to shipping queries 
(answerShippingQuery)
+| `AnswerPreCheckoutQueryMessage` | To respond to a pre-checkout query from a 
payment (answerPreCheckoutQuery)
 | `byte[]` | To send any media type supported. It requires the 
`CamelTelegramMediaType` header to be set to the appropriate media type
 | `String` | To send a text message to a chat. It gets converted automatically 
into a `OutgoingTextMessage`
 
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/TelegramService.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/TelegramMessage.java
similarity index 61%
copy from 
components/camel-telegram/src/main/java/org/apache/camel/component/telegram/TelegramService.java
copy to 
components/camel-telegram/src/main/java/org/apache/camel/component/telegram/TelegramMessage.java
index 0a6d59abd242..0b2235cfbb76 100644
--- 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/TelegramService.java
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/TelegramMessage.java
@@ -16,22 +16,10 @@
  */
 package org.apache.camel.component.telegram;
 
-import org.apache.camel.AsyncCallback;
-import org.apache.camel.Exchange;
-import org.apache.camel.component.telegram.model.OutgoingMessage;
-import org.apache.camel.component.telegram.model.UpdateResult;
+import java.io.Serializable;
 
 /**
- * Allows interacting with the Telegram server to exchange messages.
+ * Marker interface for all supported Telegram message types that can be sent 
via the Telegram Bot API.
  */
-public interface TelegramService {
-
-    UpdateResult getUpdates(Long offset, Integer limit, Integer 
timeoutSeconds);
-
-    void sendMessage(Exchange exchange, AsyncCallback callback, 
OutgoingMessage message);
-
-    boolean setWebhook(String url);
-
-    boolean removeWebhook();
-
+public interface TelegramMessage extends Serializable {
 }
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/TelegramProducer.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/TelegramProducer.java
index cd6c7e36c89a..4fd0dc0fe476 100644
--- 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/TelegramProducer.java
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/TelegramProducer.java
@@ -40,32 +40,42 @@ public class TelegramProducer extends DefaultAsyncProducer {
 
     @Override
     public boolean process(Exchange exchange, AsyncCallback callback) {
+        final Object body = exchange.getIn().getBody();
 
-        if (exchange.getIn().getBody() == null) {
+        if (body == null) {
             // fail fast
             LOG.debug("Received exchange with empty body, skipping");
             callback.done(true);
             return true;
         }
 
-        TelegramConfiguration config = endpoint.getConfiguration();
-
-        // Tries to get a message in its OutgoingMessage format
-        // Automatic conversion applies here
-        OutgoingMessage message = 
exchange.getIn().getBody(OutgoingMessage.class);
-        if (message == null) {
-            throw new IllegalArgumentException("Cannot convert the content to 
a Telegram OutgoingMessage");
-        }
-
-        if (message.getChatId() == null) {
-            LOG.debug("Chat id is null on outgoing message, trying 
resolution");
-            String chatId = resolveChatId(config, message, exchange);
-            LOG.debug("Resolved chat id is {}", chatId);
-            message.setChatId(chatId);
+        if (body instanceof TelegramMessage telegramMessage) {
+            // The body is a supported Telegram message; send it as is
+            return sendMessage(exchange, callback, telegramMessage);
+        } else {
+            // Tries to get a message in its OutgoingMessage format
+            // Automatic conversion applies here
+            OutgoingMessage message = 
exchange.getIn().getBody(OutgoingMessage.class);
+            if (message == null) {
+                throw new IllegalArgumentException("Cannot convert the content 
to a Telegram OutgoingMessage");
+            }
+            return sendMessage(exchange, callback, message);
         }
+    }
 
+    private boolean sendMessage(Exchange exchange, AsyncCallback callback, 
TelegramMessage message) {
         final TelegramService service = endpoint.getTelegramService();
 
+        if (message instanceof OutgoingMessage outgoingMessage) {
+            if (outgoingMessage.getChatId() == null) {
+                TelegramConfiguration config = endpoint.getConfiguration();
+                LOG.debug("Chat id is null on outgoing message, trying 
resolution");
+                String chatId = resolveChatId(config, outgoingMessage, 
exchange);
+                LOG.debug("Resolved chat id is {}", chatId);
+                outgoingMessage.setChatId(chatId);
+            }
+        }
+
         LOG.debug("Message being sent is: {}", message);
         LOG.debug("Headers of message being sent are: {}", 
exchange.getIn().getHeaders());
 
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/TelegramService.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/TelegramService.java
index 0a6d59abd242..387c4c773156 100644
--- 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/TelegramService.java
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/TelegramService.java
@@ -18,7 +18,6 @@ package org.apache.camel.component.telegram;
 
 import org.apache.camel.AsyncCallback;
 import org.apache.camel.Exchange;
-import org.apache.camel.component.telegram.model.OutgoingMessage;
 import org.apache.camel.component.telegram.model.UpdateResult;
 
 /**
@@ -28,7 +27,14 @@ public interface TelegramService {
 
     UpdateResult getUpdates(Long offset, Integer limit, Integer 
timeoutSeconds);
 
-    void sendMessage(Exchange exchange, AsyncCallback callback, 
OutgoingMessage message);
+    /**
+     * Sends a message to Telegram.
+     *
+     * @param exchange the exchange
+     * @param callback the async callback
+     * @param message  the message to send
+     */
+    void sendMessage(Exchange exchange, AsyncCallback callback, 
TelegramMessage message);
 
     boolean setWebhook(String url);
 
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/IncomingMessage.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/IncomingMessage.java
index 4c05a61c5946..5e9492eb79d6 100644
--- 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/IncomingMessage.java
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/IncomingMessage.java
@@ -25,6 +25,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import org.apache.camel.component.telegram.model.payments.SuccessfulPayment;
 
 /**
  * A message that is exchanged with the Telegram network.
@@ -74,6 +75,9 @@ public class IncomingMessage implements Serializable {
 
     private IncomingVoice voice;
 
+    @JsonProperty("successful_payment")
+    private SuccessfulPayment successfulPayment;
+
     public IncomingMessage() {
     }
 
@@ -213,6 +217,14 @@ public class IncomingMessage implements Serializable {
         this.voice = voice;
     }
 
+    public SuccessfulPayment getSuccessfulPayment() {
+        return successfulPayment;
+    }
+
+    public void setSuccessfulPayment(SuccessfulPayment successfulPayment) {
+        this.successfulPayment = successfulPayment;
+    }
+
     @Override
     public String toString() {
         final StringBuilder sb = new StringBuilder("IncomingMessage{");
@@ -233,6 +245,7 @@ public class IncomingMessage implements Serializable {
         sb.append(", replyMarkup=").append(replyMarkup);
         sb.append(", game=").append(game);
         sb.append(", voice=").append(voice);
+        sb.append(", successfulPayment=").append(successfulPayment);
         sb.append('}');
         return sb.toString();
     }
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/InlineKeyboardButton.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/InlineKeyboardButton.java
index 680ef66e2cc9..de748df39d0a 100644
--- 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/InlineKeyboardButton.java
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/InlineKeyboardButton.java
@@ -54,6 +54,8 @@ public class InlineKeyboardButton implements Serializable {
     @JsonProperty("request_location")
     private Boolean requestLocation;
 
+    private Boolean pay;
+
     public InlineKeyboardButton() {
 
     }
@@ -73,6 +75,12 @@ public class InlineKeyboardButton implements Serializable {
     public InlineKeyboardButton(String text, String url, LoginUrl loginUrl,
                                 String callbackData, CallbackGame callbackGame,
                                 Boolean requestContact, Boolean 
requestLocation) {
+        this(text, url, loginUrl, callbackData, callbackGame, requestContact, 
requestLocation, null);
+    }
+
+    public InlineKeyboardButton(String text, String url, LoginUrl loginUrl,
+                                String callbackData, CallbackGame callbackGame,
+                                Boolean requestContact, Boolean 
requestLocation, Boolean pay) {
         this.text = text;
         this.url = url;
         this.loginUrl = loginUrl;
@@ -80,6 +88,7 @@ public class InlineKeyboardButton implements Serializable {
         this.callbackGame = callbackGame;
         this.requestContact = requestContact;
         this.requestLocation = requestLocation;
+        this.pay = pay;
     }
 
     public String getText() {
@@ -138,6 +147,14 @@ public class InlineKeyboardButton implements Serializable {
         this.requestLocation = requestLocation;
     }
 
+    public Boolean getPay() {
+        return pay;
+    }
+
+    public void setPay(Boolean pay) {
+        this.pay = pay;
+    }
+
     public static Builder builder() {
         return new Builder();
     }
@@ -151,6 +168,7 @@ public class InlineKeyboardButton implements Serializable {
         private CallbackGame callbackGame;
         private Boolean requestContact;
         private Boolean requestLocation;
+        private Boolean pay;
 
         public Builder text(String text) {
             this.text = text;
@@ -187,8 +205,14 @@ public class InlineKeyboardButton implements Serializable {
             return this;
         }
 
+        public Builder pay(Boolean pay) {
+            this.pay = pay;
+            return this;
+        }
+
         public InlineKeyboardButton build() {
-            return new InlineKeyboardButton(text, url, loginUrl, callbackData, 
callbackGame, requestContact, requestLocation);
+            return new InlineKeyboardButton(
+                    text, url, loginUrl, callbackData, callbackGame, 
requestContact, requestLocation, pay);
         }
     }
 
@@ -202,6 +226,7 @@ public class InlineKeyboardButton implements Serializable {
         sb.append(", callbackGame=").append(callbackGame);
         sb.append(", requestContact=").append(requestContact);
         sb.append(", requestLocation=").append(requestLocation);
+        sb.append(", pay=").append(pay);
         sb.append('}');
         return sb.toString();
     }
@@ -221,11 +246,12 @@ public class InlineKeyboardButton implements Serializable 
{
                 && Objects.equals(callbackData, that.callbackData)
                 && Objects.equals(callbackGame, that.callbackGame)
                 && Objects.equals(requestContact, that.requestContact)
-                && Objects.equals(requestLocation, that.requestLocation);
+                && Objects.equals(requestLocation, that.requestLocation)
+                && Objects.equals(pay, that.pay);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(text, url, loginUrl, callbackData, callbackGame, 
requestContact, requestLocation);
+        return Objects.hash(text, url, loginUrl, callbackData, callbackGame, 
requestContact, requestLocation, pay);
     }
 }
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/MessageResultString.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/MessageResultString.java
new file mode 100644
index 000000000000..2230268354b4
--- /dev/null
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/MessageResultString.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.telegram.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class MessageResultString extends MessageResult {
+
+    @JsonProperty("result")
+    private String result;
+
+    public MessageResultString() {
+    }
+
+    public String getResult() {
+        return result;
+    }
+
+    @JsonSetter("result")
+    public void setResult(String result) {
+        this.result = result;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("MessageResultString{");
+        sb.append("result='").append(result).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/OutgoingMessage.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/OutgoingMessage.java
index 094218ca300c..76f905d6f88b 100644
--- 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/OutgoingMessage.java
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/OutgoingMessage.java
@@ -16,16 +16,17 @@
  */
 package org.apache.camel.component.telegram.model;
 
-import java.io.Serializable;
-
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.camel.component.telegram.TelegramMessage;
 
 /**
- * The superclass of all outgoing messages.
+ * Abstract base class for outgoing messages that require a chat ID.
+ *
+ * @see TelegramMessage
  */
 @JsonInclude(JsonInclude.Include.NON_NULL)
-public abstract class OutgoingMessage implements Serializable {
+public abstract class OutgoingMessage implements TelegramMessage {
 
     private static final long serialVersionUID = -5958829164103569292L;
 
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/Update.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/Update.java
index 8fde75be4736..ae1f016fc259 100644
--- 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/Update.java
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/Update.java
@@ -20,6 +20,8 @@ import java.io.Serializable;
 
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.camel.component.telegram.model.payments.PreCheckoutQuery;
+import org.apache.camel.component.telegram.model.payments.ShippingQuery;
 
 /**
  * Represents an update with reference to the previous state.
@@ -43,6 +45,12 @@ public class Update implements Serializable {
     @JsonProperty("inline_query")
     private IncomingInlineQuery inlineQuery;
 
+    @JsonProperty("pre_checkout_query")
+    private PreCheckoutQuery preCheckoutQuery;
+
+    @JsonProperty("shipping_query")
+    private ShippingQuery shippingQuery;
+
     public Update() {
     }
 
@@ -86,6 +94,22 @@ public class Update implements Serializable {
         this.inlineQuery = incomingInlineQuery;
     }
 
+    public PreCheckoutQuery getPreCheckoutQuery() {
+        return preCheckoutQuery;
+    }
+
+    public void setPreCheckoutQuery(PreCheckoutQuery preCheckoutQuery) {
+        this.preCheckoutQuery = preCheckoutQuery;
+    }
+
+    public ShippingQuery getShippingQuery() {
+        return shippingQuery;
+    }
+
+    public void setShippingQuery(ShippingQuery shippingQuery) {
+        this.shippingQuery = shippingQuery;
+    }
+
     @Override
     public String toString() {
         final StringBuilder sb = new StringBuilder("Update{");
@@ -94,6 +118,8 @@ public class Update implements Serializable {
         sb.append(", channel_post=").append(channelpost);
         sb.append(", callbackQuery=").append(callbackQuery);
         sb.append(", inlineQuery=").append(inlineQuery);
+        sb.append(", preCheckoutQuery=").append(preCheckoutQuery);
+        sb.append(", shippingQuery=").append(shippingQuery);
         sb.append('}');
         return sb.toString();
     }
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/AnswerPreCheckoutQueryMessage.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/AnswerPreCheckoutQueryMessage.java
new file mode 100644
index 000000000000..99247fcebbec
--- /dev/null
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/AnswerPreCheckoutQueryMessage.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.component.telegram.model.payments;
+
+import java.io.Serial;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.camel.component.telegram.TelegramMessage;
+
+/**
+ * Use this method to respond to the pre-checkout queries. Note: The Bot API 
must receive an answer within 10 seconds
+ * after the pre-checkout query was sent.
+ *
+ * @see <a href=
+ *      
"https://core.telegram.org/bots/api#answerprecheckoutquery";>https://core.telegram.org/bots/api#answerprecheckoutquery</a>
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class AnswerPreCheckoutQueryMessage implements TelegramMessage {
+
+    @Serial
+    private static final long serialVersionUID = -3641680219624856747L;
+
+    @JsonProperty("pre_checkout_query_id")
+    private String preCheckoutQueryId;
+
+    private Boolean ok;
+
+    @JsonProperty("error_message")
+    private String errorMessage;
+
+    public AnswerPreCheckoutQueryMessage(String preCheckoutQueryId, Boolean 
ok, String errorMessage) {
+        this.preCheckoutQueryId = preCheckoutQueryId;
+        this.ok = ok;
+        this.errorMessage = errorMessage;
+    }
+
+    public AnswerPreCheckoutQueryMessage() {
+    }
+
+    public String getPreCheckoutQueryId() {
+        return preCheckoutQueryId;
+    }
+
+    public void setPreCheckoutQueryId(String preCheckoutQueryId) {
+        this.preCheckoutQueryId = preCheckoutQueryId;
+    }
+
+    public Boolean getOk() {
+        return ok;
+    }
+
+    public void setOk(Boolean ok) {
+        this.ok = ok;
+    }
+
+    public String getErrorMessage() {
+        return errorMessage;
+    }
+
+    public void setErrorMessage(String errorMessage) {
+        this.errorMessage = errorMessage;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new 
StringBuilder("AnswerPreCheckoutQueryMessage{");
+        
sb.append("preCheckoutQueryId='").append(preCheckoutQueryId).append('\'');
+        sb.append(", ok=").append(ok);
+        sb.append(", errorMessage='").append(errorMessage).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/AnswerShippingQueryMessage.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/AnswerShippingQueryMessage.java
new file mode 100644
index 000000000000..4a8e5587f8ad
--- /dev/null
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/AnswerShippingQueryMessage.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.component.telegram.model.payments;
+
+import java.io.Serial;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.camel.component.telegram.TelegramMessage;
+
+/**
+ * If you sent an invoice requesting a shipping address and the parameter 
is_flexible was specified, the Bot API will
+ * send an Update with a shipping_query field to the bot. Use this method to 
reply to shipping queries. On success, True
+ * is returned.
+ *
+ * @see <a href=
+ *      
"https://core.telegram.org/bots/api#answershippingquery";>https://core.telegram.org/bots/api#answershippingquery</a>
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class AnswerShippingQueryMessage implements TelegramMessage {
+
+    @Serial
+    private static final long serialVersionUID = 2895708820216636657L;
+
+    @JsonProperty("shipping_query_id")
+    private String shippingQueryId;
+
+    private Boolean ok;
+
+    @JsonProperty("shipping_options")
+    private List<ShippingOption> shippingOptions;
+
+    @JsonProperty("error_message")
+    private String errorMessage;
+
+    public AnswerShippingQueryMessage(String shippingQueryId, Boolean ok, 
List<ShippingOption> shippingOptions,
+                                      String errorMessage) {
+        this.shippingQueryId = shippingQueryId;
+        this.ok = ok;
+        this.shippingOptions = shippingOptions;
+        this.errorMessage = errorMessage;
+    }
+
+    public AnswerShippingQueryMessage() {
+    }
+
+    public String getShippingQueryId() {
+        return shippingQueryId;
+    }
+
+    public void setShippingQueryId(String shippingQueryId) {
+        this.shippingQueryId = shippingQueryId;
+    }
+
+    public Boolean getOk() {
+        return ok;
+    }
+
+    public void setOk(Boolean ok) {
+        this.ok = ok;
+    }
+
+    public List<ShippingOption> getShippingOptions() {
+        return shippingOptions;
+    }
+
+    public void setShippingOptions(List<ShippingOption> shippingOptions) {
+        this.shippingOptions = shippingOptions;
+    }
+
+    public String getErrorMessage() {
+        return errorMessage;
+    }
+
+    public void setErrorMessage(String errorMessage) {
+        this.errorMessage = errorMessage;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new 
StringBuilder("AnswerShippingQueryMessage{");
+        sb.append("shippingQueryId='").append(shippingQueryId).append('\'');
+        sb.append(", ok=").append(ok);
+        sb.append(", shippingOptions=").append(shippingOptions);
+        sb.append(", errorMessage='").append(errorMessage).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/CreateInvoiceLinkMessage.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/CreateInvoiceLinkMessage.java
new file mode 100644
index 000000000000..1a97690ae080
--- /dev/null
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/CreateInvoiceLinkMessage.java
@@ -0,0 +1,308 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.component.telegram.model.payments;
+
+import java.io.Serial;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.camel.component.telegram.TelegramMessage;
+import org.apache.camel.component.telegram.model.MessageResultString;
+
+/**
+ * Use this method to create a link for an invoice. On success, returns a 
{@link MessageResultString} object.
+ *
+ * @see <a href=
+ *      
"https://core.telegram.org/bots/api#createinvoicelink";>https://core.telegram.org/bots/api#createinvoicelink</a>
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class CreateInvoiceLinkMessage implements TelegramMessage {
+
+    @Serial
+    private static final long serialVersionUID = 8472615429183746521L;
+
+    @JsonProperty("business_connection_id")
+    private String businessConnectionId;
+
+    private String title;
+
+    private String description;
+
+    private String payload;
+
+    @JsonProperty("provider_token")
+    private String providerToken;
+
+    private String currency;
+
+    private List<LabeledPrice> prices;
+
+    @JsonProperty("subscription_period")
+    private Integer subscriptionPeriod;
+
+    @JsonProperty("max_tip_amount")
+    private Integer maxTipAmount;
+
+    @JsonProperty("suggested_tip_amounts")
+    private List<Integer> suggestedTipAmounts;
+
+    @JsonProperty("provider_data")
+    private String providerData;
+
+    @JsonProperty("photo_url")
+    private String photoUrl;
+
+    @JsonProperty("photo_size")
+    private Integer photoSize;
+
+    @JsonProperty("photo_width")
+    private Integer photoWidth;
+
+    @JsonProperty("photo_height")
+    private Integer photoHeight;
+
+    @JsonProperty("need_name")
+    private Boolean needName;
+
+    @JsonProperty("need_phone_number")
+    private Boolean needPhoneNumber;
+
+    @JsonProperty("need_email")
+    private Boolean needEmail;
+
+    @JsonProperty("need_shipping_address")
+    private Boolean needShippingAddress;
+
+    @JsonProperty("send_phone_number_to_provider")
+    private Boolean sendPhoneNumberToProvider;
+
+    @JsonProperty("send_email_to_provider")
+    private Boolean sendEmailToProvider;
+
+    @JsonProperty("is_flexible")
+    private Boolean isFlexible;
+
+    public CreateInvoiceLinkMessage() {
+    }
+
+    public String getBusinessConnectionId() {
+        return businessConnectionId;
+    }
+
+    public void setBusinessConnectionId(String businessConnectionId) {
+        this.businessConnectionId = businessConnectionId;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getPayload() {
+        return payload;
+    }
+
+    public void setPayload(String payload) {
+        this.payload = payload;
+    }
+
+    public String getProviderToken() {
+        return providerToken;
+    }
+
+    public void setProviderToken(String providerToken) {
+        this.providerToken = providerToken;
+    }
+
+    public String getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(String currency) {
+        this.currency = currency;
+    }
+
+    public List<LabeledPrice> getPrices() {
+        return prices;
+    }
+
+    public void setPrices(List<LabeledPrice> prices) {
+        this.prices = prices;
+    }
+
+    public Integer getSubscriptionPeriod() {
+        return subscriptionPeriod;
+    }
+
+    public void setSubscriptionPeriod(Integer subscriptionPeriod) {
+        this.subscriptionPeriod = subscriptionPeriod;
+    }
+
+    public Integer getMaxTipAmount() {
+        return maxTipAmount;
+    }
+
+    public void setMaxTipAmount(Integer maxTipAmount) {
+        this.maxTipAmount = maxTipAmount;
+    }
+
+    public List<Integer> getSuggestedTipAmounts() {
+        return suggestedTipAmounts;
+    }
+
+    public void setSuggestedTipAmounts(List<Integer> suggestedTipAmounts) {
+        this.suggestedTipAmounts = suggestedTipAmounts;
+    }
+
+    public String getProviderData() {
+        return providerData;
+    }
+
+    public void setProviderData(String providerData) {
+        this.providerData = providerData;
+    }
+
+    public String getPhotoUrl() {
+        return photoUrl;
+    }
+
+    public void setPhotoUrl(String photoUrl) {
+        this.photoUrl = photoUrl;
+    }
+
+    public Integer getPhotoSize() {
+        return photoSize;
+    }
+
+    public void setPhotoSize(Integer photoSize) {
+        this.photoSize = photoSize;
+    }
+
+    public Integer getPhotoWidth() {
+        return photoWidth;
+    }
+
+    public void setPhotoWidth(Integer photoWidth) {
+        this.photoWidth = photoWidth;
+    }
+
+    public Integer getPhotoHeight() {
+        return photoHeight;
+    }
+
+    public void setPhotoHeight(Integer photoHeight) {
+        this.photoHeight = photoHeight;
+    }
+
+    public Boolean getNeedName() {
+        return needName;
+    }
+
+    public void setNeedName(Boolean needName) {
+        this.needName = needName;
+    }
+
+    public Boolean getNeedPhoneNumber() {
+        return needPhoneNumber;
+    }
+
+    public void setNeedPhoneNumber(Boolean needPhoneNumber) {
+        this.needPhoneNumber = needPhoneNumber;
+    }
+
+    public Boolean getNeedEmail() {
+        return needEmail;
+    }
+
+    public void setNeedEmail(Boolean needEmail) {
+        this.needEmail = needEmail;
+    }
+
+    public Boolean getNeedShippingAddress() {
+        return needShippingAddress;
+    }
+
+    public void setNeedShippingAddress(Boolean needShippingAddress) {
+        this.needShippingAddress = needShippingAddress;
+    }
+
+    public Boolean getSendPhoneNumberToProvider() {
+        return sendPhoneNumberToProvider;
+    }
+
+    public void setSendPhoneNumberToProvider(Boolean 
sendPhoneNumberToProvider) {
+        this.sendPhoneNumberToProvider = sendPhoneNumberToProvider;
+    }
+
+    public Boolean getSendEmailToProvider() {
+        return sendEmailToProvider;
+    }
+
+    public void setSendEmailToProvider(Boolean sendEmailToProvider) {
+        this.sendEmailToProvider = sendEmailToProvider;
+    }
+
+    public Boolean getFlexible() {
+        return isFlexible;
+    }
+
+    public void setFlexible(Boolean flexible) {
+        isFlexible = flexible;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new 
StringBuilder("CreateInvoiceLinkMessage{");
+        
sb.append("businessConnectionId='").append(businessConnectionId).append('\'');
+        sb.append(", title='").append(title).append('\'');
+        sb.append(", description='").append(description).append('\'');
+        sb.append(", payload='").append(payload).append('\'');
+        sb.append(", providerToken='").append(providerToken).append('\'');
+        sb.append(", currency='").append(currency).append('\'');
+        sb.append(", prices=").append(prices);
+        sb.append(", subscriptionPeriod=").append(subscriptionPeriod);
+        sb.append(", maxTipAmount=").append(maxTipAmount);
+        sb.append(", suggestedTipAmounts=").append(suggestedTipAmounts);
+        sb.append(", providerData='").append(providerData).append('\'');
+        sb.append(", photoUrl='").append(photoUrl).append('\'');
+        sb.append(", photoSize=").append(photoSize);
+        sb.append(", photoWidth=").append(photoWidth);
+        sb.append(", photoHeight=").append(photoHeight);
+        sb.append(", needName=").append(needName);
+        sb.append(", needPhoneNumber=").append(needPhoneNumber);
+        sb.append(", needEmail=").append(needEmail);
+        sb.append(", needShippingAddress=").append(needShippingAddress);
+        sb.append(", 
sendPhoneNumberToProvider=").append(sendPhoneNumberToProvider);
+        sb.append(", sendEmailToProvider=").append(sendEmailToProvider);
+        sb.append(", isFlexible=").append(isFlexible);
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/LabeledPrice.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/LabeledPrice.java
new file mode 100644
index 000000000000..1932c63da673
--- /dev/null
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/LabeledPrice.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.component.telegram.model.payments;
+
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+/**
+ * This object represents a portion of the price for goods or services.
+ *
+ * @see <a 
href="https://core.telegram.org/bots/api#labeledprice";>https://core.telegram.org/bots/api#labeledprice</a>
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class LabeledPrice implements Serializable {
+
+    private static final long serialVersionUID = 266995423954925422L;
+
+    private String label;
+
+    private Integer amount;
+
+    public LabeledPrice(String label, Integer amount) {
+        this.label = label;
+        this.amount = amount;
+    }
+
+    public LabeledPrice() {
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    public void setLabel(String label) {
+        this.label = label;
+    }
+
+    public Integer getAmount() {
+        return amount;
+    }
+
+    public void setAmount(Integer amount) {
+        this.amount = amount;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("LabeledPrice{");
+        sb.append("label='").append(label).append('\'');
+        sb.append(", amount=").append(amount);
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/OrderInfo.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/OrderInfo.java
new file mode 100644
index 000000000000..3f147428bb23
--- /dev/null
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/OrderInfo.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.component.telegram.model.payments;
+
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * This object represents information about an order.
+ *
+ * @see <a 
href="https://core.telegram.org/bots/api#orderinfo";>https://core.telegram.org/bots/api#orderinfo</a>
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class OrderInfo implements Serializable {
+
+    private static final long serialVersionUID = -553444461843613420L;
+
+    private String name;
+
+    @JsonProperty("phone_number")
+    private String phoneNumber;
+
+    private String email;
+
+    @JsonProperty("shipping_address")
+    private ShippingAddress shippingAddress;
+
+    public OrderInfo(String name, String phoneNumber, String email, 
ShippingAddress shippingAddress) {
+        this.name = name;
+        this.phoneNumber = phoneNumber;
+        this.email = email;
+        this.shippingAddress = shippingAddress;
+    }
+
+    public OrderInfo() {
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPhoneNumber() {
+        return phoneNumber;
+    }
+
+    public void setPhoneNumber(String phoneNumber) {
+        this.phoneNumber = phoneNumber;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public ShippingAddress getShippingAddress() {
+        return shippingAddress;
+    }
+
+    public void setShippingAddress(ShippingAddress shippingAddress) {
+        this.shippingAddress = shippingAddress;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("OrderInfo{");
+        sb.append("name='").append(name).append('\'');
+        sb.append(", phoneNumber='").append(phoneNumber).append('\'');
+        sb.append(", email='").append(email).append('\'');
+        sb.append(", shippingAddress=").append(shippingAddress);
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/PreCheckoutQuery.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/PreCheckoutQuery.java
new file mode 100644
index 000000000000..5ac3b3f94a66
--- /dev/null
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/PreCheckoutQuery.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.component.telegram.model.payments;
+
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.camel.component.telegram.model.User;
+
+/**
+ * This object contains information about an incoming pre-checkout query.
+ *
+ * @see <a href=
+ *      
"https://core.telegram.org/bots/api#precheckoutquery";>https://core.telegram.org/bots/api#precheckoutquery</a>
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class PreCheckoutQuery implements Serializable {
+
+    private static final long serialVersionUID = -1840129234669542264L;
+
+    private String id;
+    private User from;
+    private String currency;
+
+    @JsonProperty("total_amount")
+    private Integer totalAmount;
+
+    @JsonProperty("invoice_payload")
+    private String invoicePayload;
+
+    @JsonProperty("shipping_option_id")
+    private String shippingOptionId;
+
+    @JsonProperty("order_info")
+    private OrderInfo orderInfo;
+
+    public PreCheckoutQuery() {
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public User getFrom() {
+        return from;
+    }
+
+    public void setFrom(User from) {
+        this.from = from;
+    }
+
+    public String getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(String currency) {
+        this.currency = currency;
+    }
+
+    public Integer getTotalAmount() {
+        return totalAmount;
+    }
+
+    public void setTotalAmount(Integer totalAmount) {
+        this.totalAmount = totalAmount;
+    }
+
+    public String getInvoicePayload() {
+        return invoicePayload;
+    }
+
+    public void setInvoicePayload(String invoicePayload) {
+        this.invoicePayload = invoicePayload;
+    }
+
+    public String getShippingOptionId() {
+        return shippingOptionId;
+    }
+
+    public void setShippingOptionId(String shippingOptionId) {
+        this.shippingOptionId = shippingOptionId;
+    }
+
+    public OrderInfo getOrderInfo() {
+        return orderInfo;
+    }
+
+    public void setOrderInfo(OrderInfo orderInfo) {
+        this.orderInfo = orderInfo;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("PreCheckoutQuery{");
+        sb.append("id='").append(id).append('\'');
+        sb.append(", from=").append(from);
+        sb.append(", currency='").append(currency).append('\'');
+        sb.append(", totalAmount=").append(totalAmount);
+        sb.append(", invoicePayload=").append(invoicePayload);
+        sb.append(", shippingOptionId=").append(shippingOptionId);
+        sb.append(", orderInfo=").append(orderInfo);
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/SendInvoiceMessage.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/SendInvoiceMessage.java
new file mode 100644
index 000000000000..9375a87439b5
--- /dev/null
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/SendInvoiceMessage.java
@@ -0,0 +1,368 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.component.telegram.model.payments;
+
+import java.io.Serial;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.camel.component.telegram.model.OutgoingMessage;
+import org.apache.camel.component.telegram.model.ReplyMarkup;
+
+/**
+ * Object to send invoices.
+ *
+ * @see <a href="https://core.telegram.org/bots/api#sendinvoice";> 
https://core.telegram.org/bots/api#sendinvoice</a>
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class SendInvoiceMessage extends OutgoingMessage {
+
+    @Serial
+    private static final long serialVersionUID = 2243358307498153269L;
+
+    @JsonProperty("message_thread_id")
+    protected Integer messageThreadId;
+
+    @JsonProperty("direct_messages_topic_id")
+    protected Integer directMessagesTopicId;
+
+    private String title;
+
+    private String description;
+
+    private String payload;
+
+    @JsonProperty("provider_token")
+    private String providerToken;
+
+    private String currency;
+
+    private List<LabeledPrice> prices;
+
+    @JsonProperty("max_tip_amount")
+    private Integer maxTipAmount;
+
+    @JsonProperty("suggested_tip_amounts")
+    private List<Integer> suggestedTipAmounts;
+
+    @JsonProperty("start_parameter")
+    private String startParameter;
+
+    @JsonProperty("provider_data")
+    private String providerData;
+
+    @JsonProperty("photo_url")
+    private String photoUrl;
+
+    @JsonProperty("photo_size")
+    private Integer photoSize;
+
+    @JsonProperty("photo_width")
+    private Integer photoWidth;
+
+    @JsonProperty("photo_height")
+    private Integer photoHeight;
+
+    @JsonProperty("need_name")
+    private Boolean needName;
+
+    @JsonProperty("need_phone_number")
+    private Boolean needPhoneNumber;
+
+    @JsonProperty("need_email")
+    private Boolean needEmail;
+
+    @JsonProperty("need_shipping_address")
+    private Boolean needShippingAddress;
+
+    @JsonProperty("send_phone_number_to_provider")
+    private Boolean sendPhoneNumberToProvider;
+
+    @JsonProperty("send_email_to_provider")
+    private Boolean sendEmailToProvider;
+
+    @JsonProperty("is_flexible")
+    private Boolean isFlexible;
+
+    @JsonProperty("protect_content")
+    private Boolean protectContent;
+
+    @JsonProperty("allow_paid_broadcast")
+    private Boolean allowPaidBroadcast;
+
+    @JsonProperty("message_effect_id")
+    private String messageEffectId;
+
+    @JsonProperty("reply_markup")
+    private ReplyMarkup replyMarkup;
+
+    public SendInvoiceMessage() {
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getPayload() {
+        return payload;
+    }
+
+    public void setPayload(String payload) {
+        this.payload = payload;
+    }
+
+    public String getProviderToken() {
+        return providerToken;
+    }
+
+    public void setProviderToken(String providerToken) {
+        this.providerToken = providerToken;
+    }
+
+    public String getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(String currency) {
+        this.currency = currency;
+    }
+
+    public List<LabeledPrice> getPrices() {
+        return prices;
+    }
+
+    public void setPrices(List<LabeledPrice> prices) {
+        this.prices = prices;
+    }
+
+    public String getStartParameter() {
+        return startParameter;
+    }
+
+    public void setStartParameter(String startParameter) {
+        this.startParameter = startParameter;
+    }
+
+    public String getProviderData() {
+        return providerData;
+    }
+
+    public void setProviderData(String providerData) {
+        this.providerData = providerData;
+    }
+
+    public Boolean getNeedPhoneNumber() {
+        return needPhoneNumber;
+    }
+
+    public void setNeedPhoneNumber(Boolean needPhoneNumber) {
+        this.needPhoneNumber = needPhoneNumber;
+    }
+
+    public Boolean getNeedEmail() {
+        return needEmail;
+    }
+
+    public void setNeedEmail(Boolean needEmail) {
+        this.needEmail = needEmail;
+    }
+
+    public Boolean getNeedShippingAddress() {
+        return needShippingAddress;
+    }
+
+    public void setNeedShippingAddress(Boolean needShippingAddress) {
+        this.needShippingAddress = needShippingAddress;
+    }
+
+    public Boolean getSendPhoneNumberToProvider() {
+        return sendPhoneNumberToProvider;
+    }
+
+    public void setSendPhoneNumberToProvider(Boolean 
sendPhoneNumberToProvider) {
+        this.sendPhoneNumberToProvider = sendPhoneNumberToProvider;
+    }
+
+    public Boolean getSendEmailToProvider() {
+        return sendEmailToProvider;
+    }
+
+    public void setSendEmailToProvider(Boolean sendEmailToProvider) {
+        this.sendEmailToProvider = sendEmailToProvider;
+    }
+
+    public Integer getMaxTipAmount() {
+        return maxTipAmount;
+    }
+
+    public void setMaxTipAmount(Integer maxTipAmount) {
+        this.maxTipAmount = maxTipAmount;
+    }
+
+    public List<Integer> getSuggestedTipAmounts() {
+        return suggestedTipAmounts;
+    }
+
+    public void setSuggestedTipAmounts(List<Integer> suggestedTipAmounts) {
+        this.suggestedTipAmounts = suggestedTipAmounts;
+    }
+
+    public String getPhotoUrl() {
+        return photoUrl;
+    }
+
+    public void setPhotoUrl(String photoUrl) {
+        this.photoUrl = photoUrl;
+    }
+
+    public Integer getPhotoSize() {
+        return photoSize;
+    }
+
+    public void setPhotoSize(Integer photoSize) {
+        this.photoSize = photoSize;
+    }
+
+    public Integer getPhotoWidth() {
+        return photoWidth;
+    }
+
+    public void setPhotoWidth(Integer photoWidth) {
+        this.photoWidth = photoWidth;
+    }
+
+    public Integer getPhotoHeight() {
+        return photoHeight;
+    }
+
+    public void setPhotoHeight(Integer photoHeight) {
+        this.photoHeight = photoHeight;
+    }
+
+    public Boolean getNeedName() {
+        return needName;
+    }
+
+    public void setNeedName(Boolean needName) {
+        this.needName = needName;
+    }
+
+    public Boolean getFlexible() {
+        return isFlexible;
+    }
+
+    public void setFlexible(Boolean flexible) {
+        isFlexible = flexible;
+    }
+
+    public Boolean getProtectContent() {
+        return protectContent;
+    }
+
+    public void setProtectContent(Boolean protectContent) {
+        this.protectContent = protectContent;
+    }
+
+    public Boolean getAllowPaidBroadcast() {
+        return allowPaidBroadcast;
+    }
+
+    public void setAllowPaidBroadcast(Boolean allowPaidBroadcast) {
+        this.allowPaidBroadcast = allowPaidBroadcast;
+    }
+
+    public String getMessageEffectId() {
+        return messageEffectId;
+    }
+
+    public void setMessageEffectId(String messageEffectId) {
+        this.messageEffectId = messageEffectId;
+    }
+
+    public ReplyMarkup getReplyMarkup() {
+        return replyMarkup;
+    }
+
+    public void setReplyMarkup(ReplyMarkup replyMarkup) {
+        this.replyMarkup = replyMarkup;
+    }
+
+    public Integer getMessageThreadId() {
+        return messageThreadId;
+    }
+
+    public void setMessageThreadId(Integer messageThreadId) {
+        this.messageThreadId = messageThreadId;
+    }
+
+    public Integer getDirectMessagesTopicId() {
+        return directMessagesTopicId;
+    }
+
+    public void setDirectMessagesTopicId(Integer directMessagesTopicId) {
+        this.directMessagesTopicId = directMessagesTopicId;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("SendInvoiceMessage{");
+        sb.append("chatId=").append(chatId);
+        sb.append(", messageThreadId=").append(messageThreadId);
+        sb.append(", directMessagesTopicId=").append(directMessagesTopicId);
+        sb.append(", title='").append(title).append('\'');
+        sb.append(", description='").append(description).append('\'');
+        sb.append(", payload='").append(payload).append('\'');
+        sb.append(", providerToken='").append(providerToken).append('\'');
+        sb.append(", currency='").append(currency).append('\'');
+        sb.append(", prices=").append(prices);
+        sb.append(", maxTipAmount=").append(maxTipAmount);
+        sb.append(", suggestedTipAmounts=").append(suggestedTipAmounts);
+        sb.append(", startParameter='").append(startParameter).append('\'');
+        sb.append(", providerData='").append(providerData).append('\'');
+        sb.append(", photoUrl='").append(photoUrl).append('\'');
+        sb.append(", photoSize=").append(photoSize);
+        sb.append(", photoWidth=").append(photoWidth);
+        sb.append(", photoHeight=").append(photoHeight);
+        sb.append(", needName=").append(needName);
+        sb.append(", needPhoneNumber=").append(needPhoneNumber);
+        sb.append(", needEmail=").append(needEmail);
+        sb.append(", needShippingAddress=").append(needShippingAddress);
+        sb.append(", 
sendPhoneNumberToProvider=").append(sendPhoneNumberToProvider);
+        sb.append(", sendEmailToProvider=").append(sendEmailToProvider);
+        sb.append(", isFlexible=").append(isFlexible);
+        sb.append(", protectContent=").append(protectContent);
+        sb.append(", allowPaidBroadcast=").append(allowPaidBroadcast);
+        sb.append(", messageEffectId='").append(messageEffectId).append('\'');
+        sb.append(", replyMarkup=").append(replyMarkup);
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/ShippingAddress.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/ShippingAddress.java
new file mode 100644
index 000000000000..3501c1c01ca6
--- /dev/null
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/ShippingAddress.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.component.telegram.model.payments;
+
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * This object represents a shipping address.
+ *
+ * @see <a href=
+ *      
"https://core.telegram.org/bots/api#shippingaddress";>https://core.telegram.org/bots/api#shippingaddress</a>
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ShippingAddress implements Serializable {
+
+    private static final long serialVersionUID = 6522567551386167131L;
+
+    @JsonProperty("country_code")
+    private String countryCode;
+
+    private String state;
+
+    private String city;
+
+    @JsonProperty("street_line1")
+    private String streetLine1;
+
+    @JsonProperty("street_line2")
+    private String streetLine2;
+
+    @JsonProperty("post_code")
+    private String postCode;
+
+    public ShippingAddress(String countryCode, String state, String city, 
String streetLine1, String streetLine2,
+                           String postCode) {
+        this.countryCode = countryCode;
+        this.state = state;
+        this.city = city;
+        this.streetLine1 = streetLine1;
+        this.streetLine2 = streetLine2;
+        this.postCode = postCode;
+    }
+
+    public ShippingAddress() {
+    }
+
+    public String getCountryCode() {
+        return countryCode;
+    }
+
+    public void setCountryCode(String countryCode) {
+        this.countryCode = countryCode;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    public String getCity() {
+        return city;
+    }
+
+    public void setCity(String city) {
+        this.city = city;
+    }
+
+    public String getStreetLine1() {
+        return streetLine1;
+    }
+
+    public void setStreetLine1(String streetLine1) {
+        this.streetLine1 = streetLine1;
+    }
+
+    public String getStreetLine2() {
+        return streetLine2;
+    }
+
+    public void setStreetLine2(String streetLine2) {
+        this.streetLine2 = streetLine2;
+    }
+
+    public String getPostCode() {
+        return postCode;
+    }
+
+    public void setPostCode(String postCode) {
+        this.postCode = postCode;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("ShippingAddress{");
+        sb.append("countryCode='").append(countryCode).append('\'');
+        sb.append(", state='").append(state).append('\'');
+        sb.append(", city='").append(city).append('\'');
+        sb.append(", streetLine1='").append(streetLine1).append('\'');
+        sb.append(", streetLine2='").append(streetLine2).append('\'');
+        sb.append(", postCode='").append(postCode).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/ShippingOption.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/ShippingOption.java
new file mode 100644
index 000000000000..5d4269638088
--- /dev/null
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/ShippingOption.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.component.telegram.model.payments;
+
+import java.io.Serializable;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+/**
+ * This object represents one shipping option.
+ *
+ * @see <a href=
+ *      
"https://core.telegram.org/bots/api#shippingoption";>https://core.telegram.org/bots/api#shippingoption</a>
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ShippingOption implements Serializable {
+
+    private static final long serialVersionUID = 1434858887897371221L;
+
+    private String id;
+    private String title;
+    private List<LabeledPrice> prices;
+
+    public ShippingOption(String id, String title, List<LabeledPrice> prices) {
+        this.id = id;
+        this.title = title;
+        this.prices = prices;
+    }
+
+    public ShippingOption() {
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public List<LabeledPrice> getPrices() {
+        return prices;
+    }
+
+    public void setPrices(List<LabeledPrice> prices) {
+        this.prices = prices;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("ShippingOption{");
+        sb.append("id='").append(id).append('\'');
+        sb.append(", title='").append(title).append('\'');
+        sb.append(", prices=").append(prices);
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/ShippingQuery.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/ShippingQuery.java
new file mode 100644
index 000000000000..0e0db8f0235c
--- /dev/null
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/ShippingQuery.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.component.telegram.model.payments;
+
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.camel.component.telegram.model.User;
+
+/**
+ * This object contains information about an incoming shipping query.
+ *
+ * @see <a href= 
"https://core.telegram.org/bots/api#shippingquery";>https://core.telegram.org/bots/api#shippingquery</a>
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ShippingQuery implements Serializable {
+
+    private static final long serialVersionUID = 1138356833926458198L;
+
+    private String id;
+    private User from;
+
+    @JsonProperty("invoice_payload")
+    private String invoicePayload;
+
+    @JsonProperty("shipping_address")
+    private ShippingAddress shippingAddress;
+
+    public ShippingQuery() {
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public User getFrom() {
+        return from;
+    }
+
+    public void setFrom(User from) {
+        this.from = from;
+    }
+
+    public String getInvoicePayload() {
+        return invoicePayload;
+    }
+
+    public void setInvoicePayload(String invoicePayload) {
+        this.invoicePayload = invoicePayload;
+    }
+
+    public ShippingAddress getShippingAddress() {
+        return shippingAddress;
+    }
+
+    public void setShippingAddress(ShippingAddress shippingAddress) {
+        this.shippingAddress = shippingAddress;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("ShippingQuery{");
+        sb.append("id='").append(id).append('\'');
+        sb.append(", from=").append(from);
+        sb.append(", invoicePayload='").append(invoicePayload).append('\'');
+        sb.append(", shippingAddress=").append(shippingAddress);
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/SuccessfulPayment.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/SuccessfulPayment.java
new file mode 100644
index 000000000000..69fbfd9ef6ef
--- /dev/null
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/model/payments/SuccessfulPayment.java
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.component.telegram.model.payments;
+
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * This object contains basic information about a successful payment.
+ *
+ * @see <a href=
+ *      
"https://core.telegram.org/bots/api#successfulpayment";>https://core.telegram.org/bots/api#successfulpayment</a>
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class SuccessfulPayment implements Serializable {
+
+    private static final long serialVersionUID = 3244496332391255696L;
+
+    private String currency;
+
+    @JsonProperty("total_amount")
+    private Integer totalAmount;
+
+    @JsonProperty("invoice_payload")
+    private String invoicePayload;
+
+    @JsonProperty("subscription_expiration_date")
+    private Integer subscriptionExpirationDate;
+
+    @JsonProperty("is_recurring")
+    private boolean isRecurring;
+
+    @JsonProperty("is_first_recurring")
+    private boolean isFirstRecurring;
+
+    @JsonProperty("shipping_option_id")
+    private String shippingOptionId;
+
+    @JsonProperty("order_info")
+    private OrderInfo orderInfo;
+
+    @JsonProperty("telegram_payment_charge_id")
+    private String telegramPaymentChargeId;
+
+    @JsonProperty("provider_payment_charge_id")
+    private String providerPaymentChargeId;
+
+    public SuccessfulPayment(String currency, Integer totalAmount, String 
invoicePayload,
+                             Integer subscriptionExpirationDate, boolean 
isRecurring, boolean isFirstRecurring,
+                             String shippingOptionId, OrderInfo orderInfo, 
String telegramPaymentChargeId,
+                             String providerPaymentChargeId) {
+        this.currency = currency;
+        this.totalAmount = totalAmount;
+        this.invoicePayload = invoicePayload;
+        this.subscriptionExpirationDate = subscriptionExpirationDate;
+        this.isRecurring = isRecurring;
+        this.isFirstRecurring = isFirstRecurring;
+        this.shippingOptionId = shippingOptionId;
+        this.orderInfo = orderInfo;
+        this.telegramPaymentChargeId = telegramPaymentChargeId;
+        this.providerPaymentChargeId = providerPaymentChargeId;
+    }
+
+    public SuccessfulPayment() {
+    }
+
+    public String getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(String currency) {
+        this.currency = currency;
+    }
+
+    public Integer getTotalAmount() {
+        return totalAmount;
+    }
+
+    public void setTotalAmount(Integer totalAmount) {
+        this.totalAmount = totalAmount;
+    }
+
+    public String getInvoicePayload() {
+        return invoicePayload;
+    }
+
+    public void setInvoicePayload(String invoicePayload) {
+        this.invoicePayload = invoicePayload;
+    }
+
+    public Integer getSubscriptionExpirationDate() {
+        return subscriptionExpirationDate;
+    }
+
+    public void setSubscriptionExpirationDate(Integer 
subscriptionExpirationDate) {
+        this.subscriptionExpirationDate = subscriptionExpirationDate;
+    }
+
+    public boolean isRecurring() {
+        return isRecurring;
+    }
+
+    public void setRecurring(boolean recurring) {
+        isRecurring = recurring;
+    }
+
+    public boolean isFirstRecurring() {
+        return isFirstRecurring;
+    }
+
+    public void setFirstRecurring(boolean firstRecurring) {
+        isFirstRecurring = firstRecurring;
+    }
+
+    public String getShippingOptionId() {
+        return shippingOptionId;
+    }
+
+    public void setShippingOptionId(String shippingOptionId) {
+        this.shippingOptionId = shippingOptionId;
+    }
+
+    public OrderInfo getOrderInfo() {
+        return orderInfo;
+    }
+
+    public void setOrderInfo(OrderInfo orderInfo) {
+        this.orderInfo = orderInfo;
+    }
+
+    public String getTelegramPaymentChargeId() {
+        return telegramPaymentChargeId;
+    }
+
+    public void setTelegramPaymentChargeId(String telegramPaymentChargeId) {
+        this.telegramPaymentChargeId = telegramPaymentChargeId;
+    }
+
+    public String getProviderPaymentChargeId() {
+        return providerPaymentChargeId;
+    }
+
+    public void setProviderPaymentChargeId(String providerPaymentChargeId) {
+        this.providerPaymentChargeId = providerPaymentChargeId;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("SuccessfulPayment{");
+        sb.append("currency='").append(currency).append('\'');
+        sb.append(", totalAmount=").append(totalAmount);
+        sb.append(", invoicePayload=").append(invoicePayload);
+        sb.append(", 
subscriptionExpirationDate=").append(subscriptionExpirationDate);
+        sb.append(", isRecurring=").append(isRecurring);
+        sb.append(", isFirstRecurring=").append(isFirstRecurring);
+        sb.append(", 
shippingOptionId='").append(shippingOptionId).append('\'');
+        sb.append(", orderInfo=").append(orderInfo);
+        sb.append(", 
telegramPaymentChargeId='").append(telegramPaymentChargeId).append('\'');
+        sb.append(", 
providerPaymentChargeId='").append(providerPaymentChargeId).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+}
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/service/OutgoingMessageHandler.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/service/OutgoingMessageHandler.java
index 0d227168c8e4..2daa1d77fbe1 100644
--- 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/service/OutgoingMessageHandler.java
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/service/OutgoingMessageHandler.java
@@ -17,101 +17,20 @@
 
 package org.apache.camel.component.telegram.service;
 
-import java.net.URI;
-import java.net.http.HttpClient;
-import java.net.http.HttpRequest;
-import java.net.http.HttpResponse;
-import java.util.concurrent.ExecutionException;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.apache.camel.AsyncCallback;
-import org.apache.camel.Exchange;
 import org.apache.camel.component.telegram.model.MessageResult;
 import org.apache.camel.component.telegram.model.OutgoingMessage;
 
-abstract class OutgoingMessageHandler<T extends OutgoingMessage> {
-    protected final ObjectMapper mapper;
-    protected final TelegramBodyPublisher bodyPublisher;
-
-    private final HttpClient client;
-    private final String contentType;
-    private final String uri;
-    private final Class<? extends MessageResult> resultClass;
-
-    public OutgoingMessageHandler(HttpClient client, ObjectMapper mapper, 
String uri,
-                                  String contentType, Class<? extends 
MessageResult> resultClass, int bufferSize) {
-        this.client = client;
-        this.mapper = mapper;
-        this.uri = uri;
-        this.contentType = contentType;
-        this.resultClass = resultClass;
-
-        bodyPublisher = new TelegramBodyPublisher(bufferSize);
-    }
-
-    public void sendMessage(Exchange exchange, AsyncCallback callback, T 
message) {
-        HttpRequest.Builder builder = 
HttpRequest.newBuilder().uri(URI.create(uri));
+abstract class OutgoingMessageHandler<T extends OutgoingMessage> extends 
TelegramMessageHandler<T> {
 
-        addBody(message);
-
-        if (bodyPublisher.getBodyParts().size() > 1) {
-            builder.setHeader("Content-type", "multipart/form-data; 
boundary=\"" + bodyPublisher.getBoundary() + "\"");
-        } else {
-            if (contentType != null) {
-                builder.setHeader("Content-type", contentType);
-            }
-        }
-
-        builder.setHeader("Accept", "application/json");
-
-        builder.POST(bodyPublisher.newPublisher());
-        try {
-            final TelegramAsyncHandler telegramAsyncHandler
-                    = new TelegramAsyncHandler(uri, resultClass, mapper, 
exchange, callback);
-
-            client.sendAsync(builder.build(), 
HttpResponse.BodyHandlers.ofInputStream())
-                    
.thenApply(telegramAsyncHandler::handleCompressedResponse).get();
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-            throw new RuntimeException(e);
-        } catch (ExecutionException e) {
-            throw new RuntimeException(e);
-        }
+    public OutgoingMessageHandler(TelegramApiClient apiClient, String uri, 
String contentType,
+                                  Class<? extends MessageResult> resultClass) {
+        super(apiClient, uri, contentType, resultClass);
     }
 
-    protected abstract void addBody(T message);
-
     protected void fillCommonMediaParts(OutgoingMessage message) {
 
         buildTextPart("chat_id", message.getChatId());
         buildTextPart("reply_to_message_id", message.getReplyToMessageId());
         buildTextPart("disable_notification", 
message.getDisableNotification());
     }
-
-    protected <T> void buildTextPart(String name, T value) {
-        buildTextPart(bodyPublisher, name, value);
-    }
-
-    static <T> void buildTextPart(TelegramBodyPublisher bodyPublisher, String 
name, T value) {
-        if (value != null) {
-            TelegramBodyPublisher.MultilineBodyPart<T> bodyPart
-                    = new TelegramBodyPublisher.MultilineBodyPart<>(name, 
value, "text/plain");
-
-            bodyPublisher.addBodyPart(bodyPart);
-        }
-    }
-
-    protected void buildMediaPart(String name, String fileNameWithExtension, 
byte[] value) {
-        buildMediaPart(bodyPublisher, name, fileNameWithExtension, value);
-    }
-
-    void buildMediaPart(TelegramBodyPublisher bodyPublisher, String name, 
String fileNameWithExtension, byte[] value) {
-        TelegramBodyPublisher.MultilineBodyPart<byte[]> bodyPart
-                = new TelegramBodyPublisher.MultilineBodyPart<>(name, value, 
"application/octet-stream", null);
-
-        bodyPart.addHeader("filename", fileNameWithExtension);
-
-        bodyPublisher.addBodyPart(bodyPart);
-    }
-
 }
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/TelegramService.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/service/TelegramApiClient.java
similarity index 57%
copy from 
components/camel-telegram/src/main/java/org/apache/camel/component/telegram/TelegramService.java
copy to 
components/camel-telegram/src/main/java/org/apache/camel/component/telegram/service/TelegramApiClient.java
index 0a6d59abd242..ee6056d3ad5f 100644
--- 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/TelegramService.java
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/service/TelegramApiClient.java
@@ -14,24 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.component.telegram;
+package org.apache.camel.component.telegram.service;
 
-import org.apache.camel.AsyncCallback;
-import org.apache.camel.Exchange;
-import org.apache.camel.component.telegram.model.OutgoingMessage;
-import org.apache.camel.component.telegram.model.UpdateResult;
+import java.net.http.HttpClient;
 
-/**
- * Allows interacting with the Telegram server to exchange messages.
- */
-public interface TelegramService {
-
-    UpdateResult getUpdates(Long offset, Integer limit, Integer 
timeoutSeconds);
-
-    void sendMessage(Exchange exchange, AsyncCallback callback, 
OutgoingMessage message);
-
-    boolean setWebhook(String url);
-
-    boolean removeWebhook();
+import com.fasterxml.jackson.databind.ObjectMapper;
 
+record TelegramApiClient(HttpClient client, ObjectMapper mapper, String 
baseUri, int bufferSize) {
 }
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/service/TelegramHandlerRegistry.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/service/TelegramHandlerRegistry.java
new file mode 100644
index 000000000000..314835d17169
--- /dev/null
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/service/TelegramHandlerRegistry.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.telegram.service;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.component.telegram.TelegramMessage;
+import org.apache.camel.component.telegram.model.MessageResult;
+
+final class TelegramHandlerRegistry {
+    private final Map<Class<?>, TelegramMessageHandler<?>> handlers;
+
+    private TelegramHandlerRegistry(Map<Class<?>, TelegramMessageHandler<?>> 
handlers) {
+        this.handlers = Collections.unmodifiableMap(handlers);
+    }
+
+    TelegramMessageHandler<?> get(Class<?> messageClass) {
+        return handlers.get(messageClass);
+    }
+
+    static Builder builder(TelegramApiClient apiClient) {
+        return new Builder(apiClient);
+    }
+
+    static final class Builder {
+        private final Map<Class<?>, TelegramMessageHandler<?>> handlers;
+        private final TelegramApiClient apiClient;
+
+        private Builder(TelegramApiClient apiClient) {
+            this.handlers = new HashMap<>();
+            this.apiClient = apiClient;
+        }
+
+        Builder register(Class<?> messageClass, TelegramMessageHandler<?> 
handler) {
+            handlers.put(messageClass, handler);
+            return this;
+        }
+
+        Builder register(Class<?> messageClass, String endpoint) {
+            handlers.put(messageClass, new JsonMessageHandler(
+                    apiClient, apiClient.baseUri() + "/" + endpoint));
+            return this;
+        }
+
+        Builder register(Class<?> messageClass, String endpoint, Class<? 
extends MessageResult> resultType) {
+            handlers.put(messageClass, new JsonMessageHandler(
+                    apiClient, apiClient.baseUri() + "/" + endpoint, 
resultType));
+            return this;
+        }
+
+        TelegramHandlerRegistry build() {
+            return new TelegramHandlerRegistry(new HashMap<>(handlers));
+        }
+    }
+
+    static class JsonMessageHandler extends 
TelegramMessageHandler<TelegramMessage> {
+
+        JsonMessageHandler(TelegramApiClient apiClient, String uri, Class<? 
extends MessageResult> returnType) {
+            super(apiClient, uri, "application/json", returnType);
+        }
+
+        JsonMessageHandler(TelegramApiClient apiClient, String uri) {
+            this(apiClient, uri, MessageResult.class);
+        }
+
+        @Override
+        protected void addBody(TelegramMessage message) {
+            try {
+                final String body = mapper.writeValueAsString(message);
+                bodyPublisher.addBodyPart(new 
TelegramBodyPublisher.SingleBodyPart(body));
+            } catch (JsonProcessingException e) {
+                throw new RuntimeCamelException("Could not serialize " + 
message);
+            }
+        }
+
+    }
+}
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/service/OutgoingMessageHandler.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/service/TelegramMessageHandler.java
similarity index 81%
copy from 
components/camel-telegram/src/main/java/org/apache/camel/component/telegram/service/OutgoingMessageHandler.java
copy to 
components/camel-telegram/src/main/java/org/apache/camel/component/telegram/service/TelegramMessageHandler.java
index 0d227168c8e4..fea04895e7ff 100644
--- 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/service/OutgoingMessageHandler.java
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/service/TelegramMessageHandler.java
@@ -14,11 +14,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.camel.component.telegram.service;
 
 import java.net.URI;
-import java.net.http.HttpClient;
 import java.net.http.HttpRequest;
 import java.net.http.HttpResponse;
 import java.util.concurrent.ExecutionException;
@@ -26,27 +24,27 @@ import java.util.concurrent.ExecutionException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.apache.camel.AsyncCallback;
 import org.apache.camel.Exchange;
+import org.apache.camel.component.telegram.TelegramMessage;
 import org.apache.camel.component.telegram.model.MessageResult;
-import org.apache.camel.component.telegram.model.OutgoingMessage;
 
-abstract class OutgoingMessageHandler<T extends OutgoingMessage> {
+abstract class TelegramMessageHandler<T extends TelegramMessage> {
     protected final ObjectMapper mapper;
     protected final TelegramBodyPublisher bodyPublisher;
 
-    private final HttpClient client;
+    private final TelegramApiClient apiClient;
     private final String contentType;
     private final String uri;
     private final Class<? extends MessageResult> resultClass;
 
-    public OutgoingMessageHandler(HttpClient client, ObjectMapper mapper, 
String uri,
-                                  String contentType, Class<? extends 
MessageResult> resultClass, int bufferSize) {
-        this.client = client;
-        this.mapper = mapper;
+    public TelegramMessageHandler(TelegramApiClient apiClient, String uri,
+                                  String contentType, Class<? extends 
MessageResult> resultClass) {
+        this.apiClient = apiClient;
+        this.mapper = apiClient.mapper();
         this.uri = uri;
         this.contentType = contentType;
         this.resultClass = resultClass;
 
-        bodyPublisher = new TelegramBodyPublisher(bufferSize);
+        bodyPublisher = new TelegramBodyPublisher(apiClient.bufferSize());
     }
 
     public void sendMessage(Exchange exchange, AsyncCallback callback, T 
message) {
@@ -69,7 +67,7 @@ abstract class OutgoingMessageHandler<T extends 
OutgoingMessage> {
             final TelegramAsyncHandler telegramAsyncHandler
                     = new TelegramAsyncHandler(uri, resultClass, mapper, 
exchange, callback);
 
-            client.sendAsync(builder.build(), 
HttpResponse.BodyHandlers.ofInputStream())
+            apiClient.client().sendAsync(builder.build(), 
HttpResponse.BodyHandlers.ofInputStream())
                     
.thenApply(telegramAsyncHandler::handleCompressedResponse).get();
         } catch (InterruptedException e) {
             Thread.currentThread().interrupt();
@@ -81,13 +79,6 @@ abstract class OutgoingMessageHandler<T extends 
OutgoingMessage> {
 
     protected abstract void addBody(T message);
 
-    protected void fillCommonMediaParts(OutgoingMessage message) {
-
-        buildTextPart("chat_id", message.getChatId());
-        buildTextPart("reply_to_message_id", message.getReplyToMessageId());
-        buildTextPart("disable_notification", 
message.getDisableNotification());
-    }
-
     protected <T> void buildTextPart(String name, T value) {
         buildTextPart(bodyPublisher, name, value);
     }
@@ -113,5 +104,4 @@ abstract class OutgoingMessageHandler<T extends 
OutgoingMessage> {
 
         bodyPublisher.addBodyPart(bodyPart);
     }
-
 }
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/service/TelegramServiceRestBotAPIAdapter.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/service/TelegramServiceRestBotAPIAdapter.java
index 295cef2bf20d..d834e2cebab4 100644
--- 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/service/TelegramServiceRestBotAPIAdapter.java
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/service/TelegramServiceRestBotAPIAdapter.java
@@ -31,6 +31,7 @@ import org.apache.camel.AsyncCallback;
 import org.apache.camel.Exchange;
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.component.telegram.TelegramException;
+import org.apache.camel.component.telegram.TelegramMessage;
 import org.apache.camel.component.telegram.TelegramService;
 import org.apache.camel.component.telegram.model.EditMessageCaptionMessage;
 import org.apache.camel.component.telegram.model.EditMessageDelete;
@@ -40,13 +41,13 @@ import 
org.apache.camel.component.telegram.model.EditMessageReplyMarkupMessage;
 import org.apache.camel.component.telegram.model.EditMessageTextMessage;
 import org.apache.camel.component.telegram.model.MessageResult;
 import org.apache.camel.component.telegram.model.MessageResultGameScores;
+import org.apache.camel.component.telegram.model.MessageResultString;
 import org.apache.camel.component.telegram.model.OutgoingAnswerInlineQuery;
 import org.apache.camel.component.telegram.model.OutgoingAudioMessage;
 import org.apache.camel.component.telegram.model.OutgoingCallbackQueryMessage;
 import org.apache.camel.component.telegram.model.OutgoingDocumentMessage;
 import org.apache.camel.component.telegram.model.OutgoingGameMessage;
 import 
org.apache.camel.component.telegram.model.OutgoingGetGameHighScoresMessage;
-import org.apache.camel.component.telegram.model.OutgoingMessage;
 import org.apache.camel.component.telegram.model.OutgoingPhotoMessage;
 import org.apache.camel.component.telegram.model.OutgoingSetGameScoreMessage;
 import org.apache.camel.component.telegram.model.OutgoingStickerMessage;
@@ -57,6 +58,10 @@ import 
org.apache.camel.component.telegram.model.SendVenueMessage;
 import 
org.apache.camel.component.telegram.model.StopMessageLiveLocationMessage;
 import org.apache.camel.component.telegram.model.UpdateResult;
 import org.apache.camel.component.telegram.model.WebhookResult;
+import 
org.apache.camel.component.telegram.model.payments.AnswerPreCheckoutQueryMessage;
+import 
org.apache.camel.component.telegram.model.payments.AnswerShippingQueryMessage;
+import 
org.apache.camel.component.telegram.model.payments.CreateInvoiceLinkMessage;
+import org.apache.camel.component.telegram.model.payments.SendInvoiceMessage;
 import org.apache.camel.util.URISupport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -67,7 +72,7 @@ import org.slf4j.LoggerFactory;
 public class TelegramServiceRestBotAPIAdapter implements TelegramService {
     private static final Logger LOG = 
LoggerFactory.getLogger(TelegramServiceRestBotAPIAdapter.class);
 
-    private final Map<Class<?>, OutgoingMessageHandler<?>> handlers;
+    private final TelegramHandlerRegistry handlerRegistry;
     private final HttpClient client;
 
     @Deprecated
@@ -80,45 +85,35 @@ public class TelegramServiceRestBotAPIAdapter implements 
TelegramService {
 
         this.baseUri = telegramBaseUri + "/bot" + authorizationToken;
         this.mapper = new ObjectMapper();
-        final Map<Class<?>, OutgoingMessageHandler<?>> m = new HashMap<>();
-        m.put(OutgoingTextMessage.class, new 
OutgoingPlainMessageHandler(client, mapper, baseUri + "/sendMessage", 
bufferSize));
-        m.put(OutgoingPhotoMessage.class, new 
OutgoingPhotoMessageHandler(client, mapper, baseUri, bufferSize));
-        m.put(OutgoingAudioMessage.class, new 
OutgoingAudioMessageHandler(client, mapper, baseUri, bufferSize));
-        m.put(OutgoingVideoMessage.class, new 
OutgoingVideoMessageHandler(client, mapper, baseUri, bufferSize));
-        m.put(OutgoingDocumentMessage.class, new 
OutgoingDocumentMessageHandler(client, mapper, baseUri, bufferSize));
-        m.put(OutgoingStickerMessage.class, new 
OutgoingStickerMessageHandler(client, mapper, baseUri, bufferSize));
-        m.put(OutgoingGameMessage.class, new 
OutgoingPlainMessageHandler(client, mapper, baseUri + "/sendGame", bufferSize));
-        m.put(SendLocationMessage.class,
-                new OutgoingPlainMessageHandler(client, mapper, baseUri + 
"/sendLocation", bufferSize));
-        m.put(EditMessageLiveLocationMessage.class,
-                new OutgoingPlainMessageHandler(client, mapper, baseUri + 
"/editMessageLiveLocation", bufferSize));
-        m.put(StopMessageLiveLocationMessage.class,
-                new OutgoingPlainMessageHandler(client, mapper, baseUri + 
"/stopMessageLiveLocation", bufferSize));
-        m.put(SendVenueMessage.class,
-                new OutgoingPlainMessageHandler(client, mapper, baseUri + 
"/sendVenue", bufferSize));
-        m.put(EditMessageTextMessage.class,
-                new OutgoingPlainMessageHandler(client, mapper, baseUri + 
"/editMessageText", bufferSize));
-        m.put(EditMessageCaptionMessage.class,
-                new OutgoingPlainMessageHandler(client, mapper, baseUri + 
"/editMessageCaption", bufferSize));
-        m.put(EditMessageMediaMessage.class,
-                new OutgoingPlainMessageHandler(client, mapper, baseUri + 
"/editMessageMedia", bufferSize));
-        m.put(EditMessageDelete.class, new OutgoingPlainMessageHandler(
-                client,
-                mapper, baseUri + "/deleteMessage", bufferSize));
-        m.put(EditMessageReplyMarkupMessage.class,
-                new OutgoingPlainMessageHandler(client, mapper, baseUri + 
"/editMessageReplyMarkup", bufferSize));
-        m.put(OutgoingCallbackQueryMessage.class, new 
OutgoingPlainMessageHandler(
-                client,
-                mapper, baseUri + "/answerCallbackQuery", bufferSize));
-        m.put(OutgoingSetGameScoreMessage.class,
-                new OutgoingPlainMessageHandler(client, mapper, baseUri + 
"/setGameScore", bufferSize));
-        m.put(OutgoingGetGameHighScoresMessage.class, new 
OutgoingPlainMessageHandler(
-                client,
-                mapper, baseUri + "/getGameHighScores", 
MessageResultGameScores.class, bufferSize));
-        m.put(OutgoingAnswerInlineQuery.class, new OutgoingPlainMessageHandler(
-                client,
-                mapper, baseUri + "/answerInlineQuery", bufferSize));
-        this.handlers = m;
+        final TelegramApiClient apiClient = new TelegramApiClient(client, 
mapper, baseUri, bufferSize);
+        this.handlerRegistry = TelegramHandlerRegistry.builder(apiClient)
+                // Media handlers (require custom addBody logic)
+                .register(OutgoingPhotoMessage.class, new 
OutgoingPhotoMessageHandler(apiClient))
+                .register(OutgoingAudioMessage.class, new 
OutgoingAudioMessageHandler(apiClient))
+                .register(OutgoingVideoMessage.class, new 
OutgoingVideoMessageHandler(apiClient))
+                .register(OutgoingDocumentMessage.class, new 
OutgoingDocumentMessageHandler(apiClient))
+                .register(OutgoingStickerMessage.class, new 
OutgoingStickerMessageHandler(apiClient))
+                // JSON handlers (simple JSON serialization)
+                .register(OutgoingTextMessage.class, "sendMessage")
+                .register(OutgoingGameMessage.class, "sendGame")
+                .register(SendLocationMessage.class, "sendLocation")
+                .register(EditMessageLiveLocationMessage.class, 
"editMessageLiveLocation")
+                .register(StopMessageLiveLocationMessage.class, 
"stopMessageLiveLocation")
+                .register(SendVenueMessage.class, "sendVenue")
+                .register(EditMessageTextMessage.class, "editMessageText")
+                .register(EditMessageCaptionMessage.class, 
"editMessageCaption")
+                .register(EditMessageMediaMessage.class, "editMessageMedia")
+                .register(EditMessageDelete.class, "deleteMessage")
+                .register(EditMessageReplyMarkupMessage.class, 
"editMessageReplyMarkup")
+                .register(OutgoingCallbackQueryMessage.class, 
"answerCallbackQuery")
+                .register(OutgoingSetGameScoreMessage.class, "setGameScore")
+                .register(OutgoingGetGameHighScoresMessage.class, 
"getGameHighScores", MessageResultGameScores.class)
+                .register(OutgoingAnswerInlineQuery.class, "answerInlineQuery")
+                .register(SendInvoiceMessage.class, "sendInvoice")
+                .register(CreateInvoiceLinkMessage.class, "createInvoiceLink", 
MessageResultString.class)
+                .register(AnswerPreCheckoutQueryMessage.class, 
"answerPreCheckoutQuery")
+                .register(AnswerShippingQueryMessage.class, 
"answerShippingQuery")
+                .build();
     }
 
     @Override
@@ -193,10 +188,10 @@ public class TelegramServiceRestBotAPIAdapter implements 
TelegramService {
     }
 
     @Override
-    public void sendMessage(Exchange exchange, AsyncCallback callback, 
OutgoingMessage message) {
+    public void sendMessage(Exchange exchange, AsyncCallback callback, 
TelegramMessage message) {
         @SuppressWarnings("unchecked")
-        final OutgoingMessageHandler<OutgoingMessage> handler = 
(OutgoingMessageHandler<OutgoingMessage>) handlers
-                .get(message.getClass());
+        final TelegramMessageHandler<TelegramMessage> handler
+                = (TelegramMessageHandler<TelegramMessage>) 
handlerRegistry.get(message.getClass());
         if (handler == null) {
             throw new IllegalArgumentException(
                     "Unsupported message type " + 
(message.getClass().getName()));
@@ -204,37 +199,10 @@ public class TelegramServiceRestBotAPIAdapter implements 
TelegramService {
         handler.sendMessage(exchange, callback, message);
     }
 
-    static class OutgoingPlainMessageHandler extends 
OutgoingMessageHandler<OutgoingMessage> {
-
-        public OutgoingPlainMessageHandler(HttpClient client, ObjectMapper 
mapper,
-                                           String uri, Class<? extends 
MessageResult> returnType, int bufferSize) {
-            super(client, mapper, uri, "application/json", returnType, 
bufferSize);
-        }
-
-        public OutgoingPlainMessageHandler(HttpClient client, ObjectMapper 
mapper,
-                                           String uri, int bufferSize) {
-            this(client, mapper, uri, MessageResult.class, bufferSize);
-        }
-
-        @Override
-        protected void addBody(OutgoingMessage message) {
-            try {
-                final String body = mapper.writeValueAsString(message);
-
-                bodyPublisher.addBodyPart(new 
TelegramBodyPublisher.SingleBodyPart(body));
-
-            } catch (JsonProcessingException e) {
-                throw new RuntimeCamelException("Could not serialize " + 
message);
-            }
-        }
-
-    }
-
     static class OutgoingAudioMessageHandler extends 
OutgoingMessageHandler<OutgoingAudioMessage> {
 
-        public OutgoingAudioMessageHandler(HttpClient client, ObjectMapper 
mapper,
-                                           String baseUri, int bufferSize) {
-            super(client, mapper, baseUri + "/sendAudio", null, 
MessageResult.class, bufferSize);
+        public OutgoingAudioMessageHandler(TelegramApiClient apiClient) {
+            super(apiClient, apiClient.baseUri() + "/sendAudio", null, 
MessageResult.class);
         }
 
         @Override
@@ -251,9 +219,8 @@ public class TelegramServiceRestBotAPIAdapter implements 
TelegramService {
 
     static class OutgoingVideoMessageHandler extends 
OutgoingMessageHandler<OutgoingVideoMessage> {
 
-        public OutgoingVideoMessageHandler(HttpClient client, ObjectMapper 
mapper,
-                                           String baseUri, int bufferSize) {
-            super(client, mapper, baseUri + "/sendVideo", null, 
MessageResult.class, bufferSize);
+        public OutgoingVideoMessageHandler(TelegramApiClient apiClient) {
+            super(apiClient, apiClient.baseUri() + "/sendVideo", null, 
MessageResult.class);
         }
 
         @Override
@@ -270,9 +237,8 @@ public class TelegramServiceRestBotAPIAdapter implements 
TelegramService {
 
     static class OutgoingDocumentMessageHandler extends 
OutgoingMessageHandler<OutgoingDocumentMessage> {
 
-        public OutgoingDocumentMessageHandler(HttpClient client, ObjectMapper 
mapper,
-                                              String baseUri, int bufferSize) {
-            super(client, mapper, baseUri + "/sendDocument", null, 
MessageResult.class, bufferSize);
+        public OutgoingDocumentMessageHandler(TelegramApiClient apiClient) {
+            super(apiClient, apiClient.baseUri() + "/sendDocument", null, 
MessageResult.class);
         }
 
         @Override
@@ -287,9 +253,8 @@ public class TelegramServiceRestBotAPIAdapter implements 
TelegramService {
 
     static class OutgoingPhotoMessageHandler extends 
OutgoingMessageHandler<OutgoingPhotoMessage> {
 
-        public OutgoingPhotoMessageHandler(HttpClient client, ObjectMapper 
mapper,
-                                           String baseUri, int bufferSize) {
-            super(client, mapper, baseUri + "/sendPhoto", null, 
MessageResult.class, bufferSize);
+        public OutgoingPhotoMessageHandler(TelegramApiClient apiClient) {
+            super(apiClient, apiClient.baseUri() + "/sendPhoto", null, 
MessageResult.class);
         }
 
         @Override
@@ -303,9 +268,8 @@ public class TelegramServiceRestBotAPIAdapter implements 
TelegramService {
     }
 
     static class OutgoingStickerMessageHandler extends 
OutgoingMessageHandler<OutgoingStickerMessage> {
-        public OutgoingStickerMessageHandler(HttpClient client, ObjectMapper 
mapper,
-                                             String baseUri, int bufferSize) {
-            super(client, mapper, baseUri + "/sendSticker", null, 
MessageResult.class, bufferSize);
+        public OutgoingStickerMessageHandler(TelegramApiClient apiClient) {
+            super(apiClient, apiClient.baseUri() + "/sendSticker", null, 
MessageResult.class);
         }
 
         @Override
diff --git 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/util/TelegramMessageHelper.java
 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/util/TelegramMessageHelper.java
index 7e72a7b81dd6..49809affaf9f 100644
--- 
a/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/util/TelegramMessageHelper.java
+++ 
b/components/camel-telegram/src/main/java/org/apache/camel/component/telegram/util/TelegramMessageHelper.java
@@ -52,6 +52,10 @@ public final class TelegramMessageHelper {
             exchange.getMessage().setBody(update.getCallbackQuery());
         } else if (update.getIncomingInlineQuery() != null) {
             exchange.getMessage().setBody(update.getIncomingInlineQuery());
+        } else if (update.getPreCheckoutQuery() != null) {
+            exchange.getMessage().setBody(update.getPreCheckoutQuery());
+        } else if (update.getShippingQuery() != null) {
+            exchange.getMessage().setBody(update.getShippingQuery());
         }
 
     }
diff --git 
a/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerPreCheckoutQueryTest.java
 
b/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerPreCheckoutQueryTest.java
new file mode 100644
index 000000000000..075e242adef9
--- /dev/null
+++ 
b/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerPreCheckoutQueryTest.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.telegram;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.component.telegram.model.payments.PreCheckoutQuery;
+import org.apache.camel.component.telegram.util.TelegramMockRoutes;
+import org.apache.camel.component.telegram.util.TelegramTestSupport;
+import org.apache.camel.component.telegram.util.TelegramTestUtil;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/**
+ * Tests that pre-checkout query updates are properly received and converted.
+ */
+public class TelegramConsumerPreCheckoutQueryTest extends TelegramTestSupport {
+
+    @EndpointInject("mock:telegram")
+    private MockEndpoint endpoint;
+
+    @Test
+    public void testReceptionOfPreCheckoutQuery() throws Exception {
+        endpoint.expectedMinimumMessageCount(1);
+        endpoint.assertIsSatisfied(5000);
+
+        Exchange exchange = endpoint.getExchanges().get(0);
+        PreCheckoutQuery query = 
exchange.getIn().getBody(PreCheckoutQuery.class);
+
+        assertNotNull(query);
+        assertEquals("pre_checkout_query_123", query.getId());
+        assertEquals("USD", query.getCurrency());
+        assertEquals(Integer.valueOf(1000), query.getTotalAmount());
+        assertEquals("test_payload", query.getInvoicePayload());
+        assertEquals("Doe", query.getFrom().getLastName());
+        assertEquals("John", query.getFrom().getFirstName());
+    }
+
+    @Override
+    protected RoutesBuilder[] createRouteBuilders() {
+        return new RoutesBuilder[] {
+                getMockRoutes(),
+                new RouteBuilder() {
+                    @Override
+                    public void configure() {
+                        from("telegram:bots?authorizationToken=mock-token")
+                                .to("mock:telegram");
+                    }
+                } };
+    }
+
+    @Override
+    protected TelegramMockRoutes createMockRoutes() {
+        return new TelegramMockRoutes(port)
+                .addEndpoint(
+                        "getUpdates",
+                        "GET",
+                        String.class,
+                        
TelegramTestUtil.stringResource("messages/updates-pre-checkout-query.json"),
+                        
TelegramTestUtil.stringResource("messages/updates-empty.json"));
+    }
+}
diff --git 
a/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerShippingQueryTest.java
 
b/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerShippingQueryTest.java
new file mode 100644
index 000000000000..a79130bde9a3
--- /dev/null
+++ 
b/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerShippingQueryTest.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.telegram;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.component.telegram.model.payments.ShippingAddress;
+import org.apache.camel.component.telegram.model.payments.ShippingQuery;
+import org.apache.camel.component.telegram.util.TelegramMockRoutes;
+import org.apache.camel.component.telegram.util.TelegramTestSupport;
+import org.apache.camel.component.telegram.util.TelegramTestUtil;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/**
+ * Tests that shipping query updates are properly received and converted.
+ */
+public class TelegramConsumerShippingQueryTest extends TelegramTestSupport {
+
+    @EndpointInject("mock:telegram")
+    private MockEndpoint endpoint;
+
+    @Test
+    public void testReceptionOfShippingQuery() throws Exception {
+        endpoint.expectedMinimumMessageCount(1);
+        endpoint.assertIsSatisfied(5000);
+
+        Exchange exchange = endpoint.getExchanges().get(0);
+        ShippingQuery query = exchange.getIn().getBody(ShippingQuery.class);
+
+        assertNotNull(query);
+        assertEquals("shipping_query_123", query.getId());
+        assertEquals("test_payload", query.getInvoicePayload());
+        assertEquals("Doe", query.getFrom().getLastName());
+        assertEquals("John", query.getFrom().getFirstName());
+
+        ShippingAddress address = query.getShippingAddress();
+        assertNotNull(address);
+        assertEquals("US", address.getCountryCode());
+        assertEquals("California", address.getState());
+        assertEquals("San Francisco", address.getCity());
+        assertEquals("123 Main St", address.getStreetLine1());
+        assertEquals("Apt 4", address.getStreetLine2());
+        assertEquals("94102", address.getPostCode());
+    }
+
+    @Override
+    protected RoutesBuilder[] createRouteBuilders() {
+        return new RoutesBuilder[] {
+                getMockRoutes(),
+                new RouteBuilder() {
+                    @Override
+                    public void configure() {
+                        from("telegram:bots?authorizationToken=mock-token")
+                                .to("mock:telegram");
+                    }
+                } };
+    }
+
+    @Override
+    protected TelegramMockRoutes createMockRoutes() {
+        return new TelegramMockRoutes(port)
+                .addEndpoint(
+                        "getUpdates",
+                        "GET",
+                        String.class,
+                        
TelegramTestUtil.stringResource("messages/updates-shipping-query.json"),
+                        
TelegramTestUtil.stringResource("messages/updates-empty.json"));
+    }
+}
diff --git 
a/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerSuccessfulPaymentTest.java
 
b/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerSuccessfulPaymentTest.java
new file mode 100644
index 000000000000..a3158cdfcde8
--- /dev/null
+++ 
b/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerSuccessfulPaymentTest.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.telegram;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.component.telegram.model.IncomingMessage;
+import org.apache.camel.component.telegram.model.payments.OrderInfo;
+import org.apache.camel.component.telegram.model.payments.ShippingAddress;
+import org.apache.camel.component.telegram.model.payments.SuccessfulPayment;
+import org.apache.camel.component.telegram.util.TelegramMockRoutes;
+import org.apache.camel.component.telegram.util.TelegramTestSupport;
+import org.apache.camel.component.telegram.util.TelegramTestUtil;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/**
+ * Tests that successful payment updates are properly received and converted.
+ */
+public class TelegramConsumerSuccessfulPaymentTest extends TelegramTestSupport 
{
+
+    @EndpointInject("mock:telegram")
+    private MockEndpoint endpoint;
+
+    @Test
+    public void testReceptionOfSuccessfulPayment() throws Exception {
+        endpoint.expectedMinimumMessageCount(1);
+        endpoint.assertIsSatisfied(5000);
+
+        Exchange exchange = endpoint.getExchanges().get(0);
+        IncomingMessage message = 
exchange.getIn().getBody(IncomingMessage.class);
+
+        assertNotNull(message);
+        SuccessfulPayment payment = message.getSuccessfulPayment();
+        assertNotNull(payment);
+
+        assertEquals("USD", payment.getCurrency());
+        assertEquals(Integer.valueOf(1000), payment.getTotalAmount());
+        assertEquals("test_payload", payment.getInvoicePayload());
+        assertEquals("shipping_option_1", payment.getShippingOptionId());
+        assertEquals("telegram_charge_123", 
payment.getTelegramPaymentChargeId());
+        assertEquals("provider_charge_456", 
payment.getProviderPaymentChargeId());
+
+        OrderInfo orderInfo = payment.getOrderInfo();
+        assertNotNull(orderInfo);
+        assertEquals("John Doe", orderInfo.getName());
+        assertEquals("+15551234567", orderInfo.getPhoneNumber());
+        assertEquals("[email protected]", orderInfo.getEmail());
+
+        ShippingAddress address = orderInfo.getShippingAddress();
+        assertNotNull(address);
+        assertEquals("US", address.getCountryCode());
+        assertEquals("California", address.getState());
+        assertEquals("San Francisco", address.getCity());
+        assertEquals("123 Main St", address.getStreetLine1());
+        assertEquals("Apt 4", address.getStreetLine2());
+        assertEquals("94102", address.getPostCode());
+    }
+
+    @Override
+    protected RoutesBuilder[] createRouteBuilders() {
+        return new RoutesBuilder[] {
+                getMockRoutes(),
+                new RouteBuilder() {
+                    @Override
+                    public void configure() {
+                        from("telegram:bots?authorizationToken=mock-token")
+                                .to("mock:telegram");
+                    }
+                } };
+    }
+
+    @Override
+    protected TelegramMockRoutes createMockRoutes() {
+        return new TelegramMockRoutes(port)
+                .addEndpoint(
+                        "getUpdates",
+                        "GET",
+                        String.class,
+                        
TelegramTestUtil.stringResource("messages/updates-successful-payment.json"),
+                        
TelegramTestUtil.stringResource("messages/updates-empty.json"));
+    }
+}
diff --git 
a/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramProducerInvoiceTest.java
 
b/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramProducerInvoiceTest.java
new file mode 100644
index 000000000000..bc5bd732d51c
--- /dev/null
+++ 
b/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramProducerInvoiceTest.java
@@ -0,0 +1,250 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.telegram;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.telegram.model.InlineKeyboardButton;
+import org.apache.camel.component.telegram.model.InlineKeyboardMarkup;
+import org.apache.camel.component.telegram.model.MessageResult;
+import org.apache.camel.component.telegram.model.MessageResultString;
+import 
org.apache.camel.component.telegram.model.payments.AnswerPreCheckoutQueryMessage;
+import 
org.apache.camel.component.telegram.model.payments.AnswerShippingQueryMessage;
+import 
org.apache.camel.component.telegram.model.payments.CreateInvoiceLinkMessage;
+import org.apache.camel.component.telegram.model.payments.LabeledPrice;
+import org.apache.camel.component.telegram.model.payments.SendInvoiceMessage;
+import org.apache.camel.component.telegram.model.payments.ShippingOption;
+import org.apache.camel.component.telegram.util.TelegramMockRoutes;
+import 
org.apache.camel.component.telegram.util.TelegramMockRoutes.MockProcessor;
+import org.apache.camel.component.telegram.util.TelegramTestSupport;
+import org.apache.camel.component.telegram.util.TelegramTestUtil;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests a producer that sends invoices and handles payment operations.
+ */
+public class TelegramProducerInvoiceTest extends TelegramTestSupport {
+
+    @Test
+    public void testSendInvoice() {
+        SendInvoiceMessage msg = new SendInvoiceMessage();
+        msg.setTitle("Test Product");
+        msg.setDescription("Test product description");
+        msg.setPayload("test_payload");
+        msg.setCurrency("USD");
+        msg.setPrices(Collections.singletonList(new LabeledPrice("Product 
Price", 1000)));
+
+        template.requestBody("direct:telegram", msg, MessageResult.class);
+
+        final MockProcessor<SendInvoiceMessage> mockProcessor = 
getMockRoutes().getMock("sendInvoice");
+        assertThat(mockProcessor.awaitRecordedMessages(1, 5000).get(0))
+                .usingRecursiveComparison()
+                .isEqualTo(msg);
+    }
+
+    @Test
+    public void testAnswerPreCheckoutQuery() {
+        AnswerPreCheckoutQueryMessage msg = new 
AnswerPreCheckoutQueryMessage("pre_checkout_query_123", true, null);
+
+        template.requestBody("direct:telegram", msg);
+
+        final MockProcessor<AnswerPreCheckoutQueryMessage> mockProcessor = 
getMockRoutes().getMock("answerPreCheckoutQuery");
+        assertThat(mockProcessor.awaitRecordedMessages(1, 5000).get(0))
+                .usingRecursiveComparison()
+                .isEqualTo(msg);
+    }
+
+    @Test
+    public void testAnswerPreCheckoutQueryWithError() {
+        AnswerPreCheckoutQueryMessage msg
+                = new AnswerPreCheckoutQueryMessage("pre_checkout_query_123", 
false, "Payment declined");
+
+        template.requestBody("direct:telegram", msg);
+
+        final MockProcessor<AnswerPreCheckoutQueryMessage> mockProcessor = 
getMockRoutes().getMock("answerPreCheckoutQuery");
+        AnswerPreCheckoutQueryMessage recorded = 
mockProcessor.awaitRecordedMessages(1, 5000).get(0);
+        
assertThat(recorded.getPreCheckoutQueryId()).isEqualTo("pre_checkout_query_123");
+        assertThat(recorded.getOk()).isFalse();
+        assertThat(recorded.getErrorMessage()).isEqualTo("Payment declined");
+    }
+
+    @Test
+    public void testCreateInvoiceLink() {
+        CreateInvoiceLinkMessage msg = new CreateInvoiceLinkMessage();
+        msg.setTitle("Test Product");
+        msg.setDescription("Test product description");
+        msg.setPayload("test_payload");
+        msg.setCurrency("USD");
+        msg.setPrices(Collections.singletonList(new LabeledPrice("Product 
Price", 1000)));
+
+        MessageResultString result = template.requestBody("direct:telegram", 
msg, MessageResultString.class);
+
+        assertThat(result).isNotNull();
+        
assertThat(result.getResult()).isEqualTo("https://t.me/$invoice_link_123";);
+
+        final MockProcessor<CreateInvoiceLinkMessage> mockProcessor = 
getMockRoutes().getMock("createInvoiceLink");
+        assertThat(mockProcessor.awaitRecordedMessages(1, 5000).get(0))
+                .usingRecursiveComparison()
+                .isEqualTo(msg);
+    }
+
+    @Test
+    public void testAnswerShippingQuery() {
+        ShippingOption option = new ShippingOption(
+                "shipping_standard",
+                "Standard Shipping",
+                Collections.singletonList(new LabeledPrice("Shipping", 500)));
+
+        AnswerShippingQueryMessage msg = new AnswerShippingQueryMessage(
+                "shipping_query_123", true, Collections.singletonList(option), 
null);
+
+        template.requestBody("direct:telegram", msg);
+
+        final MockProcessor<AnswerShippingQueryMessage> mockProcessor = 
getMockRoutes().getMock("answerShippingQuery");
+        AnswerShippingQueryMessage recorded = 
mockProcessor.awaitRecordedMessages(1, 5000).get(0);
+        
assertThat(recorded.getShippingQueryId()).isEqualTo("shipping_query_123");
+        assertThat(recorded.getOk()).isTrue();
+        assertThat(recorded.getShippingOptions()).hasSize(1);
+        
assertThat(recorded.getShippingOptions().get(0).getId()).isEqualTo("shipping_standard");
+    }
+
+    @Test
+    public void testAnswerShippingQueryWithError() {
+        AnswerShippingQueryMessage msg = new AnswerShippingQueryMessage(
+                "shipping_query_123", false, null, "Cannot ship to this 
address");
+
+        template.requestBody("direct:telegram", msg);
+
+        final MockProcessor<AnswerShippingQueryMessage> mockProcessor = 
getMockRoutes().getMock("answerShippingQuery");
+        AnswerShippingQueryMessage recorded = 
mockProcessor.awaitRecordedMessages(1, 5000).get(0);
+        
assertThat(recorded.getShippingQueryId()).isEqualTo("shipping_query_123");
+        assertThat(recorded.getOk()).isFalse();
+        assertThat(recorded.getErrorMessage()).isEqualTo("Cannot ship to this 
address");
+    }
+
+    @Test
+    public void testAnswerShippingQueryWithMultipleOptions() {
+        ShippingOption standardOption = new ShippingOption(
+                "shipping_standard",
+                "Standard Shipping (5-7 days)",
+                Collections.singletonList(new LabeledPrice("Standard 
Shipping", 500)));
+        ShippingOption expressOption = new ShippingOption(
+                "shipping_express",
+                "Express Shipping (1-2 days)",
+                Collections.singletonList(new LabeledPrice("Express Shipping", 
1500)));
+
+        AnswerShippingQueryMessage msg = new AnswerShippingQueryMessage(
+                "shipping_query_123", true, Arrays.asList(standardOption, 
expressOption), null);
+
+        template.requestBody("direct:telegram", msg);
+
+        final MockProcessor<AnswerShippingQueryMessage> mockProcessor = 
getMockRoutes().getMock("answerShippingQuery");
+        AnswerShippingQueryMessage recorded = 
mockProcessor.awaitRecordedMessages(1, 5000).get(0);
+        assertThat(recorded.getShippingOptions()).hasSize(2);
+        
assertThat(recorded.getShippingOptions().get(0).getTitle()).isEqualTo("Standard 
Shipping (5-7 days)");
+        
assertThat(recorded.getShippingOptions().get(1).getTitle()).isEqualTo("Express 
Shipping (1-2 days)");
+    }
+
+    @Test
+    public void testInlineKeyboardMarkupWithPayButton() {
+        InlineKeyboardButton payButton = InlineKeyboardButton.builder()
+                .text("Pay $10.00")
+                .pay(true)
+                .build();
+
+        assertThat(payButton.getText()).isEqualTo("Pay $10.00");
+        assertThat(payButton.getPay()).isTrue();
+
+        InlineKeyboardMarkup markup = InlineKeyboardMarkup.builder()
+                .addRow(Collections.singletonList(payButton))
+                .build();
+
+        assertThat(markup.getInlineKeyboard()).hasSize(1);
+        assertThat(markup.getInlineKeyboard().get(0)).hasSize(1);
+        assertThat(markup.getInlineKeyboard().get(0).get(0).getPay()).isTrue();
+        
assertThat(markup.getInlineKeyboard().get(0).get(0).getText()).isEqualTo("Pay 
$10.00");
+
+        // Verify it can be set on SendInvoiceMessage
+        SendInvoiceMessage msg = new SendInvoiceMessage();
+        msg.setReplyMarkup(markup);
+        assertThat(msg.getReplyMarkup()).isEqualTo(markup);
+    }
+
+    @Test
+    public void testInlineKeyboardButtonPayFieldBuilder() {
+        InlineKeyboardButton button = InlineKeyboardButton.builder()
+                .text("Pay Now")
+                .pay(true)
+                .build();
+
+        assertThat(button.getText()).isEqualTo("Pay Now");
+        assertThat(button.getPay()).isTrue();
+        assertThat(button.getUrl()).isNull();
+        assertThat(button.getCallbackData()).isNull();
+    }
+
+    @Test
+    public void testInlineKeyboardButtonPayFieldConstructor() {
+        InlineKeyboardButton button = new InlineKeyboardButton(
+                "Pay Now", null, null, null, null, null, null, true);
+
+        assertThat(button.getText()).isEqualTo("Pay Now");
+        assertThat(button.getPay()).isTrue();
+    }
+
+    @Override
+    protected RoutesBuilder[] createRouteBuilders() {
+        return new RoutesBuilder[] {
+                getMockRoutes(),
+                new RouteBuilder() {
+                    @Override
+                    public void configure() {
+                        
from("direct:telegram").to("telegram:bots?authorizationToken=mock-token&chatId="
 + chatId);
+                    }
+                } };
+    }
+
+    @Override
+    protected TelegramMockRoutes createMockRoutes() {
+        return new TelegramMockRoutes(port)
+                .addEndpoint(
+                        "sendInvoice",
+                        "POST",
+                        SendInvoiceMessage.class,
+                        
TelegramTestUtil.stringResource("messages/send-invoice.json"))
+                .addEndpoint(
+                        "answerPreCheckoutQuery",
+                        "POST",
+                        AnswerPreCheckoutQueryMessage.class,
+                        
TelegramTestUtil.stringResource("messages/answer-pre-checkout-query.json"))
+                .addEndpoint(
+                        "createInvoiceLink",
+                        "POST",
+                        CreateInvoiceLinkMessage.class,
+                        
TelegramTestUtil.stringResource("messages/create-invoice-link.json"))
+                .addEndpoint(
+                        "answerShippingQuery",
+                        "POST",
+                        AnswerShippingQueryMessage.class,
+                        
TelegramTestUtil.stringResource("messages/answer-shipping-query.json"));
+    }
+}
diff --git 
a/components/camel-telegram/src/test/resources/messages/answer-pre-checkout-query.json
 
b/components/camel-telegram/src/test/resources/messages/answer-pre-checkout-query.json
new file mode 100644
index 000000000000..db6536f4907e
--- /dev/null
+++ 
b/components/camel-telegram/src/test/resources/messages/answer-pre-checkout-query.json
@@ -0,0 +1,4 @@
+{
+    "ok": true,
+    "result": true
+}
\ No newline at end of file
diff --git 
a/components/camel-telegram/src/test/resources/messages/answer-shipping-query.json
 
b/components/camel-telegram/src/test/resources/messages/answer-shipping-query.json
new file mode 100644
index 000000000000..db6536f4907e
--- /dev/null
+++ 
b/components/camel-telegram/src/test/resources/messages/answer-shipping-query.json
@@ -0,0 +1,4 @@
+{
+    "ok": true,
+    "result": true
+}
\ No newline at end of file
diff --git 
a/components/camel-telegram/src/test/resources/messages/create-invoice-link.json
 
b/components/camel-telegram/src/test/resources/messages/create-invoice-link.json
new file mode 100644
index 000000000000..de4a4b977a1e
--- /dev/null
+++ 
b/components/camel-telegram/src/test/resources/messages/create-invoice-link.json
@@ -0,0 +1,4 @@
+{
+    "ok": true,
+    "result": "https://t.me/$invoice_link_123";
+}
\ No newline at end of file
diff --git 
a/components/camel-telegram/src/test/resources/messages/send-invoice.json 
b/components/camel-telegram/src/test/resources/messages/send-invoice.json
new file mode 100644
index 000000000000..e62b96147fc7
--- /dev/null
+++ b/components/camel-telegram/src/test/resources/messages/send-invoice.json
@@ -0,0 +1,26 @@
+{
+    "ok": true,
+    "result": {
+        "message_id": 1001,
+        "from": {
+            "id": 770882310,
+            "is_bot": true,
+            "first_name": "camelDemoBot",
+            "username": "camelDemoBot"
+        },
+        "chat": {
+            "id": 434822960,
+            "first_name": "John",
+            "last_name": "Doe",
+            "type": "private"
+        },
+        "date": 1576249600,
+        "invoice": {
+            "title": "Test Product",
+            "description": "Test product description",
+            "start_parameter": "test_start",
+            "currency": "USD",
+            "total_amount": 1000
+        }
+    }
+}
\ No newline at end of file
diff --git 
a/components/camel-telegram/src/test/resources/messages/updates-pre-checkout-query.json
 
b/components/camel-telegram/src/test/resources/messages/updates-pre-checkout-query.json
new file mode 100644
index 000000000000..8225b3d4a452
--- /dev/null
+++ 
b/components/camel-telegram/src/test/resources/messages/updates-pre-checkout-query.json
@@ -0,0 +1,19 @@
+{
+    "ok": true,
+    "result": [
+        {
+            "update_id": 219398824,
+            "pre_checkout_query": {
+                "id": "pre_checkout_query_123",
+                "from": {
+                    "id": 1585844777,
+                    "first_name": "John",
+                    "last_name": "Doe"
+                },
+                "currency": "USD",
+                "total_amount": 1000,
+                "invoice_payload": "test_payload"
+            }
+        }
+    ]
+}
\ No newline at end of file
diff --git 
a/components/camel-telegram/src/test/resources/messages/updates-shipping-query.json
 
b/components/camel-telegram/src/test/resources/messages/updates-shipping-query.json
new file mode 100644
index 000000000000..712b59f68ddb
--- /dev/null
+++ 
b/components/camel-telegram/src/test/resources/messages/updates-shipping-query.json
@@ -0,0 +1,25 @@
+{
+    "ok": true,
+    "result": [
+        {
+            "update_id": 219398825,
+            "shipping_query": {
+                "id": "shipping_query_123",
+                "from": {
+                    "id": 1585844777,
+                    "first_name": "John",
+                    "last_name": "Doe"
+                },
+                "invoice_payload": "test_payload",
+                "shipping_address": {
+                    "country_code": "US",
+                    "state": "California",
+                    "city": "San Francisco",
+                    "street_line1": "123 Main St",
+                    "street_line2": "Apt 4",
+                    "post_code": "94102"
+                }
+            }
+        }
+    ]
+}
\ No newline at end of file
diff --git 
a/components/camel-telegram/src/test/resources/messages/updates-successful-payment.json
 
b/components/camel-telegram/src/test/resources/messages/updates-successful-payment.json
new file mode 100644
index 000000000000..63ea312f4238
--- /dev/null
+++ 
b/components/camel-telegram/src/test/resources/messages/updates-successful-payment.json
@@ -0,0 +1,44 @@
+{
+    "ok": true,
+    "result": [
+        {
+            "update_id": 219398826,
+            "message": {
+                "message_id": 12345,
+                "from": {
+                    "id": 1585844777,
+                    "first_name": "John",
+                    "last_name": "Doe"
+                },
+                "date": 1234567890,
+                "chat": {
+                    "id": 1585844777,
+                    "first_name": "John",
+                    "last_name": "Doe",
+                    "type": "private"
+                },
+                "successful_payment": {
+                    "currency": "USD",
+                    "total_amount": 1000,
+                    "invoice_payload": "test_payload",
+                    "shipping_option_id": "shipping_option_1",
+                    "telegram_payment_charge_id": "telegram_charge_123",
+                    "provider_payment_charge_id": "provider_charge_456",
+                    "order_info": {
+                        "name": "John Doe",
+                        "phone_number": "+15551234567",
+                        "email": "[email protected]",
+                        "shipping_address": {
+                            "country_code": "US",
+                            "state": "California",
+                            "city": "San Francisco",
+                            "street_line1": "123 Main St",
+                            "street_line2": "Apt 4",
+                            "post_code": "94102"
+                        }
+                    }
+                }
+            }
+        }
+    ]
+}
\ No newline at end of file


Reply via email to