You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

372 lines
10 KiB

package biz
import (
"bkb-payment/api"
"bkb-payment/internal/data/model"
"context"
"github.com/go-kratos/kratos/v2/errors"
"github.com/go-kratos/kratos/v2/log"
)
// ErrUserNotFound is user not found.
var ErrUserNotFound = errors.NotFound(api.ErrorReason_USER_NOT_FOUND.String(), "user not found")
// Greeter is a Greeter model.
type Greeter struct {
Hello string
}
// GreeterRepo is a Greater repo.
type GreeterRepo interface {
Save(context.Context, *Greeter) (*Greeter, error)
FindByID(context.Context, int64) (*Greeter, error)
ListByName(context.Context, string) ([]*Greeter, error)
ListAll(context.Context) ([]*Greeter, error)
CountryList(context.Context) ([]*api.Country, error)
DistrictCascade(context.Context, uint) ([]*DistrictCascade, error)
GetAccount(context.Context, string) (*model.Account, error)
CreateBill(context.Context, *CreateBillReq) (*Bill, error)
GetBillByOutTradeNo(context.Context, string, string) (model.Bill, error)
GetBillByTransactionId(context.Context, string, string) (model.Bill, error)
GetBillByPayId(context.Context, string, string, string) (model.Bill, error)
GetBillByOutTradeNoPayId(context.Context, string, string, string) (model.Bill, error)
UpdateBillPayChannel(context.Context, string, string, string) error
UpdateBillPayId(context.Context, string, string, string) error
UpdateBillTradeStatus(context.Context, string, string, string) error
UpdateBillTradeStatusByPayId(context.Context, string, string, string) error
GetBillAttachByPayId(context.Context, string, string) (*BillAttach, error)
UpdateBillAttachNotifyStatus(context.Context, string, int) error
CloseBill(context.Context, string) error
PaypalToken(ctx context.Context) (string, error)
}
// GreeterUsecase is a Greeter usecase.
type GreeterUsecase struct {
repo GreeterRepo
log *log.Helper
}
// NewGreeterUsecase new a Greeter usecase.
func NewGreeterUsecase(repo GreeterRepo, logger log.Logger) *GreeterUsecase {
return &GreeterUsecase{repo: repo, log: log.NewHelper(logger)}
}
// CreateGreeter creates a Greeter, and returns the new Greeter.
func (uc *GreeterUsecase) CreateGreeter(ctx context.Context, g *Greeter) (*Greeter, error) {
uc.log.WithContext(ctx).Infof("CreateGreeter: %v", g.Hello)
return uc.repo.Save(ctx, g)
}
func (uc *GreeterUsecase) CountList(ctx context.Context) (result []*api.Country, err error) {
result, err = uc.repo.CountryList(ctx)
return
}
type DistrictCascade struct {
ID uint `json:"id"`
ParentID uint `json:"parentId"`
Name string `json:"label"`
Adcode string `json:"adcode"`
Children []*DistrictCascade `gorm:"-" json:"children"`
}
func (uc *GreeterUsecase) DistrictCascadeList(ctx context.Context, parentId uint) (result []*api.District, err error) {
var (
districtList []*DistrictCascade
districtMap = make(map[int32]*api.District)
)
districtList, err = uc.repo.DistrictCascade(ctx, parentId)
if err != nil {
return
}
for _, cascade := range districtList {
pId := int32(cascade.ParentID)
id := int32(cascade.ID)
tmp := &api.District{
Label: cascade.Name,
Adcode: cascade.Adcode,
ParentId: pId,
Children: []*api.District{},
}
if _, ok := districtMap[pId]; !ok {
pTmp := &api.District{
Children: []*api.District{tmp},
}
districtMap[pId] = pTmp
} else {
districtMap[pId].Children = append(districtMap[pId].Children, tmp)
}
if _, ok := districtMap[id]; ok {
tmp.Children = districtMap[id].Children
districtMap[id] = tmp
} else {
districtMap[id] = tmp
}
}
result = districtMap[0].Children
return
}
type CreateBillReq struct {
api.PayTransRequest
OsType string
TerminalType string
TradeType string
PayAccount string
PaymentMethod string
}
type Bill struct {
OutTradeNo string `json:"outTradeNo"`
TransactionId string `json:"transactionId"`
TradeState string `json:"tradeState"`
PayChannel string `json:"payChannel"`
Currency string `json:"currency"`
Amount float64 `json:"amount"`
PaymentMethod string `json:"payment_method"`
PayId string
}
type BillAttach struct {
Bill
Attach string `json:"attach"`
NotifyUrl string `json:"notifyUrl"`
}
func (uc *GreeterUsecase) PayTransaction(ctx context.Context, params *CreateBillReq) (result *Bill, err error) {
var mch *model.Account
mch, err = uc.repo.GetAccount(ctx, params.Appid)
if err != nil {
return
}
if mch.Mchid != params.Mchid {
err = errors.New(400, "", "appid does not match mchid")
return
}
// 校验账号下payChannel
if params.PayChannel != "" {
}
result, err = uc.repo.CreateBill(ctx, params)
if err != nil {
return
}
return
}
type Amount struct {
Currency string
Amount float64
}
func (uc *GreeterUsecase) GetBillByTransactionId(ctx context.Context, mchid, transactionId string) (*Bill, error) {
var (
err error
bill model.Bill
result Bill
)
bill, err = uc.repo.GetBillByTransactionId(ctx, mchid, transactionId)
if err != nil {
return nil, err
}
result.OutTradeNo = bill.OutTradeNo
result.TransactionId = bill.TransactionId
result.PayChannel = bill.PayChannel
result.TradeState = bill.TradeState
result.Currency = bill.Currency
result.Amount = bill.Amount
result.PaymentMethod = bill.PaymentMethod
result.PayId = bill.PayId
return &result, err
}
func (uc *GreeterUsecase) GetBillByOutTradeNo(ctx context.Context, mchid, outTradeNo string) (*Bill, error) {
var (
err error
bill model.Bill
result Bill
)
bill, err = uc.repo.GetBillByOutTradeNo(ctx, mchid, outTradeNo)
if err != nil {
return nil, err
}
result.OutTradeNo = bill.OutTradeNo
result.TransactionId = bill.TransactionId
result.PayChannel = bill.PayChannel
result.TradeState = bill.TradeState
result.Currency = bill.Currency
result.Amount = bill.Amount
result.PaymentMethod = bill.PaymentMethod
result.PayId = bill.PayId
return &result, err
}
func (uc *GreeterUsecase) GetBillByPayId(ctx context.Context, mchid, payChannel, payId string) (*Bill, error) {
var (
err error
bill model.Bill
result Bill
)
bill, err = uc.repo.GetBillByPayId(ctx, mchid, payChannel, payId)
if err != nil {
return nil, err
}
result.OutTradeNo = bill.OutTradeNo
result.TransactionId = bill.TransactionId
result.PayChannel = bill.PayChannel
result.TradeState = bill.TradeState
result.Currency = bill.Currency
result.Amount = bill.Amount
result.PaymentMethod = bill.PaymentMethod
result.PayId = bill.PayId
return &result, err
}
func (uc *GreeterUsecase) GetBillByOutTradeNoPayId(ctx context.Context, mchid, outTradeNo, payId string) (*Bill, error) {
var (
err error
bill model.Bill
result Bill
)
bill, err = uc.repo.GetBillByOutTradeNoPayId(ctx, mchid, outTradeNo, payId)
if err != nil {
return nil, err
}
result.OutTradeNo = bill.OutTradeNo
result.TransactionId = bill.TransactionId
result.PayChannel = bill.PayChannel
result.TradeState = bill.TradeState
result.Currency = bill.Currency
result.Amount = bill.Amount
result.PaymentMethod = bill.PaymentMethod
result.PayId = bill.PayId
return &result, err
}
func (uc *GreeterUsecase) UpdateBillTradeStatus(ctx context.Context, mchid, transactionId, status string) error {
return uc.repo.UpdateBillTradeStatus(ctx, mchid, transactionId, status)
}
func (uc *GreeterUsecase) UpdateBillTradeStatusByPayId(ctx context.Context, payChannel, payId, status string) error {
return uc.repo.UpdateBillTradeStatusByPayId(ctx, payChannel, payId, status)
}
func (uc *GreeterUsecase) UpdateBillPayChannel(ctx context.Context, mchid, transactionId, payChannel string) error {
return uc.repo.UpdateBillPayChannel(ctx, mchid, transactionId, payChannel)
}
func (uc *GreeterUsecase) UpdateBillPayId(ctx context.Context, mchid, transactionId, payId string) error {
return uc.repo.UpdateBillPayId(ctx, mchid, transactionId, payId)
}
func (uc *GreeterUsecase) GetBillAttachByPayId(ctx context.Context, payChannel, payId string) (*BillAttach, error) {
return uc.repo.GetBillAttachByPayId(ctx, payChannel, payId)
}
func (uc *GreeterUsecase) UpdateBillAttachNotifyStatus(ctx context.Context, transactionId string, notifyStatus int) error {
return uc.repo.UpdateBillAttachNotifyStatus(ctx, transactionId, notifyStatus)
}
func (uc *GreeterUsecase) CancelBill(ctx context.Context, params *api.CancelBillRequest) (err error) {
return uc.repo.CloseBill(ctx, params.TransactionId)
}
type PayBot interface {
Consult(ctx context.Context, info *ConsultPay) ([]PayMethod, error)
CreateOrder(context.Context, *CreateOrder) (PayResp, error)
CaptureOrder(context.Context, *Order) (bool, string, string)
Payouts(context.Context, *CreatePayout) (PayResp, error)
ShowPayoutsDetail(context.Context, *Payouts) (bool, string)
CancelOrder(context.Context, string) (bool, error)
RefundOrder(context.Context, *Refund) (RefundResp, error)
}
type ConsultPay struct {
Currency string
Amount string
ProductCode string
UserRegion string
OsType string
TerminalType string
}
type CreateOrder struct {
Currency string
Amount string
ReturnUrl string
CancelUrl string
NotifyUrl string
TransactionId string
Description string
PaymentMethodType string
OsType string
TerminalType string
}
type PayMethod struct {
LogoName string
LogoUrl string
Type string
Category string
Enabled bool
}
type Order struct {
OrderId string
PayId string
Currency string
Value string
}
type Refund struct {
TransactionId string
PayId string
Currency string
Amount string
Reason string
NotifyUrl string
}
type RefundResp struct {
RefundId string
Status string
}
type PayResp struct {
ID string `json:"id"`
Status string `json:"status"`
Method string `json:"method"`
Link string `json:"link"`
}
type CreatePayout struct {
PayerName string
Currency string
Amount string
SenderBatchId string
}
type Payouts struct {
PayoutBatchId string
}
//type PayoutResp struct {
// ID string `json:"id"`
// Status string `json:"status"`
//}
func (uc *GreeterUsecase) NewPayBot(ctx context.Context, bot string) (PayBot, error) {
switch bot {
case "paypal":
token, err := uc.repo.PaypalToken(ctx)
if err != nil {
return nil, err
}
paypalBot := newPaypalBot(token)
return paypalBot, nil
case "alipay-g":
alipayGBot := newAlipayGBot()
return alipayGBot, nil
default:
return nil, errors.BadRequest("", "pay method disabled")
}
}