package localjx import ( "encoding/json" "fmt" "git.rosy.net.cn/baseapi/platformapi/lakala" "git.rosy.net.cn/jx-callback/business/partner" "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/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" "github.com/astaxie/beego/client/orm" ) func pay4OrderByLaKaLa(ctx *jxcontext.Context, order *model.GoodsOrder, payType int, vendorPayType, subAppID, code, source, ip string) (orderPay *model.OrderPay, err error) { merchantObj, err := dao.GetStoreInfoByMerchantID(dao.GetDB(), "", order.JxStoreID, "", "") if err != nil { return nil, err } param := &lakala.AggregatePayReq{ MerchantNo: merchantObj.MerchantNo, TermNo: merchantObj.TermNo, OutTradeNo: order.VendorOrderID, TotalAmount: utils.Int64ToStr(order.ActualPayPrice), LocationInfo: lakala.LocationInfoObj{ RequestIp: ip, }, NotifyUrl: lakala.PayStatusCallback, Subject: fmt.Sprintf("感谢您在本店%s消费,欢迎下次再来", order.StoreName), SettleType: "1", AccBusiFields: nil, } if vendorPayType == tonglianpayapi.PayTypeWxXcx || vendorPayType == "JSAPI" || vendorPayType == tonglianpayapi.PayTypeWxCode { accBusiFeilds := &lakala.AccBusiFieldsByWeChat{ TimeoutExpress: "15", SubAppid: subAppID, } if source == "pc" || vendorPayType == "JSAPI" { accBusiFeilds.DeviceInfo = "WEB" } switch vendorPayType { case "JSAPI": param.TransType = "51" case tonglianpayapi.PayTypeWxXcx: param.TransType = "71" } authInfo, err := ctx.GetV2AuthInfo() // 微信小程序支付 if err == nil && authInfo.GetAuthType() == weixin.AuthTypeMini && authInfo.GetAuthTypeID() == subAppID { accBusiFeilds.UserId = authInfo.GetAuthID() } if code != "" { appAuth := strings.Split(code, "_") sessionInfo, err := weixin.GetAPI(appAuth[0]).SNSCode2Session(appAuth[1]) if err != nil { return nil, err } accBusiFeilds.UserId = sessionInfo.OpenID } param.AccBusiFields = accBusiFeilds param.AccountType = lakala.Wechat } // 支付宝暂时不关注小程序 //if vendorPayType == tonglianpayapi.PayTypeZfbJS || vendorPayType == tonglianpayapi.PayTypeZfbApp { // accBusiFeilds := &lakala.AccBusiFieldsByAliPay{ // TimeoutExpress: "15", // UserId: openId, // } // param.AccBusiFields = accBusiFeilds //} result, err := api.LaKaLaApi.AggregatePay(param) if err == nil { orderPay = &model.OrderPay{ PayOrderID: param.OutTradeNo, PayType: payType, VendorPayType: vendorPayType, TransactionID: result.LogNo, VendorOrderID: order.VendorOrderID, VendorID: order.VendorID, Status: 0, PayCreatedAt: time.Now(), PrepayID: result.TradeNo, CodeURL: "", TotalFee: int(order.ActualPayPrice), } if result.AccRespFields != nil { fields, _ := json.Marshal(result.AccRespFields) orderPay.CodeURL = utils.LimitUTF8StringLen(string(fields), 3200) } } return orderPay, err } func OnLaKaLaPayCallback(call *lakala.PayStatusCallBack) (err error) { switch call.TradeStatus { case lakala.PayStatusSUCCESS, lakala.PayStatusFAIL: // 支付成功 FAIL-交易失败 err = onLaKaLaPayFinished(call) case lakala.PayStatusCLOSE, lakala.PayStatusREVOKED, lakala.PayStatusREFUND: // CLOSE-订单关闭 REVOKED-订单撤销 err = onLaKaLaOrderCancel(call) case lakala.PayStatusPARTREFUND: // PART_REFUND-部分退款 REFUND-全部退款 err = onLaKaLaPayRefund(call) default: //INIT-初始化 CREATE-下单成功 DEAL-交易处理中 UNKNOWN-未知状态 return nil } return err } // onLaKaLaPayFinished 订单支付成功或失败 func onLaKaLaPayFinished(call *lakala.PayStatusCallBack) (err error) { orderPay := &model.OrderPay{ PayOrderID: call.OutTradeNo, } orderPay.DeletedAt = utils.DefaultTimeValue db := dao.GetDB() if err = dao.GetEntity(db, orderPay, "PayOrderID", "DeletedAt"); err == nil { if orderPay.Status != 0 { return err } loc, _ := time.LoadLocation("Local") t1, _ := time.ParseInLocation("20060102150405", call.TradeTime, loc) orderPay.PayFinishedAt = utils.Time2Pointer(t1) orderPay.OriginalData = utils.Format4Output(call, true) if call.TradeStatus == lakala.PayStatusSUCCESS { orderPay.Status = model.PayStatusYes } else { orderPay.Status = model.PayStatusFailed } dao.UpdateEntity(db, orderPay) if call.TradeStatus == lakala.PayStatusSUCCESS { err = OnPayFinished(orderPay) } } else { globals.SugarLogger.Debugf("onTLpayFinished msg:%s, err:%v", utils.Format4Output(call, true), err) } return err } // onLaKaLaOrderCancel 订单取消或撤单 func onLaKaLaOrderCancel(call *lakala.PayStatusCallBack) (err error) { orderPay := &model.OrderPay{ PayOrderID: call.OutTradeNo, } orderPay.DeletedAt = utils.DefaultTimeValue db := dao.GetDB() if err = dao.GetEntity(db, orderPay, "PayOrderID", "DeletedAt"); err == nil { orderPay.Status = model.RefundStatusFailed orderPay.PayFinishedAt = utils.Time2Pointer(time.Now()) dao.UpdateEntity(db, orderPay, "Status", "PayFinishedAt") order, _ := partner.CurOrderManager.LoadOrder(orderPay.VendorOrderID, orderPay.VendorID) order.Status = model.OrderStatusCanceled order.VendorStatus = call.TradeStatus order.OrderFinishedAt = time.Now() dao.UpdateEntity(db, order, "Status", "VendorStatus", "OrderFinishedAt") } return err } func onLaKaLaPayRefund(call *lakala.PayStatusCallBack) (err error) { orderPayRefund := &model.OrderPayRefund{ RefundID: call.OutTradeNo, } db := dao.GetDB() if err = dao.GetEntity(db, orderPayRefund, "RefundID"); err != nil && err == orm.ErrNoRows { orderPayRefund = &model.OrderPayRefund{ RefundID: call.OutTradeNo, VendorRefundID: call.AccTradeNo, VendorOrderID: call.OutTradeNo, VendorID: model.VendorIDJX, TransactionID: call.LogNo, Status: model.RefundStatusYes, RefundCreatedAt: time.Now(), RefundFinishedAt: utils.Time2Pointer(time.Now()), RefundFee: utils.Str2Int(call.PayerAmount), OriginalData: "", } dao.WrapAddIDCULDEntity(orderPayRefund, "system") dao.CreateEntity(db, orderPayRefund) } order, _ := partner.CurOrderManager.LoadOrder(call.OutTradeNo, model.VendorIDJX) afsOrder, _ := partner.CurOrderManager.LoadAfsOrder(call.OutTradeNo, model.VendorIDJX) if call.TradeStatus == lakala.PayStatusREFUND { order.Status = model.OrderStatusCanceled orderPayRefund.Status = model.PayStatusRefund } order.OrderFinishedAt = time.Now() order.VendorStatus = call.TradeStatus afsOrder.Status = model.AfsOrderStatusFinished afsOrder.AfsFinishedAt = time.Now() afsOrder.VendorStatus = call.TradeStatus orderPayRefund.RefundFinishedAt = utils.Time2Pointer(time.Now()) dao.UpdateEntity(db, order, "Status", "VendorStatus", "OrderFinishedAt") dao.UpdateEntity(db, afsOrder, "Status", "VendorStatus", "AfsFinishedAt") dao.UpdateEntity(db, orderPayRefund, "Status", "RefundFinishedAt") return err }