shan
This commit is contained in:
740
business/partner/purchase/jx/localjx/order.go
Normal file
740
business/partner/purchase/jx/localjx/order.go
Normal file
@@ -0,0 +1,740 @@
|
||||
package localjx
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"git.rosy.net.cn/baseapi/platformapi/jdshopapi"
|
||||
|
||||
"git.rosy.net.cn/baseapi/platformapi/wxpayapi"
|
||||
|
||||
"git.rosy.net.cn/jx-callback/globals/api"
|
||||
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"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/business/partner"
|
||||
)
|
||||
|
||||
const (
|
||||
OrderCreateTypePre = 0 // 预创建
|
||||
OrderCreateTypeNormal = 1 // 正常创建
|
||||
|
||||
PayWaitingTime = 10 * time.Minute // 等待支付的最长时间
|
||||
DingShiDaMinTime = 1 * time.Hour
|
||||
|
||||
specialStoreID = 100274
|
||||
specialFreightPrice = 1500
|
||||
|
||||
wxAppID = "wx4b5930c13f8b1170"
|
||||
|
||||
autoCancelOrderReason = "支付超时,系统自动取消!"
|
||||
cancelMatterOrderReason = "失败重发!"
|
||||
settleDiscountActRefundReason = "守价订单生成补退款"
|
||||
|
||||
splitMatterOrderMinWeight = 4500 //物料订单分包最少要4.5kg
|
||||
jxwxfMatterEclpID = "EMG4418113943423" //京西五香粉物料编码
|
||||
)
|
||||
|
||||
type JxSkuInfo struct {
|
||||
SkuID int `json:"skuID"`
|
||||
Count int `json:"count"`
|
||||
|
||||
Price int64 `json:"price,omitempty"` // 原价
|
||||
SalePrice int64 `json:"salePrice,omitempty"` // 售卖价
|
||||
|
||||
Name string `json:"name"`
|
||||
Weight int `json:"weight"`
|
||||
GroupSign bool `json:"groupSign"`
|
||||
|
||||
DefendPrice int64 `json:"defendPrice"` //守价
|
||||
}
|
||||
|
||||
type JxSkuInfo2 struct {
|
||||
SkuID int `json:"skuID"`
|
||||
Count int `json:"count"`
|
||||
|
||||
Price int64 `json:"price,omitempty"` // 原价
|
||||
SalePrice int64 `json:"salePrice,omitempty"` // 售卖价
|
||||
|
||||
Name string `json:"name"`
|
||||
Weight int `json:"weight"`
|
||||
GroupSign bool `json:"groupSign"`
|
||||
}
|
||||
|
||||
type JxSkuInfoList []*JxSkuInfo
|
||||
|
||||
func (l JxSkuInfoList) Len() int {
|
||||
return len(l)
|
||||
}
|
||||
|
||||
func (l JxSkuInfoList) Less(i, j int) bool {
|
||||
if l[i].SkuID == l[j].SkuID {
|
||||
return l[i].SalePrice < l[j].SalePrice
|
||||
}
|
||||
return l[i].SkuID < l[j].SkuID
|
||||
}
|
||||
|
||||
func (l JxSkuInfoList) Swap(i, j int) {
|
||||
l[i], l[j] = l[j], l[i]
|
||||
}
|
||||
|
||||
type JxOrderInfo struct {
|
||||
BuyerComment string `json:"buyerComment"`
|
||||
StoreID int `json:"storeID"`
|
||||
Skus []*JxSkuInfo `json:"skus"`
|
||||
|
||||
ExpectedDeliveredTimestamp int64 `json:"expectedDeliveredTimestamp"` // 预期送达时间
|
||||
|
||||
TotalPrice int64 `json:"totalPrice"` // 单位为分 订单总价
|
||||
FreightPrice int64 `json:"freightPrice"` // 单位为分 订单配送费
|
||||
OrderPrice int64 `json:"orderPrice"` // 单位为分 订单商品价格
|
||||
ActualPayPrice int64 `json:"actualPayPrice"` // 单位为分 顾客实际支付
|
||||
|
||||
OrderID int64 `json:"orderID"`
|
||||
StoreName string `json:"storeName"`
|
||||
Weight int `json:"weight"`
|
||||
FromStoreID int `json:"fromStoreID"`
|
||||
EarningType int `json:"earningType"`
|
||||
OrderType int `json:"orderType"`
|
||||
IsBuyNowPrice int `json:"isBuyNowPrice"`
|
||||
IsPriceDefend int `json:"isPriceDefend"`
|
||||
OrderID2 string `json:"-"`
|
||||
UserID string `json:"userID"`
|
||||
}
|
||||
|
||||
type DeliveryTimeItem struct {
|
||||
ViewTime string `json:"viewTime"`
|
||||
UnixTime int64 `json:"unixTime"`
|
||||
ViewShippingFee string `json:"viewShippingFee"`
|
||||
}
|
||||
|
||||
type DeliveryDayTimeInfo struct {
|
||||
Date string `json:"date"`
|
||||
TimeList []*DeliveryTimeItem `json:"timeList"`
|
||||
}
|
||||
|
||||
type MatterOrderStatus struct {
|
||||
Time time.Time `json:"time"`
|
||||
Status string `json:"status"`
|
||||
Name string `json:"name"`
|
||||
Sign int `sign`
|
||||
}
|
||||
|
||||
var (
|
||||
weekdayMap = map[int]string{
|
||||
1: "一",
|
||||
2: "二",
|
||||
3: "三",
|
||||
4: "四",
|
||||
5: "五",
|
||||
6: "六",
|
||||
0: "日",
|
||||
}
|
||||
dayList = []string{"今天", "明天", "后天"}
|
||||
|
||||
bagMap = map[int]int{
|
||||
6039382: 100,
|
||||
6039383: 200,
|
||||
6039384: 200,
|
||||
6039387: 200,
|
||||
6039390: 200,
|
||||
}
|
||||
|
||||
regexpCnameAndCmobile = regexp.MustCompile(`配送员,(.*),手机号,(.*)`)
|
||||
regexpCnameAndCmobile2 = regexp.MustCompile(`(快递员:(.*),联系电话:(.*))`)
|
||||
|
||||
bagSkuMap = map[int]int{ //京西物料袋子skuid
|
||||
6039382: 6039382,
|
||||
6039383: 6039383,
|
||||
6039384: 6039384,
|
||||
6039387: 6039387,
|
||||
6039390: 6039390,
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
}
|
||||
|
||||
func buildDefendPriceOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64) (vendorOrderID string) {
|
||||
var (
|
||||
issue = 0
|
||||
db = dao.GetDB()
|
||||
)
|
||||
issue = jxutils.GetDefendPriceIssue()
|
||||
priceDefendOrder := &model.PriceDefendOrder{
|
||||
VendorOrderID: utils.Int64ToStr(jxutils.GenOrderNo()),
|
||||
StoreID: jxOrder.StoreID,
|
||||
SkuID: jxOrder.Skus[0].SkuID,
|
||||
AddressID: addressID,
|
||||
Count: jxOrder.Skus[0].Count,
|
||||
DefendPrice: jxOrder.Skus[0].DefendPrice,
|
||||
OriginPrice: jxOrder.Skus[0].Price,
|
||||
IsBuyNowPrice: jxOrder.IsBuyNowPrice,
|
||||
Issue: issue,
|
||||
IsSuccess: model.NO, //默认是不成功
|
||||
IsPay: model.NO,
|
||||
}
|
||||
dao.WrapAddIDCULDEntity(priceDefendOrder, ctx.GetUserName())
|
||||
priceDefendOrder.ActualPayPrice = int64(priceDefendOrder.Count)*jxOrder.Skus[0].Price + jxOrder.FreightPrice
|
||||
dao.CreateEntity(db, priceDefendOrder)
|
||||
return priceDefendOrder.VendorOrderID
|
||||
}
|
||||
|
||||
// 买家取消(或申请取消)订单
|
||||
func BuyerCancelOrder(ctx *jxcontext.Context, orderID int64, reason string) (canceled bool, err error) {
|
||||
order, err := partner.CurOrderManager.LoadOrder(utils.Int64ToStr(orderID), model.VendorIDJX)
|
||||
if err == nil {
|
||||
if order.Status < model.OrderStatusNew {
|
||||
order.Status = model.OrderStatusCanceled
|
||||
order.VendorStatus = utils.Int2Str(model.OrderStatusCanceled)
|
||||
if err = partner.CurOrderManager.UpdateOrderFields(order, []string{model.FieldStatus, "VendorStatus"}); err == nil {
|
||||
canceled = true
|
||||
}
|
||||
} else {
|
||||
err = fmt.Errorf("暂不支持自行取消订单,请联系商家取消")
|
||||
// err = changeOrderStatus(utils.Int64ToStr(orderID), model.OrderStatusApplyCancel, fmt.Sprintf("用户%s主动取消", ctx.GetUserName()))
|
||||
}
|
||||
}
|
||||
return canceled, err
|
||||
}
|
||||
|
||||
func Pay4Order(ctx *jxcontext.Context, orderID int64, payType int, vendorPayType string) (orderPay *model.OrderPay, err error) {
|
||||
order, err := partner.CurOrderManager.LoadOrder(utils.Int64ToStr(orderID), model.VendorIDJX)
|
||||
if err == nil {
|
||||
switch payType {
|
||||
case model.PayTypeWX:
|
||||
if orderPay, err = pay4OrderByWX(ctx, order, vendorPayType); err == nil {
|
||||
dao.WrapAddIDCULDEntity(orderPay, ctx.GetUserName())
|
||||
err = dao.CreateEntity(dao.GetDB(), orderPay)
|
||||
}
|
||||
case model.PayTypeTL:
|
||||
if orderPay, err = pay4OrderByTL(ctx, order, payType, vendorPayType); err == nil && orderPay != nil {
|
||||
dao.WrapAddIDCULDEntity(orderPay, ctx.GetUserName())
|
||||
err = dao.CreateEntity(dao.GetDB(), orderPay)
|
||||
}
|
||||
default:
|
||||
err = fmt.Errorf("支付方式:%d当前不支持", payType)
|
||||
}
|
||||
} else {
|
||||
// priceDefendOrders, _ := dao.GetPriceDefendOrder(db, utils.Int64ToStr(orderID), nil, nil, []int{jxutils.GetDefendPriceIssue()}, 0, -1, -1, 0, "", utils.ZeroTimeValue, utils.ZeroTimeValue, false)
|
||||
// if len(priceDefendOrders) == 0 {
|
||||
// err = fmt.Errorf("未查询到待支付订单!order_id: %v", orderID)
|
||||
// }
|
||||
// order2 := &model.GoodsOrder{
|
||||
// VendorOrderID: priceDefendOrders[0].VendorOrderID,
|
||||
// ActualPayPrice: priceDefendOrders[0].ActualPayPrice,
|
||||
// VendorID: model.VendorIDJX,
|
||||
// }
|
||||
// if orderPay, err = pay4OrderByTL(ctx, order2, payType, vendorPayType); err == nil && orderPay != nil {
|
||||
// dao.WrapAddIDCULDEntity(orderPay, ctx.GetUserName())
|
||||
// err = dao.CreateEntity(dao.GetDB(), orderPay)
|
||||
// }
|
||||
}
|
||||
return orderPay, err
|
||||
}
|
||||
|
||||
func Pay4User(ctx *jxcontext.Context, thingID, payType int, vendorPayType string) (orderPay *model.OrderPay, err error) {
|
||||
var (
|
||||
db = dao.GetDB()
|
||||
order *model.GoodsOrder
|
||||
dicountCards []*model.DiscountCard
|
||||
vendorOrderID string
|
||||
)
|
||||
switch payType {
|
||||
case model.PayTypeTL_DiscountCard:
|
||||
if configList, err := dao.QueryConfigs(db, "会员折扣卡", model.ConfigTypeDiscountCard, ""); err == nil {
|
||||
jxutils.Strings2Objs(configList[0].Value, &dicountCards)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
discountCard := findDiscountCard(dicountCards, thingID)
|
||||
// flag, userMemberOrigin, err := checkMember(db, ctx.GetUserID(), discountCard)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vendorOrderID = utils.Int64ToStr(jxutils.GenOrderNo())
|
||||
order = &model.GoodsOrder{
|
||||
VendorOrderID: vendorOrderID,
|
||||
ActualPayPrice: int64(discountCard.Price),
|
||||
VendorID: model.VendorIDJX,
|
||||
}
|
||||
if orderPay, err = pay4OrderByTL(ctx, order, payType, vendorPayType); err == nil && orderPay != nil {
|
||||
dao.WrapAddIDCULDEntity(orderPay, ctx.GetUserName())
|
||||
err = dao.CreateEntity(dao.GetDB(), orderPay)
|
||||
}
|
||||
// userMember := &model.UserMember{
|
||||
// VendorOrderID: vendorOrderID,
|
||||
// UserID: ctx.GetUserID(),
|
||||
// MemberType: model.MemberTypeDiscountCard,
|
||||
// EndAt: utils.Str2Time(time.Now().AddDate(0, 1, 0).AddDate(0, 0, -1).Format("2006-01-02") + " 23:59:59"),
|
||||
// MemberTypeID: thingID,
|
||||
// IsPay: model.NO,
|
||||
// }
|
||||
// dao.WrapAddIDCULDEntity(userMember, ctx.GetUserName())
|
||||
// if flag == 0 {
|
||||
// dao.CreateEntity(db, userMember)
|
||||
// } else if flag == 1 {
|
||||
// userMemberOrigin.EndAt = userMemberOrigin.EndAt.AddDate(0, 1, 0)
|
||||
// dao.UpdateEntity(db, userMemberOrigin, "EndAt")
|
||||
// }
|
||||
}
|
||||
default:
|
||||
err = fmt.Errorf("支付方式:%d当前不支持", payType)
|
||||
}
|
||||
return orderPay, err
|
||||
}
|
||||
|
||||
//flag
|
||||
//0 正常购买
|
||||
//1 续费
|
||||
//-1 不能购买
|
||||
func checkMember(db *dao.DaoDB, userID string, discountCard *model.DiscountCard) (flag int, userMember *model.UserMember, err error) {
|
||||
// userMembers, err := dao.GetUserMember(db, userID, "", model.MemberTypeDiscountCard, model.YES)
|
||||
// if len(userMembers) > 0 {
|
||||
// userMember = userMembers[0]
|
||||
// if userMember.ID < discountCard.ID {
|
||||
// return 0, userMember, err
|
||||
// } else if userMember.ID == discountCard.ID {
|
||||
// return 1, userMember, err
|
||||
// } else {
|
||||
// return -1, userMember, fmt.Errorf("已购买更高档次的会员,无法继续购买!")
|
||||
// }
|
||||
// }
|
||||
return 0, userMember, err
|
||||
}
|
||||
|
||||
func time2ShortTimeStr(t time.Time) string {
|
||||
return t.Format("15:04")
|
||||
}
|
||||
|
||||
func findDiscountCard(dicountCards []*model.DiscountCard, thingID int) (dicountCard *model.DiscountCard) {
|
||||
for _, v := range dicountCards {
|
||||
if v.ID == thingID {
|
||||
return v
|
||||
}
|
||||
}
|
||||
return dicountCard
|
||||
}
|
||||
|
||||
func OnPayFinished(orderPay *model.OrderPay) (err error) {
|
||||
order, err := partner.CurOrderManager.LoadOrder(orderPay.VendorOrderID, orderPay.VendorID)
|
||||
if err == nil {
|
||||
db := dao.GetDB()
|
||||
dao.UpdateEntity(db, orderPay)
|
||||
// if count, err2 := dao.GetJxOrderCount(db, jxutils.GetSaleStoreIDFromOrder(order), order.VendorOrderID, order.OrderCreatedAt); err2 == nil {
|
||||
// order.OrderSeq = count + 1
|
||||
// partner.CurOrderManager.UpdateOrderFields(order, []string{"OrderSeq"})
|
||||
// }
|
||||
order.Status = model.OrderStatusNew
|
||||
order.VendorStatus = utils.Int2Str(model.OrderStatusNew)
|
||||
order.StatusTime = *orderPay.PayFinishedAt
|
||||
err = callNewOrder(order)
|
||||
//如果是物料的订单,直接到拣货完成,配送中的状态
|
||||
if order.OrderType != model.OrderTypeNormal {
|
||||
// if order.FromStoreID != 0 {
|
||||
if order.OrderType != model.OrderTypeDefendPrice {
|
||||
// netprinter.PrintOrderByOrder(jxcontext.AdminCtx, order)
|
||||
}
|
||||
// PickupGoods(order, false, "jxadmin")
|
||||
// }
|
||||
}
|
||||
} else {
|
||||
switch orderPay.PayType {
|
||||
case model.PayTypeTL_DiscountCard:
|
||||
// userMembers, _ := dao.GetUserMember(dao.GetDB(), "", orderPay.VendorOrderID, model.MemberTypeDiscountCard, model.NO)
|
||||
// if len(userMembers) > 0 {
|
||||
// userMembers[0].IsPay = model.YES
|
||||
// dao.UpdateEntity(dao.GetDB(), userMembers[0], "IsPay")
|
||||
// err = nil
|
||||
// }
|
||||
default:
|
||||
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func GenPayOrderID(order *model.GoodsOrder) (payOrderID int64) {
|
||||
return utils.Str2Int64(order.VendorOrderID)
|
||||
}
|
||||
|
||||
func GenRefundID(order *model.GoodsOrder) (refundID int64) {
|
||||
const suffix = 100000
|
||||
refundID = utils.Str2Int64(order.VendorOrderID) * suffix
|
||||
refundID += int64(time.Now().Sub(order.OrderFinishedAt) / time.Minute)
|
||||
return refundID
|
||||
}
|
||||
|
||||
func formalizeSkus(skus []*JxSkuInfo) (outSkus []*JxSkuInfo) {
|
||||
skuMap := make(map[int]int)
|
||||
for _, v := range skus {
|
||||
skuMap[v.SkuID] += v.Count
|
||||
}
|
||||
for skuID, skuCount := range skuMap {
|
||||
outSkus = append(outSkus, &JxSkuInfo{
|
||||
SkuID: skuID,
|
||||
Count: skuCount,
|
||||
})
|
||||
}
|
||||
return outSkus
|
||||
}
|
||||
|
||||
func isTimeInOpTime(openTime1, closeTime1, openTime2, closeTime2 int16, time2Check time.Time) bool {
|
||||
timeStrList := []string{
|
||||
jxutils.OperationTime2StrWithSecond(openTime1),
|
||||
jxutils.OperationTime2StrWithSecond(closeTime1),
|
||||
}
|
||||
if openTime1 > 0 {
|
||||
timeStrList = append(timeStrList,
|
||||
jxutils.OperationTime2StrWithSecond(openTime2),
|
||||
jxutils.OperationTime2StrWithSecond(closeTime2),
|
||||
)
|
||||
}
|
||||
checkTimeStr := utils.Time2TimeStr(time2Check)
|
||||
for i := 0; i < len(timeStrList); i += 2 {
|
||||
if checkTimeStr >= timeStrList[i] && checkTimeStr <= timeStrList[i+1] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
func jxOrder2GoodsOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, deliveryAddress *dao.UserDeliveryAddressEx, userID string, IsDeliverySelf bool) (order *model.GoodsOrder, err error) {
|
||||
order = &model.GoodsOrder{
|
||||
VendorOrderID: utils.Int64ToStr(jxOrder.OrderID),
|
||||
VendorID: model.VendorIDJX,
|
||||
VendorStoreID: utils.Int2Str(jxOrder.StoreID),
|
||||
StoreID: jxOrder.StoreID,
|
||||
StoreName: jxOrder.StoreName,
|
||||
// UserID: ctx.GetUserID(),
|
||||
|
||||
ConsigneeName: deliveryAddress.ConsigneeName,
|
||||
ConsigneeMobile: deliveryAddress.ConsigneeMobile,
|
||||
ConsigneeMobile2: deliveryAddress.ConsigneeMobile,
|
||||
ConsigneeAddress: fmt.Sprintf("%s%s", deliveryAddress.Address, deliveryAddress.DetailAddress),
|
||||
CoordinateType: model.CoordinateTypeMars,
|
||||
ConsigneeLng: jxutils.StandardCoordinate2Int(deliveryAddress.Lng),
|
||||
ConsigneeLat: jxutils.StandardCoordinate2Int(deliveryAddress.Lat),
|
||||
|
||||
Status: model.OrderStatusUnknown,
|
||||
VendorStatus: "realnew",
|
||||
OrderSeq: 0,
|
||||
BuyerComment: jxOrder.BuyerComment,
|
||||
|
||||
DeliveryType: model.OrderDeliveryTypeStoreSelf,
|
||||
StatusTime: time.Now(),
|
||||
EarningType: jxOrder.EarningType,
|
||||
OrderType: jxOrder.OrderType,
|
||||
VendorOrderID2: jxOrder.OrderID2,
|
||||
}
|
||||
if userID == "" {
|
||||
order.UserID = ctx.GetUserID()
|
||||
} else {
|
||||
order.UserID = userID
|
||||
}
|
||||
order.OrderCreatedAt = order.StatusTime
|
||||
order.VendorUserID = order.UserID
|
||||
if order.UserID == "" && order.VendorUserID == "" {
|
||||
if jxOrder.UserID != "" {
|
||||
order.UserID = jxOrder.UserID
|
||||
order.VendorUserID = jxOrder.UserID
|
||||
}
|
||||
}
|
||||
if jxOrder.ExpectedDeliveredTimestamp != 0 {
|
||||
order.ExpectedDeliveredTime = utils.Timestamp2Time(jxOrder.ExpectedDeliveredTimestamp)
|
||||
order.BusinessType = model.BusinessTypeDingshida
|
||||
} else {
|
||||
order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
|
||||
order.BusinessType = model.BusinessTypeImmediate
|
||||
}
|
||||
for _, sku := range jxOrder.Skus {
|
||||
order.Skus = append(order.Skus, &model.OrderSku{
|
||||
Count: sku.Count,
|
||||
VendorSkuID: utils.Int2Str(sku.SkuID),
|
||||
SkuID: sku.SkuID,
|
||||
SkuName: sku.Name,
|
||||
VendorPrice: sku.Price,
|
||||
SalePrice: sku.SalePrice,
|
||||
})
|
||||
order.TotalShopMoney += int64(sku.Count) * sku.SalePrice
|
||||
}
|
||||
order.TotalShopMoney += jxOrder.FreightPrice
|
||||
order.ActualPayPrice = jxOrder.ActualPayPrice
|
||||
order.TotalShopMoney = utils.Float64TwoInt64(float64(order.TotalShopMoney) * jdshopapi.JdsPayPercentage)
|
||||
if jxOrder.FromStoreID != 0 {
|
||||
order.FromStoreID = jxOrder.FromStoreID
|
||||
order.DeliveryFlag = model.OrderDeliveryFlagMaskScheduleDisabled
|
||||
order.Flag = 1
|
||||
if jxOrder.OrderType == model.OrderTypeMatter {
|
||||
order.WaybillVendorID = model.VendorIDJDWL
|
||||
order.ConsigneeAddress = deliveryAddress.Address
|
||||
}
|
||||
}
|
||||
//如果是自提单就设置
|
||||
if IsDeliverySelf {
|
||||
order.DeliveryType = model.OrderDeliveryTypeSelfTake
|
||||
}
|
||||
return order, err
|
||||
}
|
||||
|
||||
func AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) {
|
||||
var status int
|
||||
if isAcceptIt {
|
||||
status = model.OrderStatusAccepted
|
||||
} else {
|
||||
status = model.OrderStatusCanceled
|
||||
}
|
||||
return changeOrderStatus(order.VendorOrderID, status, "")
|
||||
}
|
||||
|
||||
func AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
func MarkArrears(db *dao.DaoDB, order *model.GoodsOrder, orderPay *model.OrderPay) {
|
||||
//退款后,若此订单下单用户有推广人,则需要将分给推广人的金额记录到该推广人的欠款中
|
||||
// orders, _ := dao.QueryOrders(db, order.VendorOrderID, 0, []int{model.VendorIDJX}, 0, utils.DefaultTimeValue, utils.DefaultTimeValue)
|
||||
// if len(orders) > 0 {
|
||||
// user, _ := dao.GetUserByID(db, "user_id", orders[0].UserID)
|
||||
// if user.ParentMobile != "" {
|
||||
// user2, _ := dao.GetUserByID(db, "mobile", user.ParentMobile)
|
||||
// user2.Arrears = user2.Arrears + (orderPay.TotalFee * user2.DividePercentage / 100)
|
||||
// dao.UpdateEntity(db, user2, "Arrears")
|
||||
// if user2.ParentMobile != "" {
|
||||
// user3, _ := dao.GetUserByID(db, "mobile", user2.ParentMobile)
|
||||
// user3.Arrears = user3.Arrears + ((orderPay.TotalFee - user2.Arrears) * user3.DividePercentage / 100)
|
||||
// dao.UpdateEntity(db, user3, "Arrears")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// todo 消息用异步可能导致丢失,单同步又有重入相关的问题
|
||||
func callNewOrder(order *model.GoodsOrder) (err error) {
|
||||
jxutils.CallMsgHandlerAsync(func() {
|
||||
err = partner.CurOrderManager.OnOrderNew(order, model.Order2Status(order))
|
||||
}, jxutils.ComposeUniversalOrderID(order.VendorOrderID, model.VendorIDJX))
|
||||
return err
|
||||
}
|
||||
|
||||
func changeOrderStatus(vendorOrderID string, status int, remark string) (err error) {
|
||||
orderStatus := &model.OrderStatus{
|
||||
VendorOrderID: vendorOrderID,
|
||||
VendorID: model.VendorIDJX,
|
||||
OrderType: model.OrderTypeOrder,
|
||||
RefVendorOrderID: vendorOrderID,
|
||||
RefVendorID: model.VendorIDJX,
|
||||
VendorStatus: utils.Int2Str(status),
|
||||
Status: status,
|
||||
StatusTime: time.Now(),
|
||||
Remark: remark,
|
||||
}
|
||||
jxutils.CallMsgHandlerAsync(func() {
|
||||
err = partner.CurOrderManager.OnOrderStatusChanged("", orderStatus)
|
||||
}, jxutils.ComposeUniversalOrderID(vendorOrderID, model.VendorIDJX))
|
||||
return err
|
||||
}
|
||||
|
||||
func PayForPopluarMan(ctx *jxcontext.Context, vendorOrderID, userID string, price int) (err error) {
|
||||
db := dao.GetDB()
|
||||
user, err := dao.GetUserByID(db, "user_id", userID)
|
||||
if user == nil {
|
||||
return fmt.Errorf("未找到此用户!用户ID:[%v]\n", userID)
|
||||
}
|
||||
auth, err := dao.GetUserBindAuthInfo(db, userID, model.AuthBindTypeAuth, []string{"weixinmini"}, "", "", "wx4b5930c13f8b1170")
|
||||
if len(auth) == 0 {
|
||||
return fmt.Errorf("未找到此用户的微信验证方式!用户ID:[%v]\n", userID)
|
||||
}
|
||||
// goods, err := dao.QueryOrders(db, vendorOrderID, 0, []int{model.VendorIDJX}, 0, utils.ZeroTimeValue, utils.ZeroTimeValue)
|
||||
// if len(goods) == 0 {
|
||||
// return fmt.Errorf("未找到此订单!订单ID:[%v]\n", vendorOrderID)
|
||||
// }
|
||||
param := &wxpayapi.TransfersParam{
|
||||
CheckName: wxpayapi.CheckName,
|
||||
PartnerTradeNo: vendorOrderID,
|
||||
Desc: "每日推广人订单分成分到个人",
|
||||
SpbillCreateIP: ctx.GetRealRemoteIP(),
|
||||
OpenID: auth[0].AuthID,
|
||||
Amount: price,
|
||||
}
|
||||
_, err = api.WxpayAPI.Transfers(param)
|
||||
return err
|
||||
}
|
||||
|
||||
//自动打款给市场推广人
|
||||
func AutoPayForPopluarMan(ctx *jxcontext.Context) (err error) {
|
||||
// var (
|
||||
// errMsg string
|
||||
// // errCode string
|
||||
// db = dao.GetDB()
|
||||
// fromDateStr = time.Now().AddDate(0, 0, -1).Format("2006-1-2") + " 00:00:00"
|
||||
// toDateStr = time.Now().AddDate(0, 0, -1).Format("2006-1-2") + " 23:59:59"
|
||||
// mapResult = make(map[string]interface{})
|
||||
// )
|
||||
// result, err := dao.GetOrdersForJxPay(db, utils.Str2Time(fromDateStr), utils.Str2Time(toDateStr))
|
||||
// for _, goods := range result {
|
||||
// var (
|
||||
// param = &wxpayapi.TransfersParam{
|
||||
// CheckName: wxpayapi.CheckName,
|
||||
// Desc: "每日推广人订单分成分到个人",
|
||||
// SpbillCreateIP: ctx.GetRealRemoteIP(),
|
||||
// }
|
||||
// payPrice1 int
|
||||
// payPrice2 int
|
||||
// )
|
||||
// user, err := dao.GetUserByID(db, "user_id", goods.UserID)
|
||||
// if user.ParentMobile == "" {
|
||||
// return err
|
||||
// }
|
||||
// user2, err := dao.GetUserByID(db, "mobile", user.ParentMobile)
|
||||
// auths, err := dao.GetUserBindAuthInfo(db, user2.UserID, model.AuthBindTypeAuth, []string{"weixinmini"}, "", "", "wx4b5930c13f8b1170")
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if len(auths) == 0 {
|
||||
// errMsg += fmt.Sprintf("打款失败!未找到此用户的微信验证方式!订单号:[%v],用户ID:[%v]\n", goods.VendorOrderID, user2.UserID)
|
||||
// } else {
|
||||
// var openID string
|
||||
// for _, auth := range auths {
|
||||
// if auth.TypeID == wxAppID {
|
||||
// openID = auth.AuthID
|
||||
// }
|
||||
// }
|
||||
// payPrice1 = int(goods.ActualPayPrice) * user2.DividePercentage / 100
|
||||
// //表示这个人之前有欠款,意思是取消订单退款时,这个推广人的分成收不回来,算作欠款,打钱的时候要扣除
|
||||
// //表示这个人之前有小于3毛钱的款没有打(微信付款api付款最低3毛),记录下来加到以后的款项中
|
||||
// rPrice := payPrice1 - user2.Arrears + user2.Profit
|
||||
// err = updateUserAndTransfers(db, param, user2, openID, rPrice)
|
||||
// if err != nil {
|
||||
// errMsg += err.Error()
|
||||
// }
|
||||
// mapResult["打款人1"] = user2.Name
|
||||
// mapResult["打款人金额1"] = rPrice
|
||||
// mapResult["打款人电话1"] = user2.Mobile
|
||||
// mapResult["打款人1userID"] = user2.UserID
|
||||
// }
|
||||
// if user2.ParentMobile != "" {
|
||||
// user3, err := dao.GetUserByID(db, "mobile", user2.ParentMobile)
|
||||
// auths, err := dao.GetUserBindAuthInfo(db, user3.UserID, model.AuthBindTypeAuth, []string{"weixinmini"}, "", "", "wx4b5930c13f8b1170")
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if len(auths) == 0 {
|
||||
// errMsg += fmt.Sprintf("打款失败!未找到此用户的微信验证方式!订单号:[%v],用户ID:[%v]\n", goods.VendorOrderID, user3.UserID)
|
||||
// } else {
|
||||
// var openID string
|
||||
// for _, auth := range auths {
|
||||
// if auth.TypeID == wxAppID {
|
||||
// openID = auth.AuthID
|
||||
// }
|
||||
// }
|
||||
// payPrice2 = (int(goods.ActualPayPrice) - payPrice1) * user3.DividePercentage / 100
|
||||
// rPrice := payPrice2 - user3.Arrears + user3.Profit
|
||||
// err = updateUserAndTransfers(db, param, user3, openID, rPrice)
|
||||
// if err != nil {
|
||||
// errMsg += err.Error()
|
||||
// }
|
||||
// mapResult["打款人2"] = user3.Name
|
||||
// mapResult["打款人金额2"] = rPrice
|
||||
// mapResult["打款人电话2"] = user3.Mobile
|
||||
// mapResult["打款人2userID"] = user3.UserID
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// user, _ := dao.GetUserByID(dao.GetDB(), "mobile", "18160030913")
|
||||
// if user != nil && errMsg != "" {
|
||||
// ddmsg.SendUserMessage(dingdingapi.MsgTyeText, user.UserID, "每日打款错误", errMsg)
|
||||
// }
|
||||
// if err != nil || errMsg != "" {
|
||||
// errMsg += err.Error()
|
||||
// errCode = model.ErrCodeGeneralFailed
|
||||
// } else {
|
||||
// errCode = model.ErrCodeSuccess
|
||||
// }
|
||||
// err = event.AddOperateEvent(ctx, ctx.GetTrackInfo(), cms.BuildDiffData(mapResult), errCode, errMsg, 0, "AutoPayForPopluarMan")
|
||||
// globals.SugarLogger.Debugf("每日订单打款:[%v]", cms.BuildDiffData(mapResult))
|
||||
return err
|
||||
}
|
||||
|
||||
func updateUserAndTransfers(db *dao.DaoDB, param *wxpayapi.TransfersParam, user *model.User, authID string, rPrice int) (err error) {
|
||||
if rPrice >= 30 {
|
||||
param.OpenID = authID
|
||||
param.Amount = rPrice
|
||||
param.PartnerTradeNo = utils.GetUUID()
|
||||
_, err = api.WxpayAPI.Transfers(param)
|
||||
user.ProfitSum = user.ProfitSum + rPrice
|
||||
user.Profit = 0
|
||||
user.Arrears = 0
|
||||
} else if rPrice >= 0 && rPrice < 30 {
|
||||
user.Profit = rPrice
|
||||
user.Arrears = 0
|
||||
} else {
|
||||
user.Profit = 0
|
||||
user.Arrears = int(utils.Float64TwoInt64(math.Abs(utils.Int2Float64(rPrice))))
|
||||
}
|
||||
_, err = dao.UpdateEntity(db, user, "ProfitSum", "Profit", "Arrears")
|
||||
return err
|
||||
}
|
||||
|
||||
func CancelPayTimeOutOrder(ctx *jxcontext.Context) (err error) {
|
||||
db := dao.GetDB()
|
||||
var orders []*model.GoodsOrder
|
||||
sql := `
|
||||
SELECT *
|
||||
FROM goods_order
|
||||
WHERE order_created_at >= ? AND order_created_at <= NOW()
|
||||
AND status = ?
|
||||
AND vendor_id = ?
|
||||
`
|
||||
sqlParams := []interface{}{
|
||||
time.Now().Add(-time.Minute * 30),
|
||||
model.OrderStatusWait4Pay,
|
||||
model.VendorIDJX,
|
||||
}
|
||||
err = dao.GetRows(db, &orders, sql, sqlParams)
|
||||
for _, v := range orders {
|
||||
if v.OrderCreatedAt.Add(PayWaitingTime).Before(time.Now()) {
|
||||
err2 := changeOrderStatus(v.VendorOrderID, model.OrderStatusCanceled, autoCancelOrderReason)
|
||||
err = err2
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func GetHalfHoursList() (strs []string) {
|
||||
for k := 0; k < 3; k++ {
|
||||
for i := 0; i < 10; i++ {
|
||||
for j := 0; j < 4; j += 3 {
|
||||
if k == 2 && i > 3 {
|
||||
break
|
||||
}
|
||||
strs = append(strs, utils.Int2Str(k)+utils.Int2Str(i)+":"+utils.Int2Str(j)+"0"+":00")
|
||||
}
|
||||
}
|
||||
}
|
||||
return strs
|
||||
}
|
||||
|
||||
func GetDiscountActHoursList() (str []string) {
|
||||
for k := 1; k < 3; k++ {
|
||||
for i := 0; i < 10; i++ {
|
||||
for j := 0; j < 6; j++ {
|
||||
if k == 1 && i == 0 && j == 0 {
|
||||
continue
|
||||
}
|
||||
if k == 2 && i > 2 {
|
||||
break
|
||||
}
|
||||
if k == 2 && i == 2 && j > 0 {
|
||||
break
|
||||
}
|
||||
str = append(str, utils.Int2Str(k)+utils.Int2Str(i)+":"+utils.Int2Str(j)+"0"+":00")
|
||||
}
|
||||
}
|
||||
}
|
||||
return str
|
||||
}
|
||||
182
business/partner/purchase/jx/localjx/tonglianpay.go
Normal file
182
business/partner/purchase/jx/localjx/tonglianpay.go
Normal file
@@ -0,0 +1,182 @@
|
||||
package localjx
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.rosy.net.cn/jx-callback/globals"
|
||||
|
||||
"git.rosy.net.cn/baseapi/platformapi/tonglianpayapi"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
|
||||
"git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin"
|
||||
"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/api"
|
||||
)
|
||||
|
||||
func pay4OrderByTL(ctx *jxcontext.Context, order *model.GoodsOrder, payType int, vendorPayType string) (orderPay *model.OrderPay, err error) {
|
||||
// if order.FromStoreID != 0 {
|
||||
// result, _ := orderman.GetMatterStoreOrderCount(nil, order.FromStoreID)
|
||||
// if !result.Flag {
|
||||
// return nil, fmt.Errorf("该门店[%v]已在一周内申请过物料,请勿重复申请!", order.FromStoreID)
|
||||
// }
|
||||
// }
|
||||
payCreatedAt := time.Now()
|
||||
param := &tonglianpayapi.CreateUnitorderOrderParam{
|
||||
Trxamt: int(order.ActualPayPrice),
|
||||
NotifyUrl: globals.TLPayNotifyURL,
|
||||
Reqsn: order.VendorOrderID,
|
||||
PayType: vendorPayType,
|
||||
}
|
||||
//暂时做兼容处理
|
||||
if vendorPayType == "JSAPI" {
|
||||
param.PayType = tonglianpayapi.PayTypeWxXcx
|
||||
}
|
||||
if vendorPayType == tonglianpayapi.PayTypeWxXcx {
|
||||
if authInfo, err := ctx.GetV2AuthInfo(); err == nil && authInfo.GetAuthType() == weixin.AuthTypeMini {
|
||||
param.Acct = authInfo.GetAuthID()
|
||||
}
|
||||
}
|
||||
if vendorPayType == tonglianpayapi.PayTypeH5 {
|
||||
param2 := &tonglianpayapi.CreateH5UnitorderOrderParam{
|
||||
Trxamt: int(order.ActualPayPrice),
|
||||
NotifyUrl: globals.TLPayNotifyURL,
|
||||
Body: "京西菜市",
|
||||
Charset: "UTF-8",
|
||||
}
|
||||
err = api.TLpayAPI.CreateH5UnitorderOrder(param2)
|
||||
} else {
|
||||
result, err := api.TLpayAPI.CreateUnitorderOrder(param)
|
||||
if err == nil {
|
||||
var result2 tonglianpayapi.PayInfo
|
||||
json.Unmarshal([]byte(result.PayInfo), &result2)
|
||||
prePayID := result2.Package[strings.LastIndex(result2.Package, "=")+1 : len(result2.Package)]
|
||||
orderPay = &model.OrderPay{
|
||||
PayOrderID: param.Reqsn,
|
||||
PayType: payType,
|
||||
VendorPayType: vendorPayType,
|
||||
TransactionID: result.TrxID,
|
||||
VendorOrderID: order.VendorOrderID,
|
||||
VendorID: order.VendorID,
|
||||
Status: 0,
|
||||
PayCreatedAt: payCreatedAt,
|
||||
PrepayID: prePayID,
|
||||
CodeURL: utils.LimitUTF8StringLen(result.PayInfo, 3200),
|
||||
TotalFee: int(order.ActualPayPrice),
|
||||
}
|
||||
}
|
||||
}
|
||||
return orderPay, err
|
||||
}
|
||||
|
||||
func OnTLPayCallback(call *tonglianpayapi.CallBackResult) (err error) {
|
||||
globals.SugarLogger.Debugf("OnTLPayCallback msg:%s", utils.Format4Output(call, true))
|
||||
switch call.TrxCode {
|
||||
case tonglianpayapi.MsgTypePay:
|
||||
err = onTLpayFinished(call)
|
||||
case tonglianpayapi.MsgTypeRefund:
|
||||
err = onTLpayRefund(call)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func onTLpayFinished(call *tonglianpayapi.CallBackResult) (err error) {
|
||||
orderPay := &model.OrderPay{
|
||||
PayOrderID: call.CusorderID,
|
||||
// PayType: model.PayTypeTL,
|
||||
}
|
||||
orderPay.DeletedAt = utils.DefaultTimeValue
|
||||
db := dao.GetDB()
|
||||
if err = dao.GetEntity(db, orderPay, "PayOrderID", "DeletedAt"); err == nil {
|
||||
if orderPay.Status != 0 {
|
||||
globals.SugarLogger.Debugf("already pay msg:%s, err:%v", utils.Format4Output(call, true), err)
|
||||
return err
|
||||
}
|
||||
loc, _ := time.LoadLocation("Local")
|
||||
t1, _ := time.ParseInLocation("20060102150405", call.PayTime, loc)
|
||||
orderPay.PayFinishedAt = utils.Time2Pointer(t1)
|
||||
// orderPay.TransactionID = call.ChnlTrxID
|
||||
orderPay.OriginalData = utils.Format4Output(call, true)
|
||||
if call.TrxStatus == tonglianpayapi.TrxStatusSuccess {
|
||||
orderPay.Status = model.PayStatusYes
|
||||
} else {
|
||||
orderPay.Status = model.PayStatusFailed
|
||||
}
|
||||
dao.UpdateEntity(db, orderPay)
|
||||
if call.TrxStatus == tonglianpayapi.TrxStatusSuccess {
|
||||
err = OnPayFinished(orderPay)
|
||||
}
|
||||
} else {
|
||||
globals.SugarLogger.Debugf("onTLpayFinished msg:%s, err:%v", utils.Format4Output(call, true), err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func onTLpayRefund(call *tonglianpayapi.CallBackResult) (err error) {
|
||||
orderPayRefund := &model.OrderPayRefund{
|
||||
RefundID: call.CusorderID,
|
||||
}
|
||||
db := dao.GetDB()
|
||||
if err = dao.GetEntity(db, orderPayRefund, "RefundID"); err == nil {
|
||||
if call.TrxStatus == tonglianpayapi.TrxStatusSuccess {
|
||||
orderPayRefund.Status = model.RefundStatusYes
|
||||
} else {
|
||||
orderPayRefund.Status = model.RefundStatusFailed
|
||||
}
|
||||
orderPayRefund.OriginalData = utils.Format4Output(call, true)
|
||||
dao.UpdateEntity(db, orderPayRefund)
|
||||
} else if dao.IsNoRowsError(err) {
|
||||
globals.SugarLogger.Warnf("收到异常的退款事件, call:%s", utils.Format4Output(call, true))
|
||||
}
|
||||
|
||||
orderPay := &model.OrderPay{
|
||||
VendorOrderID: orderPayRefund.VendorOrderID,
|
||||
VendorID: jxutils.GetPossibleVendorIDFromVendorOrderID(orderPayRefund.VendorOrderID),
|
||||
PayType: model.PayTypeWX,
|
||||
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
|
||||
}
|
||||
|
||||
func RefundOrderByTL(ctx *jxcontext.Context, orderPay *model.OrderPay, refundID string, refundFee int, refundDesc string) (orderPayRefund *model.OrderPayRefund, err error) {
|
||||
result, err := api.TLpayAPI.PayRefund(&tonglianpayapi.PayRefundParam{
|
||||
Trxamt: refundFee,
|
||||
Reqsn: utils.GetUUID(),
|
||||
Remark: refundDesc,
|
||||
OldTrxID: orderPay.TransactionID,
|
||||
})
|
||||
if err == nil {
|
||||
orderPayRefund = &model.OrderPayRefund{
|
||||
RefundID: refundID,
|
||||
VendorRefundID: result.TrxID,
|
||||
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.TrxStatus == tonglianpayapi.TrxStatusSuccess {
|
||||
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
|
||||
}
|
||||
152
business/partner/purchase/jx/localjx/wxpay.go
Normal file
152
business/partner/purchase/jx/localjx/wxpay.go
Normal file
@@ -0,0 +1,152 @@
|
||||
package localjx
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"git.rosy.net.cn/baseapi/platformapi/wxpayapi"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin"
|
||||
"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 vendorPayType2WxpayType(vendorPayType string) string {
|
||||
return vendorPayType
|
||||
}
|
||||
|
||||
func getOrderBrief(order *model.GoodsOrder) string {
|
||||
return fmt.Sprintf("%s等共%d件商品", order.Skus[0].SkuName, order.GoodsCount)
|
||||
}
|
||||
|
||||
func pay4OrderByWX(ctx *jxcontext.Context, order *model.GoodsOrder, vendorPayType string) (orderPay *model.OrderPay, err error) {
|
||||
payCreatedAt := time.Now()
|
||||
param := &wxpayapi.CreateOrderParam{
|
||||
OutTradeNo: utils.Int64ToStr(GenPayOrderID(order)),
|
||||
Body: getOrderBrief(order),
|
||||
NotifyURL: globals.WxpayNotifyURL,
|
||||
SpbillCreateIP: ctx.GetRealRemoteIP(),
|
||||
TradeType: vendorPayType2WxpayType(vendorPayType),
|
||||
TotalFee: int(order.ActualPayPrice),
|
||||
|
||||
TimeStart: wxpayapi.Time2PayTime(payCreatedAt),
|
||||
// TimeExpire: wxpayapi.Time2PayTime(payCreatedAt.Add(PayWaitingTime)),
|
||||
ProfitSharing: wxpayapi.OptYes,
|
||||
}
|
||||
if authInfo, err := ctx.GetV2AuthInfo(); err == nil && authInfo.GetAuthType() == weixin.AuthTypeMini {
|
||||
param.OpenID = authInfo.GetAuthID()
|
||||
}
|
||||
result, err := api.WxpayAPI.CreateUnifiedOrder(param)
|
||||
if err == nil {
|
||||
orderPay = &model.OrderPay{
|
||||
PayOrderID: param.OutTradeNo,
|
||||
PayType: model.PayTypeWX,
|
||||
VendorPayType: vendorPayType,
|
||||
|
||||
VendorOrderID: order.VendorOrderID,
|
||||
VendorID: order.VendorID,
|
||||
Status: 0,
|
||||
PayCreatedAt: payCreatedAt,
|
||||
PrepayID: result.PrepayID,
|
||||
CodeURL: result.CodeURL,
|
||||
TotalFee: int(order.ActualPayPrice),
|
||||
}
|
||||
}
|
||||
return orderPay, err
|
||||
}
|
||||
|
||||
func OnWxPayCallback(msg *wxpayapi.CallbackMsg) (err error) {
|
||||
globals.SugarLogger.Debugf("OnWxPayCallback msg:%s", utils.Format4Output(msg, true))
|
||||
switch msg.MsgType {
|
||||
case wxpayapi.MsgTypePay:
|
||||
err = onWxpayFinished(msg.Data.(*wxpayapi.PayResultMsg))
|
||||
case wxpayapi.MsgTypeRefund:
|
||||
err = onWxpayRefund(msg.Data.(*wxpayapi.RefundResultMsg))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func onWxpayFinished(msg *wxpayapi.PayResultMsg) (err error) {
|
||||
orderPay := &model.OrderPay{
|
||||
PayOrderID: msg.OutTradeNo,
|
||||
PayType: model.PayTypeWX,
|
||||
}
|
||||
orderPay.DeletedAt = utils.DefaultTimeValue
|
||||
db := dao.GetDB()
|
||||
if err = dao.GetEntity(db, orderPay, "PayOrderID", "PayType", "DeletedAt"); err == nil {
|
||||
orderPay.PayFinishedAt = utils.Time2Pointer(wxpayapi.PayTime2Time(msg.TimeEnd))
|
||||
orderPay.TransactionID = msg.TransactionID
|
||||
orderPay.OriginalData = utils.Format4Output(msg, true)
|
||||
if msg.ResultCode == wxpayapi.ResponseCodeSuccess {
|
||||
orderPay.Status = model.PayStatusYes
|
||||
} else {
|
||||
orderPay.Status = model.PayStatusFailed
|
||||
}
|
||||
dao.UpdateEntity(db, orderPay)
|
||||
if msg.ResultCode == wxpayapi.ResponseCodeSuccess {
|
||||
err = OnPayFinished(orderPay)
|
||||
}
|
||||
} else {
|
||||
globals.SugarLogger.Debugf("onWxpayFinished msg:%s, err:%v", utils.Format4Output(msg, true), err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func onWxpayRefund(msg *wxpayapi.RefundResultMsg) (err error) {
|
||||
orderPayRefund := &model.OrderPayRefund{
|
||||
RefundID: msg.ReqInfoObj.OutRefundNo,
|
||||
}
|
||||
db := dao.GetDB()
|
||||
if err = dao.GetEntity(db, orderPayRefund, "RefundID"); err == nil {
|
||||
if msg.ResultCode == wxpayapi.ResponseCodeSuccess {
|
||||
orderPayRefund.Status = model.RefundStatusYes
|
||||
} else {
|
||||
orderPayRefund.Status = model.RefundStatusFailed
|
||||
}
|
||||
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.PayTypeWX,
|
||||
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
|
||||
}
|
||||
|
||||
func refundOrderByWX(ctx *jxcontext.Context, orderPay *model.OrderPay, refundID string, refundFee int, refundDesc string) (orderPayRefund *model.OrderPayRefund, err error) {
|
||||
result, err := api.WxpayAPI.PayRefund(&wxpayapi.PayRefundParam{
|
||||
OutTradeNo: orderPay.VendorOrderID,
|
||||
NotifyURL: globals.WxpayNotifyURL,
|
||||
OutRefundNo: refundID,
|
||||
TotalFee: orderPay.TotalFee,
|
||||
RefundFee: refundFee,
|
||||
RefundDesc: wxpayapi.CData(refundDesc),
|
||||
})
|
||||
if err == nil {
|
||||
orderPayRefund = &model.OrderPayRefund{
|
||||
RefundID: refundID,
|
||||
VendorRefundID: result.RefundID,
|
||||
VendorOrderID: orderPay.VendorOrderID,
|
||||
VendorID: orderPay.VendorID,
|
||||
Status: model.RefundStatusNo,
|
||||
TransactionID: orderPay.TransactionID,
|
||||
RefundFee: orderPay.TotalFee,
|
||||
RefundCreatedAt: time.Now(),
|
||||
}
|
||||
}
|
||||
return orderPayRefund, err
|
||||
}
|
||||
Reference in New Issue
Block a user