Skip to content

Commit

Permalink
payments: complete shipping API
Browse files Browse the repository at this point in the history
  • Loading branch information
demget committed May 20, 2020
1 parent 8affb94 commit 16e74b8
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 49 deletions.
69 changes: 51 additions & 18 deletions bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ type Update struct {
Callback *Callback `json:"callback_query,omitempty"`
Query *Query `json:"inline_query,omitempty"`
ChosenInlineResult *ChosenInlineResult `json:"chosen_inline_result,omitempty"`
ShippingQuery *ShippingQuery `json:"shipping_query,omitempty"`
PreCheckoutQuery *PreCheckoutQuery `json:"pre_checkout_query,omitempty"`
Poll *Poll `json:"poll,omitempty"`
PollAnswer *PollAnswer `json:"poll_answer,omitempty"`
Expand All @@ -126,24 +127,6 @@ type Command struct {
Description string `json:"description"`
}

// ChosenInlineResult represents a result of an inline query that was chosen
// by the user and sent to their chat partner.
type ChosenInlineResult struct {
From User `json:"from"`
Location *Location `json:"location,omitempty"`
ResultID string `json:"result_id"`
Query string `json:"query"`
MessageID string `json:"inline_message_id"` // inline messages only!
}

type PreCheckoutQuery struct {
Sender *User `json:"from"`
ID string `json:"id"`
Currency string `json:"currency"`
Payload string `json:"invoice_payload"`
Total int `json:"total_amount"`
}

// Handle lets you set the handler for some command name or
// one of the supported endpoints.
//
Expand Down Expand Up @@ -391,6 +374,19 @@ func (b *Bot) ProcessUpdate(upd Update) {
return
}

if upd.ShippingQuery != nil {
if handler, ok := b.handlers[OnShipping]; ok {
handler, ok := handler.(func(*ShippingQuery))
if !ok {
panic("telebot: shipping query handler is bad")
}

b.runHandler(func() { handler(upd.ShippingQuery) })
}

return
}

if upd.PreCheckoutQuery != nil {
if handler, ok := b.handlers[OnCheckout]; ok {
handler, ok := handler.(func(*PreCheckoutQuery))
Expand Down Expand Up @@ -935,6 +931,43 @@ func (b *Bot) Notify(to Recipient, action ChatAction) error {
return err
}

// Ship replies to the shipping query, if you sent an invoice
// requesting an address and the parameter is_flexible was specified.
//
// Usage:
// b.Ship(query) // OK
// b.Ship(query, options...) // OK with options
// b.Ship(query, "Oops!") // Error message
//
func (b *Bot) Ship(query *ShippingQuery, what ...interface{}) error {
params := map[string]string{
"shipping_query_id": query.ID,
}

if len(what) == 0 {
params["ok"] = "True"
} else if s, ok := what[0].(string); ok {
params["ok"] = "False"
params["error_message"] = s
} else {
var opts []ShippingOption
for _, v := range what {
opt, ok := v.(ShippingOption)
if !ok {
return ErrUnsupportedWhat
}
opts = append(opts, opt)
}

params["ok"] = "True"
data, _ := json.Marshal(opts)
params["shipping_options"] = string(data)
}

_, err := b.Raw("answerShippingQuery", params)
return err
}

// Accept finalizes the deal.
func (b *Bot) Accept(query *PreCheckoutQuery, errorMessage ...string) error {
params := map[string]string{
Expand Down
2 changes: 1 addition & 1 deletion callbacks.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func (t *InlineButton) With(data string) *InlineButton {
InlineQueryChat: t.InlineQueryChat,
Login: t.Login,

Data: data,
Data: data,
}
}

Expand Down
2 changes: 1 addition & 1 deletion data_payments.go

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions inline.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ import (
"fmt"
)

// ChosenInlineResult represents a result of an inline query that was chosen
// by the user and sent to their chat partner.
type ChosenInlineResult struct {
From User `json:"from"`
Location *Location `json:"location,omitempty"`
ResultID string `json:"result_id"`
Query string `json:"query"`
MessageID string `json:"inline_message_id"` // inline messages only!
}

// Query is an incoming inline query. When the user sends
// an empty query, your bot could return some default or
// trending results.
Expand Down
3 changes: 1 addition & 2 deletions media.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
)

// Album lets you group multiple media (so-called InputMedia)
// into a single messsage.
// into a single message.
//
// On older clients albums look like N regular messages.
type Album []InputMedia
Expand All @@ -24,7 +24,6 @@ type Photo struct {

Width int `json:"width"`
Height int `json:"height"`
Size int `json:"photo_size"`

// (Optional)
Caption string `json:"caption,omitempty"`
Expand Down
87 changes: 63 additions & 24 deletions payments.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,87 @@ import (
"math"
)

type Invoice struct {
// Product name, 1-32 characters.
Title string `json:"title"`

// Product description, 1-255 characters.
Description string `json:"description"`

// Custom payload, required, 1-128 bytes.
Payload string `json:"payload"`
// ShippingQuery contains information about an incoming shipping query.
type ShippingQuery struct {
Sender *User `json:"from"`
ID string `json:"id"`
Payload string `json:"invoice_payload"`
Address ShippingAddress `json:"shipping_address"`
}

// Unique deep-linking parameter that can be used to
// generate this invoice when used as a start parameter.
Start string `json:"start_parameter"`
// ShippingAddress represents a shipping address.
type ShippingAddress struct {
CountryCode string `json:"country_code"`
State string `json:"state"`
City string `json:"city"`
StreetLine1 string `json:"street_line1"`
StreetLine2 string `json:"street_line2"`
PostCode string `json:"post_code"`
}

// Provider token to use.
Token string `json:"provider_token"`
// ShippingOption represents one shipping option.
type ShippingOption struct {
ID string `json:"id"`
Title string `json:"title"`
Prices []Price `json:"prices"`
}

// PreCheckoutQuery contains information about an incoming pre-checkout query.
type PreCheckoutQuery struct {
Sender *User `json:"from"`
ID string `json:"id"`
Currency string `json:"currency"`
Payload string `json:"invoice_payload"`
Total int `json:"total_amount"`
OptionID string `json:"shipping_option_id"`
Order Order `json:"order_info"`
}

Prices []Price `json:"prices"`
// Order represents information about an order.
type Order struct {
Name string `json:"name"`
PhoneNumber string `json:"phone_number"`
Email string `json:"email"`
Address ShippingAddress `json:"shipping_address"`
}

ProviderData string `json:"provider_data"`
// Invoice contains basic information about an invoice.
type Invoice struct {
Title string `json:"title"`
Description string `json:"description"`
Payload string `json:"payload"`
Token string `json:"provider_token"`
Currency string `json:"currency"`
Prices []Price `json:"prices"`
ProviderData string `json:"provider_data"`

Photo *Photo `json:"photo"`
PhotoSize int `json:"photo_size"`

// Start is a unique deep-linking parameter that can be used to
// generate this invoice when used as a start parameter.
Start string `json:"start_parameter"`

// Processing photo_url, photo_size, photo_width, photo_height fields.
Photo *Photo
// Total shows the total price in the smallest units of the currency.
// For example, for a price of US$ 1.45 pass amount = 145.
Total int `json:"total_amount"`

NeedName bool `json:"need_name"`
NeedPhoneNumber bool `json:"need_phone_number"`
NeedEmail bool `json:"need_email"`
NeedShippingAddress bool `json:"need_shipping_address"`

SendPhone bool `json:"send_phone_number_to_provider"`
SendEmail bool `json:"send_email_to_provider"`

IsFlexible bool `json:"is_flexible"`
SendPhoneNumber bool `json:"send_phone_number_to_provider"`
SendEmail bool `json:"send_email_to_provider"`
IsFlexible bool `json:"is_flexible"`
}

// Price represents a portion of the price for goods or services.
type Price struct {
Label string `json:"label"`
Amount int `json:"amount"`
}

// Currency contains information about supported currency for payments.
type Currency struct {
Code string `json:"code"`
Title string `json:"title"`
Expand All @@ -72,7 +111,7 @@ func (c Currency) ToTotal(total float64) int {
var SupportedCurrencies = map[string]Currency{}

func init() {
err := json.Unmarshal([]byte(dataSupportedCurrenciesJSON), &SupportedCurrencies)
err := json.Unmarshal([]byte(dataCurrencies), &SupportedCurrencies)
if err != nil {
panic(err)
}
Expand Down
6 changes: 3 additions & 3 deletions sendable.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,16 +310,16 @@ func (i *Invoice) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error)
"need_phone_number": strconv.FormatBool(i.NeedPhoneNumber),
"need_email": strconv.FormatBool(i.NeedEmail),
"need_shipping_address": strconv.FormatBool(i.NeedShippingAddress),
"send_phone_number_to_provider": strconv.FormatBool(i.SendPhone),
"send_phone_number_to_provider": strconv.FormatBool(i.SendPhoneNumber),
"send_email_to_provider": strconv.FormatBool(i.SendEmail),
"is_flexible": strconv.FormatBool(i.IsFlexible),
}
if i.Photo != nil {
if i.Photo.FileURL != "" {
params["photo_url"] = i.Photo.FileURL
}
if i.Photo.Size > 0 {
params["photo_size"] = strconv.Itoa(i.Photo.Size)
if i.PhotoSize > 0 {
params["photo_size"] = strconv.Itoa(i.PhotoSize)
}
if i.Photo.Width > 0 {
params["photo_width"] = strconv.Itoa(i.Photo.Width)
Expand Down
5 changes: 5 additions & 0 deletions telebot.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ const (
// Handler: func(*ChosenInlineResult)
OnChosenInlineResult = "\achosen_inline_result"

// Will fire on ShippingQuery.
//
// Handler: func(*ShippingQuery)
OnShipping = "\ashipping_query"

// Will fire on PreCheckoutQuery.
//
// Handler: func(*PreCheckoutQuery)
Expand Down

0 comments on commit 16e74b8

Please sign in to comment.