电报支付 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,并提供以下参数:
-
inputInvoiceMessage,已使用:
- 如果用户点击keyboardButtonBuy按钮,则包含发票预览消息的消息 ID。
- 购买付费媒体时»
-
输入发票别名
- 如果用户打开发票深度链接,则包含该slug参数
- 如果客户端需要处理Telegram Premium付款,则包含premium_invoice_slug应用配置参数 »
-
输入发票高级礼品码
-
如果用户希望发起频道抽奖或向频道成员发送礼品码以换取推广,则可以使用此字段。抽奖活动应填充`inputStorePaymentPremiumGiveaway`,礼品应填充`inputStorePaymentPremiumGiftCode`。
该字段应填充`payments.getPremiumGiftCodeOptions`返回的抽奖选项之一。更多信息,请参阅“抽奖”文档。purpose
option
-
如果用户希望发起频道抽奖或向频道成员发送礼品码以换取推广,则可以使用此字段。抽奖活动应填充`inputStorePaymentPremiumGiveaway`,礼品应填充`inputStorePaymentPremiumGiftCode`。
-
输入发票星
-
用于购买 Telegram 星星。此option字段应填写 `payments.getStarsTopupOptions`返回的星星充值选项之一。更多信息
请参阅星星 »文档。
-
用于购买 Telegram 星星。此option字段应填写 `payments.getStarsTopupOptions`返回的星星充值选项之一。更多信息
-
输入发票聊天邀请订阅
-
用于实现机器人和频道订阅 »。有关更多信息,
请参阅订阅 »文档。
-
用于实现机器人和频道订阅 »。有关更多信息,
-
输入发票星礼
-
用于购买 Telegram 星星礼物。更多信息
请参阅礼物 »文档。
-
用于购买 Telegram 星星礼物。更多信息
-
输入发票星礼升级
-
用于付费将普通礼物升级为收藏品礼物。更多信息
请参阅收藏品礼物»文档。
-
用于付费将普通礼物升级为收藏品礼物。更多信息
-
输入发票StarGift预付升级
-
用于支付费用,让其他人将普通礼物升级为收藏品礼物。更多信息
请参阅收藏品礼物»文档。
-
用于支付费用,让其他人将普通礼物升级为收藏品礼物。更多信息
-
输入发票StarGiftTransfer
-
用于支付将礼物转让给其他用户的费用。
请参阅礼物»文档了解更多信息。
-
用于支付将礼物转让给其他用户的费用。
-
输入发票StarGiftResale
-
用于购买二手礼品。更多信息
请参阅礼品»文档。
-
用于购买二手礼品。更多信息
-
输入发票高级礼品星
-
用于向其他用户赠送高级会员资格,使用 Telegram Stars 支付。更多信息
请参阅Telegram Premium »文档。
-
用于向其他用户赠送高级会员资格,使用 Telegram Stars 支付。更多信息
-
输入发票业务机器人TransferStars
-
用于将受商业机器人控制的用户账户中的 Telegram Stars 转移到机器人的账户余额。更多信息
请参阅Telegram Business »文档。
-
用于将受商业机器人控制的用户账户中的 Telegram Stars 转移到机器人的账户余额。更多信息
返回的表单将包含一些字段,这些字段需要与完整的发票一起传递给支付服务提供商。支付表单还包含之前保存的支付凭证和订单信息(姓名、电话号码、电子邮件地址、收货地址等)。
完整发票包含订单所需信息、价格和币种,以及该订单是否有效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服务消息。