package pay import ( "encoding/json" "time" "yunyan/comm" "yunyan/pb" "yunyan/sys/pay/alipay" "yunyan/sys/pay/appleiap" "yunyan/sys/pay/googleiap" "yunyan/sys/pay/paypal" "yunyan/sys/pay/wechat" ) // @Summary 创建支付订单 // @Description 创建支付订单并返回支付信息 // @Tags Pay // @Accept json // @Produce json // @Security BearerAuth // @Param order body pb.PayCreatePayOrderReq true "订单信息" // @Success 200 {object} comm.HttpResult{data=pb.PayCreatePayOrderResp} "支付订单信息" // @Router /api/home/pay_createorder [post] func (this *apiComp) CreateOrder(session comm.IUserSession, req *pb.PayCreatePayOrderReq) (resp *pb.PayCreatePayOrderResp, errdata *pb.ErrorData) { var ( osrderNo string appPayParams *wechat.AppPayParams alipayPayParams string paypalPayParams string err error ) resp = &pb.PayCreatePayOrderResp{ Orderid: osrderNo, ProductId: req.ProductId, ProductName: req.ProductName, } if req.PaymentMethod == pb.PaymentMethod_WxAPP { osrderNo = wechat.GenerateOrderNo("WxAPP") if appPayParams, err = wechat.CreateAppOrder(session, osrderNo, req.Amount, req.ProductName, req.NotifyUrl); err != nil { errdata = &pb.ErrorData{ Code: pb.ErrorCode_PayCreateOrderFail, Message: "创建微信支付订单失败:" + err.Error(), } return } resp.PayParams = &pb.AppPayParams{ Appid: appPayParams.AppID, Partnerid: appPayParams.PartnerID, Prepayid: appPayParams.PrepayID, Package: appPayParams.Package, Noncestr: appPayParams.NonceStr, Timestamp: appPayParams.TimeStamp, Sign: appPayParams.Sign, } } else if req.PaymentMethod == pb.PaymentMethod_Alipay { osrderNo = alipay.GenerateOrderNo("Alipay") if alipayPayParams, err = alipay.CreateAppOrder(session, osrderNo, req.Amount, req.ProductName, req.NotifyUrl); err != nil { errdata = &pb.ErrorData{ Code: pb.ErrorCode_PayCreateOrderFail, Message: "创建微信支付订单失败:" + err.Error(), } return } resp.AlipayPayParams = alipayPayParams } else if req.PaymentMethod == pb.PaymentMethod_PayPal { osrderNo = paypal.GenerateOrderNo("PayPal") if paypalPayParams, err = paypal.CreateAppOrder(session, osrderNo, req.Amount, req.ProductName, req.ReturnUrl, req.CancelUrl); err != nil { errdata = &pb.ErrorData{ Code: pb.ErrorCode_PayCreateOrderFail, Message: "创建PayPal支付订单失败:" + err.Error(), } return } // CreateAppOrder 返回 JSON 字符串,包含 order_id 和 links resp.PaypalPayParams = paypalPayParams } else if req.PaymentMethod == pb.PaymentMethod_AppleIAP { osrderNo = appleiap.GenerateOrderNo("AppleIAP") } else if req.PaymentMethod == pb.PaymentMethod_GoogleIAP { osrderNo = googleiap.GenerateOrderNo("GoogleIAP") } else { errdata = &pb.ErrorData{ Code: pb.ErrorCode_PayCreateOrderFail, Message: "不支持的支付方式", } return } // this.module.Debugf("CreateOrder appPayParams:%v", appPayParams) // 如果是 PayPal,解析并保存第三方订单号(用于后续 capture) var paypalOrderID string if req.PaymentMethod == pb.PaymentMethod_PayPal && paypalPayParams != "" { var m map[string]any if json.Unmarshal([]byte(paypalPayParams), &m) == nil { if v, ok := m["order_id"].(string); ok { paypalOrderID = v } } } // 来源设备快照:客户端带的「当前使用设备」优先,否则回退用户最后绑定设备。 // 下单即冻结,月结算按它把订单归到品牌商/渠道商名下。 src := this.resolveOrderSource(session.GetUserId(), req.Devicemac, req.License) if err = this.module.model.createPayOrder(&pb.DBPayOrder{ OrderId: osrderNo, SrcLicense: src.License, SrcMac: src.Mac, SrcProductid: src.ProductId, SrcBrandid: src.BrandId, SrcChannelid: src.ChannelId, Uid: session.GetUserId(), ProductId: req.ProductId, ProductName: req.ProductName, Amount: req.Amount, PaymentMethod: req.PaymentMethod, Status: pb.PayOrderStatus_PAY_ORDER_PENDING, TransactionId: paypalOrderID, CreateTime: time.Now().Unix(), }); err != nil { errdata = &pb.ErrorData{ Code: pb.ErrorCode_PayCreateOrderFail, Message: "创建支付订单失败:" + err.Error(), } return } // 订单创建埋点:与订单快照同源(来源设备的产品/渠道商),保证统计与结算口径一致。 if this.module.analyze != nil { this.module.analyze.Report(&comm.StatEvent{ Type: comm.StatEventOrderCreate, ProductId: src.ProductId, ChannelId: src.ChannelId, Uid: session.GetUserId(), Amount: req.Amount, }) } resp.Orderid = osrderNo return }