README
¶
go-crypto-pay
Crypto Pay is a payment system based on @CryptoBot, which allows you to accept payments in cryptocurrency using the API.
This library help you to work with Crypto Pay via Crypto Pay API.
Install
go get -u github.com/vitaliy-ukiru/go-cryptopay
Documentation
For start, you need to create your application and get an API token.
Open @CryptoBot
or @CryptoTestnetBot (for testnet), send a command /pay
to
create a new app and get API Token.
In this library, the high-level is the Client
.
Internally, it calls the ApiCore
methods, which is lower-level and is essentially a gateway for API
requests. The Client
methods, in addition to the usual errors, can return an api error (ApiError)
. If
you want to check whether the received error is such, call the GetApiError
function.
if apiErr := cryptopay.GetApiError(err); apiErr != nil {
// handling error of api.
// apiErr is *ApiError
}
Configure NewClient
- Token - token of you app.
- ApiHost - url to api host. Default mainnet.
- HttpClient - client for make requests. Default
http.DefaultClient
. - Webhook - webhook configure
- OnError - handler for error handling in webhook.
- DefaultHandler - set of default handlers. Default empty.
Networks in CryptoPay:
Net | Bot | Hostname | Code reference |
---|---|---|---|
mainnet | @CryptoBot | https://pay.crypt.bot/ | cryptopay.MainNetHost |
testnet | @CryptoTestnetBot | https://testnet-pay.crypt.bot/ | cryptopay.TestNetHost |
Webhooks
To get started, send /pay
command to bot, choose "My Apps", select application, open "Webhooks" and set
your endpoint.
To work with webhooks, you need to start the server yourself and install Webhook.ServeHTTP
as a handler
to the endpoint. If you are running a "net/http" server, you can pass the Webhook
as http.Handler
type. But if you don't use std server, see the Adaptation section.
Examples
getMe
package main
import (
"fmt"
"github.com/vitaliy-ukiru/go-cryptopay"
)
func main() {
client := cryptopay.NewClient(cryptopay.ClientSettings{
Token: "your_token_here",
ApiHost: cryptopay.TestNetHost,
})
app, err := client.GetMe()
if err != nil {
panic(err)
}
fmt.Printf(
"app_id=%d; name=%q; payment_bot=%q",
app.Id,
app.Name,
app.PaymentBotUsername,
)
}
transfer
package main
import (
"fmt"
"time"
"github.com/vitaliy-ukiru/go-cryptopay"
)
func main() {
client := cryptopay.NewClient(cryptopay.ClientSettings{
Token: "your_token",
})
transfer, err := client.DoTransfer(-1, cryptopay.USDT, 100, "generate unique data", cryptopay.DoTransferOptions{
Comment: "You winner!",
})
if err != nil {
panic(err)
}
fmt.Printf("Transfer completed at %s", transfer.CompletedAt.Format(time.RFC850))
}
webhook
package main
import (
"fmt"
"net/http"
"time"
"github.com/vitaliy-ukiru/go-cryptopay"
)
func main() {
client := cryptopay.NewClient(cryptopay.ClientSettings{
Token: "your_token", // token required for webhooks, because using for verification updates
Webhook: cryptopay.WebhookSettings{
OnError: func(_ *http.Request, err error) {
panic(err)
},
},
})
client.OnInvoicePaid(func(update *cryptopay.WebhookUpdate) {
invoice := update.Payload
fmt.Printf(
"Invoice № %d for %s %s was paid on %s",
invoice.Id,
invoice.Amount,
invoice.Asset,
invoice.PaidAt.Format(time.RFC850))
})
}
Webhook Adaptation
If you use other router you can adapt. For this you must create handler that call ServeHTTP
method.
For gin-gonic/gin:
// router is gin.Engine
router.POST("/path/", func (c *gin.Context) {
webhook.ServerHTTP(http.ResponseWriter(c.Writer), c.Request)
})
// router is httprouter.Router.
router.POST("/path", func (w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
webhook.ServerHTTP(w, r)
})
For gorilla/mux
// router is mux.Router
router.Handle("/path", webhook)
Documentation
¶
Index ¶
- Constants
- Variables
- type ApiCore
- func (c ApiCore) CreateInvoice(opt CreateInvoiceOptions) (*CreateInvoiceResponse, error)
- func (c ApiCore) DoTransfer(opt DoTransferOptions) (*DoTransferResponse, error)
- func (c ApiCore) GetBalance() (*GetBalanceResponse, error)
- func (c ApiCore) GetCurrencies() (*GetCurrenciesResponse, error)
- func (c ApiCore) GetExchangeRates() (*GetExchangeRatesResponse, error)
- func (c ApiCore) GetInvoices(opt *GetInvoicesOptions) (*GetInvoicesResponse, error)
- func (c ApiCore) GetMe() (*GetMeResponse, error)
- type ApiError
- type AppInfo
- type Asset
- type BalanceCurrency
- type BalanceInfo
- type BaseApiResponse
- type Client
- func (c Client) Api() ApiCore
- func (c *Client) CreateInvoice(asset Asset, amount float64, opt CreateInvoiceOptions) (*Invoice, error)
- func (c *Client) DeleteAllHandlersFor(updateType UpdateType)
- func (c *Client) DeleteHandler(updateType UpdateType, i int)
- func (c *Client) DoTransfer(userId int, asset Asset, amount float64, spendId string, opt DoTransferOptions) (*Transfer, error)
- func (c *Client) GetBalance() (BalanceInfo, error)
- func (c *Client) GetCurrencies() (CurrencyInfoArray, error)
- func (c *Client) GetExchangeRates() (ExchangeRateArray, error)
- func (c *Client) GetInvoices(opt *GetInvoicesOptions) ([]Invoice, error)
- func (c *Client) GetMe() (*AppInfo, error)
- func (c *Client) On(updateType UpdateType, handler Handler) int
- func (c *Client) OnInvoicePaid(handler Handler) int
- func (c *Client) Once(updateType UpdateType, handler Handler)
- func (c Client) Webhook() Webhook
- type ClientSettings
- type CreateInvoiceOptions
- type CreateInvoiceResponse
- type CurrencyInfo
- type CurrencyInfoArray
- type DoTransferOptions
- type DoTransferResponse
- type ErrorHandler
- type ExchangeRate
- type ExchangeRateArray
- type GetBalanceResponse
- type GetCurrenciesResponse
- type GetExchangeRatesResponse
- type GetInvoicesOptions
- type GetInvoicesResponse
- type GetMeResponse
- type Handler
- type Invoice
- type InvoiceStatus
- type PaidButton
- type RatesKey
- type Transfer
- type UpdateType
- type Webhook
- type WebhookSettings
- type WebhookUpdate
Constants ¶
const ( MainNetHost = "https://pay.crypt.bot" TestNetHost = "https://testnet-pay.crypt.bot" )
Aliases for officials hosts
Variables ¶
var ErrorWrongSignature = fmt.Errorf("crypto-pay/webhook: %s", wrongSignature)
ErrorWrongSignature is returned if webhook don't verify update. For example, this can happen if someone who knows webhook's path endpoint and sends fake requests. Also, it could happen when request body was changed from outside.
If this happens, the update is not processed, but Webhook.OnError is called
Functions ¶
This section is empty.
Types ¶
type ApiCore ¶
type ApiCore struct {
// contains filtered or unexported fields
}
func (ApiCore) CreateInvoice ¶
func (c ApiCore) CreateInvoice(opt CreateInvoiceOptions) (*CreateInvoiceResponse, error)
CreateInvoice call api/createInvoice.
func (ApiCore) DoTransfer ¶
func (c ApiCore) DoTransfer(opt DoTransferOptions) (*DoTransferResponse, error)
DoTransfer call api/transfer.
func (ApiCore) GetBalance ¶
func (c ApiCore) GetBalance() (*GetBalanceResponse, error)
GetBalance call api/getBalance.
func (ApiCore) GetCurrencies ¶
func (c ApiCore) GetCurrencies() (*GetCurrenciesResponse, error)
GetCurrencies call api/getCurrencies.
func (ApiCore) GetExchangeRates ¶
func (c ApiCore) GetExchangeRates() (*GetExchangeRatesResponse, error)
GetExchangeRates call api/getExchangeRates.
func (ApiCore) GetInvoices ¶
func (c ApiCore) GetInvoices(opt *GetInvoicesOptions) (*GetInvoicesResponse, error)
GetInvoices call api/getInvoices. Set opt as nil for empty API params.
type ApiError ¶
type ApiError struct { Code int `json:"code"` // HTTP Code of error. Name string `json:"name"` // Name of error. }
ApiError is error of CryptoPay API.
func GetApiError ¶
GetApiError retrieves the ApiError from given error. If unsuccessfully returns nil.
type AppInfo ¶
type AppInfo struct { Id int `json:"app_id"` // ID of application. Name string `json:"name"` // Name of application (sets on create app). PaymentBotUsername string `json:"payment_processing_bot_username"` // Telegram username of the bot that processing payments. }
AppInfo basic information about an app.
type BalanceCurrency ¶
type BalanceCurrency struct { CurrencyCode Asset `json:"currency_code"` Available string `json:"available"` // Balance }
BalanceCurrency contains information about available funds for a particular currency.
type BalanceInfo ¶
type BalanceInfo []BalanceCurrency
BalanceInfo alias for slice of BalanceCurrency.
func (BalanceInfo) AsMap ¶
func (b BalanceInfo) AsMap() map[Asset]string
AsMap returns transformed BalanceInfo ([]BalanceCurrency) into map, key - currency code (Asset), value - balance for Asset as string
func (BalanceInfo) AsMapFloat ¶
func (b BalanceInfo) AsMapFloat() (map[Asset]float64, error)
AsMapFloat returns transformed BalanceInfo ([]BalanceCurrency) into map, key - currency code (Asset), value - balance for Asset as float64
type BaseApiResponse ¶
type BaseApiResponse struct { // Ok indicates whether the request was successfully executed. Ok bool `json:"ok"` // Error from API, nil on successfully. Error *ApiError `json:"error,omitempty"` }
BaseApiResponse is contained in all api responses .
func (BaseApiResponse) IsSuccessfully ¶
func (r BaseApiResponse) IsSuccessfully() bool
IsSuccessfully indicates whether API request success.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is high-level API.
Methods that call API and return error can return ApiError. For get ApiError use GetApiError.
If you want set regular params in opt parameter - set regular parameters default value (empty string for Asset & string, 0 for numbers).
func (*Client) CreateInvoice ¶
func (c *Client) CreateInvoice(asset Asset, amount float64, opt CreateInvoiceOptions) (*Invoice, error)
CreateInvoice is representation for api/createInvoice.
func (*Client) DeleteAllHandlersFor ¶
func (c *Client) DeleteAllHandlersFor(updateType UpdateType)
DeleteAllHandlersFor alias for Webhook.DeleteHandlers.
Delete all handlers for given update type. Also if update type is "*" reset handlers to empty value for EVERY UPDATE TYPE
func (*Client) DeleteHandler ¶
func (c *Client) DeleteHandler(updateType UpdateType, i int)
func (*Client) DoTransfer ¶
func (c *Client) DoTransfer(userId int, asset Asset, amount float64, spendId string, opt DoTransferOptions) (*Transfer, error)
DoTransfer is representation for api/transfer. Error regular or ApiError.
If you want set regular params in opt - set regular parameters default value (empty string for Asset & string, 0 for numbers) spendId must be unique for every operation.
func (*Client) GetBalance ¶
func (c *Client) GetBalance() (BalanceInfo, error)
GetBalance is representation for api/getBalance.
func (*Client) GetCurrencies ¶
func (c *Client) GetCurrencies() (CurrencyInfoArray, error)
GetCurrencies is representation for api/getCurrencies.
func (*Client) GetExchangeRates ¶
func (c *Client) GetExchangeRates() (ExchangeRateArray, error)
GetExchangeRates is representation for api/getExchangeRates.
func (*Client) GetInvoices ¶
func (c *Client) GetInvoices(opt *GetInvoicesOptions) ([]Invoice, error)
GetInvoices is representation for api/getInvoices. Set opt parameter as nil for empty API params.
func (*Client) On ¶
func (c *Client) On(updateType UpdateType, handler Handler) int
On alias for Webhook.Bind. Add handler to slice for given update type. Return index of new handler
func (*Client) OnInvoicePaid ¶
OnInvoicePaid is shortcut for Client.On with update type "invoice_paid".
func (*Client) Once ¶
func (c *Client) Once(updateType UpdateType, handler Handler)
Once add handler that will call once.
type ClientSettings ¶
type ClientSettings struct { // Token of CryptoPay App. Token string // ApiHost url to api host. Default mainnet (MainNetHost). ApiHost string // HttpClient for make requests. Default http.DefaultClient. HttpClient *http.Client // Webhook settings. If set default value webhook can correct work. Webhook WebhookSettings }
ClientSettings for easy configure NewClient.
type CreateInvoiceOptions ¶
type CreateInvoiceOptions struct { Asset Asset // Currency code. Amount string // Amount of the invoice in float. Description string // Optional. Description for the invoice. User will see this description when they pay the invoice. Up to 1024 characters. HiddenMessage string // Optional. Text of the message that will be shown to a user after the invoice is paid. Up to 2o48 characters. PaidButtonName PaidButton // Optional. Name of the button that will be shown to a user after the invoice is paid. PaidButtonUrl string // Optional. Required if PaidButtonName is used. URL to be opened when the button is pressed. You can set any success link (for example, a link to your bot). Starts with https or http. Payload string // Optional. Any data you want to attach to the invoice (for example, user ID, payment ID, ect). Up to 4kb. AllowComments bool // Optional. Allow a user to add a comment to the payment. Default is true. AllowAnonymous bool // Optional. Allow a user to pay the invoice anonymously. Default is true. ExpiresIn int // Optional. You can set a payment time limit for the invoice in seconds. Values between 1-2678400 are accepted }
CreateInvoiceOptions for `createInvoice` api method.
func (CreateInvoiceOptions) QueryParams ¶
func (opt CreateInvoiceOptions) QueryParams() string
QueryParams encode options to query params for `createInvoice` method.
type CreateInvoiceResponse ¶
type CreateInvoiceResponse struct { BaseApiResponse Result *Invoice `json:"result,omitempty"` }
CreateInvoiceResponse for `createInvoice` method
type CurrencyInfo ¶
type CurrencyInfo struct { IsBlockchain bool `json:"is_blockchain"` // Indicates what currency is crypto. IsStablecoin bool `json:"is_stablecoin"` // Indicates what currency is stablecoin. IsFiat bool `json:"is_fiat"` // Indicates what currency is fiat (real) Name string `json:"name"` // Name of currency Code Asset `json:"code"` // Currency code Url string `json:"url"` // Url to currency homepage Decimals int `json:"decimals"` // I don't know what is }
type CurrencyInfoArray ¶
type CurrencyInfoArray []CurrencyInfo
CurrencyInfoArray alias for slice of CurrencyInfo
func (CurrencyInfoArray) AsMap ¶
func (c CurrencyInfoArray) AsMap() map[Asset]CurrencyInfo
AsMap returns transformed CurrencyInfoArray ([]CurrencyInfo) into map.
type DoTransferOptions ¶
type DoTransferOptions struct { UserId int // Telegram user ID. User must have previously used @CryptoBot (@CryptoTestnetBot for testnet). Asset Asset // Currency code. Amount string // Amount of the invoice in float. SpendId string // Unique ID to make your request idempotent and ensure that only one of the transfers with the same spend_id will be accepted by Crypto Pay API. More https://telegra.ph/Crypto-Pay-API-11-25#transfer Comment string // Optional. Comment for the transfer. Users will see this comment when they receive a notification about the transfer. Up to 1024 symbols. DisableSendNotification bool // Optional. Pass true if the user should not receive a notification about the transfer. Default is false. }
DoTransferOptions for `transfer` (DoTransfer) api method.
func (DoTransferOptions) QueryParams ¶
func (opt DoTransferOptions) QueryParams() string
QueryParams encode options to query params for `transfer` method.
type DoTransferResponse ¶
type DoTransferResponse struct { BaseApiResponse Result *Transfer `json:"result,omitempty"` }
DoTransferResponse for `transfer` method
type ErrorHandler ¶
ErrorHandler is signature of Webhook.OnError
type ExchangeRate ¶
type ExchangeRateArray ¶
type ExchangeRateArray []ExchangeRate
ExchangeRateArray alias for slice of ExchangeRate.
func (ExchangeRateArray) AsMap ¶
func (e ExchangeRateArray) AsMap() map[RatesKey]ExchangeRate
AsMap returns transformed ExchangeRateArray ([]ExchangeRate) into map.
type GetBalanceResponse ¶
type GetBalanceResponse struct { BaseApiResponse Result []BalanceCurrency `json:"result,omitempty"` }
GetBalanceResponse for `getBalance` method
type GetCurrenciesResponse ¶
type GetCurrenciesResponse struct { BaseApiResponse Result []CurrencyInfo `json:"result,omitempty"` }
GetCurrenciesResponse for `getCurrencies` method
type GetExchangeRatesResponse ¶
type GetExchangeRatesResponse struct { BaseApiResponse Result []ExchangeRate `json:"result,omitempty"` }
GetExchangeRatesResponse for `getExchangeRates` method
type GetInvoicesOptions ¶
type GetInvoicesOptions struct { Asset Asset // Currency code. InvoiceIds []string // Optional. Invoice IDs Status InvoiceStatus // Optional. Status of invoices to be returned. Defaults to all statuses. Offset int // Optional. Offset needed to return a specific subset of invoices. Default is 0. Count int // Optional. Number of invoices to be returned. Values between 1-1000 are accepted. Defaults to 100. }
GetInvoicesOptions for `getInvoices` api method.
func (GetInvoicesOptions) QueryParams ¶
func (opt GetInvoicesOptions) QueryParams() string
QueryParams encode options to query params for `getInvoices` method.
type GetInvoicesResponse ¶
type GetInvoicesResponse struct { BaseApiResponse Result struct { Items []Invoice `json:"items"` } `json:"result,omitempty"` }
GetInvoicesResponse for `getInvoices` method
type GetMeResponse ¶
type GetMeResponse struct { BaseApiResponse Result *AppInfo `json:"result,omitempty"` }
GetMeResponse for `getMe` method
type Invoice ¶
type Invoice struct { Id int `json:"invoice_id"` // Unique ID for this invoice. Status InvoiceStatus `json:"status"` // Status of the invoice, can be either . Hash string `json:"hash,omitempty"` // Hash of the invoice. Asset Asset `json:"asset"` // Currency code. Amount string `json:"amount"` // Amount of the invoice. Fee string `json:"fee"` // Optional. Amount of charged service fees. PayUrl string `json:"pay_url,omitempty"` // URL should be presented to the user to pay the invoice. CreatedAt time.Time `json:"created_at"` // Date the invoice was created in ISO 8601 format. USDRate string `json:"usd_rate"` // Optional. Price of the Asset in USD at the time the invoice was paid. AllowComments bool `json:"allow_comments,omitempty"` // True, if the user can add comment to the payment. AllowAnonymous bool `json:"allow_anonymous,omitempty"` // True, if the user can pay the invoice anonymously. PaidAt time.Time `json:"paid_at,omitempty"` // Optional. Date the invoice was paid in Unix time. PaidAnonymously bool `json:"paid_anonymously,omitempty"` // Optional. Text of the hidden message for this invoice. Description string `json:"description,omitempty"` // Optional. Description for this invoice. ExpirationDate string `json:"expiration_date,omitempty"` // Optional. Date the invoice expires in Unix time. (not timestamp) Comment string `json:"comment,omitempty"` // Optional. Comment to the payment from the user. HiddenMessage string `json:"hidden_message,omitempty"` // Optional. Text of the hidden message for this invoice. Payload string `json:"payload,omitempty"` // Optional. Previously provided data for this invoice. PaidBtnName PaidButton `json:"paid_btn_name,omitempty"` // Optional. Name of the button. PaidBtnUrl string `json:"paid_btn_url,omitempty"` // Optional. URL of the button. }
Invoice object.
type InvoiceStatus ¶
type InvoiceStatus string
InvoiceStatus is status of the invoice.
const ( StatusActive InvoiceStatus = "active" StatusPaid InvoiceStatus = "paid" StatusExpired InvoiceStatus = "expired" )
func (InvoiceStatus) String ¶
func (i InvoiceStatus) String() string
type PaidButton ¶
type PaidButton string
PaidButton is name of the button that will be shown to a user after the invoice is paid.
const ( ButtonViewItem PaidButton = "viewItem" ButtonOpenChannel PaidButton = "openChannel" ButtonOpenBot PaidButton = "openBot" ButtonCallback PaidButton = "callback" )
func (PaidButton) String ¶
func (p PaidButton) String() string
type Transfer ¶
type Transfer struct { Id int `json:"transfer_id"` // Unique ID for this transfer. UserId int `json:"user_id"` // Telegram user ID the transfer was sent to. Asset Asset `json:"asset"` // Currency code. Amount string `json:"amount"` // Amount of the transfer. Status string `json:"status"` // Status of the transfer, can be “completed”. CompletedAt time.Time `json:"completed_at"` // Date the transfer was completed in ISO 8601 format. Comment string `json:"comment,omitempty"` // Optional. Comment for this transfer. }
Transfer object
type UpdateType ¶
type UpdateType string
UpdateType is type of webhook update.
const ( // UpdateInvoicePaid update type, indicates that invoice was paid. UpdateInvoicePaid UpdateType = "invoice_paid" )
type Webhook ¶
type Webhook struct { // OnError handler for errors OnError ErrorHandler // contains filtered or unexported fields }
Webhook representation http.Handler for works with CryptoPay updates
func NewWebhook ¶
func NewWebhook(token string, defaultHandlers map[UpdateType][]Handler, onError ErrorHandler) *Webhook
NewWebhook returns new Webhook.
func (*Webhook) Bind ¶
func (w *Webhook) Bind(updateType UpdateType, handler Handler) int
Bind add handler given update type. Returns handler index.
func (*Webhook) DeleteHandlerByIndex ¶
func (w *Webhook) DeleteHandlerByIndex(updateType UpdateType, i int)
DeleteHandlerByIndex deletes handler given type and index.
func (*Webhook) DeleteHandlers ¶
func (w *Webhook) DeleteHandlers(updateType UpdateType)
DeleteHandlers deletes all handlers given type. Also, can delete all handlers for all update types. If you want to delete all handlers for all types, then pass "*" as a parameter
func (Webhook) ServeHTTP ¶
func (w Webhook) ServeHTTP(rw http.ResponseWriter, r *http.Request)
ServeHTTP implementing http.Handler.
Thanks to this, you can transmit a webhook as a handler for a "net/http" server. By recommended use this like as http.Handler parameter for function http.Handle.
If you use other router you can adapt. For this you must create handler that call this method. Examples of adapt see in README.md file
type WebhookSettings ¶
type WebhookSettings struct { // OnError is handler for error in webhook. OnError func(r *http.Request, err error) // DefaultHandlers is set of default handlers. Default creates new set. DefaultHandlers map[UpdateType][]Handler }
WebhookSettings for configure webhook in ClientSettings.
type WebhookUpdate ¶
type WebhookUpdate struct { // Id is Non-unique update ID. Id int `json:"update_id"` // UpdateType is webhook update type. UpdateType UpdateType `json:"update_type"` // RequestDate is date the request was sent in ISO 8601 format. RequestDate time.Time `json:"request_date"` // Payload is base invoice information. Payload Invoice `json:"payload"` }
WebhookUpdate is object of update from request body.