169 lines
4.4 KiB
Go
169 lines
4.4 KiB
Go
|
package payway
|
|||
|
|
|||
|
import (
|
|||
|
"bitbucket.org/skeris/treasurer/dal"
|
|||
|
"context"
|
|||
|
"crypto/md5"
|
|||
|
"encoding/json"
|
|||
|
"fmt"
|
|||
|
"github.com/fatih/structs"
|
|||
|
"sort"
|
|||
|
)
|
|||
|
|
|||
|
const UrlBt = "https://merchant.betatransfer.io/api"
|
|||
|
|
|||
|
type BetaTransfer struct {
|
|||
|
MongoID string
|
|||
|
Name string
|
|||
|
MerchantID string
|
|||
|
WalletID string
|
|||
|
Secret1 string // Request key
|
|||
|
Secret2 string // Response key
|
|||
|
Secret3 string // Wallet API Key
|
|||
|
PayoutTypeList []dal.PayoutType
|
|||
|
PaymentTypeList []dal.PayWayPayment
|
|||
|
}
|
|||
|
|
|||
|
func NewBt(ctx context.Context, conn *dal.MongoConnection) (*BetaTransfer, error) {
|
|||
|
bt, err := conn.GetPayWayByName(ctx, "BetaTransfer")
|
|||
|
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
|
|||
|
paymentList, err := conn.GetPayWayPaymentByPayWay(ctx, bt.ShortName)
|
|||
|
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
|
|||
|
return &BetaTransfer{
|
|||
|
MongoID: bt.ID,
|
|||
|
Name: bt.Name,
|
|||
|
MerchantID: bt.MerchantID,
|
|||
|
WalletID: bt.WalletID,
|
|||
|
Secret1: bt.Secret1,
|
|||
|
Secret2: bt.Secret2,
|
|||
|
PayoutTypeList: bt.PayoutTypeList,
|
|||
|
PaymentTypeList: paymentList,
|
|||
|
}, nil
|
|||
|
}
|
|||
|
|
|||
|
func (bt *BetaTransfer) GetMongoID() string {
|
|||
|
return bt.MongoID
|
|||
|
}
|
|||
|
|
|||
|
func (bt *BetaTransfer) GetName() string {
|
|||
|
return bt.Name
|
|||
|
}
|
|||
|
|
|||
|
func (bt *BetaTransfer) UpdateData(data *dal.PayWay) {
|
|||
|
bt.MongoID = data.ID
|
|||
|
bt.Name = data.MerchantID
|
|||
|
bt.MerchantID = data.MerchantID
|
|||
|
bt.Secret1 = data.Secret1
|
|||
|
bt.Secret2 = data.Secret2
|
|||
|
bt.Secret3 = data.Secret3
|
|||
|
}
|
|||
|
|
|||
|
func (bt *BetaTransfer) UpdatePayment(data []dal.PayWayPayment) {
|
|||
|
bt.PaymentTypeList = data
|
|||
|
}
|
|||
|
|
|||
|
func (bt *BetaTransfer) UpdatePayout(data []dal.PayoutType) {
|
|||
|
bt.PayoutTypeList = data
|
|||
|
}
|
|||
|
|
|||
|
type ReqPaymentListenerBt struct {
|
|||
|
Sign string
|
|||
|
Amount float64
|
|||
|
OrderId string
|
|||
|
UserComment string
|
|||
|
}
|
|||
|
|
|||
|
// GetPayoutTypeList - возвращает локальные способы вывода средств из кошелька
|
|||
|
func (bt *BetaTransfer) GetPayoutTypeList() []dal.PayoutType {
|
|||
|
return bt.PayoutTypeList
|
|||
|
}
|
|||
|
|
|||
|
// GetPayoutType - возвращает локальный указанный способ вывода средств, либо nil если не найдено
|
|||
|
func (bt *BetaTransfer) GetPayoutType(payoutType string) *dal.PayoutType {
|
|||
|
for _, v := range bt.PayoutTypeList {
|
|||
|
if v.ApiId == payoutType {
|
|||
|
return &v
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return nil
|
|||
|
}
|
|||
|
|
|||
|
// GetPaymentTypeList - возвращает локальные способы пополнения
|
|||
|
func (bt *BetaTransfer) GetPaymentTypeList() []dal.PayWayPayment {
|
|||
|
return bt.PaymentTypeList
|
|||
|
}
|
|||
|
|
|||
|
// GetPaymentType - возвращает локальный указанный способ пополнения, либо nil если не найдено
|
|||
|
func (bt *BetaTransfer) GetPaymentType(paymentType string) *dal.PayWayPayment {
|
|||
|
for _, v := range bt.PaymentTypeList {
|
|||
|
if v.ApiId == paymentType {
|
|||
|
return &v
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return nil
|
|||
|
}
|
|||
|
|
|||
|
// FindPayoutType - возвращает локальный указанный способ вывода средств учитывая amount.
|
|||
|
// Возвращает nil если ничего не найдено
|
|||
|
func (bt *BetaTransfer) FindPayoutType(payoutType string, amount float64) *dal.PayoutType {
|
|||
|
for _, v := range bt.PayoutTypeList {
|
|||
|
if v.ApiId == payoutType && amount > v.Minimum && amount < v.Maximum {
|
|||
|
return &v
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return nil
|
|||
|
}
|
|||
|
|
|||
|
// prepareData - сортирует структуру по имени поля, добавляет подпись и переводит в байты
|
|||
|
func (bt *BetaTransfer) prepareData(data interface{}) ([]byte, error) {
|
|||
|
s := structs.New(data)
|
|||
|
structMap := s.Map() // Преобразуем структуру в map
|
|||
|
|
|||
|
// Сортируем по ключу
|
|||
|
keys := make([]string, 0, len(structMap))
|
|||
|
for k := range structMap {
|
|||
|
keys = append(keys, k)
|
|||
|
}
|
|||
|
sort.Strings(keys)
|
|||
|
|
|||
|
sorted := map[string]interface{}{}
|
|||
|
var str string
|
|||
|
|
|||
|
for _, k := range keys {
|
|||
|
if structMap[k] != "" {
|
|||
|
sorted[s.Field(k).Tag("json")] = structMap[k]
|
|||
|
str += fmt.Sprintf("%v", structMap[k])
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Добавляем подпись
|
|||
|
sorted["sign"] = bt.createSign([]string{str})
|
|||
|
|
|||
|
// Переводим в байты
|
|||
|
return json.Marshal(sorted)
|
|||
|
}
|
|||
|
|
|||
|
// createSign - создает md5-подпись из указанного массива строк. В конец строки добавляет Secret2
|
|||
|
func (bt *BetaTransfer) createSign(s []string) string {
|
|||
|
var str string
|
|||
|
for _, v := range s {
|
|||
|
str += v
|
|||
|
}
|
|||
|
|
|||
|
str += bt.Secret2
|
|||
|
|
|||
|
h := md5.Sum([]byte(str))
|
|||
|
return fmt.Sprintf("%x", h)
|
|||
|
}
|