Files
jx-callback/business/partner/purchase/jx/localjx/kuaishou_pay.go
邹宗楠 e48f0e5b8b 1
2023-06-07 18:27:03 +08:00

197 lines
6.4 KiB
Go

package localjx
import (
"errors"
"fmt"
"git.rosy.net.cn/baseapi/platformapi/kuaishou_mini"
beego "github.com/astaxie/beego/server/web"
"strings"
"time"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/auth2/authprovider/kuaishou"
"git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/globals/api"
)
func getOrderBriefKs(order *model.GoodsOrder) string {
sku := make([]string, len(order.Skus))
for _, v := range order.Skus {
sku = append(sku, fmt.Sprintf("%s x %d件商品", v.SkuName, v.Count))
}
return strings.Join(sku, ",")
}
func pay4OrderByKs(ctx *jxcontext.Context, order *model.GoodsOrder, vendorPayType, subAppID string) (orderPay *model.OrderPay, err error) {
// 获取用户快手OpenId
var (
db = dao.GetDB()
)
authBindList, err := dao.GetUserBindAuthInfo(db, ctx.GetUserID(), model.AuthBindTypeAuth, []string{kuaishou.AuthTypeKuaiShouMini}, "", "", nil)
if err != nil {
return nil, err
}
if len(authBindList) == model.NO {
return nil, errors.New("用户未绑定快手,无法快手支付")
}
param := &kuaishou_mini.PreCreateOrderReq{
OutOrderNo: utils.Int64ToStr(GenPayOrderID(order)),
OpenId: authBindList[0].AuthID,
TotalAmount: order.ActualPayPrice,
Subject: "蔬菜水果日用品",
Detail: getOrderBriefKs(order),
TypeDetail: 1832, // 蔬菜:费率2%,水果:1833%2
ExpireTime: 60 * 10,
Sign: "",
//Attach: "",
//GoodsId: "",
//GoodsDetailUrl: "",
//MultiCopiesGoodsInfo: "",
CancelOrder: 0,
}
if beego.BConfig.RunMode == "jxgy" {
param.NotifyUrl = "https://callback-jxgy.jxc4.com/kuaishou/kuaiShouCallback"
} else {
param.NotifyUrl = "https://callback.jxc4.com/kuaishou/kuaiShouCallback"
}
// 预下单
prePayInfo, err := api.KuaiShouApi.PreCreateOrder(param)
if err == nil {
orderPay = &model.OrderPay{
PayOrderID: order.VendorOrderID, // 抖音订单id
PayType: model.PayTypeKuaiShou,
VendorPayType: vendorPayType,
VendorOrderID: order.VendorOrderID,
VendorID: order.VendorID,
Status: 0,
PayCreatedAt: time.Now(),
PrepayID: prePayInfo.OrderNo,
CodeURL: prePayInfo.OrderInfoToken, // 抖音支付token
TotalFee: int(order.ActualPayPrice),
}
}
return orderPay, err
}
func OnKSPayCallback(msg *kuaishou_mini.CallBackDetail, refund *kuaishou_mini.RefundCallBack, payType string) (err error) {
switch payType {
case kuaishou_mini.CallbackTypePay: // 支付回调
err = onKSPayFinished(msg)
case kuaishou_mini.CallbackTypeRefund: // 退款回调
err = onKSPayRefund(refund)
}
return err
}
func onKSPayFinished(msg *kuaishou_mini.CallBackDetail) (err error) {
orderPay := &model.OrderPay{
PayOrderID: msg.OutOrderNo,
PayType: model.PayTypeKuaiShou,
}
orderPay.DeletedAt = utils.DefaultTimeValue
db := dao.GetDB()
if err = dao.GetEntity(db, orderPay, "PayOrderID", "PayType", "DeletedAt"); err == nil {
orderPay.PayFinishedAt = utils.Time2Pointer(time.Now())
orderPay.TransactionID = msg.TradeNo
orderPay.OriginalData = utils.Format4Output(msg, true)
switch msg.Status {
case kuaishou_mini.OrderPayStatusHandleing:
orderPay.Status = model.PayStatusNo
case kuaishou_mini.OrderPayStatusSuccess:
orderPay.Status = model.PayStatusYes
case kuaishou_mini.OrderPayStatusFailed:
orderPay.Status = model.PayStatusFailed
}
dao.UpdateEntity(db, orderPay)
if msg.Status == kuaishou_mini.OrderPayStatusSuccess {
err = OnPayFinished(orderPay)
}
} else {
globals.SugarLogger.Debugf("onKSPayFinished msg:%s, err:%v", utils.Format4Output(msg, true), err)
}
return err
}
func onKSPayRefund(msg *kuaishou_mini.RefundCallBack) (err error) {
orderPayRefund := &model.OrderPayRefund{
RefundID: msg.OutRefundNo,
}
db := dao.GetDB()
if err = dao.GetEntity(db, orderPayRefund, "RefundID"); err == nil {
switch msg.Status {
case kuaishou_mini.OrderPayStatusHandleing:
orderPayRefund.Status = model.PayStatusNo
case kuaishou_mini.OrderPayStatusSuccess:
orderPayRefund.Status = model.PayStatusYes
case kuaishou_mini.OrderPayStatusFailed:
orderPayRefund.Status = model.PayStatusFailed
}
orderPayRefund.OriginalData = utils.Format4Output(msg, true)
dao.UpdateEntity(db, orderPayRefund)
} else if dao.IsNoRowsError(err) {
globals.SugarLogger.Warnf("收到异常的退款事件, msg:%s", utils.Format4Output(msg, true))
}
orderPay := &model.OrderPay{
VendorOrderID: orderPayRefund.VendorOrderID,
VendorID: jxutils.GetPossibleVendorIDFromVendorOrderID(orderPayRefund.VendorOrderID),
PayType: model.PayTypeKuaiShou,
Status: model.PayStatusYes,
}
orderPay.DeletedAt = utils.DefaultTimeValue
if err = dao.GetEntity(db, orderPay, "VendorOrderID", "VendorID", "PayType", "Status", "DeletedAt"); err == nil {
orderPay.Status = model.PayStatusRefund
dao.UpdateEntity(db, orderPay)
}
return err
}
// RefundOrderByKS 申请退款
func RefundOrderByKS(ctx *jxcontext.Context, orderPay *model.OrderPay, refundID string, refundFee int, refundDesc string) (orderPayRefund *model.OrderPayRefund, err error) {
param := kuaishou_mini.RefundParam{
OutOrderNo: orderPay.VendorOrderID,
OutRefundNo: refundID,
Reason: refundDesc,
Attach: "",
NotifyUrl: "https://callback.jxc4.com/kuaishou/kuaiShouCallback",
RefundAmount: int64(orderPay.TotalFee),
Sign: "",
MultiCopiesGoodsInfo: "",
}
result, err := api.KuaiShouApi.RefundOrder(&param)
if err == nil {
orderPayRefund = &model.OrderPayRefund{
RefundID: refundID,
VendorRefundID: result,
VendorOrderID: orderPay.VendorOrderID,
VendorID: orderPay.VendorID,
Status: model.RefundStatusNo,
TransactionID: orderPay.TransactionID,
RefundFee: refundFee,
RefundCreatedAt: time.Now(),
}
dao.WrapAddIDCULDEntity(orderPayRefund, ctx.GetUserName())
db := dao.GetDB()
if result != "" {
orderPayRefund.Status = model.RefundStatusYes
} else {
orderPayRefund.Status = model.RefundStatusFailed
}
orderPayRefund.OriginalData = utils.Format4Output(result, true)
dao.CreateEntity(db, orderPayRefund)
orderPay.Status = model.PayStatusRefund
dao.UpdateEntity(db, orderPay)
}
return orderPayRefund, err
}