mirror of
https://github.com/MarshalX/telegram-crawler.git
synced 2024-11-28 19:23:11 +01:00
366 lines
53 KiB
HTML
366 lines
53 KiB
HTML
<!DOCTYPE html>
|
||
<html class="">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<title>Payments API</title>
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta property="description" content="You can accept payments from Telegram users via Telegram Bots.
|
||
Note: This article is intended for MTProto API developers.…">
|
||
<meta property="og:title" content="Payments API">
|
||
<meta property="og:image" content="">
|
||
<meta property="og:description" content="You can accept payments from Telegram users via Telegram Bots.
|
||
Note: This article is intended for MTProto API developers.…">
|
||
<link rel="shortcut icon" href="/favicon.ico?4" type="image/x-icon" />
|
||
|
||
<link href="/css/bootstrap.min.css?3" rel="stylesheet">
|
||
|
||
<link href="/css/telegram.css?214" rel="stylesheet" media="screen">
|
||
<style>
|
||
</style>
|
||
</head>
|
||
<body class="preload">
|
||
<div class="dev_page_wrap">
|
||
<div class="dev_page_head navbar navbar-static-top navbar-tg">
|
||
<div class="navbar-inner">
|
||
<div class="container clearfix">
|
||
<ul class="nav navbar-nav navbar-right hidden-xs"><li class="navbar-twitter"><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)"><i class="icon icon-twitter"></i><span> Twitter</span></a></li></ul>
|
||
<ul class="nav navbar-nav">
|
||
<li><a href="//telegram.org/">Home</a></li>
|
||
<li class="hidden-xs"><a href="//telegram.org/faq">FAQ</a></li>
|
||
<li class="hidden-xs"><a href="//telegram.org/apps">Apps</a></li>
|
||
<li class="active"><a href="/api">API</a></li>
|
||
<li class=""><a href="/mtproto">Protocol</a></li>
|
||
<li class=""><a href="/schema">Schema</a></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="container clearfix">
|
||
<div class="dev_page">
|
||
<div id="dev_page_content_wrap" class=" ">
|
||
<div class="dev_page_bread_crumbs"><ul class="breadcrumb clearfix"><li><a href="/api" >API</a></li><i class="icon icon-breadcrumb-divider"></i><li><a href="/api/payments" >Payments API</a></li></ul></div>
|
||
<h1 id="dev_page_title">Payments API</h1>
|
||
|
||
<div id="dev_page_content"><!-- scroll_nav -->
|
||
|
||
<p>You can accept payments from Telegram users via <a href="/bots">Telegram Bots</a>.</p>
|
||
<blockquote>
|
||
<p>Note: This article is intended for MTProto API developers. If you're looking for a general overview of Telegram Payments, check out the <a href="https://telegram.org/blog/payments">Telegram blog</a> and the <a href="/bots/payments">bot API payment manual</a>.</p>
|
||
</blockquote>
|
||
<h3><a class="anchor" href="#introducing-payments" id="introducing-payments" name="introducing-payments"><i class="anchor-icon"></i></a>Introducing Payments</h3>
|
||
<p>Telegram bots can accept payments for goods and services from users.
|
||
For more info on how payments work, check out the <a href="https://telegram.org/blog/payments">Telegram Blog</a> and the <a href="/bots/payments">bot API payment manual</a>.</p>
|
||
<p>This page will elaborate on the actions required to work with payments using the <strong>MTProto API</strong>.</p>
|
||
<blockquote>
|
||
<p>A simplified version of the process is available only for bots using the <a href="/bots/payments">bot API</a>.</p>
|
||
</blockquote>
|
||
<p>The first step for bots is <a href="/bots/payments#the-payments-api">enable payments as described here »</a>.</p>
|
||
<p>Then, we work with payments as follows.</p>
|
||
<h3><a class="anchor" href="#1-create-invoice" id="1-create-invoice" name="1-create-invoice"><i class="anchor-icon"></i></a>1. Create Invoice</h3>
|
||
<pre><code><a href='/constructor/inputWebDocument'>inputWebDocument</a>#9bed434d url:<a href='/type/string'>string</a> size:<a href='/type/int'>int</a> mime_type:<a href='/type/string'>string</a> attributes:<a href='/type/Vector%20t'>Vector</a><<a href='/type/DocumentAttribute'>DocumentAttribute</a>> = <a href='/type/InputWebDocument'>InputWebDocument</a>;
|
||
|
||
<a href='/constructor/labeledPrice'>labeledPrice</a>#cb296bf8 label:<a href='/type/string'>string</a> amount:<a href='/type/long'>long</a> = <a href='/type/LabeledPrice'>LabeledPrice</a>;
|
||
|
||
<a href='/constructor/invoice'>invoice</a>#cd886e0 flags:<a href='/type/%23'>#</a> test:flags.0?<a href='/constructor/true'>true</a> name_requested:flags.1?<a href='/constructor/true'>true</a> phone_requested:flags.2?<a href='/constructor/true'>true</a> email_requested:flags.3?<a href='/constructor/true'>true</a> shipping_address_requested:flags.4?<a href='/constructor/true'>true</a> flexible:flags.5?<a href='/constructor/true'>true</a> phone_to_provider:flags.6?<a href='/constructor/true'>true</a> email_to_provider:flags.7?<a href='/constructor/true'>true</a> currency:<a href='/type/string'>string</a> prices:<a href='/type/Vector%20t'>Vector</a><<a href='/type/LabeledPrice'>LabeledPrice</a>> max_tip_amount:flags.8?<a href='/type/long'>long</a> suggested_tip_amounts:flags.8?<a href='/type/Vector%20t'>Vector</a><<a href='/type/long'>long</a>> = <a href='/type/Invoice'>Invoice</a>;
|
||
|
||
<a href='/constructor/inputMediaInvoice'>inputMediaInvoice</a>#d9799874 flags:<a href='/type/%23'>#</a> title:<a href='/type/string'>string</a> description:<a href='/type/string'>string</a> photo:flags.0?<a href='/type/InputWebDocument'>InputWebDocument</a> invoice:<a href='/type/Invoice'>Invoice</a> payload:<a href='/type/bytes'>bytes</a> provider:<a href='/type/string'>string</a> provider_data:<a href='/type/DataJSON'>DataJSON</a> start_param:flags.1?<a href='/type/string'>string</a> = <a href='/type/InputMedia'>InputMedia</a>;
|
||
|
||
---functions---
|
||
|
||
<a href='/method/messages.sendMedia'>messages.sendMedia</a>#3491eba9 flags:<a href='/type/%23'>#</a> silent:flags.5?<a href='/constructor/true'>true</a> background:flags.6?<a href='/constructor/true'>true</a> clear_draft:flags.7?<a href='/constructor/true'>true</a> peer:<a href='/type/InputPeer'>InputPeer</a> reply_to_msg_id:flags.0?<a href='/type/int'>int</a> media:<a href='/type/InputMedia'>InputMedia</a> message:<a href='/type/string'>string</a> random_id:<a href='/type/long'>long</a> reply_markup:flags.2?<a href='/type/ReplyMarkup'>ReplyMarkup</a> entities:flags.3?<a href='/type/Vector%20t'>Vector</a><<a href='/type/MessageEntity'>MessageEntity</a>> schedule_date:flags.10?<a href='/type/int'>int</a> = <a href='/type/Updates'>Updates</a>;</code></pre>
|
||
<p>The user contacts the bot and requests to purchase something.
|
||
The bot forms an <a href="/constructor/inputMediaInvoice">inputMediaInvoice</a> with an <a href="/constructor/invoice">invoice</a> constructor with a description of the goods or service, amount to be paid, as well as requested shipping info.
|
||
The <code>provider</code> parameter of the <a href="/constructor/inputMediaInvoice">inputMediaInvoice</a> constructor is where you put the token value that <a href="/bots/payments#the-payments-api">you've obtained earlier via Botfather</a>. It is possible for one merchant bot to use several different tokens for different users or different goods and services.</p>
|
||
<p>Use the <a href="/method/messages.sendMedia">messages.sendMedia</a> method to send the <a href="/constructor/invoice">invoice</a>.
|
||
You can also attach an inline keyboard to the message using the <code>reply_markup</code> field: if provided, the first button must be a <a href="/constructor/keyboardButtonBuy">keyboardButtonBuy</a> button. Otherwise, an inline keyboard will be generated automatically, with a <code>Pay 'total price'</code> <a href="/constructor/keyboardButtonBuy">keyboardButtonBuy</a> as only button.</p>
|
||
<p>An invoice message with a pay button can only be sent to a private chat with the user. Groups and channels are not supported.</p>
|
||
<h3><a class="anchor" href="#2-order-information" id="2-order-information" name="2-order-information"><i class="anchor-icon"></i></a>2. Order information</h3>
|
||
<h4><a class="anchor" href="#21-invoice-message" id="21-invoice-message" name="21-invoice-message"><i class="anchor-icon"></i></a>2.1 Invoice message</h4>
|
||
<pre><code><a href='/constructor/keyboardButtonBuy'>keyboardButtonBuy</a>#afd93fbb text:<a href='/type/string'>string</a> = <a href='/type/KeyboardButton'>KeyboardButton</a>;
|
||
|
||
<a href='/constructor/keyboardButtonRow'>keyboardButtonRow</a>#77608b83 buttons:<a href='/type/Vector%20t'>Vector</a><<a href='/type/KeyboardButton'>KeyboardButton</a>> = <a href='/type/KeyboardButtonRow'>KeyboardButtonRow</a>;
|
||
<a href='/constructor/replyInlineMarkup'>replyInlineMarkup</a>#48a30254 rows:<a href='/type/Vector%20t'>Vector</a><<a href='/type/KeyboardButtonRow'>KeyboardButtonRow</a>> = <a href='/type/ReplyMarkup'>ReplyMarkup</a>;
|
||
|
||
<a href='/constructor/webDocument'>webDocument</a>#1c570ed1 url:<a href='/type/string'>string</a> access_hash:<a href='/type/long'>long</a> size:<a href='/type/int'>int</a> mime_type:<a href='/type/string'>string</a> attributes:<a href='/type/Vector%20t'>Vector</a><<a href='/type/DocumentAttribute'>DocumentAttribute</a>> = <a href='/type/WebDocument'>WebDocument</a>;
|
||
<a href='/constructor/webDocumentNoProxy'>webDocumentNoProxy</a>#f9c8bcc6 url:<a href='/type/string'>string</a> size:<a href='/type/int'>int</a> mime_type:<a href='/type/string'>string</a> attributes:<a href='/type/Vector%20t'>Vector</a><<a href='/type/DocumentAttribute'>DocumentAttribute</a>> = <a href='/type/WebDocument'>WebDocument</a>;
|
||
|
||
<a href='/constructor/messageMediaInvoice'>messageMediaInvoice</a>#84551347 flags:<a href='/type/%23'>#</a> shipping_address_requested:flags.1?<a href='/constructor/true'>true</a> test:flags.3?<a href='/constructor/true'>true</a> title:<a href='/type/string'>string</a> description:<a href='/type/string'>string</a> photo:flags.0?<a href='/type/WebDocument'>WebDocument</a> receipt_msg_id:flags.2?<a href='/type/int'>int</a> currency:<a href='/type/string'>string</a> total_amount:<a href='/type/long'>long</a> start_param:<a href='/type/string'>string</a> = <a href='/type/MessageMedia'>MessageMedia</a>;
|
||
|
||
<a href='/constructor/message'>message</a>#85d6cbe2 flags:<a href='/type/%23'>#</a> out:flags.1?<a href='/constructor/true'>true</a> mentioned:flags.4?<a href='/constructor/true'>true</a> media_unread:flags.5?<a href='/constructor/true'>true</a> silent:flags.13?<a href='/constructor/true'>true</a> post:flags.14?<a href='/constructor/true'>true</a> from_scheduled:flags.18?<a href='/constructor/true'>true</a> legacy:flags.19?<a href='/constructor/true'>true</a> edit_hide:flags.21?<a href='/constructor/true'>true</a> pinned:flags.24?<a href='/constructor/true'>true</a> id:<a href='/type/int'>int</a> from_id:flags.8?<a href='/type/Peer'>Peer</a> peer_id:<a href='/type/Peer'>Peer</a> fwd_from:flags.2?<a href='/type/MessageFwdHeader'>MessageFwdHeader</a> via_bot_id:flags.11?<a href='/type/long'>long</a> reply_to:flags.3?<a href='/type/MessageReplyHeader'>MessageReplyHeader</a> date:<a href='/type/int'>int</a> message:<a href='/type/string'>string</a> media:flags.9?<a href='/type/MessageMedia'>MessageMedia</a> reply_markup:flags.6?<a href='/type/ReplyMarkup'>ReplyMarkup</a> entities:flags.7?<a href='/type/Vector%20t'>Vector</a><<a href='/type/MessageEntity'>MessageEntity</a>> views:flags.10?<a href='/type/int'>int</a> forwards:flags.10?<a href='/type/int'>int</a> replies:flags.23?<a href='/type/MessageReplies'>MessageReplies</a> edit_date:flags.15?<a href='/type/int'>int</a> post_author:flags.16?<a href='/type/string'>string</a> grouped_id:flags.17?<a href='/type/long'>long</a> restriction_reason:flags.22?<a href='/type/Vector%20t'>Vector</a><<a href='/type/RestrictionReason'>RestrictionReason</a>> ttl_period:flags.25?<a href='/type/int'>int</a> = <a href='/type/Message'>Message</a>;
|
||
|
||
<a href='/constructor/updateNewMessage'>updateNewMessage</a>#1f2b0afd message:<a href='/type/Message'>Message</a> pts:<a href='/type/int'>int</a> pts_count:<a href='/type/int'>int</a> = <a href='/type/Update'>Update</a>;</code></pre>
|
||
<p>The user receives an <a href="/constructor/updateNewMessage">updateNewMessage</a> constructor from the bot, containing a <a href="/constructor/messageMediaInvoice">messageMediaInvoice</a> constructor with basic info about the product.</p>
|
||
<p>The <a href="/constructor/message">message</a> will also have a <a href="/constructor/replyInlineMarkup">replyInlineMarkup</a> keyboard attached to it.
|
||
The the first button of the keyboard will always be a <a href="/constructor/keyboardButtonBuy">keyboardButtonBuy</a> button.</p>
|
||
<h4><a class="anchor" href="#22-getting-invoice-info-about-the-product" id="22-getting-invoice-info-about-the-product" name="22-getting-invoice-info-about-the-product"><i class="anchor-icon"></i></a>2.2 Getting invoice info about the product</h4>
|
||
<pre><code><a href='/constructor/invoice'>invoice</a>#cd886e0 flags:<a href='/type/%23'>#</a> test:flags.0?<a href='/constructor/true'>true</a> name_requested:flags.1?<a href='/constructor/true'>true</a> phone_requested:flags.2?<a href='/constructor/true'>true</a> email_requested:flags.3?<a href='/constructor/true'>true</a> shipping_address_requested:flags.4?<a href='/constructor/true'>true</a> flexible:flags.5?<a href='/constructor/true'>true</a> phone_to_provider:flags.6?<a href='/constructor/true'>true</a> email_to_provider:flags.7?<a href='/constructor/true'>true</a> currency:<a href='/type/string'>string</a> prices:<a href='/type/Vector%20t'>Vector</a><<a href='/type/LabeledPrice'>LabeledPrice</a>> max_tip_amount:flags.8?<a href='/type/long'>long</a> suggested_tip_amounts:flags.8?<a href='/type/Vector%20t'>Vector</a><<a href='/type/long'>long</a>> = <a href='/type/Invoice'>Invoice</a>;
|
||
|
||
<a href='/constructor/paymentRequestedInfo'>paymentRequestedInfo</a>#909c3f94 flags:<a href='/type/%23'>#</a> name:flags.0?<a href='/type/string'>string</a> phone:flags.1?<a href='/type/string'>string</a> email:flags.2?<a href='/type/string'>string</a> shipping_address:flags.3?<a href='/type/PostAddress'>PostAddress</a> = <a href='/type/PaymentRequestedInfo'>PaymentRequestedInfo</a>;
|
||
|
||
<a href='/constructor/paymentSavedCredentialsCard'>paymentSavedCredentialsCard</a>#cdc27a1f id:<a href='/type/string'>string</a> title:<a href='/type/string'>string</a> = <a href='/type/PaymentSavedCredentials'>PaymentSavedCredentials</a>;
|
||
|
||
<a href='/constructor/payments.paymentForm'>payments.paymentForm</a>#1694761b flags:<a href='/type/%23'>#</a> can_save_credentials:flags.2?<a href='/constructor/true'>true</a> password_missing:flags.3?<a href='/constructor/true'>true</a> form_id:<a href='/type/long'>long</a> bot_id:<a href='/type/long'>long</a> invoice:<a href='/type/Invoice'>Invoice</a> provider_id:<a href='/type/long'>long</a> url:<a href='/type/string'>string</a> native_provider:flags.4?<a href='/type/string'>string</a> native_params:flags.4?<a href='/type/DataJSON'>DataJSON</a> saved_info:flags.0?<a href='/type/PaymentRequestedInfo'>PaymentRequestedInfo</a> saved_credentials:flags.1?<a href='/type/PaymentSavedCredentials'>PaymentSavedCredentials</a> users:<a href='/type/Vector%20t'>Vector</a><<a href='/type/User'>User</a>> = <a href='/type/payments.PaymentForm'>payments.PaymentForm</a>;
|
||
|
||
---functions---
|
||
|
||
<a href='/method/payments.getPaymentForm'>payments.getPaymentForm</a>#8a333c8d flags:<a href='/type/%23'>#</a> peer:<a href='/type/InputPeer'>InputPeer</a> msg_id:<a href='/type/int'>int</a> theme_params:flags.0?<a href='/type/DataJSON'>DataJSON</a> = <a href='/type/payments.PaymentForm'>payments.PaymentForm</a>;</code></pre>
|
||
<p>If the user clicks on the <a href="/constructor/keyboardButtonBuy">keyboardButtonBuy</a> button, the client proceeds to call <a href="/method/payments.getPaymentForm">payments.getPaymentForm</a> with the message ID of the invoice preview message to get the <a href="/constructor/payments.paymentForm">payment form</a>.</p>
|
||
<p>The returned form will contain fields that should be passed to the payment provider along with the full <a href="/constructor/invoice">invoice</a>.
|
||
The payment form also contains info about previously saved payment credentials and order information (name, phone number, email, shipping address & so on).</p>
|
||
<p>The full <a href="/constructor/invoice">invoice</a> contains info about the information required for the order, the price and the currency, and whether this is a <code>test</code> order.</p>
|
||
<h4><a class="anchor" href="#23-verifying-information" id="23-verifying-information" name="23-verifying-information"><i class="anchor-icon"></i></a>2.3 Verifying information</h4>
|
||
<pre><code><a href='/constructor/invoice'>invoice</a>#cd886e0 flags:<a href='/type/%23'>#</a> test:flags.0?<a href='/constructor/true'>true</a> name_requested:flags.1?<a href='/constructor/true'>true</a> phone_requested:flags.2?<a href='/constructor/true'>true</a> email_requested:flags.3?<a href='/constructor/true'>true</a> shipping_address_requested:flags.4?<a href='/constructor/true'>true</a> flexible:flags.5?<a href='/constructor/true'>true</a> phone_to_provider:flags.6?<a href='/constructor/true'>true</a> email_to_provider:flags.7?<a href='/constructor/true'>true</a> currency:<a href='/type/string'>string</a> prices:<a href='/type/Vector%20t'>Vector</a><<a href='/type/LabeledPrice'>LabeledPrice</a>> max_tip_amount:flags.8?<a href='/type/long'>long</a> suggested_tip_amounts:flags.8?<a href='/type/Vector%20t'>Vector</a><<a href='/type/long'>long</a>> = <a href='/type/Invoice'>Invoice</a>;
|
||
|
||
<a href='/constructor/postAddress'>postAddress</a>#1e8caaeb street_line1:<a href='/type/string'>string</a> street_line2:<a href='/type/string'>string</a> city:<a href='/type/string'>string</a> state:<a href='/type/string'>string</a> country_iso2:<a href='/type/string'>string</a> post_code:<a href='/type/string'>string</a> = <a href='/type/PostAddress'>PostAddress</a>;
|
||
|
||
<a href='/constructor/paymentRequestedInfo'>paymentRequestedInfo</a>#909c3f94 flags:<a href='/type/%23'>#</a> name:flags.0?<a href='/type/string'>string</a> phone:flags.1?<a href='/type/string'>string</a> email:flags.2?<a href='/type/string'>string</a> shipping_address:flags.3?<a href='/type/PostAddress'>PostAddress</a> = <a href='/type/PaymentRequestedInfo'>PaymentRequestedInfo</a>;
|
||
|
||
<a href='/constructor/payments.validatedRequestedInfo'>payments.validatedRequestedInfo</a>#d1451883 flags:<a href='/type/%23'>#</a> id:flags.0?<a href='/type/string'>string</a> shipping_options:flags.1?<a href='/type/Vector%20t'>Vector</a><<a href='/type/ShippingOption'>ShippingOption</a>> = <a href='/type/payments.ValidatedRequestedInfo'>payments.ValidatedRequestedInfo</a>;
|
||
|
||
---functions---
|
||
|
||
<a href='/method/payments.validateRequestedInfo'>payments.validateRequestedInfo</a>#db103170 flags:<a href='/type/%23'>#</a> save:flags.0?<a href='/constructor/true'>true</a> peer:<a href='/type/InputPeer'>InputPeer</a> msg_id:<a href='/type/int'>int</a> info:<a href='/type/PaymentRequestedInfo'>PaymentRequestedInfo</a> = <a href='/type/payments.ValidatedRequestedInfo'>payments.ValidatedRequestedInfo</a>;</code></pre>
|
||
<p>If any data at all is requested by the <a href="/constructor/invoice"><strong>invoice</strong></a> (<code>name_requested</code>, <code>phone_requested</code>, <code>email_requested</code>, <code>shipping_address_requested</code>), the user must call <a href="/method/payments.validateRequestedInfo">payments.validateRequestedInfo</a>, providing the required data (as usual, <code>msg_id</code> is the ID of the invoice message).
|
||
The user can choose to save order information for future use by setting the <code>save</code> flag.
|
||
Data can be autofilled as described in <a href="#2-3-1-autofill">autofill</a>.</p>
|
||
<p>If no errors are found in the submitted info, the <a href="/constructor/payments.ValidatedRequestedInfo">response</a> of the method will contain an <code>id</code> flag, to be used later to complete the payment.</p>
|
||
<p>If the <code>flexible</code> flag of the invoice is set, calling the <a href="/method/payments.validateRequestedInfo">payments.validateRequestedInfo</a> method will send a <a href="/constructor/updateBotShippingQuery">shipping query update</a> to the bot, to which the bot will reply with the available shipping options for the specified address <a href="#2-4-select-delivery-option">as described here »</a>.
|
||
The return value in this case will also contain a <code>shipping_options</code> field with the available shipping options.</p>
|
||
<p>If any errors are found in the submmitted data, a <a href="/constructor/updateServiceNotification">service notification</a> will be sent to the user, with a description of the error from the bot.</p>
|
||
<h4><a class="anchor" href="#231-autofill" id="231-autofill" name="231-autofill"><i class="anchor-icon"></i></a>2.3.1 Autofill</h4>
|
||
<pre><code><a href='/constructor/payments.savedInfo'>payments.savedInfo</a>#fb8fe43c flags:<a href='/type/%23'>#</a> has_saved_credentials:flags.1?<a href='/constructor/true'>true</a> saved_info:flags.0?<a href='/type/PaymentRequestedInfo'>PaymentRequestedInfo</a> = <a href='/type/payments.SavedInfo'>payments.SavedInfo</a>;
|
||
|
||
---functions---
|
||
|
||
<a href='/method/payments.getSavedInfo'>payments.getSavedInfo</a>#227d824b = <a href='/type/payments.SavedInfo'>payments.SavedInfo</a>;
|
||
<a href='/method/payments.clearSavedInfo'>payments.clearSavedInfo</a>#d83d70c1 flags:<a href='/type/%23'>#</a> credentials:flags.0?<a href='/constructor/true'>true</a> info:flags.1?<a href='/constructor/true'>true</a> = <a href='/type/Bool'>Bool</a>;</code></pre>
|
||
<p>The requested fields can be autofilled with the info provided in the <code>saved_info</code> field of the <a href="/constructor/payments.paymentForm">payment form</a>, or with the info fetched manually using <a href="/method/payments.getSavedInfo">payments.getSavedInfo</a>.</p>
|
||
<p>Saved order information can also be cleared using <a href="/method/payments.clearSavedInfo">payments.clearSavedInfo</a>.</p>
|
||
<h4><a class="anchor" href="#24-select-delivery-option" id="24-select-delivery-option" name="24-select-delivery-option"><i class="anchor-icon"></i></a>2.4 Select delivery option</h4>
|
||
<pre><code><a href='/constructor/labeledPrice'>labeledPrice</a>#cb296bf8 label:<a href='/type/string'>string</a> amount:<a href='/type/long'>long</a> = <a href='/type/LabeledPrice'>LabeledPrice</a>;
|
||
|
||
<a href='/constructor/shippingOption'>shippingOption</a>#b6213cdf id:<a href='/type/string'>string</a> title:<a href='/type/string'>string</a> prices:<a href='/type/Vector%20t'>Vector</a><<a href='/type/LabeledPrice'>LabeledPrice</a>> = <a href='/type/ShippingOption'>ShippingOption</a>;
|
||
|
||
<a href='/constructor/updateBotShippingQuery'>updateBotShippingQuery</a>#b5aefd7d query_id:<a href='/type/long'>long</a> user_id:<a href='/type/long'>long</a> payload:<a href='/type/bytes'>bytes</a> shipping_address:<a href='/type/PostAddress'>PostAddress</a> = <a href='/type/Update'>Update</a>;
|
||
|
||
---functions---
|
||
|
||
<a href='/method/messages.setBotShippingResults'>messages.setBotShippingResults</a>#e5f672fa flags:<a href='/type/%23'>#</a> query_id:<a href='/type/long'>long</a> error:flags.0?<a href='/type/string'>string</a> shipping_options:flags.1?<a href='/type/Vector%20t'>Vector</a><<a href='/type/ShippingOption'>ShippingOption</a>> = <a href='/type/Bool'>Bool</a>;</code></pre>
|
||
<p>If a shipping address was requested and the bot included the parameter <code>flexible</code>, when the user <a href="#2-3-verifying-information">validates order information</a> the Telegram API will send an <a href="/constructor/updateBotShippingQuery">updateBotShippingQuery</a> to the bot.
|
||
The bot must respond using <a href="/method/messages.setBotShippingResults">messages.setBotShippingResults</a> either with a list of possible delivery options and the relevant delivery prices, or with an error (for example, if delivery to the specified address is not possible).</p>
|
||
<p>The returned shipping options or the shipping error will be returned to the user while <a href="#2-3-verifying-information">validating order information</a>.</p>
|
||
<h3><a class="anchor" href="#3-payment" id="3-payment" name="3-payment"><i class="anchor-icon"></i></a>3. Payment</h3>
|
||
<pre><code><a href='/constructor/inputPaymentCredentialsSaved'>inputPaymentCredentialsSaved</a>#c10eb2cf id:<a href='/type/string'>string</a> tmp_password:<a href='/type/bytes'>bytes</a> = <a href='/type/InputPaymentCredentials'>InputPaymentCredentials</a>;
|
||
<a href='/constructor/inputPaymentCredentials'>inputPaymentCredentials</a>#3417d728 flags:<a href='/type/%23'>#</a> save:flags.0?<a href='/constructor/true'>true</a> data:<a href='/type/DataJSON'>DataJSON</a> = <a href='/type/InputPaymentCredentials'>InputPaymentCredentials</a>;
|
||
<a href='/constructor/inputPaymentCredentialsApplePay'>inputPaymentCredentialsApplePay</a>#aa1c39f payment_data:<a href='/type/DataJSON'>DataJSON</a> = <a href='/type/InputPaymentCredentials'>InputPaymentCredentials</a>;
|
||
<a href='/constructor/inputPaymentCredentialsGooglePay'>inputPaymentCredentialsGooglePay</a>#8ac32801 payment_token:<a href='/type/DataJSON'>DataJSON</a> = <a href='/type/InputPaymentCredentials'>InputPaymentCredentials</a>;
|
||
|
||
|
||
<a href='/constructor/payments.paymentForm'>payments.paymentForm</a>#1694761b flags:<a href='/type/%23'>#</a> can_save_credentials:flags.2?<a href='/constructor/true'>true</a> password_missing:flags.3?<a href='/constructor/true'>true</a> form_id:<a href='/type/long'>long</a> bot_id:<a href='/type/long'>long</a> invoice:<a href='/type/Invoice'>Invoice</a> provider_id:<a href='/type/long'>long</a> url:<a href='/type/string'>string</a> native_provider:flags.4?<a href='/type/string'>string</a> native_params:flags.4?<a href='/type/DataJSON'>DataJSON</a> saved_info:flags.0?<a href='/type/PaymentRequestedInfo'>PaymentRequestedInfo</a> saved_credentials:flags.1?<a href='/type/PaymentSavedCredentials'>PaymentSavedCredentials</a> users:<a href='/type/Vector%20t'>Vector</a><<a href='/type/User'>User</a>> = <a href='/type/payments.PaymentForm'>payments.PaymentForm</a>;</code></pre>
|
||
<h4><a class="anchor" href="#31-web-payment" id="31-web-payment" name="31-web-payment"><i class="anchor-icon"></i></a>3.1 Web payment</h4>
|
||
<pre><code><a href='/constructor/inputPaymentCredentials'>inputPaymentCredentials</a>#3417d728 flags:<a href='/type/%23'>#</a> save:flags.0?<a href='/constructor/true'>true</a> data:<a href='/type/DataJSON'>DataJSON</a> = <a href='/type/InputPaymentCredentials'>InputPaymentCredentials</a>;
|
||
|
||
<a href='/constructor/payments.paymentForm'>payments.paymentForm</a>#1694761b flags:<a href='/type/%23'>#</a> can_save_credentials:flags.2?<a href='/constructor/true'>true</a> password_missing:flags.3?<a href='/constructor/true'>true</a> form_id:<a href='/type/long'>long</a> bot_id:<a href='/type/long'>long</a> invoice:<a href='/type/Invoice'>Invoice</a> provider_id:<a href='/type/long'>long</a> url:<a href='/type/string'>string</a> native_provider:flags.4?<a href='/type/string'>string</a> native_params:flags.4?<a href='/type/DataJSON'>DataJSON</a> saved_info:flags.0?<a href='/type/PaymentRequestedInfo'>PaymentRequestedInfo</a> saved_credentials:flags.1?<a href='/type/PaymentSavedCredentials'>PaymentSavedCredentials</a> users:<a href='/type/Vector%20t'>Vector</a><<a href='/type/User'>User</a>> = <a href='/type/payments.PaymentForm'>payments.PaymentForm</a>;</code></pre>
|
||
<p>Typically, payment takes place by opening the <code>url</code> in the specified <a href="/constructor/payments.paymentForm">payment form</a>, which leads to a payment form on the website of the payment gateway.
|
||
Once the user finishes entering their payment credentials, a <a href="/api/web-events"><code>payment_form_submit</code> web event</a> is generated by the payment gateway, containing <code>data</code> and <code>title</code> JSON fields.</p>
|
||
<p>The <code>title</code> is used by the client app to represent the payment credentials (typically a censored version of credit card information).
|
||
The <code>data</code> is used to generate an <a href="/constructor/inputPaymentCredentials">inputPaymentCredentials</a> constructor.
|
||
Eventually, you can set the <code>save</code> flag to save the credit card info for future use, only if <a href="/api/srp">2FA</a> is enabled.</p>
|
||
<p>Telegram <strong>does not</strong> have access to your card information. Credit card details will be handled only by the payment system.</p>
|
||
<h4><a class="anchor" href="#32-native-payment" id="32-native-payment" name="32-native-payment"><i class="anchor-icon"></i></a>3.2 Native payment</h4>
|
||
<pre><code><a href='/constructor/inputPaymentCredentials'>inputPaymentCredentials</a>#3417d728 flags:<a href='/type/%23'>#</a> save:flags.0?<a href='/constructor/true'>true</a> data:<a href='/type/DataJSON'>DataJSON</a> = <a href='/type/InputPaymentCredentials'>InputPaymentCredentials</a>;
|
||
|
||
<a href='/constructor/payments.paymentForm'>payments.paymentForm</a>#1694761b flags:<a href='/type/%23'>#</a> can_save_credentials:flags.2?<a href='/constructor/true'>true</a> password_missing:flags.3?<a href='/constructor/true'>true</a> form_id:<a href='/type/long'>long</a> bot_id:<a href='/type/long'>long</a> invoice:<a href='/type/Invoice'>Invoice</a> provider_id:<a href='/type/long'>long</a> url:<a href='/type/string'>string</a> native_provider:flags.4?<a href='/type/string'>string</a> native_params:flags.4?<a href='/type/DataJSON'>DataJSON</a> saved_info:flags.0?<a href='/type/PaymentRequestedInfo'>PaymentRequestedInfo</a> saved_credentials:flags.1?<a href='/type/PaymentSavedCredentials'>PaymentSavedCredentials</a> users:<a href='/type/Vector%20t'>Vector</a><<a href='/type/User'>User</a>> = <a href='/type/payments.PaymentForm'>payments.PaymentForm</a>;</code></pre>
|
||
<p>Most telegram apps support working natively with the native APIs of some payment providers, without opening the website of the payment and receiving a JS event.</p>
|
||
<p>This is done using the JSON <code>native_params</code> parameters field of the <a href="/constructor/payments.paymentForm">payments.paymentForm</a> constructor, which contains an object, which can contain one or more of the following fields:</p>
|
||
<ul>
|
||
<li><code>publishable_key</code>: Stripe API publishable key</li>
|
||
<li><code>apple_pay_merchant_id</code>: Apple Pay merchant ID</li>
|
||
<li><code>android_pay_public_key</code>: Android Pay public key</li>
|
||
<li><code>android_pay_bgcolor</code>: Android Pay form background color</li>
|
||
<li><code>android_pay_inverse</code>: Whether to use the dark theme in the Android Pay form</li>
|
||
<li><code>need_country</code>: True, if the user country must be provided,</li>
|
||
<li><code>need_zip</code>: True, if the user ZIP/postal code must be provided,</li>
|
||
<li><code>need_cardholder_name</code>: True, if the cardholder name must be provided</li>
|
||
</ul>
|
||
<p>The payment gateway to use is decided based on the value of the <code>native_provider</code> field.</p>
|
||
<h5><a class="anchor" href="#321-stripe" id="321-stripe" name="321-stripe"><i class="anchor-icon"></i></a>3.2.1 Stripe</h5>
|
||
<pre><code><a href='/constructor/inputPaymentCredentials'>inputPaymentCredentials</a>#3417d728 flags:<a href='/type/%23'>#</a> save:flags.0?<a href='/constructor/true'>true</a> data:<a href='/type/DataJSON'>DataJSON</a> = <a href='/type/InputPaymentCredentials'>InputPaymentCredentials</a>;
|
||
|
||
<a href='/constructor/payments.paymentForm'>payments.paymentForm</a>#1694761b flags:<a href='/type/%23'>#</a> can_save_credentials:flags.2?<a href='/constructor/true'>true</a> password_missing:flags.3?<a href='/constructor/true'>true</a> form_id:<a href='/type/long'>long</a> bot_id:<a href='/type/long'>long</a> invoice:<a href='/type/Invoice'>Invoice</a> provider_id:<a href='/type/long'>long</a> url:<a href='/type/string'>string</a> native_provider:flags.4?<a href='/type/string'>string</a> native_params:flags.4?<a href='/type/DataJSON'>DataJSON</a> saved_info:flags.0?<a href='/type/PaymentRequestedInfo'>PaymentRequestedInfo</a> saved_credentials:flags.1?<a href='/type/PaymentSavedCredentials'>PaymentSavedCredentials</a> users:<a href='/type/Vector%20t'>Vector</a><<a href='/type/User'>User</a>> = <a href='/type/payments.PaymentForm'>payments.PaymentForm</a>;</code></pre>
|
||
<p>If the <code>native_provider</code> field is set and equal to <code>stripe</code>, the client can make use of the <a href="https://stripe.com/docs/api/tokens/object">native Stripe token APIs</a> with the <code>publishable_key</code> from the <code>native_params</code> to add a payment method to Stripe, and then use the token <code>type</code> and <code>id</code> to generate a JSON object:</p>
|
||
<pre><code>{"type":"token.type", "id":"token.id"}"</code></pre>
|
||
<p>The generated JSON object can then be passed to the <code>data</code> field of the <a href="/constructor/inputPaymentCredentials">inputPaymentCredentials</a>.
|
||
Eventually, you can set the <code>save</code> flag to save the credit card info for future use, only if <a href="/api/srp">2FA</a> is enabled.</p>
|
||
<p>Telegram <strong>does not</strong> have access to your card information. Credit card details will be handled only by the payment system.</p>
|
||
<p>Example implementation: <a href="https://github.com/DrKLO/Telegram">Telegram for Android</a>.</p>
|
||
<h4><a class="anchor" href="#33-apple-pay" id="33-apple-pay" name="33-apple-pay"><i class="anchor-icon"></i></a>3.3 Apple pay</h4>
|
||
<pre><code><a href='/constructor/inputPaymentCredentialsApplePay'>inputPaymentCredentialsApplePay</a>#aa1c39f payment_data:<a href='/type/DataJSON'>DataJSON</a> = <a href='/type/InputPaymentCredentials'>InputPaymentCredentials</a>;</code></pre>
|
||
<p>On iOS devices, Apple Pay can be used to generate payment data, which is then sent using the <a href="/constructor/inputPaymentCredentialsApplePay">inputPaymentCredentialsApplePay</a> constructor.</p>
|
||
<p>Example implementation: <a href="https://github.com/TelegramMessenger/Telegram-iOS/">Telegram for iOS</a>.</p>
|
||
<h4><a class="anchor" href="#34-android-pay" id="34-android-pay" name="34-android-pay"><i class="anchor-icon"></i></a>3.4 Android pay</h4>
|
||
<pre><code><a href='/constructor/inputPaymentCredentialsGooglePay'>inputPaymentCredentialsGooglePay</a>#8ac32801 payment_token:<a href='/type/DataJSON'>DataJSON</a> = <a href='/type/InputPaymentCredentials'>InputPaymentCredentials</a>;</code></pre>
|
||
<p>On Android devices, Google Pay can be used to generate payment data, which is then sent using the <a href="/constructor/inputPaymentCredentialsApplePay">inputPaymentCredentialsGooglePay</a> constructor.</p>
|
||
<p>Example implementation: <a href="https://github.com/DrKLO/Telegram/blob/ff5735503e068a6f1cada09b977f633df7caf98d/TMessagesProj/src/main/java/org/telegram/ui/PaymentFormActivity.java">Telegram for Android</a>.</p>
|
||
<h4><a class="anchor" href="#35-using-saved-payment-credentials" id="35-using-saved-payment-credentials" name="35-using-saved-payment-credentials"><i class="anchor-icon"></i></a>3.5 Using saved payment credentials</h4>
|
||
<pre><code><a href='/constructor/inputPaymentCredentialsSaved'>inputPaymentCredentialsSaved</a>#c10eb2cf id:<a href='/type/string'>string</a> tmp_password:<a href='/type/bytes'>bytes</a> = <a href='/type/InputPaymentCredentials'>InputPaymentCredentials</a>;
|
||
|
||
<a href='/constructor/paymentSavedCredentialsCard'>paymentSavedCredentialsCard</a>#cdc27a1f id:<a href='/type/string'>string</a> title:<a href='/type/string'>string</a> = <a href='/type/PaymentSavedCredentials'>PaymentSavedCredentials</a>;
|
||
|
||
<a href='/constructor/payments.paymentForm'>payments.paymentForm</a>#1694761b flags:<a href='/type/%23'>#</a> can_save_credentials:flags.2?<a href='/constructor/true'>true</a> password_missing:flags.3?<a href='/constructor/true'>true</a> form_id:<a href='/type/long'>long</a> bot_id:<a href='/type/long'>long</a> invoice:<a href='/type/Invoice'>Invoice</a> provider_id:<a href='/type/long'>long</a> url:<a href='/type/string'>string</a> native_provider:flags.4?<a href='/type/string'>string</a> native_params:flags.4?<a href='/type/DataJSON'>DataJSON</a> saved_info:flags.0?<a href='/type/PaymentRequestedInfo'>PaymentRequestedInfo</a> saved_credentials:flags.1?<a href='/type/PaymentSavedCredentials'>PaymentSavedCredentials</a> users:<a href='/type/Vector%20t'>Vector</a><<a href='/type/User'>User</a>> = <a href='/type/payments.PaymentForm'>payments.PaymentForm</a>;
|
||
|
||
<a href='/constructor/account.tmpPassword'>account.tmpPassword</a>#db64fd34 tmp_password:<a href='/type/bytes'>bytes</a> valid_until:<a href='/type/int'>int</a> = <a href='/type/account.TmpPassword'>account.TmpPassword</a>;
|
||
|
||
---functions---
|
||
|
||
<a href='/method/account.getTmpPassword'>account.getTmpPassword</a>#449e0b51 password:<a href='/type/InputCheckPasswordSRP'>InputCheckPasswordSRP</a> period:<a href='/type/int'>int</a> = <a href='/type/account.TmpPassword'>account.TmpPassword</a>;</code></pre>
|
||
<p>To reuse saved payment methods, the <code>saved_credentials</code> field of the <a href="/constructor/payments.paymentForm">payment form</a> is used.
|
||
The <code>title</code> of the <a href="/constructor/paymentSavedCredentialsCard">paymentSavedCredentialsCard</a> can be used to preview a censored version of credit card info.
|
||
The <code>id</code> field is provided by the payment provider directly to the Telegram servers when saving the payment method, and identifies the payment method.
|
||
Full credit card info <strong>is not</strong> saved on Telegram Servers, and cannot be fetched by the user.</p>
|
||
<p>In order to <strong>use</strong> the saved payment method, <a href="/api/srp">2FA</a> must be enabled: the user must verify their identity by entering their <a href="/api/srp">2FA</a> password, which is then used as described in the <a href="/api/srp">SRP docs</a> to generate SRP parameters which must be passed to <a href="/method/account.getTmpPassword">account.getTmpPassword</a>.</p>
|
||
<p>The generated temporary password can then be used to make payments using the saved credentials using the <a href="/constructor/inputPaymentCredentialsSaved">inputPaymentCredentialsSaved</a> constructor.</p>
|
||
<ul>
|
||
<li>The <code>id</code> field is the <a href="/constructor/paymentSavedCredentialsCard">paymentSavedCredentialsCard</a> <code>id</code>.</li>
|
||
<li>The <code>tmp_password</code> is the temporary payment password generated by the server, if the user provided a correct <a href="/api/srp">2FA password</a>.</li>
|
||
</ul>
|
||
<p>Example implementation: <a href="https://github.com/DrKLO/Telegram">Telegram for Android</a>.</p>
|
||
<h3><a class="anchor" href="#4-pre-checkout" id="4-pre-checkout" name="4-pre-checkout"><i class="anchor-icon"></i></a>4. Pre-Checkout</h3>
|
||
<pre><code><a href='/constructor/inputPaymentCredentialsSaved'>inputPaymentCredentialsSaved</a>#c10eb2cf id:<a href='/type/string'>string</a> tmp_password:<a href='/type/bytes'>bytes</a> = <a href='/type/InputPaymentCredentials'>InputPaymentCredentials</a>;
|
||
<a href='/constructor/inputPaymentCredentials'>inputPaymentCredentials</a>#3417d728 flags:<a href='/type/%23'>#</a> save:flags.0?<a href='/constructor/true'>true</a> data:<a href='/type/DataJSON'>DataJSON</a> = <a href='/type/InputPaymentCredentials'>InputPaymentCredentials</a>;
|
||
<a href='/constructor/inputPaymentCredentialsApplePay'>inputPaymentCredentialsApplePay</a>#aa1c39f payment_data:<a href='/type/DataJSON'>DataJSON</a> = <a href='/type/InputPaymentCredentials'>InputPaymentCredentials</a>;
|
||
<a href='/constructor/inputPaymentCredentialsGooglePay'>inputPaymentCredentialsGooglePay</a>#8ac32801 payment_token:<a href='/type/DataJSON'>DataJSON</a> = <a href='/type/InputPaymentCredentials'>InputPaymentCredentials</a>;
|
||
|
||
<a href='/constructor/payments.paymentResult'>payments.paymentResult</a>#4e5f810d updates:<a href='/type/Updates'>Updates</a> = <a href='/type/payments.PaymentResult'>payments.PaymentResult</a>;
|
||
<a href='/constructor/payments.paymentVerificationNeeded'>payments.paymentVerificationNeeded</a>#d8411139 url:<a href='/type/string'>string</a> = <a href='/type/payments.PaymentResult'>payments.PaymentResult</a>;
|
||
|
||
---functions---
|
||
|
||
<a href='/method/payments.sendPaymentForm'>payments.sendPaymentForm</a>#30c3bc9d flags:<a href='/type/%23'>#</a> form_id:<a href='/type/long'>long</a> peer:<a href='/type/InputPeer'>InputPeer</a> msg_id:<a href='/type/int'>int</a> requested_info_id:flags.0?<a href='/type/string'>string</a> shipping_option_id:flags.1?<a href='/type/string'>string</a> credentials:<a href='/type/InputPaymentCredentials'>InputPaymentCredentials</a> tip_amount:flags.2?<a href='/type/long'>long</a> = <a href='/type/payments.PaymentResult'>payments.PaymentResult</a>;</code></pre>
|
||
<p>After <a href="#2-3-verifying-information">verifying order information</a>, the final step for the client is to call <a href="/method/payments.sendPaymentForm">payments.sendPaymentForm</a>, with the following parameters:</p>
|
||
<ul>
|
||
<li>The <code>msg_id</code> is set to the ID of the invoice message</li>
|
||
<li><code>requested_info_id</code> is set to the <code>id</code> of the <a href="#2-3-verifying-information">verified order information</a>, if it was requested</li>
|
||
<li><code>shipping_option_id</code> is set to the <a href="#2-5-select-delivery-option">selected delivery option</a>, if shipping was requested.</li>
|
||
<li><code>credentials</code> are the payment credentials generated by the payment provider, required to complete the order.</li>
|
||
</ul>
|
||
<p>Payment method info can also be saved to the Telegram Servers and reused, by setting the <code>save</code> flag of <a href="/constructor/inputPaymentCredentials">inputPaymentCredentials</a> when sending the form.
|
||
This is only possible on accounts with <a href="/api/srp">2FA</a> enabled.</p>
|
||
<p>The bot then <a href="#4-1-receiving-pre-checkout-query">replies to the received precheckout query</a>, finally the user <a href="#5-checkout">proceeds to checkout</a>.</p>
|
||
<p>Please note that if the result of the method is a <a href="/constructor/payments.paymentVerificationNeeded">payments.paymentVerificationNeeded</a>, before <a href="#5-checkout">proceeding to checkout</a> the payment provider requires the user to verify his identity by opening the provided <code>url</code> and following instructions.
|
||
Once the user finishes working with the webpage, the client can <a href="#5-checkout">proceed to checkout</a>.</p>
|
||
<p>Eventual errors are returned in the form of RPC errors, with the description of the error by the bot contained in <a href="/constructor/updateServiceNotification">service updates</a>.</p>
|
||
<h4><a class="anchor" href="#41-receiving-pre-checkout-query" id="41-receiving-pre-checkout-query" name="41-receiving-pre-checkout-query"><i class="anchor-icon"></i></a>4.1 Receiving pre-checkout query</h4>
|
||
<pre><code><a href='/constructor/paymentRequestedInfo'>paymentRequestedInfo</a>#909c3f94 flags:<a href='/type/%23'>#</a> name:flags.0?<a href='/type/string'>string</a> phone:flags.1?<a href='/type/string'>string</a> email:flags.2?<a href='/type/string'>string</a> shipping_address:flags.3?<a href='/type/PostAddress'>PostAddress</a> = <a href='/type/PaymentRequestedInfo'>PaymentRequestedInfo</a>;
|
||
|
||
<a href='/constructor/updateBotPrecheckoutQuery'>updateBotPrecheckoutQuery</a>#8caa9a96 flags:<a href='/type/%23'>#</a> query_id:<a href='/type/long'>long</a> user_id:<a href='/type/long'>long</a> payload:<a href='/type/bytes'>bytes</a> info:flags.0?<a href='/type/PaymentRequestedInfo'>PaymentRequestedInfo</a> shipping_option_id:flags.1?<a href='/type/string'>string</a> currency:<a href='/type/string'>string</a> total_amount:<a href='/type/long'>long</a> = <a href='/type/Update'>Update</a>;
|
||
|
||
---functions---
|
||
|
||
<a href='/method/messages.setBotPrecheckoutResults'>messages.setBotPrecheckoutResults</a>#9c2dd95 flags:<a href='/type/%23'>#</a> success:flags.1?<a href='/constructor/true'>true</a> query_id:<a href='/type/long'>long</a> error:flags.0?<a href='/type/string'>string</a> = <a href='/type/Bool'>Bool</a>;</code></pre>
|
||
<p>The user enters their payment information as described above and presses the final pay button.
|
||
At this moment the Telegram API sends an <a href="/constructor/updateBotPrecheckoutQuery">updateBotPrecheckoutQuery</a> constructor that contains all the available information about the order to the bot.
|
||
The bot must reply using <a href="/method/messages.setBotPrecheckoutResults">messages.setBotPrecheckoutResults</a> <strong>within 10 seconds</strong> after receiving this update or the transaction is canceled.</p>
|
||
<p>The bot may return an error if it can‘t process the order for any reason. We highly recommend specifying a reason for failure to complete the order in human readable form (e.g. "Sorry, we’re all out of rubber ducks! Would you be interested in a steel bear instead?"). Telegram will display this reason to the user.</p>
|
||
<h3><a class="anchor" href="#5-checkout" id="5-checkout" name="5-checkout"><i class="anchor-icon"></i></a>5. Checkout</h3>
|
||
<pre><code><a href='/constructor/keyboardButtonBuy'>keyboardButtonBuy</a>#afd93fbb text:<a href='/type/string'>string</a> = <a href='/type/KeyboardButton'>KeyboardButton</a>;
|
||
|
||
<a href='/constructor/keyboardButtonRow'>keyboardButtonRow</a>#77608b83 buttons:<a href='/type/Vector%20t'>Vector</a><<a href='/type/KeyboardButton'>KeyboardButton</a>> = <a href='/type/KeyboardButtonRow'>KeyboardButtonRow</a>;
|
||
<a href='/constructor/replyInlineMarkup'>replyInlineMarkup</a>#48a30254 rows:<a href='/type/Vector%20t'>Vector</a><<a href='/type/KeyboardButtonRow'>KeyboardButtonRow</a>> = <a href='/type/ReplyMarkup'>ReplyMarkup</a>;
|
||
|
||
<a href='/constructor/messageMediaInvoice'>messageMediaInvoice</a>#84551347 flags:<a href='/type/%23'>#</a> shipping_address_requested:flags.1?<a href='/constructor/true'>true</a> test:flags.3?<a href='/constructor/true'>true</a> title:<a href='/type/string'>string</a> description:<a href='/type/string'>string</a> photo:flags.0?<a href='/type/WebDocument'>WebDocument</a> receipt_msg_id:flags.2?<a href='/type/int'>int</a> currency:<a href='/type/string'>string</a> total_amount:<a href='/type/long'>long</a> start_param:<a href='/type/string'>string</a> = <a href='/type/MessageMedia'>MessageMedia</a>;
|
||
|
||
<a href='/constructor/message'>message</a>#85d6cbe2 flags:<a href='/type/%23'>#</a> out:flags.1?<a href='/constructor/true'>true</a> mentioned:flags.4?<a href='/constructor/true'>true</a> media_unread:flags.5?<a href='/constructor/true'>true</a> silent:flags.13?<a href='/constructor/true'>true</a> post:flags.14?<a href='/constructor/true'>true</a> from_scheduled:flags.18?<a href='/constructor/true'>true</a> legacy:flags.19?<a href='/constructor/true'>true</a> edit_hide:flags.21?<a href='/constructor/true'>true</a> pinned:flags.24?<a href='/constructor/true'>true</a> id:<a href='/type/int'>int</a> from_id:flags.8?<a href='/type/Peer'>Peer</a> peer_id:<a href='/type/Peer'>Peer</a> fwd_from:flags.2?<a href='/type/MessageFwdHeader'>MessageFwdHeader</a> via_bot_id:flags.11?<a href='/type/long'>long</a> reply_to:flags.3?<a href='/type/MessageReplyHeader'>MessageReplyHeader</a> date:<a href='/type/int'>int</a> message:<a href='/type/string'>string</a> media:flags.9?<a href='/type/MessageMedia'>MessageMedia</a> reply_markup:flags.6?<a href='/type/ReplyMarkup'>ReplyMarkup</a> entities:flags.7?<a href='/type/Vector%20t'>Vector</a><<a href='/type/MessageEntity'>MessageEntity</a>> views:flags.10?<a href='/type/int'>int</a> forwards:flags.10?<a href='/type/int'>int</a> replies:flags.23?<a href='/type/MessageReplies'>MessageReplies</a> edit_date:flags.15?<a href='/type/int'>int</a> post_author:flags.16?<a href='/type/string'>string</a> grouped_id:flags.17?<a href='/type/long'>long</a> restriction_reason:flags.22?<a href='/type/Vector%20t'>Vector</a><<a href='/type/RestrictionReason'>RestrictionReason</a>> ttl_period:flags.25?<a href='/type/int'>int</a> = <a href='/type/Message'>Message</a>;
|
||
|
||
<a href='/constructor/updateNewMessage'>updateNewMessage</a>#1f2b0afd message:<a href='/type/Message'>Message</a> pts:<a href='/type/int'>int</a> pts_count:<a href='/type/int'>int</a> = <a href='/type/Update'>Update</a>;
|
||
|
||
<a href='/constructor/payments.paymentReceipt'>payments.paymentReceipt</a>#70c4fe03 flags:<a href='/type/%23'>#</a> date:<a href='/type/int'>int</a> bot_id:<a href='/type/long'>long</a> provider_id:<a href='/type/long'>long</a> title:<a href='/type/string'>string</a> description:<a href='/type/string'>string</a> photo:flags.2?<a href='/type/WebDocument'>WebDocument</a> invoice:<a href='/type/Invoice'>Invoice</a> info:flags.0?<a href='/type/PaymentRequestedInfo'>PaymentRequestedInfo</a> shipping:flags.1?<a href='/type/ShippingOption'>ShippingOption</a> tip_amount:flags.3?<a href='/type/long'>long</a> currency:<a href='/type/string'>string</a> total_amount:<a href='/type/long'>long</a> credentials_title:<a href='/type/string'>string</a> users:<a href='/type/Vector%20t'>Vector</a><<a href='/type/User'>User</a>> = <a href='/type/payments.PaymentReceipt'>payments.PaymentReceipt</a>;
|
||
|
||
---functions---
|
||
|
||
<a href='/method/payments.getPaymentReceipt'>payments.getPaymentReceipt</a>#2478d1cc peer:<a href='/type/InputPeer'>InputPeer</a> msg_id:<a href='/type/int'>int</a> = <a href='/type/payments.PaymentReceipt'>payments.PaymentReceipt</a>;</code></pre>
|
||
<p>In case the bot confirms the order, Telegram requests the payment provider to complete the transaction. If the payment information was entered correctly and the payment goes through, the Telegram API will modify the invoice message and send a service message as described below. Once your bot receives this message, it should proceed with delivering the goods or services purchased by the user.</p>
|
||
<p>If all is OK, the user receives a <a href="/constructor/payments.paymentResult">payments.paymentResult</a> in reply to the <a href="/method/payments.sendPaymentForm">payments.sendPaymentForm</a> query, containing info about the updated invoice message in the form of an <a href="/constructor/updateEditMessage">updateEditMessage</a>.</p>
|
||
<p>The invoice message will be updated as follows: the attached <a href="/constructor/messageMediaInvoice">messageMediaInvoice</a> will now have a <code>receipt_msg_id</code> field.
|
||
Clients should treat invoice messages with a <code>receipt_msg_id</code> field as receipt messages, <strong>locally</strong> modifying the label of the <a href="/constructor/keyboardButtonBuy">keyboardButtonBuy</a> button to a localized version of the word <code>Receipt</code>.
|
||
From this point, clicking on the <code>Receipt</code> button should trigger a call to <a href="/method/payments.getPaymentReceipt">payments.getPaymentReceipt</a>, providing the <code>receipt_msg_id</code> to the <code>msg_id</code> field, which will return info about the transaction.</p>
|
||
<p>The payment will also generate one service message of type <a href="/constructor/messageActionPaymentSent">messageActionPaymentSent</a> or <a href="/constructor/messageActionPaymentSentMe">messageActionPaymentSentMe</a>, replying to the invoice.
|
||
For bots, the service message will be of type <a href="/constructor/messageActionPaymentSentMe">messageActionPaymentSentMe</a>, for users it will be a <a href="/constructor/messageActionPaymentSent">messageActionPaymentSent</a>.</p>
|
||
<pre><code><a href='/constructor/messageActionPaymentSentMe'>messageActionPaymentSentMe</a>#8f31b327 flags:<a href='/type/%23'>#</a> currency:<a href='/type/string'>string</a> total_amount:<a href='/type/long'>long</a> payload:<a href='/type/bytes'>bytes</a> info:flags.0?<a href='/type/PaymentRequestedInfo'>PaymentRequestedInfo</a> shipping_option_id:flags.1?<a href='/type/string'>string</a> charge:<a href='/type/PaymentCharge'>PaymentCharge</a> = <a href='/type/MessageAction'>MessageAction</a>;
|
||
<a href='/constructor/messageActionPaymentSent'>messageActionPaymentSent</a>#40699cd0 currency:<a href='/type/string'>string</a> total_amount:<a href='/type/long'>long</a> = <a href='/type/MessageAction'>MessageAction</a>;</code></pre></div>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
<div class="footer_wrap">
|
||
<div class="footer_columns_wrap footer_desktop">
|
||
<div class="footer_column footer_column_telegram">
|
||
<h5>Telegram</h5>
|
||
<div class="footer_telegram_description"></div>
|
||
Telegram is a cloud-based mobile and desktop messaging app with a focus on security and speed.
|
||
</div>
|
||
|
||
<div class="footer_column">
|
||
<h5><a href="//telegram.org/faq">About</a></h5>
|
||
<ul>
|
||
<li><a href="//telegram.org/faq">FAQ</a></li>
|
||
<li><a href="//telegram.org/blog">Blog</a></li>
|
||
<li><a href="//telegram.org/jobs">Jobs</a></li>
|
||
</ul>
|
||
</div>
|
||
<div class="footer_column">
|
||
<h5><a href="//telegram.org/apps#mobile-apps">Mobile Apps</a></h5>
|
||
<ul>
|
||
<li><a href="//telegram.org/dl/ios">iPhone/iPad</a></li>
|
||
<li><a href="//telegram.org/dl/android">Android</a></li>
|
||
<li><a href="//telegram.org/dl/wp">Windows Phone</a></li>
|
||
</ul>
|
||
</div>
|
||
<div class="footer_column">
|
||
<h5><a href="//telegram.org/apps#desktop-apps">Desktop Apps</a></h5>
|
||
<ul>
|
||
<li><a href="//desktop.telegram.org/">PC/Mac/Linux</a></li>
|
||
<li><a href="//macos.telegram.org/">macOS</a></li>
|
||
<li><a href="//telegram.org/dl/web">Web-browser</a></li>
|
||
</ul>
|
||
</div>
|
||
<div class="footer_column footer_column_platform">
|
||
<h5><a href="/">Platform</a></h5>
|
||
<ul>
|
||
<li><a href="/api">API</a></li>
|
||
<li><a href="//translations.telegram.org/">Translations</a></li>
|
||
<li><a href="//instantview.telegram.org/">Instant View</a></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div class="footer_columns_wrap footer_mobile">
|
||
<div class="footer_column">
|
||
<h5><a href="//telegram.org/faq">About</a></h5>
|
||
</div>
|
||
<div class="footer_column">
|
||
<h5><a href="//telegram.org/blog">Blog</a></h5>
|
||
</div>
|
||
<div class="footer_column">
|
||
<h5><a href="//telegram.org/apps">Apps</a></h5>
|
||
</div>
|
||
<div class="footer_column">
|
||
<h5><a href="/">Platform</a></h5>
|
||
</div>
|
||
<div class="footer_column">
|
||
<h5><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)">Twitter</a></h5>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<script src="/js/main.js?42"></script>
|
||
<script src="/js/jquery.min.js?1"></script>
|
||
<script src="/js/bootstrap.min.js"></script>
|
||
|
||
<script>window.initDevPageNav&&initDevPageNav();
|
||
backToTopInit("Go up");
|
||
removePreloadInit();
|
||
</script>
|
||
</body>
|
||
</html>
|
||
|