电报支付 API

您可以通过Telegram 机器人接收来自 Telegram 用户的付款。

注:本文面向 MTProto API 开发人员。如果您想了解 Telegram Payments 的总体概述,请查看Telegram 博客和机器人 API 支付手册。

介绍支付

Telegram 机器人可以接受用户支付的商品和服务费用。有关支付方式的更多信息,请查看Telegram 博客和机器人 API 支付手册。

本页将详细介绍使用MTProto API处理支付所需的操作。

简化版流程仅适用于使用机器人 API 的机器人。

机器人的第一步是启用支付功能,具体操作请参见此处 »。

然后,我们按如下方式处理付款。

1. 创建发票

1.1 创建发票消息

inputWebDocument#9bed434d url:string size:int mime_type:string attributes:Vector<DocumentAttribute> = InputWebDocument;labeledPrice#cb296bf8 label:string amount:long = LabeledPrice;invoice#49ee584 flags:# test:flags.0?true name_requested:flags.1?true phone_requested:flags.2?true email_requested:flags.3?true shipping_address_requested:flags.4?true flexible:flags.5?true phone_to_provider:flags.6?true email_to_provider:flags.7?true recurring:flags.9?true currency:string prices:Vector<LabeledPrice> max_tip_amount:flags.8?long suggested_tip_amounts:flags.8?Vector<long> terms_url:flags.10?string subscription_period:flags.11?int = Invoice;inputMediaInvoice#405fef0d flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:flags.3?string provider_data:DataJSON start_param:flags.1?string extended_media:flags.2?InputMedia = InputMedia;---functions---messages.sendMedia#ac55d9c1 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long allow_paid_stars:flags.21?long suggested_post:flags.22?SuggestedPost = Updates;

用户联系机器人并请求购买商品。机器人会创建一个inputMediaInvoice对象,该对象包含一个发票构造函数,其中包含商品或服务的描述、待付金额以及所需的配送信息。inputMediaInvoice构造provider函数的参数用于放置您之前通过 Botfather 获取的令牌值。一个商家机器人可以为不同的用户或不同的商品/服务使用多个不同的令牌。

使用messages.sendMedia方法发送发票。您还可以使用以下字段为消息添加内联键盘reply_markup:如果提供此字段,则第一个按钮必须是keyboardButtonBuy按钮。否则,系统将自动生成一个内联键盘,其中只有一个Pay 'total price'keyboardButtonBuy按钮。

带有付款按钮的发票消息只能发送到与用户的私聊中,不支持群组和频道。

1.2 创建发票链接

inputMediaInvoice#405fef0d flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:flags.3?string provider_data:DataJSON start_param:flags.1?string extended_media:flags.2?InputMedia = InputMedia;payments.exportedInvoice#aed0cbd9 url:string = payments.ExportedInvoice;---functions---payments.exportInvoice#f91b065 invoice_media:InputMedia = payments.ExportedInvoice;

机器人还可以使用payments.exportInvoice生成发票深度链接。

返回的payments.exportedInvoice将包含一个发票深度链接,可以直接共享,也可以在机器人小程序web_app_open_invoice事件中发送。

2. 订单信息

2.1 发票

keyboardButtonBuy#afd93fbb text:string = KeyboardButton;keyboardButtonRow#77608b83 buttons:Vector<KeyboardButton> = KeyboardButtonRow; replyInlineMarkup#48a30254 rows:Vector<KeyboardButtonRow> = ReplyMarkup;webDocument#1c570ed1 url:string access_hash:long size:int mime_type:string attributes:Vector<DocumentAttribute> = WebDocument; webDocumentNoProxy#f9c8bcc6 url:string size:int mime_type:string attributes:Vector<DocumentAttribute> = WebDocument;messageMediaInvoice#f6a548d3 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument receipt_msg_id:flags.2?int currency:string total_amount:long start_param:string extended_media:flags.4?MessageExtendedMedia = MessageMedia;message#9815cec8 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true noforwards:flags.26?true invert_media:flags.27?true flags2:# offline:flags2.1?true video_processing_pending:flags2.4?true paid_suggested_post_stars:flags2.8?true paid_suggested_post_ton:flags2.9?true id:int from_id:flags.8?Peer from_boosts_applied:flags.29?int peer_id:Peer saved_peer_id:flags.28?Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long via_business_bot_id:flags2.0?long reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long reactions:flags.20?MessageReactions restriction_reason:flags.22?Vector<RestrictionReason> ttl_period:flags.25?int quick_reply_shortcut_id:flags.30?int effect:flags2.2?long factcheck:flags2.3?FactCheck report_delivery_until_date:flags2.5?int paid_message_stars:flags2.6?long suggested_post:flags2.7?SuggestedPost = Message;updateNewMessage#1f2b0afd message:Message pts:int pts_count:int = Update;

用户会收到来自机器人的发票深度链接或updateNewMessage构造函数,其中包含一个messageMediaInvoice构造函数,其中包含有关产品的基本信息。

对于发票消息,消息中还会附加一个replyInlineMarkup键盘。该键盘的第一个按钮始终是keyboardButtonBuy按钮。

在Telegram Stars中,通过“PassXTRas”currency请求付款。

2.2 获取产品发票信息

inputStorePaymentPremiumGiveaway#160544ca flags:# only_new_subscribers:flags.0?true winners_are_visible:flags.3?true boost_peer:InputPeer additional_peers:flags.1?Vector<InputPeer> countries_iso2:flags.2?Vector<string> prize_description:flags.4?string random_id:long until_date:int currency:string amount:long = InputStorePaymentPurpose; inputStorePaymentPremiumGiftCode#fb790393 flags:# users:Vector<InputUser> boost_peer:flags.0?InputPeer currency:string amount:long message:flags.1?TextWithEntities = InputStorePaymentPurpose;inputInvoiceMessage#c5b56859 peer:InputPeer msg_id:int = InputInvoice; inputInvoiceSlug#c326caef slug:string = InputInvoice; inputInvoicePremiumGiftCode#98986c0d purpose:InputStorePaymentPurpose option:PremiumGiftCodeOption = InputInvoice; inputInvoiceStars#65f00ce3 purpose:InputStorePaymentPurpose = InputInvoice; inputInvoiceChatInviteSubscription#34e793f1 hash:string = InputInvoice; inputInvoiceStarGift#e8625e92 flags:# hide_name:flags.0?true include_upgrade:flags.2?true peer:InputPeer gift_id:long message:flags.1?TextWithEntities = InputInvoice; inputInvoiceStarGiftUpgrade#4d818d5d flags:# keep_original_details:flags.0?true stargift:InputSavedStarGift = InputInvoice; inputInvoiceStarGiftPrepaidUpgrade#9a0b48b8 peer:InputPeer hash:string = InputInvoice; inputInvoiceStarGiftTransfer#4a5f5bd9 stargift:InputSavedStarGift to_id:InputPeer = InputInvoice; inputInvoicePremiumGiftStars#dabab2ef flags:# user_id:InputUser months:int message:flags.0?TextWithEntities = InputInvoice; inputInvoiceBusinessBotTransferStars#f4997e42 bot:InputUser stars:long = InputInvoice; inputInvoiceStarGiftResale#c39f5324 flags:# ton:flags.0?true slug:string to_id:InputPeer = InputInvoice;invoice#49ee584 flags:# test:flags.0?true name_requested:flags.1?true phone_requested:flags.2?true email_requested:flags.3?true shipping_address_requested:flags.4?true flexible:flags.5?true phone_to_provider:flags.6?true email_to_provider:flags.7?true recurring:flags.9?true currency:string prices:Vector<LabeledPrice> max_tip_amount:flags.8?long suggested_tip_amounts:flags.8?Vector<long> terms_url:flags.10?string subscription_period:flags.11?int = Invoice;paymentRequestedInfo#909c3f94 flags:# name:flags.0?string phone:flags.1?string email:flags.2?string shipping_address:flags.3?PostAddress = PaymentRequestedInfo;paymentSavedCredentialsCard#cdc27a1f id:string title:string = PaymentSavedCredentials;payments.paymentForm#a0058751 flags:# can_save_credentials:flags.2?true password_missing:flags.3?true form_id:long bot_id:long title:string description:string photo:flags.5?WebDocument invoice:Invoice provider_id:long url:string native_provider:flags.4?string native_params:flags.4?DataJSON additional_methods:flags.6?Vector<PaymentFormMethod> saved_info:flags.0?PaymentRequestedInfo saved_credentials:flags.1?Vector<PaymentSavedCredentials> users:Vector<User> = payments.PaymentForm;payments.paymentFormStars#7bf6b15c flags:# form_id:long bot_id:long title:string description:string photo:flags.5?WebDocument invoice:Invoice users:Vector<User> = payments.PaymentForm; payments.paymentFormStarGift#b425cfe1 form_id:long invoice:Invoice = payments.PaymentForm;---functions---payments.getPaymentForm#37148dbb flags:# invoice:InputInvoice theme_params:flags.0?DataJSON = payments.PaymentForm;

payments.getPaymentForm用于从发票返回付款表单invoice,并提供以下参数:

返回的表单将包含一些字段,这些字段需要与完整的发票一起传递给支付服务提供商。支付表单还包含之前保存的支付凭证和订单信息(姓名、电话号码、电子邮件地址、收货地址等)。

完整发票包含订单所需信息、价格和币种,以及该订单是否有效test。recurring发票将标记为已启用定期付款,并recurring_terms_url链接至定期付款服务条款:用户必须阅读并接受这些条款后才能继续。

如果使用Telegram Stars进行付款,则会返回payments.paymentFormStars/payments.paymentFormStarGift,详情请参见此处 »(请注意,此构造函数用于向机器人和用户支付 Telegram Stars 款项,使用inputInvoiceStars为当前帐户充值 Telegram Star 余额时不会返回此构造函数):关联的发票将用作。XTRcurrency

2.3 信息核实

invoice#49ee584 flags:# test:flags.0?true name_requested:flags.1?true phone_requested:flags.2?true email_requested:flags.3?true shipping_address_requested:flags.4?true flexible:flags.5?true phone_to_provider:flags.6?true email_to_provider:flags.7?true recurring:flags.9?true currency:string prices:Vector<LabeledPrice> max_tip_amount:flags.8?long suggested_tip_amounts:flags.8?Vector<long> terms_url:flags.10?string subscription_period:flags.11?int = Invoice;postAddress#1e8caaeb street_line1:string street_line2:string city:string state:string country_iso2:string post_code:string = PostAddress;paymentRequestedInfo#909c3f94 flags:# name:flags.0?string phone:flags.1?string email:flags.2?string shipping_address:flags.3?PostAddress = PaymentRequestedInfo;payments.validatedRequestedInfo#d1451883 flags:# id:flags.0?string shipping_options:flags.1?Vector<ShippingOption> = payments.ValidatedRequestedInfo;---functions---payments.validateRequestedInfo#b6c8f12b flags:# save:flags.0?true invoice:InputInvoice info:PaymentRequestedInfo = payments.ValidatedRequestedInfo;

如果发票请求任何数据(name_requested,,,),用户必须调用`payments.validateRequestedInfo`并提供所需数据(通常情况下,是发票消息的 ID)。用户可以设置标志来选择保存订单信息以供将来使用phone_requested。数据可以按照自动填充部分中的说明自动填充。email_requestedshipping_address_requestedmsg_idsave

如果提交的信息中没有发现错误,该方法的响应id将包含一个标志,稍后将使用该标志完成付款。

如果flexible发票的标志已设置,调用`payments.validateRequestedInfo`方法会将运费查询更新发送给机器人,机器人会根据此处的说明,回复指定地址可用的运费选项。在这种情况下,返回值也会包含一个shipping_options包含可用运费选项的字段。

如果提交的数据中发现任何错误,机器人将向用户发送服务通知,其中包含对错误的描述。

2.3.1 自动填充

payments.savedInfo#fb8fe43c flags:# has_saved_credentials:flags.1?true saved_info:flags.0?PaymentRequestedInfo = payments.SavedInfo;---functions---payments.getSavedInfo#227d824b = payments.SavedInfo; payments.clearSavedInfo#d83d70c1 flags:# credentials:flags.0?true info:flags.1?true = Bool;请求的字段可以使用付款表单saved_info字段中提供的信息自动填充,也可以使用payments.getSavedInfo手动获取的信息填充。


也可以使用payments.clearSavedInfo清除已保存的订单信息。

2.4 选择配送方式

labeledPrice#cb296bf8 label:string amount:long = LabeledPrice;shippingOption#b6213cdf id:string title:string prices:Vector<LabeledPrice> = ShippingOption;updateBotShippingQuery#b5aefd7d query_id:long user_id:long payload:bytes shipping_address:PostAddress = Update;---functions---messages.setBotShippingResults#e5f672fa flags:# query_id:long error:flags.0?string shipping_options:flags.1?Vector<ShippingOption> = Bool;如果用户请求了收货地址,并且机器人包含了该参数flexible,那么当用户验证订单信息时,Telegram API 会向机器人发送一个updateBotShippingQuery请求。机器人必须使用messages.setBotShippingResults方法返回可能的配送选项列表及其对应的配送价格,或者返回错误信息(例如,如果无法配送到指定的地址)。


在验证订单信息时,退回的配送选项或配送错误将返回给用户。

3. 付款

3.1 星级付款

payments.paymentFormStars#7bf6b15c flags:# form_id:long bot_id:long title:string description:string photo:flags.5?WebDocument invoice:Invoice users:Vector<User> = payments.PaymentForm; payments.paymentFormStarGift#b425cfe1 form_id:long invoice:Invoice = payments.PaymentForm;---functions---payments.sendStarsForm#7998c914 form_id:long invoice:InputInvoice = payments.PaymentResult;

如果要使用Telegram Stars进行付款,则在步骤 4中调用payments.sendStarsForm而不是payments.sendPaymentForm,将返回payments.paymentFormStars或payments.paymentFormStarGift。

使用相同的参数两次调用payments.sendStarsFormform_id不会重复交易。

请注意,返回的表单仅在 10 分钟内有效,之后调用payments.sendStarsForm将返回400FORM_EXPIRED错误。收到此错误时,只需按照步骤 2.2
中的说明重新生成表单,然后重新调用payments.sendStarsForm即可。

如果当前 Telegram Stars 余额不足以完成交易,则payments.sendStarsForm400BALANCE_TOO_LOW将发出错误:收到此错误时,客户端应邀请用户充值其 Telegram Stars 余额 »,然后再重新调用payments.sendStarsForm。

3.2 网络支付

inputPaymentCredentials#3417d728 flags:# save:flags.0?true data:DataJSON = InputPaymentCredentials;payments.paymentForm#a0058751 flags:# can_save_credentials:flags.2?true password_missing:flags.3?true form_id:long bot_id:long title:string description:string photo:flags.5?WebDocument invoice:Invoice provider_id:long url:string native_provider:flags.4?string native_params:flags.4?DataJSON additional_methods:flags.6?Vector<PaymentFormMethod> saved_info:flags.0?PaymentRequestedInfo saved_credentials:flags.1?Vector<PaymentSavedCredentials> users:Vector<User> = payments.PaymentForm;paymentFormMethod#88f8f21b url:string title:string = PaymentFormMethod;

用户可以选择使用主支付平台(通过`payments.paymentForm`url实现),或者使用其他支付平台(通过所选的`paymentFormMethod`实现)。支付过程通过在指定的支付表单中打开所选支付平台的表单来完成,该表单会将用户引导至支付网关网站上的支付表单。用户输入支付凭证后,支付网关会生成一个包含 `payment.paymentForm`和`payment.paymentForm` 字段的Web 事件。

payment_form_submitcredentialstitle


title客户端应用程序使用此参数来表示支付凭证(通常是经过过滤的信用卡信息)。此credentials参数用于生成 `inputPaymentCredentials`构造函数。最终,您可以设置save标志以保存信用卡信息以供将来使用,但前提是已启用双因素身份验证(2FA)。

Telegram无法获取您的银行卡信息。信用卡信息仅由支付系统处理。

3.3 原生支付

inputPaymentCredentials#3417d728 flags:# save:flags.0?true data:DataJSON = InputPaymentCredentials;payments.paymentForm#a0058751 flags:# can_save_credentials:flags.2?true password_missing:flags.3?true form_id:long bot_id:long title:string description:string photo:flags.5?WebDocument invoice:Invoice provider_id:long url:string native_provider:flags.4?string native_params:flags.4?DataJSON additional_methods:flags.6?Vector<PaymentFormMethod> saved_info:flags.0?PaymentRequestedInfo saved_credentials:flags.1?Vector<PaymentSavedCredentials> users:Vector<User> = payments.PaymentForm;

大多数 Telegram 应用支持与某些支付提供商的原生 API 进行原生交互,而无需打开支付网站并接收 JS 事件。

这是通过payments.paymentFormnative_params构造函数的 JSON 参数字段实现的,该字段包含一个对象,该对象可以包含以下一个或多个字段:

  • publishable_keyStripe API 可发布密钥
  • apple_pay_merchant_id:Apple Pay 商户 ID
  • android_pay_public_keyAndroid Pay 公钥
  • android_pay_bgcolorAndroid Pay 表单背景颜色
  • android_pay_inverse是否在 Android Pay 表单中使用深色主题
  • need_country:是的,如果需要提供用户国家/地区信息,
  • need_zip:是的,如果必须提供用户邮政编码,
  • need_cardholder_name:是的,如果必须提供持卡人姓名。

使用哪个支付网关取决于该native_provider字段的值。

3.3.1 Stripe
inputPaymentCredentials#3417d728 flags:# save:flags.0?true data:DataJSON = InputPaymentCredentials;payments.paymentForm#a0058751 flags:# can_save_credentials:flags.2?true password_missing:flags.3?true form_id:long bot_id:long title:string description:string photo:flags.5?WebDocument invoice:Invoice provider_id:long url:string native_provider:flags.4?string native_params:flags.4?DataJSON additional_methods:flags.6?Vector<PaymentFormMethod> saved_info:flags.0?PaymentRequestedInfo saved_credentials:flags.1?Vector<PaymentSavedCredentials> users:Vector<User> = payments.PaymentForm;

如果该native_provider字段已设置且等于stripe,则客户端可以使用Stripe 原生令牌 API,通过publishable_key从中native_params添加支付方式到 Stripe,然后使用该令牌type生成idJSON 对象:

{"type":"token.type", "id":"token.id"}"

生成的 JSON 对象可以传递给inputPaymentCredentialsdata字段。最后,您可以设置标志以保存信用卡信息以供将来使用,但前提是已启用双因素身份验证(2FA) 。save

Telegram无法获取您的银行卡信息。信用卡信息仅由支付系统处理。

示例实现:Android 版 Telegram。

3.4 Apple Pay

inputPaymentCredentialsApplePay#aa1c39f payment_data:DataJSON = InputPaymentCredentials;

在 iOS 设备上,可以使用 Apple Pay 生成支付数据,然后使用inputPaymentCredentialsApplePay构造函数发送该数据。

示例实现:iOS 版 Telegram。

3.5 Android Pay

inputPaymentCredentialsGooglePay#8ac32801 payment_token:DataJSON = InputPaymentCredentials;

在 Android 设备上,可以使用 Google Pay 生成支付数据,然后使用inputPaymentCredentialsGooglePay构造函数发送该数据。

示例实现:Android 版 Telegram。

3.6 使用已保存的支付凭证

inputPaymentCredentialsSaved#c10eb2cf id:string tmp_password:bytes = InputPaymentCredentials;paymentSavedCredentialsCard#cdc27a1f id:string title:string = PaymentSavedCredentials;payments.paymentForm#a0058751 flags:# can_save_credentials:flags.2?true password_missing:flags.3?true form_id:long bot_id:long title:string description:string photo:flags.5?WebDocument invoice:Invoice provider_id:long url:string native_provider:flags.4?string native_params:flags.4?DataJSON additional_methods:flags.6?Vector<PaymentFormMethod> saved_info:flags.0?PaymentRequestedInfo saved_credentials:flags.1?Vector<PaymentSavedCredentials> users:Vector<User> = payments.PaymentForm;account.tmpPassword#db64fd34 tmp_password:bytes valid_until:int = account.TmpPassword;---functions---account.getTmpPassword#449e0b51 password:InputCheckPasswordSRP period:int = account.TmpPassword;

要重复使用已保存的支付方式,需要使用支付表单saved_credentials中的相应字段。`paymentSavedCredentialsCard`字段可用于预览经过审查的信用卡信息。该字段由支付服务提供商在保存支付方式时直接提供给 Telegram 服务器,用于标识支付方式。完整的信用卡信息不会保存在 Telegram 服务器上,用户也无法获取。titleid

要使用已保存的付款方式,必须启用2FA :用户必须通过输入其2FA密码来验证其身份,然后按照SRP 文档中的描述使用该密码生成 SRP 参数,这些参数必须传递给account.getTmpPassword。

然后可以使用生成的临时密码,通过inputPaymentCredentialsSaved构造函数,利用已保存的凭据进行支付。

  • 该id字段为paymentSavedCredentialsCard id。
  • 这tmp_password是服务器生成的临时支付密码(如果用户提供了正确的2FA 密码)。

示例实现:Android 版 Telegram。

4. 结账前

inputPaymentCredentialsSaved#c10eb2cf id:string tmp_password:bytes = InputPaymentCredentials; inputPaymentCredentials#3417d728 flags:# save:flags.0?true data:DataJSON = InputPaymentCredentials; inputPaymentCredentialsApplePay#aa1c39f payment_data:DataJSON = InputPaymentCredentials; inputPaymentCredentialsGooglePay#8ac32801 payment_token:DataJSON = InputPaymentCredentials;payments.paymentResult#4e5f810d updates:Updates = payments.PaymentResult; payments.paymentVerificationNeeded#d8411139 url:string = payments.PaymentResult;---functions---payments.sendPaymentForm#2d03522f flags:# form_id:long invoice:InputInvoice requested_info_id:flags.0?string shipping_option_id:flags.1?string credentials:InputPaymentCredentials tip_amount:flags.2?long = payments.PaymentResult;payments.sendStarsForm#7998c914 form_id:long invoice:InputInvoice = payments.PaymentResult;

验证订单信息后,客户的最后一步是调用payments.sendPaymentForm或payments.sendStarsForm(用于使用 Telegram Stars进行支付),并传入以下参数:

  • 该form_id值设置为表单的 ID。
  • 设置invoice为之前通过的发票
  • requested_info_id如果已请求,则设置为已验证id订单信息的值。
  • shipping_option_id如果选择了送货方式,则设置为所选的送货选项。
  • credentials是支付服务提供商生成的支付凭证,用于完成订单。

支付方式信息也可以保存到 Telegram 服务器并重复使用,只需在提交表单时设置`inputPaymentCredentials`save标志即可。此功能仅适用于已启用双重验证 (2FA)的帐户。

然后,机器人回复收到的结账前查询,最后用户继续结账。

请注意,如果该方法的结果为payments.paymentVerificationNeeded,则在继续结账url之前,支付提供商会要求用户打开提供的链接并按照说明(例如 3-D Secure)验证其身份。
用户完成网页操作后,即可继续结账。

最终错误以 RPC 错误的形式返回(rpc_error),机器人对错误的描述包含在单独收到的其他服务更新中,请参阅此处了解更多信息。

请注意,如果在附加验证期间发生最终的支付错误(如果返回payments.paymentVerificationNeeded并且用户 TOTP 验证失败),则不会通过 MTProto 向客户端发送此类错误:此类错误只会显示在验证 webview 中,不会收到 MTProto 更新或 RPC 错误(rpc_error)。

4.1 接收结账前查询

paymentRequestedInfo#909c3f94 flags:# name:flags.0?string phone:flags.1?string email:flags.2?string shipping_address:flags.3?PostAddress = PaymentRequestedInfo;updateBotPrecheckoutQuery#8caa9a96 flags:# query_id:long user_id:long payload:bytes info:flags.0?PaymentRequestedInfo shipping_option_id:flags.1?string currency:string total_amount:long = Update;---functions---messages.setBotPrecheckoutResults#9c2dd95 flags:# success:flags.1?true query_id:long error:flags.0?string = Bool;

用户按照上述步骤输入支付信息并点击最终支付按钮。此时,Telegram API 会向机器人发送一个包含订单所有可用信息的updateBotPrecheckoutQuery构造函数。机器人必须在收到此更新后的10 秒内使用messages.setBotPrecheckoutResults 进行回复,否则交易将被取消。

如果机器人因任何原因无法处理订单,可能会返回错误信息。我们强烈建议您以易于理解的方式说明订单失败的原因(例如:“抱歉,我们的橡皮鸭已经售罄!您是否想要一只钢熊?”)。Telegram 会将此原因显示给用户。

5. 结账

keyboardButtonBuy#afd93fbb text:string = KeyboardButton;keyboardButtonRow#77608b83 buttons:Vector<KeyboardButton> = KeyboardButtonRow; replyInlineMarkup#48a30254 rows:Vector<KeyboardButtonRow> = ReplyMarkup;messageMediaInvoice#f6a548d3 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument receipt_msg_id:flags.2?int currency:string total_amount:long start_param:string extended_media:flags.4?MessageExtendedMedia = MessageMedia;message#9815cec8 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true noforwards:flags.26?true invert_media:flags.27?true flags2:# offline:flags2.1?true video_processing_pending:flags2.4?true paid_suggested_post_stars:flags2.8?true paid_suggested_post_ton:flags2.9?true id:int from_id:flags.8?Peer from_boosts_applied:flags.29?int peer_id:Peer saved_peer_id:flags.28?Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long via_business_bot_id:flags2.0?long reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long reactions:flags.20?MessageReactions restriction_reason:flags.22?Vector<RestrictionReason> ttl_period:flags.25?int quick_reply_shortcut_id:flags.30?int effect:flags2.2?long factcheck:flags2.3?FactCheck report_delivery_until_date:flags2.5?int paid_message_stars:flags2.6?long suggested_post:flags2.7?SuggestedPost = Message;updateNewMessage#1f2b0afd message:Message pts:int pts_count:int = Update;payments.paymentReceipt#70c4fe03 flags:# date:int bot_id:long provider_id:long title:string description:string photo:flags.2?WebDocument invoice:Invoice info:flags.0?PaymentRequestedInfo shipping:flags.1?ShippingOption tip_amount:flags.3?long currency:string total_amount:long credentials_title:string users:Vector<User> = payments.PaymentReceipt;payments.paymentReceiptStars#dabbf83a flags:# date:int bot_id:long title:string description:string photo:flags.2?WebDocument invoice:Invoice currency:string total_amount:long transaction_id:string users:Vector<User> = payments.PaymentReceipt;---functions---payments.getPaymentReceipt#2478d1cc peer:InputPeer msg_id:int = payments.PaymentReceipt;

如果机器人确认订单,Telegram 会请求支付服务提供商完成交易。如果支付信息输入正确且支付成功,Telegram API 将修改发票消息并发送如下所述的服务消息。机器人收到此消息后,应继续交付用户购买的商品或服务。

如果一切正常,用户将收到payments.paymentResult作为对payments.sendPaymentForm查询的回复,其中包含有关更新发票消息的信息,该消息以updateEditMessage的形式提供。

发票消息将更新如下:附加的消息 MediaInvoice现在将包含一个receipt_msg_id字段。客户应将包含此字段的发票消息视为receipt_msg_id收据消息,并在本地修改keyboardButtonBuy按钮的标签,将其更改为本地化的单词Receipt。之后,点击该Receipt按钮应触发对payments.getPaymentReceipt 的调用,并将此字段的值传递receipt_msg_id给该msg_id字段,该字段将返回有关交易的信息。

付款时还会生成一条类型为messageActionPaymentSent或messageActionPaymentSentMe的服务消息,用于回复发票。对于机器人,服务消息类型为messageActionPaymentSentMe;对于用户,服务消息类型为messageActionPaymentSent。如果此次付款启用了未来的定期付款,则会设置相应的标志。
后续的定期付款将自动发送带有该标志的messageActionPaymentSentMe和messageActionPaymentSent消息。recurring_init
recurring_used

messageActionPaymentSentMe#ffa00ccc flags:# recurring_init:flags.2?true recurring_used:flags.3?true currency:string total_amount:long payload:bytes info:flags.0?PaymentRequestedInfo shipping_option_id:flags.1?string charge:PaymentCharge subscription_until_date:flags.4?int = MessageAction; messageActionPaymentSent#c624b16e flags:# recurring_init:flags.2?true recurring_used:flags.3?true currency:string total_amount:long invoice_slug:flags.0?string subscription_until_date:flags.4?int = MessageAction;

6. 退款

paymentCharge#ea02c27e id:string provider_charge_id:string = PaymentCharge;messageActionPaymentSentMe#ffa00ccc flags:# recurring_init:flags.2?true recurring_used:flags.3?true currency:string total_amount:long payload:bytes info:flags.0?PaymentRequestedInfo shipping_option_id:flags.1?string charge:PaymentCharge subscription_until_date:flags.4?int = MessageAction;messageActionPaymentRefunded#41b3e202 flags:# peer:Peer currency:string total_amount:long payload:flags.0?bytes charge:PaymentCharge = MessageAction;---functions---payments.refundStarsCharge#25ae8f4a user_id:InputUser charge_id:string = Updates;

使用Telegram Stars 进行的付款 »可以通过调用payments.refundStarsCharge进行退款,将付款用户的 ID传递给messageActionPaymentSentMe服务消息操作,以接收付款。user_idcharge_idprovider_charge_id

这将发出一个messageActionPaymentRefunded服务消息。