diff --git a/app/customer/enum/enum_pay.go b/app/customer/enum/enum_pay.go new file mode 100644 index 0000000..9782091 --- /dev/null +++ b/app/customer/enum/enum_pay.go @@ -0,0 +1,19 @@ +package enum + +type PayWay int32 + +const ( + PayWayForAli = 1 + PayWayForWx = 2 +) + +func (gt PayWay) String() string { + switch gt { + case PayWayForAli: + return "支付宝" + case PayWayForWx: + return "微信" + default: + return "未知" + } +} diff --git a/app/customer/enum/enum_qrcode.go b/app/customer/enum/enum_qrcode.go deleted file mode 100644 index 12ab106..0000000 --- a/app/customer/enum/enum_qrcode.go +++ /dev/null @@ -1,67 +0,0 @@ -package enum - -type QrcodeBatchState int32 - -const ( - QrcodeBatchStateForUseIng = 1 - QrcodeBatchStateForUseAlready = 2 - QrcodeBatchStateForExpire = 3 - QrcodeBatchStateForCancel = 4 -) - -func (gt QrcodeBatchState) String() string { - switch gt { - case QrcodeBatchStateForUseIng: - return "使用中" - case QrcodeBatchStateForUseAlready: - return "使用完" - case QrcodeBatchStateForExpire: - return "已过期" - case QrcodeBatchStateForCancel: - return "已作废" - default: - return "未知" - } -} - -type QrcodeWithBatchRecordsSate int32 - -const ( - QrcodeWithBatchRecordsStateForWait = 1 - QrcodeWithBatchRecordsStateForAlready = 2 - QrcodeWithBatchRecordsStateForExpire = 3 - QrcodeWithBatchRecordsStateForCancel = 4 -) - -func (gt QrcodeWithBatchRecordsSate) String() string { - switch gt { - case QrcodeWithBatchRecordsStateForWait: - return "待使用" - case QrcodeWithBatchRecordsStateForAlready: - return "已使用" - case QrcodeWithBatchRecordsStateForExpire: - return "已过期" - case QrcodeWithBatchRecordsStateForCancel: - return "已作废" - default: - return "未知" - } -} - -type QrcodeSate int32 - -const ( - QrcodeSateAllowUse = 1 - QrcodeSateAllowNotUse = 2 -) - -func (gt QrcodeSate) String() string { - switch gt { - case QrcodeSateAllowUse: - return "可使用" - case QrcodeSateAllowNotUse: - return "不可用" - default: - return "未知" - } -} diff --git a/app/customer/hdl/hdl_pay.go b/app/customer/hdl/hdl_pay.go index 67817c3..752175c 100644 --- a/app/customer/hdl/hdl_pay.go +++ b/app/customer/hdl/hdl_pay.go @@ -25,7 +25,7 @@ func BuyPackage(c *gin.Context) { return } fmt.Println("req>>>>>>>>>>>>", utils.Serialize(req)) - outTradeNo, tradeNo, total, err := svc.BuyPackage(c, req) + outTradeNo, tradeNo, total, err := svc.BuyPackageForAli(c, req) if err != nil { e.OutErr(c, e.ERR, err.Error()) return @@ -48,14 +48,14 @@ func BuyPackageForWx(c *gin.Context) { return } fmt.Println("req>>>>>>>>>>>>", utils.Serialize(req)) - outTradeNo, tradeNo, total, err := svc.BuyPackage(c, req) + outTradeNo, prepayId, total, err := svc.BuyPackageForWx(c, req) if err != nil { e.OutErr(c, e.ERR, err.Error()) return } e.OutSuc(c, map[string]interface{}{ "out_trade_no": outTradeNo, - "trade_no": tradeNo, + "prepay_id": prepayId, "total": total, }, nil) return diff --git a/app/customer/svc/svc_pay.go b/app/customer/svc/svc_pay.go index 8931a5a..91415c0 100644 --- a/app/customer/svc/svc_pay.go +++ b/app/customer/svc/svc_pay.go @@ -1,22 +1,26 @@ package svc import ( + "applet/app/customer/enum" "applet/app/customer/md" "applet/app/db" "applet/app/db/model" enum2 "applet/app/enum" + svc3 "applet/app/svc" "applet/app/utils" "applet/app/utils/logx" "encoding/json" "errors" "fmt" "github.com/gin-gonic/gin" + "github.com/wechatpay-apiv3/wechatpay-go/core" + "github.com/wechatpay-apiv3/wechatpay-go/services/partnerpayments/jsapi" "io/ioutil" "net/url" "time" ) -func BuyPackage(c *gin.Context, req md.BuyPackageReq) (outTradeNo, tradeNo, total string, err error) { +func BuyPackageForAli(c *gin.Context, req md.BuyPackageReq) (outTradeNo, tradeNo, total string, err error) { user := GetUser(c) session := db.Db.NewSession() defer session.Close() @@ -117,6 +121,7 @@ func BuyPackage(c *gin.Context, req md.BuyPackageReq) (outTradeNo, tradeNo, tota OrdState: enum2.CentralKitchenForSchoolPackageOrdOrdStateForWait, ReqContent: string(utils.Serialize(req)), WithDayData: string(utils.Serialize(data)), + PayWay: enum.PayWayForAli, CreateAt: now.Format("2006-01-02 15:04:05"), UpdateAt: now.Format("2006-01-02 15:04:05"), }) @@ -129,6 +134,126 @@ func BuyPackage(c *gin.Context, req md.BuyPackageReq) (outTradeNo, tradeNo, tota return } +func BuyPackageForWx(c *gin.Context, req md.BuyPackageReq) (outTradeNo, prepayId, total string, err error) { + user := GetUser(c) + session := db.Db.NewSession() + defer session.Close() + session.Begin() + if err != nil { + _ = session.Rollback() + return + } + + //1、判断是否为教师 + isTeacher := false + userIdentityDb := db.UserIdentityDb{} + userIdentityDb.Set(0) + userIdentity, err := userIdentityDb.GetUserIdentity(req.UserIdentityId) + if err != nil { + return + } + if userIdentity == nil { + err = errors.New("未查询到对应身份记录") + return + } + if userIdentity.Identity == enum2.UserIdentityForCentralKitchenForTeacher { + isTeacher = true + } + + //2、计算数据(1:按学期购买 2:按月购买 3:按天购买 4:补餐) + var totalPrice float64 + var data []*model.CentralKitchenForSchoolUserWithDay + if req.Kind == 1 { + totalPrice, data, err = CalcBySchoolTerm(user.Id, isTeacher, req) + if err != nil { + return + } + } + if req.Kind == 2 { + totalPrice, data, err = CalcByMonth(user.Id, isTeacher, req) + if err != nil { + return + } + } + if req.Kind == 3 { + totalPrice, data, err = CalcByDay(user.Id, isTeacher, req) + if err != nil { + return + } + } + if req.Kind == 4 { + totalPrice, data, err = CalcSupplementaryByDay(user.Id, isTeacher, req) + if err != nil { + return + } + } + total = utils.Float64ToStr(totalPrice) + + //3、生成订单号 + outTradeNo = utils.OrderUUID(user.Id) + + //4、请求 /v3/pay/partner/transactions/jsapi (生成预支付交易单) + sysCfgDb := db.SysCfgDb{} + sysCfgDb.Set() + client, err := svc3.NewWxPayClient(c) + if err != nil { + return + } + wxSvc := jsapi.JsapiApiService{Client: client} + sysCfg := sysCfgDb.SysCfgFindWithDb(enum2.WxSpAppId, enum2.WxSpMchId, enum2.WxAppletAppId, enum2.WxMchId, enum2.WxJsapiPayNotifyUrl) + + resp, _, err := wxSvc.Prepay(c, + jsapi.PrepayRequest{ + SpAppid: core.String(sysCfg[enum2.WxSpAppId]), + SpMchid: core.String(sysCfg[enum2.WxSpMchId]), + SubAppid: core.String(sysCfg[enum2.WxAppletAppId]), + SubMchid: core.String(sysCfg[enum2.WxMchId]), + Description: core.String("购买食堂套餐"), + OutTradeNo: core.String(outTradeNo), + TimeExpire: core.Time(time.Now().Add(30 * time.Minute)), + //Attach: core.String("自定义数据说明"), + NotifyUrl: core.String(sysCfg[enum2.WxJsapiPayNotifyUrl]), + Amount: &jsapi.Amount{ + Currency: core.String("CNY"), + Total: core.Int64(utils.StrToInt64(total) * 100), + }, + Payer: &jsapi.Payer{ + //SpOpenid: core.String("oUpF8uMuAJO_M2pxb1Q9zNjWeS6o"), + SubOpenid: core.String(user.OpenId), + }, + }, + ) + + //5、插入订单记录 + now := time.Now() + centralKitchenForSchoolPackageOrd := db.CentralKitchenForSchoolPackageOrd{} + centralKitchenForSchoolPackageOrd.Set(outTradeNo) + _, err = centralKitchenForSchoolPackageOrd.CentralKitchenForSchoolPackageOrdInsertBySession(session, &model.CentralKitchenForSchoolPackageOrd{ + EnterpriseId: req.EnterpriseId, + Uid: user.Id, + UserIdentityId: req.UserIdentityId, + UserIdentityName: userIdentity.Name, + TotalPrice: total, + Kind: req.Kind, + OutTradeNo: outTradeNo, + TradeNo: "", + State: enum2.CentralKitchenForSchoolPackageOrdStateForWait, + OrdState: enum2.CentralKitchenForSchoolPackageOrdOrdStateForWait, + ReqContent: string(utils.Serialize(req)), + WithDayData: string(utils.Serialize(data)), + PayWay: enum.PayWayForWx, + CreateAt: now.Format("2006-01-02 15:04:05"), + UpdateAt: now.Format("2006-01-02 15:04:05"), + }) + if err != nil { + _ = session.Rollback() + return + } + session.Commit() + prepayId = *resp.PrepayId + return +} + func NursingHomeBuyPackageReq(c *gin.Context, req md.NursingHomeBuyPackageReq) (outTradeNo, tradeNo, total string, err error) { user := GetUser(c) session := db.Db.NewSession() diff --git a/app/db/model/central_kitchen_for_school_package_ord.go b/app/db/model/central_kitchen_for_school_package_ord.go index 8338e80..7646c95 100644 --- a/app/db/model/central_kitchen_for_school_package_ord.go +++ b/app/db/model/central_kitchen_for_school_package_ord.go @@ -14,6 +14,7 @@ type CentralKitchenForSchoolPackageOrd struct { OrdState int `json:"ord_state" xorm:"not null default 0 comment('订单状态(0:待支付 1:预约成功 2:退款中 3:部分退款 4:已退款 5:已完成)') TINYINT(1)"` ReqContent string `json:"req_content" xorm:"comment('请求内容') TEXT"` WithDayData string `json:"with_day_data" xorm:"comment('待支付成功插入 central_kitchen_for_school_user_with_day') TEXT"` + PayWay int `json:"pay_way" xorm:"not null default 1 comment('支付方式(1:支付宝 2:微信)') TINYINT(1)"` CreateAt string `json:"create_at" xorm:"not null pk default 'CURRENT_TIMESTAMP' DATETIME"` UpdateAt string `json:"update_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` } diff --git a/app/enum/enum_sys_cfg.go b/app/enum/enum_sys_cfg.go index 84cc96b..4f38bf4 100644 --- a/app/enum/enum_sys_cfg.go +++ b/app/enum/enum_sys_cfg.go @@ -38,6 +38,7 @@ const ( WxSpMchCertificateSerialNumber = "wx_sp_mch_certificate_serial_number" WxSpAppId = "wx_sp_app_id" WxSpMchId = "wx_sp_mch_id" + WxJsapiPayNotifyUrl = "wx_jsapi_pay_notify_url" ) func (gt SysCfg) String() string { @@ -108,6 +109,8 @@ func (gt SysCfg) String() string { return "微信服务商-appid" case WxSpMchId: return "微信服务商-商户id" + case WxJsapiPayNotifyUrl: + return "微信-jsapi支付-异步通知" default: return "未知" }