mirror of
https://github.com/MarshalX/telegram-crawler.git
synced 2024-12-29 15:59:13 +01:00
399 lines
61 KiB
HTML
399 lines
61 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.">
|
|
<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.">
|
|
<link rel="icon" type="image/svg+xml" href="/img/website_icon.svg?4">
|
|
<link rel="apple-touch-icon" sizes="180x180" href="/img/apple-touch-icon.png">
|
|
<link rel="icon" type="image/png" sizes="32x32" href="/img/favicon-32x32.png">
|
|
<link rel="icon" type="image/png" sizes="16x16" href="/img/favicon-16x16.png">
|
|
<link rel="alternate icon" href="/img/favicon.ico" type="image/x-icon" />
|
|
<link href="/css/bootstrap.min.css?3" rel="stylesheet">
|
|
|
|
<link href="/css/telegram.css?234" 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>
|
|
<h4><a class="anchor" href="#11-create-invoice-message" id="11-create-invoice-message" name="11-create-invoice-message"><i class="anchor-icon"></i></a>1.1 Create Invoice Message</h4>
|
|
<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>#3e85a91b 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> recurring:flags.9?<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>> recurring_terms_url:flags.9?<a href='/type/string'>string</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>#e25ff8e0 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> noforwards:flags.14?<a href='/constructor/true'>true</a> update_stickersets_order:flags.15?<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> send_as:flags.13?<a href='/type/InputPeer'>InputPeer</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>
|
|
<h4><a class="anchor" href="#12-create-invoice-link" id="12-create-invoice-link" name="12-create-invoice-link"><i class="anchor-icon"></i></a>1.2 Create Invoice Link</h4>
|
|
<pre><code><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>;
|
|
|
|
<a href='/constructor/payments.exportedInvoice'>payments.exportedInvoice</a>#aed0cbd9 url:<a href='/type/string'>string</a> = <a href='/type/payments.ExportedInvoice'>payments.ExportedInvoice</a>;
|
|
|
|
---functions---
|
|
|
|
<a href='/method/payments.exportInvoice'>payments.exportInvoice</a>#f91b065 invoice_media:<a href='/type/InputMedia'>InputMedia</a> = <a href='/type/payments.ExportedInvoice'>payments.ExportedInvoice</a>;</code></pre>
|
|
<p>Bots may also generate <a href="/api/links#invoice-links">invoice deep links</a> using <a href="/method/payments.exportInvoice">payments.exportInvoice</a>. </p>
|
|
<p>The returned <a href="/constructor/payments.exportedInvoice">payments.exportedInvoice</a> will contain an <a href="/api/links#invoice-links">invoice deep link</a> that can be shared directly, or sent in a bot web app <a href="/api/web-events#web-app-open-invoice"><code>web_app_open_invoice</code> event</a>.</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" id="21-invoice" name="21-invoice"><i class="anchor-icon"></i></a>2.1 Invoice</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>#38116ee0 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> noforwards:flags.26?<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> reactions:flags.20?<a href='/type/MessageReactions'>MessageReactions</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="/api/links#invoice-links">invoice deep link</a> or 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>For invoice messages, 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/inputInvoiceMessage'>inputInvoiceMessage</a>#c5b56859 peer:<a href='/type/InputPeer'>InputPeer</a> msg_id:<a href='/type/int'>int</a> = <a href='/type/InputInvoice'>InputInvoice</a>;
|
|
<a href='/constructor/inputInvoiceSlug'>inputInvoiceSlug</a>#c326caef slug:<a href='/type/string'>string</a> = <a href='/type/InputInvoice'>InputInvoice</a>;
|
|
|
|
<a href='/constructor/invoice'>invoice</a>#3e85a91b 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> recurring:flags.9?<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>> recurring_terms_url:flags.9?<a href='/type/string'>string</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>#a0058751 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> title:<a href='/type/string'>string</a> description:<a href='/type/string'>string</a> photo:flags.5?<a href='/type/WebDocument'>WebDocument</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> additional_methods:flags.6?<a href='/type/Vector%20t'>Vector</a><<a href='/type/PaymentFormMethod'>PaymentFormMethod</a>> saved_info:flags.0?<a href='/type/PaymentRequestedInfo'>PaymentRequestedInfo</a> saved_credentials:flags.1?<a href='/type/Vector%20t'>Vector</a><<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>#37148dbb flags:<a href='/type/%23'>#</a> invoice:<a href='/type/InputInvoice'>InputInvoice</a> theme_params:flags.0?<a href='/type/DataJSON'>DataJSON</a> = <a href='/type/payments.PaymentForm'>payments.PaymentForm</a>;</code></pre>
|
|
<p><a href="/method/payments.getPaymentForm">payments.getPaymentForm</a> is used to return a <a href="/constructor/payments.paymentForm">payment form</a> from an invoice, providing the following <code>invoice</code> parameter:</p>
|
|
<ul>
|
|
<li><a href="/constructor/inputInvoiceMessage">inputInvoiceMessage</a><ul>
|
|
<li>Used if the user clicks on the <a href="/constructor/keyboardButtonBuy">keyboardButtonBuy</a> button, contains the message ID of the invoice preview message. </li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="/constructor/inputInvoiceSlug">inputInvoiceSlug</a><ul>
|
|
<li>If the user opens an <a href="/api/links#invoice-links">invoice deep link</a>, contains the <code>slug</code> parameter</li>
|
|
<li>If the client has to process a <a href="/api/premium">Telegram Premium</a> payment, contains the <a href="/api/config#premium-invoice-slug"><code>premium_invoice_slug</code> app config parameter »</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<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.
|
|
The <code>recurring</code> flag will be set for recurring payments, and <code>recurring_terms_url</code> will link to the terms of service of the recurring payment: the user must read and accept them before continuing. </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>#3e85a91b 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> recurring:flags.9?<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>> recurring_terms_url:flags.9?<a href='/type/string'>string</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>#b6c8f12b flags:<a href='/type/%23'>#</a> save:flags.0?<a href='/constructor/true'>true</a> invoice:<a href='/type/InputInvoice'>InputInvoice</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="#231-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="#24-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 submitted 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="#23-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="#23-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>#a0058751 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> title:<a href='/type/string'>string</a> description:<a href='/type/string'>string</a> photo:flags.5?<a href='/type/WebDocument'>WebDocument</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> additional_methods:flags.6?<a href='/type/Vector%20t'>Vector</a><<a href='/type/PaymentFormMethod'>PaymentFormMethod</a>> saved_info:flags.0?<a href='/type/PaymentRequestedInfo'>PaymentRequestedInfo</a> saved_credentials:flags.1?<a href='/type/Vector%20t'>Vector</a><<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>#a0058751 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> title:<a href='/type/string'>string</a> description:<a href='/type/string'>string</a> photo:flags.5?<a href='/type/WebDocument'>WebDocument</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> additional_methods:flags.6?<a href='/type/Vector%20t'>Vector</a><<a href='/type/PaymentFormMethod'>PaymentFormMethod</a>> saved_info:flags.0?<a href='/type/PaymentRequestedInfo'>PaymentRequestedInfo</a> saved_credentials:flags.1?<a href='/type/Vector%20t'>Vector</a><<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/paymentFormMethod'>paymentFormMethod</a>#88f8f21b url:<a href='/type/string'>string</a> title:<a href='/type/string'>string</a> = <a href='/type/PaymentFormMethod'>PaymentFormMethod</a>;</code></pre>
|
|
<p>The user can choose to use either the main payment platform, using the <code>url</code> of the <a href="/constructor/payments.paymentForm">payments.paymentForm</a>, or any of the additional payment platforms, using the <code>url</code> of the chosen <a href="/constructor/paymentFormMethod">paymentFormMethod</a>.<br>
|
|
Payment takes place by opening the <code>url</code> of the chosen payment platform in the specified <a href="/constructor/payments.paymentForm">payment form</a>, which leads to a payment form on the website of the payment gateway.<br>
|
|
Once the user finishes entering their payment credentials, a <a href="/api/web-events#payment-form-submit"><code>payment_form_submit</code> web event</a> is generated by the payment gateway, containing <code>credentials</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>credentials</code> are 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>#a0058751 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> title:<a href='/type/string'>string</a> description:<a href='/type/string'>string</a> photo:flags.5?<a href='/type/WebDocument'>WebDocument</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> additional_methods:flags.6?<a href='/type/Vector%20t'>Vector</a><<a href='/type/PaymentFormMethod'>PaymentFormMethod</a>> saved_info:flags.0?<a href='/type/PaymentRequestedInfo'>PaymentRequestedInfo</a> saved_credentials:flags.1?<a href='/type/Vector%20t'>Vector</a><<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>#a0058751 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> title:<a href='/type/string'>string</a> description:<a href='/type/string'>string</a> photo:flags.5?<a href='/type/WebDocument'>WebDocument</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> additional_methods:flags.6?<a href='/type/Vector%20t'>Vector</a><<a href='/type/PaymentFormMethod'>PaymentFormMethod</a>> saved_info:flags.0?<a href='/type/PaymentRequestedInfo'>PaymentRequestedInfo</a> saved_credentials:flags.1?<a href='/type/Vector%20t'>Vector</a><<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>#a0058751 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> title:<a href='/type/string'>string</a> description:<a href='/type/string'>string</a> photo:flags.5?<a href='/type/WebDocument'>WebDocument</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> additional_methods:flags.6?<a href='/type/Vector%20t'>Vector</a><<a href='/type/PaymentFormMethod'>PaymentFormMethod</a>> saved_info:flags.0?<a href='/type/PaymentRequestedInfo'>PaymentRequestedInfo</a> saved_credentials:flags.1?<a href='/type/Vector%20t'>Vector</a><<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>#2d03522f flags:<a href='/type/%23'>#</a> form_id:<a href='/type/long'>long</a> invoice:<a href='/type/InputInvoice'>InputInvoice</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="#23-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="#23-verifying-information">verified order information</a>, if it was requested</li>
|
|
<li><code>shipping_option_id</code> is set to the <a href="#24-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="#41-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 their identity by opening the provided <code>url</code> and following instructions (ie 3-D Secure).<br>
|
|
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 (<code>rpc_error</code>), with the description of the error by the bot contained in additional <a href="/constructor/updateServiceNotification">service updates</a> received separately, see <a href="/api/errors#406-not-acceptable">here</a> for more info. </p>
|
|
<p>Note that eventual payment errors will not be sent to the client via MTProto if they occur during additional verification (if a <a href="/constructor/payments.paymentVerificationNeeded">payments.paymentVerificationNeeded</a> is returned and the user fails TOTP verification): such errors will only be displayed inside of the verification webview, no MTProto updates or RPC errors (<code>rpc_error</code>) will be received. </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>#38116ee0 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> noforwards:flags.26?<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> reactions:flags.20?<a href='/type/MessageReactions'>MessageReactions</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>.<br>
|
|
The <code>recurring_init</code> flag will be set if this payment also enables future recurring payments.<br>
|
|
Further recurring payments will automatically send <a href="/constructor/messageActionPaymentSentMe">messageActionPaymentSentMe</a> and <a href="/constructor/messageActionPaymentSent">messageActionPaymentSent</a> messages with the <code>recurring_used</code> flag set. </p>
|
|
<pre><code><a href='/constructor/messageActionPaymentSentMe'>messageActionPaymentSentMe</a>#8f31b327 flags:<a href='/type/%23'>#</a> recurring_init:flags.2?<a href='/constructor/true'>true</a> recurring_used:flags.3?<a href='/constructor/true'>true</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>#96163f56 flags:<a href='/type/%23'>#</a> recurring_init:flags.2?<a href='/constructor/true'>true</a> recurring_used:flags.3?<a href='/constructor/true'>true</a> currency:<a href='/type/string'>string</a> total_amount:<a href='/type/long'>long</a> invoice_slug:flags.0?<a href='/type/string'>string</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/privacy">Privacy</a></li>
|
|
<li><a href="//telegram.org/press">Press</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/android">Android</a></li>
|
|
<li><a href="//telegram.org/dl/web">Mobile Web</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?47"></script>
|
|
<script src="/js/jquery.min.js?1"></script>
|
|
<script src="/js/bootstrap.min.js?1"></script>
|
|
|
|
<script>window.initDevPageNav&&initDevPageNav();
|
|
backToTopInit("Go up");
|
|
removePreloadInit();
|
|
</script>
|
|
</body>
|
|
</html>
|
|
|