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") } }