pay
This commit is contained in:
parent
4fa4327845
commit
e3f5baefda
|
@ -4,6 +4,7 @@ import "encoding/json"
|
||||||
|
|
||||||
type CorpConfig struct {
|
type CorpConfig struct {
|
||||||
CorpId string `json:"corpid"`
|
CorpId string `json:"corpid"`
|
||||||
|
Password string `json:"password"`
|
||||||
EnterpriseAgent string `json:"enterprise_agent"`
|
EnterpriseAgent string `json:"enterprise_agent"`
|
||||||
EnterpriseSecret string `json:"enterprise_secret"`
|
EnterpriseSecret string `json:"enterprise_secret"`
|
||||||
ApproveAgent string `json:"approve_agent"`
|
ApproveAgent string `json:"approve_agent"`
|
||||||
|
@ -16,6 +17,7 @@ type CorpConfig struct {
|
||||||
PayApiKeyV2 string `json:"pay_api_key_v2"`
|
PayApiKeyV2 string `json:"pay_api_key_v2"`
|
||||||
PayCertPem string `json:"pay_cert_pem"`
|
PayCertPem string `json:"pay_cert_pem"`
|
||||||
PayKeyPem string `json:"pay_key_pem"`
|
PayKeyPem string `json:"pay_key_pem"`
|
||||||
|
PayChannel string `json:"pay_channel"`
|
||||||
|
|
||||||
TplIdCheckin string `json:"tplid_checkin"`
|
TplIdCheckin string `json:"tplid_checkin"`
|
||||||
TplIdRefund string `json:"tplid_refund"`
|
TplIdRefund string `json:"tplid_refund"`
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package api
|
||||||
|
|
||||||
|
type PayReq struct {
|
||||||
|
Username string `json:"username"` //用户名
|
||||||
|
Password string `json:"password"` //密码
|
||||||
|
Amount int64 `json:"amount"` //单位分
|
||||||
|
Title string `json:"title"` //转账标题
|
||||||
|
}
|
|
@ -14,6 +14,10 @@ import (
|
||||||
type StaffCheckin struct {
|
type StaffCheckin struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewStaffCheckin() *StaffCheckin {
|
||||||
|
return &StaffCheckin{}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *StaffCheckin) List(ctx *gin.Context) {
|
func (s *StaffCheckin) List(ctx *gin.Context) {
|
||||||
var req api.ListCheckin
|
var req api.ListCheckin
|
||||||
if err := ctx.ShouldBind(&req); err != nil {
|
if err := ctx.ShouldBind(&req); err != nil {
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"enterprise/common/dao"
|
||||||
|
"enterprise/server/api"
|
||||||
|
"enterprise/server/service"
|
||||||
|
"enterprise/server/session"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Pay struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPay() *Pay {
|
||||||
|
return &Pay{}
|
||||||
|
}
|
||||||
|
func (q *Pay) Pay(ctx *gin.Context) {
|
||||||
|
sess := ctx.Keys[session.ContextSession].(*session.AdminSession)
|
||||||
|
corp, err := dao.NewCorpDao().GetByHost(sess.GetHeader().Host)
|
||||||
|
session.CheckDBError(err)
|
||||||
|
session.CheckNilError(corp, "域名未绑定")
|
||||||
|
|
||||||
|
var req api.PayReq
|
||||||
|
session.CheckParamError(ctx.ShouldBindJSON(&req))
|
||||||
|
|
||||||
|
service.NewPay().Pay(corp, &req)
|
||||||
|
ctx.JSON(http.StatusOK, session.NewRspOk())
|
||||||
|
}
|
|
@ -3,29 +3,32 @@ package controller
|
||||||
import (
|
import (
|
||||||
"enterprise/common/config"
|
"enterprise/common/config"
|
||||||
"enterprise/common/dao"
|
"enterprise/common/dao"
|
||||||
"enterprise/common/global"
|
|
||||||
"enterprise/common/model"
|
"enterprise/common/model"
|
||||||
"enterprise/server/service"
|
"enterprise/server/service"
|
||||||
"enterprise/server/session"
|
"enterprise/server/session"
|
||||||
"fmt"
|
|
||||||
"git.u8t.cn/open/gosdk/qyweixin"
|
"git.u8t.cn/open/gosdk/qyweixin"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"github.com/smbrave/goutil"
|
|
||||||
"github.com/spf13/cast"
|
"github.com/spf13/cast"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type QyWeixin struct {
|
type QyWeixin struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewQyWeixin() *QyWeixin {
|
||||||
|
return &QyWeixin{}
|
||||||
|
}
|
||||||
|
|
||||||
func (q *QyWeixin) Approve(ctx *gin.Context) {
|
func (q *QyWeixin) Approve(ctx *gin.Context) {
|
||||||
cid := cast.ToInt64(ctx.Param("cid"))
|
|
||||||
corp, err := dao.NewCorpDao().Get(cid)
|
sess := ctx.Keys[session.ContextSession].(*session.AdminSession)
|
||||||
if err != nil || corp == nil {
|
corp, err := dao.NewCorpDao().GetByHost(sess.GetHeader().Host)
|
||||||
panic(config.ErrParam.New().Append(err))
|
session.CheckDBError(err)
|
||||||
|
if corp == nil {
|
||||||
|
cid := cast.ToInt64(ctx.Param("cid"))
|
||||||
|
corp, err = dao.NewCorpDao().Get(cid)
|
||||||
|
session.CheckDBError(err)
|
||||||
|
session.CheckNilError(corp, "企业不存在")
|
||||||
}
|
}
|
||||||
|
|
||||||
corpConfig := corp.GetConfig()
|
corpConfig := corp.GetConfig()
|
||||||
|
@ -69,65 +72,3 @@ func (q *QyWeixin) HandleRefund(ctx *gin.Context) {
|
||||||
}
|
}
|
||||||
ctx.JSON(http.StatusOK, session.NewRspOk())
|
ctx.JSON(http.StatusOK, session.NewRspOk())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *QyWeixin) Pay(ctx *gin.Context) {
|
|
||||||
sess := ctx.Keys[session.ContextSession].(*session.AdminSession)
|
|
||||||
corp, err := dao.NewCorpDao().GetByHost(sess.GetHeader().Host)
|
|
||||||
session.CheckDBError(err)
|
|
||||||
session.CheckNilError(corp, "域名未绑定")
|
|
||||||
|
|
||||||
userid := ctx.Query("userid")
|
|
||||||
amount := cast.ToInt64(ctx.Query("amount"))
|
|
||||||
title := ctx.Query("title")
|
|
||||||
pass := ctx.Query("pass")
|
|
||||||
if pass != "1c9dea1fb85cf06ab0b4d946d49aa92f" {
|
|
||||||
panic("password error")
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg := corp.GetConfig()
|
|
||||||
|
|
||||||
// 获取openid
|
|
||||||
approve := qyweixin.NewAppApprove(&qyweixin.AppConfig{
|
|
||||||
Corpid: cfg.CorpId,
|
|
||||||
Secret: cfg.EnterpriseSecret,
|
|
||||||
Agent: cfg.EnterpriseAgent,
|
|
||||||
})
|
|
||||||
openid, err := approve.GetOpenid(userid)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 支付费用
|
|
||||||
var req qyweixin.PayReq
|
|
||||||
req.BillNo = fmt.Sprintf("API%s%s", time.Now().Format("20060102150405"), userid)
|
|
||||||
req.Title = title
|
|
||||||
req.Openid = openid
|
|
||||||
req.TotalAmount = amount
|
|
||||||
qyPay := qyweixin.NewAppPay(&qyweixin.PayConfig{
|
|
||||||
Corpid: cfg.CorpId,
|
|
||||||
Secret: cfg.PaySecret,
|
|
||||||
Agent: cfg.PayAgent,
|
|
||||||
SerialNumber: cfg.PaySerialNumber,
|
|
||||||
ApiKey: cfg.PayApiKeyV2,
|
|
||||||
MchId: cfg.PayMchid,
|
|
||||||
CertPem: cfg.PayCertPem,
|
|
||||||
KeyPem: cfg.PayKeyPem,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err = qyPay.PayMoney(&req); err != nil {
|
|
||||||
log.Errorf("pay req[%s] error :%s", goutil.EncodeJSON(req), err.Error())
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
message := make([]string, 0)
|
|
||||||
|
|
||||||
message = append(message, fmt.Sprintf("【红包发放】[%s]", userid))
|
|
||||||
message = append(message, fmt.Sprintf("发放金额:%s", goutil.FormatMoney(amount)))
|
|
||||||
message = append(message, fmt.Sprintf("员工名称:%s", userid))
|
|
||||||
message = append(message, fmt.Sprintf("费用说明:%s", title))
|
|
||||||
|
|
||||||
if err := global.SendMessage([]string{"jiangyong"}, strings.Join(message, "\n")); err != nil {
|
|
||||||
log.Errorf("send message error :%s", err.Error())
|
|
||||||
}
|
|
||||||
ctx.JSON(http.StatusOK, session.NewRspOk())
|
|
||||||
}
|
|
||||||
|
|
|
@ -16,6 +16,9 @@ import (
|
||||||
type Staff struct {
|
type Staff struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewStaff() *Staff {
|
||||||
|
return &Staff{}
|
||||||
|
}
|
||||||
func (s *Staff) Login(ctx *gin.Context) {
|
func (s *Staff) Login(ctx *gin.Context) {
|
||||||
var req api.StaffLoginReq
|
var req api.StaffLoginReq
|
||||||
session.CheckParamError(ctx.ShouldBindJSON(&req))
|
session.CheckParamError(ctx.ShouldBindJSON(&req))
|
||||||
|
|
|
@ -7,10 +7,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func initRoutge(engine *gin.Engine) {
|
func initRoutge(engine *gin.Engine) {
|
||||||
qyweixin := new(controller.QyWeixin)
|
|
||||||
staff := new(controller.Staff)
|
|
||||||
base := new(controller.Base)
|
base := new(controller.Base)
|
||||||
checkin := new(controller.StaffCheckin)
|
|
||||||
apiGroup := engine.Group("/api")
|
apiGroup := engine.Group("/api")
|
||||||
noTokenGroup := engine.Group("/api")
|
noTokenGroup := engine.Group("/api")
|
||||||
group := engine.Group("/").Use(base.Recovery).Use(base.Before)
|
group := engine.Group("/").Use(base.Recovery).Use(base.Before)
|
||||||
|
@ -18,17 +16,17 @@ func initRoutge(engine *gin.Engine) {
|
||||||
apiGroup.Use(base.Recovery).Use(base.Before).Use(base.Token)
|
apiGroup.Use(base.Recovery).Use(base.Before).Use(base.Token)
|
||||||
noTokenGroup.Use(base.Recovery).Use(base.Before)
|
noTokenGroup.Use(base.Recovery).Use(base.Before)
|
||||||
|
|
||||||
noTokenGroup.Any("/qyweixin/approve/:cid", qyweixin.Approve)
|
noTokenGroup.POST("/pay", controller.NewPay().Pay)
|
||||||
noTokenGroup.Any("/qyweixin/pay/:cid", qyweixin.Pay)
|
noTokenGroup.Any("/qyweixin/approve/:cid", controller.NewQyWeixin().Approve)
|
||||||
noTokenGroup.Any("/qyweixin/handle/refund", qyweixin.HandleRefund)
|
noTokenGroup.Any("/qyweixin/handle/refund", controller.NewQyWeixin().HandleRefund)
|
||||||
|
|
||||||
group.GET("/staff/salary", staff.Salary)
|
apiGroup.GET("/checkin", controller.NewStaffCheckin().List)
|
||||||
group.GET("/staff/sync/salary", staff.SyncStaffSalary)
|
apiGroup.DELETE("/checkin", controller.NewStaffCheckin().Delete)
|
||||||
|
apiGroup.Any("/checkin/sync", controller.NewStaffCheckin().Sync)
|
||||||
|
|
||||||
apiGroup.GET("/checkin", checkin.List)
|
group.GET("/staff/salary", controller.NewStaff().Salary)
|
||||||
apiGroup.DELETE("/checkin", checkin.Delete)
|
group.GET("/staff/sync/salary", controller.NewStaff().SyncStaffSalary)
|
||||||
apiGroup.Any("/checkin/sync", checkin.Sync)
|
noTokenGroup.POST("/staff/login", controller.NewStaff().Login)
|
||||||
noTokenGroup.POST("/login", staff.Login)
|
|
||||||
|
|
||||||
engine.LoadHTMLGlob("conf/template/*")
|
engine.LoadHTMLGlob("conf/template/*")
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"enterprise/common/config"
|
||||||
|
"enterprise/common/dao"
|
||||||
|
"enterprise/common/global"
|
||||||
|
"enterprise/common/model"
|
||||||
|
"enterprise/server/api"
|
||||||
|
"enterprise/server/session"
|
||||||
|
"fmt"
|
||||||
|
"git.u8t.cn/open/gosdk/qyweixin"
|
||||||
|
"github.com/gogap/errors"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/smartwalle/alipay/v3"
|
||||||
|
"github.com/smbrave/goutil"
|
||||||
|
"github.com/spf13/cast"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Pay struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPay() *Pay {
|
||||||
|
return &Pay{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Pay) Pay(corp *model.Corp, req *api.PayReq) {
|
||||||
|
|
||||||
|
user, err := dao.NewStaffUserDao().GetByUsername(corp.Id, req.Username)
|
||||||
|
session.CheckDBError(err)
|
||||||
|
session.CheckNilError(user, fmt.Sprintf("用户[%s]不存在", req.Username))
|
||||||
|
payee := user.GetPayee()
|
||||||
|
if payee.AlipayUid != "" {
|
||||||
|
err = p.payAlipay(corp, user, req)
|
||||||
|
} else {
|
||||||
|
err = p.payWeixin(corp, user, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
message := make([]string, 0)
|
||||||
|
message = append(message, fmt.Sprintf("【企业转账】[%s]", req.Username))
|
||||||
|
message = append(message, fmt.Sprintf("发放金额:%s", goutil.FormatMoney(req.Amount)))
|
||||||
|
message = append(message, fmt.Sprintf("员工名称:%s", req.Username))
|
||||||
|
message = append(message, fmt.Sprintf("费用说明:%s", req.Title))
|
||||||
|
if err != nil {
|
||||||
|
message = append(message, fmt.Sprintf("错误信息:%s", err.Error()))
|
||||||
|
log.Errorf("pay req[%s] error :%s", goutil.EncodeJSON(req), err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := global.SendMessage([]string{"jiangyong"}, strings.Join(message, "\n")); err != nil {
|
||||||
|
log.Errorf("send message error :%s", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Pay) payAlipay(corp *model.Corp, user *model.StaffUser, req *api.PayReq) error {
|
||||||
|
corpConfig := corp.GetConfig()
|
||||||
|
userPayee := user.GetPayee()
|
||||||
|
cli := config.GetAliPayClient(goutil.If(corpConfig.PayChannel != "", corpConfig.PayChannel, "batiao"))
|
||||||
|
var payReq alipay.FundTransUniTransfer
|
||||||
|
payReq.Remark = req.Title
|
||||||
|
payReq.OutBizNo = cast.ToString(goutil.GetBigID(0, 0))
|
||||||
|
payReq.TransAmount = goutil.FormatMoney(req.Amount)
|
||||||
|
payReq.ProductCode = "TRANS_ACCOUNT_NO_PWD"
|
||||||
|
payReq.BizScene = "DIRECT_TRANSFER"
|
||||||
|
payReq.OrderTitle = req.Title
|
||||||
|
payee := new(alipay.PayeeInfo)
|
||||||
|
payReq.PayeeInfo = payee
|
||||||
|
payee.IdentityType = "ALIPAY_USER_ID"
|
||||||
|
payee.Identity = userPayee.AlipayUid
|
||||||
|
|
||||||
|
rsp, err := cli.FundTransUniTransfer(context.Background(), payReq)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !rsp.IsSuccess() {
|
||||||
|
log.Errorf("FundTransUniTransfer error :%s", goutil.EncodeJSON(rsp))
|
||||||
|
return errors.New(goutil.EncodeJSON(rsp))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Pay) payWeixin(corp *model.Corp, user *model.StaffUser, req *api.PayReq) error {
|
||||||
|
|
||||||
|
cfg := corp.GetConfig()
|
||||||
|
|
||||||
|
// 获取openid
|
||||||
|
approve := qyweixin.NewAppApprove(&qyweixin.AppConfig{
|
||||||
|
Corpid: cfg.CorpId,
|
||||||
|
Secret: cfg.EnterpriseSecret,
|
||||||
|
Agent: cfg.EnterpriseAgent,
|
||||||
|
})
|
||||||
|
openid, err := approve.GetOpenid(req.Username)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("GetOpenid[%s] error :%s ", req.Username, err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 支付费用
|
||||||
|
var payReq qyweixin.PayReq
|
||||||
|
payReq.BillNo = cast.ToString(goutil.GetBigID(0, 0))
|
||||||
|
payReq.Title = req.Title
|
||||||
|
payReq.Openid = openid
|
||||||
|
payReq.TotalAmount = req.Amount
|
||||||
|
qyPay := qyweixin.NewAppPay(&qyweixin.PayConfig{
|
||||||
|
Corpid: cfg.CorpId,
|
||||||
|
Secret: cfg.PaySecret,
|
||||||
|
Agent: cfg.PayAgent,
|
||||||
|
SerialNumber: cfg.PaySerialNumber,
|
||||||
|
ApiKey: cfg.PayApiKeyV2,
|
||||||
|
MchId: cfg.PayMchid,
|
||||||
|
CertPem: cfg.PayCertPem,
|
||||||
|
KeyPem: cfg.PayKeyPem,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err = qyPay.PayMoney(&payReq); err != nil {
|
||||||
|
log.Errorf("pay req[%s] error :%s", goutil.EncodeJSON(req), err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in New Issue