tinkoff

package module
v1.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 27, 2022 License: Apache-2.0 Imports: 11 Imported by: 0

README

Golang Tinkoff Acquiring API (v2) client

The package allows to send token-signed requests to Tinkoff Acquiring API and parse incoming HTTP notifications.

Acquiring API Docs: https://oplata.tinkoff.ru/develop/api/payments/

Contents

Installation

Use go mod as usual or install the package with dep:

dep ensure -add github.com/nikita-vanyasin/tinkoff

Usage

Automatically generated documentation can be found here.

Some examples of usage can be found in *_test.go files.

Create client

Provide terminal key and password from terminal settings page.

client := tinkoff.NewClient(terminalKey, terminalPassword)
Handle HTTP notification

Docs. Example using gin:

router.POST("/payment/notification/tinkoff", func(c *gin.Context) {
    notification, err := client.ParseNotification(c.Request.Body)
    if err != nil {
        handleInternalError(c, err)
        return
    }

    // handle notification, e.g. update payment status in your DB

    // response well-formed body back on success. If you don't do this, the bank will send notification again later
    c.String(http.StatusOK, client.GetNotificationSuccessResponse())
}
Create payment

Init

req := &tinkoff.InitRequest{
    Amount:      60000,
    OrderID:     "123456",
    CustomerKey: "123",
    Description: "some really useful product",
    RedirectDueDate: tinkoff.Time(time.Now().Add(4 * 24 * time.Hour)),
    Receipt: &tinkoff.Receipt{
        Email: "user@example.com",
        Items: []*tinkoff.ReceiptItem{
            {
                Price:    60000,
                Quantity: "1",
                Amount:   60000,
                Name:     "Product #1",
                Tax:      tinkoff.VATNone,
            },
        },
        Taxation: tinkoff.TaxationUSNIncome,
        Payments: &tinkoff.ReceiptPayments{
            Electronic: 60000,
        },
    },
    Data: map[string]string{
        "custom data field 1": "aasd6da78dasd9",
        "custom data field 2": "0",
    },
}
res, err := client.Init(req)
// ...
fmt.Println("payment form url: %s", res.PaymentPageURL)
Create QR
req := &tinkoff.InitRequest{
    Amount:      1000,                 // минимум 1000 копеек 
    OrderID:     "123456",
    Data: map[string]string{"": "",},  // nil - недопустим.
res, err := client.Init(req)
gqr := &tinkoff.GetQrRequest{
    PaymentID: res.PayID,
}
resQR, errQ := client.GetQR(gqr)
Cancel or refund payment

Cancel

req := &tinkoff.CancelRequest{
    PaymentID: "66623",
    Amount: 60000,
}
res, err := client.Cancel(req)
Get payment state

GetState

res, err := client.GetState(&tinkoff.GetStateRequest{PaymentID: "3293"})
// ...
if res.Status == tinkoff.StatusConfirmed {
    fmt.Println("payment completed")
}
Confirm two-step payment

Confirm

res, err := client.Confirm(&tinkoff.ConfirmRequest{PaymentID: "3294"})
// ...
if res.Status == tinkoff.StatusConfirmed {
    fmt.Println("payment completed")
}
Resend notifications

Resend

res, err := c.Resend()
// ...
fmt.Println("resend scheduled for %d notifications", res.Count)
Helper functions

client.PostRequest allows you to implement API requests which are not implemented in this package yet (e.g. when Tinkoff Bank adds new method to API). Use BaseRequest type to implement any API request:

type myCouponUpgradeRequest struct {
  tinkoff.BaseRequest
  PaymentID string `json:"PaymentId"`
  Coupon    string `json:"coupon"`
}
httpResp, err := client.PostRequest(&myCouponUpgradeRequest{PaymentID: "3293", Coupon: "whatever"})

References

The code in this repo based on some code from koorgoo/tinkoff. Differences:

  • Support for API v2
  • 'reflect' package is not used
  • No additional error wrapping

More useful links:

Contribution

All contributions are welcome! There are plenty of API methods that are not implemented yet due to their rare use-cases:

  • FinishAuthorize
  • Submit3DSAuthorization
  • Charge
  • AddCustomer / GetCustomer / RemoveCustomer
  • GetCardList / RemoveCard

Documentation

Overview

Package tinkoff allows to send token-signed requests to Tinkoff Acquiring API and parse incoming HTTP notifications

Index

Constants

View Source
const (
	PayTypeOneStep  = "O"
	PayTypeTwoSteps = "T"
)
View Source
const (
	TaxationOSN              = "osn"                // общая СН
	TaxationUSNIncome        = "usn_income"         // упрощенная СН (доходы)
	TaxationUSNIncomeOutcome = "usn_income_outcome" // упрощенная СН (доходы минус расходы)
	TaxationENVD             = "envd"               // единый налог на вмененный доход
	TaxationESN              = "esn"                // единый сельскохозяйственный налог
	TaxationPatent           = "patent"             // патентная СН
)
View Source
const (
	VATNone = "none"   // без НДС
	VAT0    = "vat0"   // НДС по ставке 0%
	VAT10   = "vat10"  // НДС чека по ставке 10%
	VAT110  = "vat110" // НДС чека по расчетной ставке 10/110

	// Deprecated: since 1 Jan 2019 vat18 will be replaced automatically to vat20 on the side of Tinkoff bank. Use VAT20 instead
	VAT18 = "vat18" // НДС чека по ставке 18%
	VAT20 = "vat20" // НДС чека по ставке 20%

	// Deprecated: since 1 Jan 2019 vat118 will be replaced automatically to vat120 on the side of Tinkoff bank. Use VAT120 instead
	VAT118 = "vat118" // НДС чека по расчетной ставке 18/118
	VAT120 = "vat120" // НДС чека по расчетной ставке 20/120
)
View Source
const (
	PaymentMethodFullPayment    = "full_payment"    // полный расчет
	PaymentMethodFullPrepayment = "full_prepayment" // предоплата 100%
	PaymentMethodPrepayment     = "prepayment"      // предоплата
	PaymentMethodAdvance        = "advance"         // аванс
	PaymentMethodPartialPayment = "partial_payment" // частичный расчет и кредит
	PaymentMethodCredit         = "credit"          // передача в кредит
	PaymentMethodCreditPayment  = "credit_payment"  // оплата кредита
)
View Source
const (
	PaymentObjectCommodity            = "commodity"             // товар
	PaymentObjectExcise               = "excise"                // подакцизный товар
	PaymentObjectJob                  = "job"                   // работа
	PaymentObjectService              = "service"               // услуга
	PaymentObjectGamblingBet          = "gambling_bet"          // ставка азартной игры
	PaymentObjectGamblingPrize        = "gambling_prize"        // выигрыш азартной игры
	PaymentObjectLottery              = "lottery"               // лотерейный билет
	PaymentObjectLotteryPrize         = "lottery_prize"         // выигрыш лотереи
	PaymentObjectIntellectualActivity = "intellectual_activity" // предоставление результатов интеллектуальной деятельности
	PaymentObjectPayment              = "payment"               // платеж
	PaymentObjectAgentCommission      = "agent_commission"      // агентское вознаграждение
	PaymentObjectComposite            = "composite"             // составной предмет расчета
	PaymentObjectAnother              = "another"               // иной предмет расчета
)
View Source
const (
	StatusNew             = "NEW"              // Создан
	StatusFormShowed      = "FORMSHOWED"       // Платежная форма открыта покупателем
	StatusDeadlineExpired = "DEADLINE_EXPIRED" // Просрочен
	StatusCanceled        = "CANCELED"         // Отменен
	StatusPreauthorizing  = "PREAUTHORIZING"   // Проверка платежных данных
	StatusAuthorizing     = "AUTHORIZING"      // Резервируется
	StatusAuthorized      = "AUTHORIZED"       // Зарезервирован
	StatusAuthFail        = "AUTH_FAIL"        // Не прошел авторизацию
	StatusRejected        = "REJECTED"         // Отклонен
	Status3DSChecking     = "3DS_CHECKING"     // Проверяется по протоколу 3-D Secure
	Status3DSChecked      = "3DS_CHECKED"      // Проверен по протоколу 3-D Secure
	StatusReversing       = "REVERSING"        // Резервирование отменяется
	StatusReversed        = "REVERSED"         // Резервирование отменено
	StatusConfirming      = "CONFIRMING"       // Подтверждается
	StatusConfirmed       = "CONFIRMED"        // Подтвержден
	StatusRefunding       = "REFUNDING"        // Возвращается
	StatusQRRefunding     = "ASYNC_REFUNDING"  // Возврат QR
	StatusPartialRefunded = "PARTIAL_REFUNDED" // Возвращен частично
	StatusRefunded        = "REFUNDED"         // Возвращен полностью
)

Variables

This section is empty.

Functions

This section is empty.

Types

type BaseRequest

type BaseRequest struct {
	TerminalKey string `json:"TerminalKey"`
	Token       string `json:"Token"`
}

func (*BaseRequest) SetTerminalKey

func (r *BaseRequest) SetTerminalKey(key string)

func (*BaseRequest) SetToken

func (r *BaseRequest) SetToken(token string)

type BaseResponse

type BaseResponse struct {
	TerminalKey  string `json:"TerminalKey"`       // Идентификатор терминала, выдается Продавцу Банком
	Success      bool   `json:"Success"`           // Успешность операции
	ErrorCode    string `json:"ErrorCode"`         // Код ошибки, «0» - если успешно
	ErrorMessage string `json:"Message,omitempty"` // Краткое описание ошибки
	ErrorDetails string `json:"Details,omitempty"` // Подробное описание ошибки
}

func (*BaseResponse) Error

func (e *BaseResponse) Error() error

type CancelRequest

type CancelRequest struct {
	BaseRequest

	PaymentID string   `json:"PaymentId"`         // Идентификатор платежа в системе банка. По офф. документации это number(20), но фактически значение передается в виде строки
	ClientIP  string   `json:"IP,omitempty"`      // IP-адрес покупателя
	Amount    uint64   `json:"Amount,omitempty"`  // Сумма возврата в копейках
	Receipt   *Receipt `json:"Receipt,omitempty"` // Чек
}

func (*CancelRequest) GetValuesForToken

func (i *CancelRequest) GetValuesForToken() map[string]string

type CancelResponse

type CancelResponse struct {
	BaseResponse
	OriginalAmount uint64 `json:"OriginalAmount"` // Сумма в копейках до операции отмены
	NewAmount      uint64 `json:"NewAmount"`      // Сумма в копейках после операции отмены
	OrderID        string `json:"OrderId"`        // Номер заказа в системе Продавца
	Status         string `json:"Status"`         // Статус транзакции
	PaymentID      string `json:"PaymentId"`      // Уникальный идентификатор транзакции в системе Банка
}

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is the main entity which execute request against the Tinkoff Acquiring API endpoint

func NewClient

func NewClient(terminalKey, password string) *Client

NewClient returns new Client instance

func (*Client) Cancel

func (c *Client) Cancel(request *CancelRequest) (*CancelResponse, error)

func (*Client) Confirm

func (c *Client) Confirm(request *ConfirmRequest) (*ConfirmResponse, error)

func (*Client) GetNotificationSuccessResponse

func (c *Client) GetNotificationSuccessResponse() string

func (*Client) GetQR added in v1.0.4

func (c *Client) GetQR(request *GetQRRequest) (*GetQRResponse, error)

func (*Client) GetState

func (c *Client) GetState(request *GetStateRequest) (*GetStateResponse, error)

func (*Client) Init

func (c *Client) Init(request *InitRequest) (*InitResponse, error)

func (*Client) ParseNotification

func (c *Client) ParseNotification(requestBody io.Reader) (*Notification, error)

func (*Client) PostRequest

func (c *Client) PostRequest(url string, request RequestInterface) (*http.Response, error)

PostRequest will automatically sign the request with token Use BaseRequest type to implement any API request

func (*Client) Resend

func (c *Client) Resend() (*ResendResponse, error)

func (*Client) SPBPayTest added in v1.0.4

func (c *Client) SPBPayTest(request *GetQRTestRequest) (*GetQRResponse, error)

SPBPayTest тестовый метод описанный в API. на рабочем терминале - функция не работает. тестовый терминал не работает у банка.

func (*Client) SetBaseURL

func (c *Client) SetBaseURL(baseURL string)

SetBaseURL allows to change default API endpoint

type ConfirmRequest

type ConfirmRequest struct {
	BaseRequest
	PaymentID string   `json:"PaymentId"`         // Идентификатор платежа в системе банка
	Amount    uint64   `json:"Amount,omitempty"`  // Сумма в копейках
	ClientIP  string   `json:"IP,omitempty"`      // IP-адрес покупателя
	Receipt   *Receipt `json:"Receipt,omitempty"` // Чек
}

func (*ConfirmRequest) GetValuesForToken

func (i *ConfirmRequest) GetValuesForToken() map[string]string

type ConfirmResponse

type ConfirmResponse struct {
	BaseResponse
	OrderID   string `json:"OrderId"`   // Номер заказа в системе Продавца
	Status    string `json:"Status"`    // Статус транзакции
	PaymentID string `json:"PaymentId"` // Идентификатор платежа в системе банка.
}

type GetQRRequest added in v1.0.4

type GetQRRequest struct {
	BaseRequest

	PaymentID string `json:"PaymentId"` // Идентификатор платежа в системе банка. По офф. документации это number(20), но фактически значение передается в виде строки
	DataType  string `json:"DataType"`  //Тип возвращаемых данных. PAYLOAD – В ответе возвращается только Payload (по-умолчанию). IMAGE – В ответе возвращается SVG изображение QR
}

func (*GetQRRequest) GetValuesForToken added in v1.0.4

func (i *GetQRRequest) GetValuesForToken() map[string]string

type GetQRResponse added in v1.0.4

type GetQRResponse struct {
	BaseResponse
	OrderID   string `json:"OrderId"`   // Номер заказа в системе Продавца
	Data      string `json:"Data"`      // Payload - или SVG
	PaymentID int    `json:"PaymentId"` // Идентификатор платежа в системе банка.
}

type GetQRTestRequest added in v1.0.4

type GetQRTestRequest struct {
	BaseRequest

	PaymentID         string `json:"PaymentId"`         // Идентификатор платежа в системе банка. По офф. документации это number(20), но фактически значение передается в виде строки
	IsDeadlineExpired bool   `json:"IsDeadlineExpired"` // Признак эмуляции отказа проведения платежа Банком по таймауту. true – требуется эмуляция (не	может быть использован вместе с IsRejected = true)
	IsRejected        bool   `json:"IsRejected"`        // Признак эмуляции отказа Банка в проведении платежа. true – требуется эмуляция (не может быть использован вместе с IsDeadlineExpired = true)
}

func (*GetQRTestRequest) GetValuesForToken added in v1.0.4

func (i *GetQRTestRequest) GetValuesForToken() map[string]string

type GetStateRequest

type GetStateRequest struct {
	BaseRequest

	PaymentID string `json:"PaymentId"`    // Идентификатор платежа в системе банка. По офф. документации это number(20), но фактически значение передается в виде строки
	ClientIP  string `json:"IP,omitempty"` // IP-адрес покупателя
}

func (*GetStateRequest) GetValuesForToken

func (i *GetStateRequest) GetValuesForToken() map[string]string

type GetStateResponse

type GetStateResponse struct {
	BaseResponse
	OrderID   string `json:"OrderId"`   // Номер заказа в системе Продавца
	Status    string `json:"Status"`    // Статус платежа
	PaymentID string `json:"PaymentId"` // Уникальный идентификатор транзакции в системе Банка
}

type InitRequest

type InitRequest struct {
	BaseRequest

	Amount          uint64            `json:"Amount,omitempty"`          // Сумма в копейках
	OrderID         string            `json:"OrderId"`                   // Идентификатор заказа в системе продавца
	ClientIP        string            `json:"IP,omitempty"`              // IP-адрес покупателя
	Description     string            `json:"Description,omitempty"`     // Описание заказа
	Language        string            `json:"Language,omitempty"`        // Язык платежной формы: ru или en
	Recurrent       string            `json:"Recurrent,omitempty"`       // Y для регистрации автоплатежа. Можно использовать SetIsRecurrent(true)
	CustomerKey     string            `json:"CustomerKey,omitempty"`     // Идентификатор покупателя в системе продавца. Передается вместе с параметром CardId. См. метод GetCardList
	Data            map[string]string `json:"DATA"`                      // Дополнительные параметры платежа
	Receipt         *Receipt          `json:"Receipt,omitempty"`         // Чек
	RedirectDueDate Time              `json:"RedirectDueDate,omitempty"` // Срок жизни ссылки
	NotificationURL string            `json:"NotificationURL,omitempty"` // Адрес для получения http нотификаций
	SuccessURL      string            `json:"SuccessURL,omitempty"`      // Страница успеха
	FailURL         string            `json:"FailURL,omitempty"`         // Страница ошибки
	PayType         string            `json:"PayType,omitempty"`         // Тип оплаты. см. PayType*
}

func (*InitRequest) GetValuesForToken

func (i *InitRequest) GetValuesForToken() map[string]string

func (*InitRequest) SetIsRecurrent

func (i *InitRequest) SetIsRecurrent(r bool)

type InitResponse

type InitResponse struct {
	BaseResponse
	Amount     uint64 `json:"Amount"`               // Сумма в копейках
	OrderID    string `json:"OrderId"`              // Номер заказа в системе Продавца
	Status     string `json:"Status"`               // Статус транзакции
	PaymentID  string `json:"PaymentId"`            // Уникальный идентификатор транзакции в системе Банка. По офф. документации это number(20), но фактически значение передается в виде строки.
	PaymentURL string `json:"PaymentURL,omitempty"` // Ссылка на страницу оплаты. По умолчанию ссылка доступна в течении 24 часов.
}

type Notification

type Notification struct {
	TerminalKey    string            `json:"TerminalKey"` // Идентификатор магазина
	OrderID        string            `json:"OrderId"`     // Номер заказа в системе Продавца
	Success        bool              `json:"Success"`     // Успешность операции
	Status         string            `json:"Status"`      // Статус платежа (см. описание статусов операций)
	PaymentID      uint64            `json:"PaymentId"`   // Уникальный идентификатор платежа. В случае нотификаций банк присылает число, а не строку, как в случае с Init или Cancel
	ErrorCode      string            `json:"ErrorCode"`   // Код ошибки, если произошла ошибка
	Amount         uint64            `json:"Amount"`      // Текущая сумма транзакции в копейках
	RebillID       string            `json:"RebillId"`    // Идентификатор рекуррентного платежа
	CardID         uint64            `json:"CardId"`      // Идентификатор привязанной карты
	PAN            string            `json:"Pan"`         // Маскированный номер карты
	DataStr        string            `json:"DATA"`
	Data           map[string]string `json:"-"`       // Дополнительные параметры платежа, переданные при создании заказа
	Token          string            `json:"Token"`   // Подпись запроса
	ExpirationDate string            `json:"ExpDate"` // Срок действия карты
}

func (*Notification) GetValuesForToken

func (n *Notification) GetValuesForToken() map[string]string

type Receipt

type Receipt struct {
	Email        string           `json:"Email,omitempty"`        // Электронная почта покупателя
	Phone        string           `json:"Phone,omitempty"`        // Контактный телефон покупателя
	EmailCompany string           `json:"EmailCompany,omitempty"` // Электронная почта продавца
	Taxation     string           `json:"Taxation"`               // Система налогооблажения. см. константы Taxation*
	Items        []*ReceiptItem   `json:"Items"`                  // Массив позиций чека с информацией о товарах.
	Payments     *ReceiptPayments `json:"Payments,omitempty"`     // Объект с информацией о видах оплаты заказа.
}

type ReceiptItem

type ReceiptItem struct {
	Name          string `json:"Name"`                    // Наименование товара
	Quantity      string `json:"Quantity"`                // Количество или вес товара
	Amount        uint64 `json:"Amount"`                  // Стоимость товара в копейках
	Price         uint64 `json:"Price"`                   // Цена товара в копейках
	PaymentMethod string `json:"PaymentMethod,omitempty"` // Признак способа расчета. см. PaymentMethod*
	PaymentObject string `json:"PaymentObject,omitempty"` // Признак предмета расчета. см. PaymentObject*
	Tax           string `json:"Tax"`                     // Ставка налога. см. константы VAT*
	Ean13         string `json:"Ean13,omitempty"`         // Ean13
	ShopCode      string `json:"ShopCode,omitempty"`      // Код магазина
}

type ReceiptPayments added in v1.0.3

type ReceiptPayments struct {
	Cash           uint64 `json:"Cash,omitempty"`           // Вид оплаты "Наличные". Сумма к оплате в копейках не более 14 знаков
	Electronic     uint64 `json:"Electronic"`               // Вид оплаты "Безналичный".
	AdvancePayment uint64 `json:"AdvancePayment,omitempty"` // Вид оплаты "Предварительная оплата (Аванс)".
	Credit         uint64 `json:"Credit,omitempty"`         // Вид оплаты "Постоплата (Кредит)"
	Provision      uint64 `json:"Provision,omitempty"`      // Вид оплаты "Иная форма оплаты".
}

type RequestInterface

type RequestInterface interface {
	GetValuesForToken() map[string]string
	SetTerminalKey(key string)
	SetToken(token string)
}

type ResendRequest

type ResendRequest struct {
	BaseRequest
}

func (*ResendRequest) GetValuesForToken

func (r *ResendRequest) GetValuesForToken() map[string]string

type ResendResponse

type ResendResponse struct {
	BaseResponse
	Count int `json:"Count"` // Количество сообщений, отправляемых повторно
}

type Time

type Time time.Time

func (Time) MarshalJSON

func (t Time) MarshalJSON() ([]byte, error)

func (Time) String

func (t Time) String() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL