fix:支付
This commit is contained in:
parent
f10e556a0a
commit
be786a4d4c
|
@ -14,6 +14,7 @@ type OrderDetail struct {
|
||||||
OrderInfo OrderInfo `json:"order_info"` // 订单信息
|
OrderInfo OrderInfo `json:"order_info"` // 订单信息
|
||||||
OrderProduct []OrderProduct `json:"order_product"` // 订单商品
|
OrderProduct []OrderProduct `json:"order_product"` // 订单商品
|
||||||
PayStatus constants.OrderPayStatusCode `json:"pay_status"` // 支付状态
|
PayStatus constants.OrderPayStatusCode `json:"pay_status"` // 支付状态
|
||||||
|
PayTimeout time.Duration `json:"pay_timeout"` // 支付状态
|
||||||
}
|
}
|
||||||
|
|
||||||
// 收货地址
|
// 收货地址
|
||||||
|
|
|
@ -11,4 +11,12 @@ type Config struct {
|
||||||
SourceMysql string
|
SourceMysql string
|
||||||
Auth types.Auth
|
Auth types.Auth
|
||||||
SourceRabbitMq string
|
SourceRabbitMq string
|
||||||
|
PayConfig struct {
|
||||||
|
Stripe struct {
|
||||||
|
EndpointSecret string
|
||||||
|
Key string
|
||||||
|
CancelURL string
|
||||||
|
SuccessURL string
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,10 @@ func NewCreatePrePaymentByBalanceLogic(ctx context.Context, svcCtx *svc.ServiceC
|
||||||
func (l *CreatePrePaymentByBalanceLogic) CreatePrePaymentByBalance(req *types.CreatePrePaymentByBalanceReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
func (l *CreatePrePaymentByBalanceLogic) CreatePrePaymentByBalance(req *types.CreatePrePaymentByBalanceReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
// userinfo 传入值时, 一定不为null
|
// userinfo 传入值时, 一定不为null
|
||||||
|
if !userinfo.IsUser() {
|
||||||
|
// 如果是,返回未授权的错误码
|
||||||
|
return resp.SetStatus(basic.CodeUnAuth)
|
||||||
|
}
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK)
|
return resp.SetStatus(basic.CodeOK)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package logic
|
package logic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fusenapi/constants"
|
||||||
|
"fusenapi/service/repositories"
|
||||||
"fusenapi/utils/auth"
|
"fusenapi/utils/auth"
|
||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
|
@ -33,8 +35,43 @@ func NewCreatePrePaymentByDepositLogic(ctx context.Context, svcCtx *svc.ServiceC
|
||||||
func (l *CreatePrePaymentByDepositLogic) CreatePrePaymentByDeposit(req *types.CreatePrePaymentByDepositReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
func (l *CreatePrePaymentByDepositLogic) CreatePrePaymentByDeposit(req *types.CreatePrePaymentByDepositReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
// userinfo 传入值时, 一定不为null
|
// userinfo 传入值时, 一定不为null
|
||||||
|
if !userinfo.IsUser() {
|
||||||
|
// 如果是,返回未授权的错误码
|
||||||
|
return resp.SetStatus(basic.CodeUnAuth)
|
||||||
|
}
|
||||||
|
if req.DeliveryMethod == constants.DELIVERYMETHODDIRECTMAIL {
|
||||||
|
if req.DeliveryAddress == nil {
|
||||||
|
return resp.SetStatus(basic.CodeErrOrderCreatePrePaymentParam)
|
||||||
|
} else {
|
||||||
|
if req.DeliveryAddress.Address == "" || req.DeliveryAddress.Mobile == "" || req.DeliveryAddress.Name == "" {
|
||||||
|
return resp.SetStatus(basic.CodeErrOrderCreatePrePaymentParam)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var orderAddress repositories.OrderAddress
|
||||||
|
if req.DeliveryAddress != nil {
|
||||||
|
orderAddress.Address = req.DeliveryAddress.Address
|
||||||
|
orderAddress.Mobile = req.DeliveryAddress.Mobile
|
||||||
|
orderAddress.Name = req.DeliveryAddress.Name
|
||||||
|
}
|
||||||
|
res, err := l.svcCtx.Repositories.NewOrder.CreatePrePaymentByDeposit(l.ctx, &repositories.CreatePrePaymentByDepositReq{
|
||||||
|
UserId: userinfo.UserId,
|
||||||
|
OrderSn: req.OrderSn,
|
||||||
|
DeliveryMethod: req.DeliveryMethod,
|
||||||
|
DeliveryAddress: &orderAddress,
|
||||||
|
Country: "US",
|
||||||
|
Currency: "usd",
|
||||||
|
StripeKey: l.svcCtx.Config.PayConfig.Stripe.Key,
|
||||||
|
})
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK)
|
if err != nil {
|
||||||
|
return resp.SetStatus(&res.ErrorCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.SetStatus(basic.CodeOK, map[string]interface{}{
|
||||||
|
"order_detail": res.OrderDetail,
|
||||||
|
"order_pay": res.OrderPay,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
|
|
@ -43,7 +43,7 @@ func (l *OrderDetailLogic) OrderDetail(req *types.OrderDetailReq, userinfo *auth
|
||||||
UserId: userinfo.UserId,
|
UserId: userinfo.UserId,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return resp.SetStatus(basic.CodeApiErr)
|
return resp.SetStatus(&res.ErrorCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK, map[string]interface{}{
|
return resp.SetStatus(basic.CodeOK, map[string]interface{}{
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package logic
|
package logic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fusenapi/service/repositories"
|
||||||
"fusenapi/utils/auth"
|
"fusenapi/utils/auth"
|
||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
|
@ -33,8 +34,25 @@ func NewOrderListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *OrderLi
|
||||||
func (l *OrderListLogic) OrderList(req *types.OrderListReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
func (l *OrderListLogic) OrderList(req *types.OrderListReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
// userinfo 传入值时, 一定不为null
|
// userinfo 传入值时, 一定不为null
|
||||||
|
if !userinfo.IsUser() {
|
||||||
|
// 如果是,返回未授权的错误码
|
||||||
|
return resp.SetStatus(basic.CodeUnAuth)
|
||||||
|
}
|
||||||
|
res, err := l.svcCtx.Repositories.NewOrder.List(l.ctx, &repositories.ListReq{
|
||||||
|
UserId: userinfo.UserId,
|
||||||
|
DeliveryMethod: req.DeliveryMethod,
|
||||||
|
OrderCycle: req.OrderCycle,
|
||||||
|
CurrentPage: req.CurrentPage,
|
||||||
|
PerPage: req.PerPage,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return resp.SetStatus(basic.CodeApiErr)
|
||||||
|
}
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK)
|
return resp.SetStatus(basic.CodeOK, map[string]interface{}{
|
||||||
|
"list": res.OrderDetailList,
|
||||||
|
"meta": res.Meta,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
|
|
@ -17,10 +17,10 @@ type CreateOrderReq struct {
|
||||||
type CreatePrePaymentByDepositReq struct {
|
type CreatePrePaymentByDepositReq struct {
|
||||||
OrderSn string `json:"order_sn"`
|
OrderSn string `json:"order_sn"`
|
||||||
DeliveryMethod int64 `json:"delivery_method,options=[1,2]"`
|
DeliveryMethod int64 `json:"delivery_method,options=[1,2]"`
|
||||||
DeliveryAddres DeliveryAddres `json:"delivery_addres,optional"`
|
DeliveryAddress *DeliveryAddress `json:"delivery_address,optional"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeliveryAddres struct {
|
type DeliveryAddress struct {
|
||||||
Address string `json:"address,optional"`
|
Address string `json:"address,optional"`
|
||||||
Name string `json:"name,optional"`
|
Name string `json:"name,optional"`
|
||||||
Mobile string `json:"mobile,optional"`
|
Mobile string `json:"mobile,optional"`
|
||||||
|
@ -32,9 +32,9 @@ type CreatePrePaymentByBalanceReq struct {
|
||||||
|
|
||||||
type OrderListReq struct {
|
type OrderListReq struct {
|
||||||
DeliveryMethod int64 `json:"delivery_method,options=[0,1,2],optional"`
|
DeliveryMethod int64 `json:"delivery_method,options=[0,1,2],optional"`
|
||||||
OrderCycle string `json:"order_cycle,optional"`
|
OrderCycle string `json:"order_cycle,optional,options=[within_one_month,within_three_month,within_six_month,within_one_year]"`
|
||||||
Current_page int64 `json:"current_page,optional,default=1"`
|
CurrentPage int64 `json:"current_page,optional,default=1"`
|
||||||
Page_size int64 `json:"page_size,optional,default=10"`
|
PerPage int64 `json:"per_page,optional,default=10"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Request struct {
|
type Request struct {
|
||||||
|
|
|
@ -40,10 +40,10 @@ type CreateOrderReq {
|
||||||
type CreatePrePaymentByDepositReq {
|
type CreatePrePaymentByDepositReq {
|
||||||
OrderSn string `json:"order_sn"`
|
OrderSn string `json:"order_sn"`
|
||||||
DeliveryMethod int64 `json:"delivery_method,options=[1,2]"`
|
DeliveryMethod int64 `json:"delivery_method,options=[1,2]"`
|
||||||
DeliveryAddres DeliveryAddres `json:"delivery_addres,optional"`
|
DeliveryAddress *DeliveryAddress `json:"delivery_address,optional"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeliveryAddres {
|
type DeliveryAddress {
|
||||||
Address string `json:"address,optional"`
|
Address string `json:"address,optional"`
|
||||||
Name string `json:"name,optional"`
|
Name string `json:"name,optional"`
|
||||||
Mobile string `json:"mobile,optional"`
|
Mobile string `json:"mobile,optional"`
|
||||||
|
@ -55,7 +55,7 @@ type CreatePrePaymentByBalanceReq {
|
||||||
|
|
||||||
type OrderListReq {
|
type OrderListReq {
|
||||||
DeliveryMethod int64 `json:"delivery_method,options=[0,1,2],optional"`
|
DeliveryMethod int64 `json:"delivery_method,options=[0,1,2],optional"`
|
||||||
OrderCycle string `json:"order_cycle,optional"`
|
OrderCycle string `json:"order_cycle,optional,options=[within_one_month,within_three_month,within_six_month,within_one_year]"`
|
||||||
Current_page int64 `json:"current_page,optional,default=1"`
|
CurrentPage int64 `json:"current_page,optional,default=1"`
|
||||||
Page_size int64 `json:"page_size,optional,default=10"`
|
PerPage int64 `json:"per_page,optional,default=10"`
|
||||||
}
|
}
|
|
@ -4,10 +4,14 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"fusenapi/constants"
|
"fusenapi/constants"
|
||||||
"fusenapi/model/gmodel"
|
"fusenapi/model/gmodel"
|
||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
|
"fusenapi/utils/fssql"
|
||||||
|
"fusenapi/utils/handlers"
|
||||||
"fusenapi/utils/order"
|
"fusenapi/utils/order"
|
||||||
|
"fusenapi/utils/pay"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/session"
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
|
@ -28,8 +32,10 @@ type (
|
||||||
Order interface {
|
Order interface {
|
||||||
// 下单
|
// 下单
|
||||||
Create(ctx context.Context, in *CreateReq) (res *CreateRes, err error)
|
Create(ctx context.Context, in *CreateReq) (res *CreateRes, err error)
|
||||||
// 预支付
|
// 预支付--定金
|
||||||
|
CreatePrePaymentByDeposit(ctx context.Context, in *CreatePrePaymentByDepositReq) (res *CreatePrePaymentByDepositRes, err error)
|
||||||
// 列表
|
// 列表
|
||||||
|
List(ctx context.Context, in *ListReq) (res *ListRes, err error)
|
||||||
// 详情
|
// 详情
|
||||||
Detail(ctx context.Context, in *DetailReq) (res *DetailRes, err error)
|
Detail(ctx context.Context, in *DetailReq) (res *DetailRes, err error)
|
||||||
}
|
}
|
||||||
|
@ -39,6 +45,38 @@ type (
|
||||||
Mobile string `json:"mobile"` // 手机
|
Mobile string `json:"mobile"` // 手机
|
||||||
Name string `json:"name"` // 姓名
|
Name string `json:"name"` // 姓名
|
||||||
}
|
}
|
||||||
|
OrderPay struct {
|
||||||
|
ClientSecret string `json:"client_secret"` // 支付方--秘钥
|
||||||
|
Country string `json:"country"` // 国家
|
||||||
|
Currency string `json:"currency"` // 货币
|
||||||
|
Metadata map[string]interface{} `json:"metadata"` // 额外参数
|
||||||
|
Method string `json:"method"` // 支付方--途径
|
||||||
|
OrderSn string `json:"order_sn"` // 订单编码
|
||||||
|
PayStage int64 `json:"pay_stage"` // 支付阶段
|
||||||
|
RedirectURL *string `json:"redirect_url"` // 支付方--重定向地址
|
||||||
|
Total OrderPayTotal `json:"total"` // 支付参数
|
||||||
|
}
|
||||||
|
// 支付参数
|
||||||
|
OrderPayTotal struct {
|
||||||
|
Amount int64 `json:"amount"` // 金额
|
||||||
|
Label string `json:"label"` // 标签
|
||||||
|
}
|
||||||
|
/* 预支付--定金 */
|
||||||
|
CreatePrePaymentByDepositReq struct {
|
||||||
|
StripeKey string `json:"stripe_key"`
|
||||||
|
Currency string `json:"currency"`
|
||||||
|
Country string `json:"country"`
|
||||||
|
UserId int64 `json:"user_id"`
|
||||||
|
OrderSn string `json:"order_sn"`
|
||||||
|
DeliveryMethod int64 `json:"delivery_method"`
|
||||||
|
DeliveryAddress *OrderAddress `json:"delivery_address"` // 收货地址
|
||||||
|
}
|
||||||
|
CreatePrePaymentByDepositRes struct {
|
||||||
|
ErrorCode basic.StatusResponse
|
||||||
|
OrderDetail gmodel.OrderDetail
|
||||||
|
OrderPay OrderPay
|
||||||
|
}
|
||||||
|
/* 预支付--定金 */
|
||||||
|
|
||||||
/* 下单 */
|
/* 下单 */
|
||||||
CreateReq struct {
|
CreateReq struct {
|
||||||
|
@ -63,49 +101,291 @@ type (
|
||||||
OrderSn string `json:"order_sn"`
|
OrderSn string `json:"order_sn"`
|
||||||
}
|
}
|
||||||
DetailRes struct {
|
DetailRes struct {
|
||||||
|
ErrorCode basic.StatusResponse
|
||||||
OrderDetail gmodel.OrderDetail
|
OrderDetail gmodel.OrderDetail
|
||||||
|
OrderDetailOriginal gmodel.OrderDetail
|
||||||
}
|
}
|
||||||
/* 详情 */
|
/* 详情 */
|
||||||
|
|
||||||
|
/* 列表 */
|
||||||
|
ListReq struct {
|
||||||
|
UserId int64 `json:"user_id"`
|
||||||
|
DeliveryMethod int64 `json:"delivery_method"`
|
||||||
|
OrderCycle string `json:"order_cycle"`
|
||||||
|
CurrentPage int64 `json:"current_page"`
|
||||||
|
PerPage int64 `json:"per_page"`
|
||||||
|
}
|
||||||
|
ListRes struct {
|
||||||
|
OrderDetailList []gmodel.OrderDetail
|
||||||
|
Meta interface{}
|
||||||
|
}
|
||||||
|
/* 列表 */
|
||||||
)
|
)
|
||||||
|
|
||||||
// 详情
|
// 预支付--定金
|
||||||
func (d *defaultOrder) Detail(ctx context.Context, in *DetailReq) (res *DetailRes, err error) {
|
func (d *defaultOrder) CreatePrePaymentByDeposit(ctx context.Context, in *CreatePrePaymentByDepositReq) (res *CreatePrePaymentByDepositRes, err error) {
|
||||||
|
var errorCode basic.StatusResponse
|
||||||
var order gmodel.FsOrder
|
var order gmodel.FsOrder
|
||||||
result := d.MysqlConn.Where("order_sn = ?", in.OrderSn).Where("user_id = ?", in.UserId).Take(&order)
|
model := d.MysqlConn.Where("is_del = ?", 0)
|
||||||
|
if in.UserId != 0 {
|
||||||
|
model.Where("user_id = ?", in.UserId)
|
||||||
|
}
|
||||||
|
if in.OrderSn != "" {
|
||||||
|
model.Where("order_sn = ?", in.OrderSn)
|
||||||
|
}
|
||||||
|
result := model.Take(&order)
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
logx.Errorf("detail failed, err: %v", err)
|
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
||||||
|
errorCode = *basic.CodeErrOrderCreatePrePaymentInfoNoFound
|
||||||
|
} else {
|
||||||
|
errorCode = *basic.CodeServiceErr
|
||||||
|
}
|
||||||
|
logx.Errorf("create prePayment deposit failed, err: %v", err)
|
||||||
|
return &CreatePrePaymentByDepositRes{
|
||||||
|
ErrorCode: errorCode,
|
||||||
|
}, result.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// 非未支付
|
||||||
|
if *order.PayStatus != int64(constants.ORDERPAYSTATUSUNPAIDDEPOSIT) {
|
||||||
|
errorCode = *basic.CodeErrOrderCreatePrePaymentInfoNoFound
|
||||||
|
err = errors.New("order pay status is not unPaidDeposit")
|
||||||
|
logx.Errorf("create prePayment deposit failed, err: %v", err)
|
||||||
|
return &CreatePrePaymentByDepositRes{
|
||||||
|
ErrorCode: errorCode,
|
||||||
|
}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 是否超时支付
|
||||||
|
ntime := time.Now().UTC()
|
||||||
|
ctime := *order.Ctime
|
||||||
|
ctimeTimeOut := ctime.Add(30 * time.Minute).UTC().Unix()
|
||||||
|
ntimeTimeOut := ntime.Unix()
|
||||||
|
if ctimeTimeOut == ntimeTimeOut {
|
||||||
|
errorCode = *basic.CodeErrOrderCreatePrePaymentTimeout
|
||||||
|
err = errors.New("order pay timeout")
|
||||||
|
logx.Errorf("create prePayment deposit failed, err: %v", err)
|
||||||
|
return &CreatePrePaymentByDepositRes{
|
||||||
|
ErrorCode: errorCode,
|
||||||
|
}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ress, err := d.OrderDetailHandler(ctx, &order)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorf("create prePayment deposit failed DetailOrderDetailHandler, err: %v", err)
|
||||||
|
errorCode = *basic.CodeServiceErr
|
||||||
|
return &CreatePrePaymentByDepositRes{
|
||||||
|
ErrorCode: errorCode,
|
||||||
|
}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var uOrderDetail = make(map[string]interface{})
|
||||||
|
|
||||||
|
var orderAddress *gmodel.OrderAddress
|
||||||
|
if in.DeliveryAddress != nil {
|
||||||
|
if in.DeliveryAddress.Name != ress.OrderDetailOriginal.DeliveryAddress.Name || in.DeliveryAddress.Address != ress.OrderDetail.DeliveryAddress.Address || in.DeliveryAddress.Mobile != ress.OrderDetail.DeliveryAddress.Mobile {
|
||||||
|
orderAddress = &gmodel.OrderAddress{
|
||||||
|
Name: in.DeliveryAddress.Name,
|
||||||
|
Mobile: in.DeliveryAddress.Mobile,
|
||||||
|
Address: in.DeliveryAddress.Address,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var sql string = fmt.Sprintf(", `utime` = '%s'", ntime)
|
||||||
|
// 是否更新
|
||||||
|
if in.DeliveryMethod != *order.DeliveryMethod {
|
||||||
|
sql = sql + fmt.Sprintf(",`delivery_method` = %d", in.DeliveryMethod)
|
||||||
|
if in.DeliveryMethod == constants.DELIVERYMETHODDIRECTMAIL {
|
||||||
|
uOrderDetail["delivery_address"] = orderAddress
|
||||||
|
} else {
|
||||||
|
uOrderDetail["delivery_address"] = nil
|
||||||
|
}
|
||||||
|
uOrderDetail["order_info"] = struct {
|
||||||
|
DeliveryMethod int64 `json:"delivery_method"`
|
||||||
|
Utime *time.Time `json:"utime"`
|
||||||
|
}{
|
||||||
|
DeliveryMethod: in.DeliveryMethod,
|
||||||
|
Utime: &ntime,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if in.DeliveryMethod == constants.DELIVERYMETHODDIRECTMAIL {
|
||||||
|
// 更新收货地址
|
||||||
|
if orderAddress != nil {
|
||||||
|
uOrderDetail["delivery_address"] = orderAddress
|
||||||
|
uOrderDetail["order_info"] = struct {
|
||||||
|
DeliveryMethod int64 `json:"delivery_method"`
|
||||||
|
Utime *time.Time `json:"utime"`
|
||||||
|
}{
|
||||||
|
DeliveryMethod: in.DeliveryMethod,
|
||||||
|
Utime: &ntime,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(uOrderDetail) > 0 {
|
||||||
|
err = fssql.MetadataOrderPATCH(d.MysqlConn, sql, in.OrderSn, gmodel.FsOrder{}, uOrderDetail, "id = ?", order.Id)
|
||||||
|
if err != nil {
|
||||||
|
errorCode = *basic.CodeServiceErr
|
||||||
|
logx.Errorf("create prePayment deposit failed MetadataOrderPATCH, err: %v", err)
|
||||||
|
return &CreatePrePaymentByDepositRes{
|
||||||
|
ErrorCode: errorCode,
|
||||||
|
}, result.Error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ress.OrderDetail.OrderInfo.Utime = &ntime
|
||||||
|
ress.OrderDetail.OrderInfo.DeliveryMethod = in.DeliveryMethod
|
||||||
|
ress.OrderDetail.DeliveryAddress = orderAddress
|
||||||
|
|
||||||
|
// 支付初始化
|
||||||
|
amount := int64(ress.OrderDetailOriginal.OrderAmount.Deposit.PayAmount.Current.CurrentAmount.(float64) / float64(10))
|
||||||
|
payConfig := &pay.Config{}
|
||||||
|
payConfig.Stripe.PayType = "intent"
|
||||||
|
payConfig.Stripe.Key = in.StripeKey
|
||||||
|
var generatePrepaymentReq = &pay.GeneratePrepaymentReq{
|
||||||
|
OrderSn: in.OrderSn,
|
||||||
|
ProductName: "支付标题",
|
||||||
|
Amount: amount,
|
||||||
|
Currency: "usd",
|
||||||
|
Quantity: 1,
|
||||||
|
ProductDescription: "支付描述",
|
||||||
|
}
|
||||||
|
payDriver := pay.NewPayDriver(1, payConfig)
|
||||||
|
|
||||||
|
prepaymentRes, err := payDriver.GeneratePrepayment(generatePrepaymentReq)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorf("create prePayment deposit failed GeneratePrepayment, err: %v", err)
|
||||||
|
errorCode = *basic.CodeServiceErr
|
||||||
|
return &CreatePrePaymentByDepositRes{
|
||||||
|
ErrorCode: errorCode,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
return &CreatePrePaymentByDepositRes{
|
||||||
|
OrderDetail: ress.OrderDetail,
|
||||||
|
OrderPay: OrderPay{
|
||||||
|
ClientSecret: prepaymentRes.ClientSecret,
|
||||||
|
Country: in.Country,
|
||||||
|
Currency: in.Currency,
|
||||||
|
Method: payConfig.Stripe.PayType,
|
||||||
|
OrderSn: in.OrderSn,
|
||||||
|
PayStage: 1,
|
||||||
|
Total: OrderPayTotal{
|
||||||
|
Amount: amount,
|
||||||
|
Label: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 列表
|
||||||
|
func (d *defaultOrder) List(ctx context.Context, in *ListReq) (res *ListRes, err error) {
|
||||||
|
var orderList []gmodel.FsOrder
|
||||||
|
model := d.MysqlConn.Model(&gmodel.FsOrder{}).Where("is_del = ?", 0)
|
||||||
|
if in.UserId != 0 {
|
||||||
|
model.Where("user_id = ?", in.UserId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Where("pay_status > ?", 0)
|
||||||
|
if in.DeliveryMethod != 0 {
|
||||||
|
model.Where("delivery_method = ?", in.DeliveryMethod)
|
||||||
|
}
|
||||||
|
if in.OrderCycle != "" {
|
||||||
|
// 下单时间
|
||||||
|
switch in.OrderCycle {
|
||||||
|
case "within_one_month":
|
||||||
|
model.Where("ctime >?", time.Now().UTC().AddDate(0, -1, 0).Unix())
|
||||||
|
case "within_three_month":
|
||||||
|
model.Where("ctime >?", time.Now().UTC().AddDate(0, -3, 0).Unix())
|
||||||
|
case "within_six_month":
|
||||||
|
model.Where("ctime >?", time.Now().UTC().AddDate(0, -6, 0).Unix())
|
||||||
|
case "within_one_year":
|
||||||
|
model.Where("ctime >?", time.Now().UTC().AddDate(-1, 0, 0).Unix())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var count int64
|
||||||
|
resultCount := model.Count(&count)
|
||||||
|
if resultCount.Error != nil {
|
||||||
|
logx.Errorf("order count failed, err: %v", err)
|
||||||
|
return nil, resultCount.Error
|
||||||
|
}
|
||||||
|
var orderDetailList []gmodel.OrderDetail
|
||||||
|
if count > 0 {
|
||||||
|
m := model.Scopes(handlers.Paginate(&in.CurrentPage, &in.PerPage))
|
||||||
|
result := m.Find(&orderList)
|
||||||
|
if result.Error != nil {
|
||||||
|
logx.Errorf("order list failed, err: %v", err)
|
||||||
return nil, result.Error
|
return nil, result.Error
|
||||||
}
|
}
|
||||||
|
for _, order := range orderList {
|
||||||
ress, err := d.OrderDetailHandler(ctx, &order)
|
ress, err := d.OrderDetailHandler(ctx, &order)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &DetailRes{
|
orderDetailList = append(orderDetailList, ress.OrderDetail)
|
||||||
ress.OrderDetail,
|
}
|
||||||
|
} else {
|
||||||
|
orderDetailList = make([]gmodel.OrderDetail, 0)
|
||||||
|
}
|
||||||
|
return &ListRes{
|
||||||
|
OrderDetailList: orderDetailList,
|
||||||
|
Meta: map[string]int64{
|
||||||
|
"total_count": count,
|
||||||
|
"page_count": count / in.PerPage,
|
||||||
|
"current_page": in.CurrentPage,
|
||||||
|
"per_page": in.PerPage,
|
||||||
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *defaultOrder) OrderDetailHandler(ctx context.Context, orderInfo *gmodel.FsOrder) (res *DetailRes, err error) {
|
// 详情
|
||||||
var orderDetail gmodel.OrderDetail
|
func (d *defaultOrder) Detail(ctx context.Context, in *DetailReq) (res *DetailRes, err error) {
|
||||||
|
var errorCode basic.StatusResponse
|
||||||
err = json.Unmarshal(*orderInfo.Metadata, &orderDetail)
|
var order gmodel.FsOrder
|
||||||
if err != nil {
|
model := d.MysqlConn.Where("is_del = ?", 0)
|
||||||
logx.Errorf("detail handler unmarshal metadata failed, err: %v", err)
|
if in.UserId != 0 {
|
||||||
return nil, err
|
model.Where("user_id = ?", in.UserId)
|
||||||
}
|
}
|
||||||
for orderProductKey, orderProduct := range orderDetail.OrderProduct {
|
if in.OrderSn != "" {
|
||||||
orderDetail.OrderProduct[orderProductKey].TotalPrice = order.GetAmountInfoFormat(&orderProduct.TotalPrice)
|
model.Where("order_sn = ?", in.OrderSn)
|
||||||
orderDetail.OrderProduct[orderProductKey].ItemPrice = order.GetAmountInfoFormat(&orderProduct.ItemPrice)
|
|
||||||
orderDetail.OrderProduct[orderProductKey].ShoppingCartSnapshot = nil
|
|
||||||
orderDetail.OrderProduct[orderProductKey].ProductSnapshot = nil
|
|
||||||
}
|
}
|
||||||
orderDetail.OrderInfo.StatusLink = order.GetOrderStatusLinkUser(orderDetail.OrderInfo.DeliveryMethod, orderDetail.OrderInfo.StatusLink)
|
result := model.Take(&order)
|
||||||
orderDetail.OrderAmount.Deposit.PayAmount = order.GetAmountInfoFormat(&orderDetail.OrderAmount.Deposit.PayAmount)
|
if result.Error != nil {
|
||||||
orderDetail.OrderAmount.RemainingBalance.PayAmount = order.GetAmountInfoFormat(&orderDetail.OrderAmount.RemainingBalance.PayAmount)
|
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
||||||
orderDetail.OrderAmount.Subtotal = order.GetAmountInfoFormat(&orderDetail.OrderAmount.Subtotal)
|
errorCode = *basic.CodeErrOrderCreatePrePaymentInfoNoFound
|
||||||
orderDetail.OrderAmount.Total = order.GetAmountInfoFormat(&orderDetail.OrderAmount.Total)
|
} else {
|
||||||
|
errorCode = *basic.CodeServiceErr
|
||||||
|
}
|
||||||
|
logx.Errorf("order detail failed, err: %v", err)
|
||||||
return &DetailRes{
|
return &DetailRes{
|
||||||
OrderDetail: orderDetail,
|
ErrorCode: errorCode,
|
||||||
|
}, result.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// 是否超时支付
|
||||||
|
ctime := *order.Ctime
|
||||||
|
ctimeTimeOut := ctime.Add(30 * time.Minute).UTC().Unix()
|
||||||
|
ntimeTimeOut := time.Now().UTC().Unix()
|
||||||
|
if ctimeTimeOut < ntimeTimeOut {
|
||||||
|
errorCode = *basic.CodeErrOrderCreatePrePaymentTimeout
|
||||||
|
err = errors.New("order pay timeout")
|
||||||
|
logx.Errorf("order detail failed, err: %v", err)
|
||||||
|
return &DetailRes{
|
||||||
|
ErrorCode: errorCode,
|
||||||
|
}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ress, err := d.OrderDetailHandler(ctx, &order)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorf("order detail failed, err: %v", err)
|
||||||
|
errorCode = *basic.CodeServiceErr
|
||||||
|
return &DetailRes{
|
||||||
|
ErrorCode: errorCode,
|
||||||
|
}, err
|
||||||
|
}
|
||||||
|
return &DetailRes{
|
||||||
|
ErrorCode: errorCode,
|
||||||
|
OrderDetail: ress.OrderDetail,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,6 +676,7 @@ func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRe
|
||||||
OrderInfo: orderInfo,
|
OrderInfo: orderInfo,
|
||||||
OrderProduct: orderProductList,
|
OrderProduct: orderProductList,
|
||||||
PayStatus: payStatus,
|
PayStatus: payStatus,
|
||||||
|
PayTimeout: 30 * time.Minute,
|
||||||
}
|
}
|
||||||
// 数据库操作
|
// 数据库操作
|
||||||
|
|
||||||
|
@ -419,7 +700,7 @@ func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRe
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Errorf("create order failed, err: %v", err)
|
logx.Errorf("order create order failed, err: %v", err)
|
||||||
|
|
||||||
if errorCode.Code == 0 {
|
if errorCode.Code == 0 {
|
||||||
errorCode.Code = basic.CodeApiErr.Code
|
errorCode.Code = basic.CodeApiErr.Code
|
||||||
|
@ -435,3 +716,32 @@ func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRe
|
||||||
ErrorCode: errorCode,
|
ErrorCode: errorCode,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 详情处理
|
||||||
|
func (d *defaultOrder) OrderDetailHandler(ctx context.Context, orderInfo *gmodel.FsOrder) (res *DetailRes, err error) {
|
||||||
|
var orderDetail gmodel.OrderDetail
|
||||||
|
|
||||||
|
err = json.Unmarshal(*orderInfo.Metadata, &orderDetail)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorf("order detail handler unmarshal metadata failed, err: %v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
orderDetailOriginal := orderDetail
|
||||||
|
for orderProductKey, orderProduct := range orderDetail.OrderProduct {
|
||||||
|
orderDetail.OrderProduct[orderProductKey].TotalPrice = order.GetAmountInfoFormat(&orderProduct.TotalPrice)
|
||||||
|
orderDetail.OrderProduct[orderProductKey].ItemPrice = order.GetAmountInfoFormat(&orderProduct.ItemPrice)
|
||||||
|
orderDetail.OrderProduct[orderProductKey].ShoppingCartSnapshot = nil
|
||||||
|
orderDetail.OrderProduct[orderProductKey].ProductSnapshot = nil
|
||||||
|
}
|
||||||
|
orderDetail.OrderInfo.StatusLink = order.GetOrderStatusLinkUser(orderDetail.OrderInfo.DeliveryMethod, orderDetail.OrderInfo.StatusLink)
|
||||||
|
orderDetail.OrderAmount.Deposit.PayAmount = order.GetAmountInfoFormat(&orderDetail.OrderAmount.Deposit.PayAmount)
|
||||||
|
orderDetail.OrderAmount.RemainingBalance.PayAmount = order.GetAmountInfoFormat(&orderDetail.OrderAmount.RemainingBalance.PayAmount)
|
||||||
|
orderDetail.OrderAmount.Subtotal = order.GetAmountInfoFormat(&orderDetail.OrderAmount.Subtotal)
|
||||||
|
orderDetail.OrderAmount.Total = order.GetAmountInfoFormat(&orderDetail.OrderAmount.Total)
|
||||||
|
orderDetail.PayTimeout = time.Duration(orderDetail.OrderInfo.Ctime.Add(orderDetail.PayTimeout).UTC().Unix() - time.Now().UTC().Unix())
|
||||||
|
|
||||||
|
return &DetailRes{
|
||||||
|
OrderDetail: orderDetail,
|
||||||
|
OrderDetailOriginal: orderDetailOriginal,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
|
@ -106,6 +106,10 @@ var (
|
||||||
CodeErrOrderCreatProductAbsent = &StatusResponse{5303, "create order failed, product is absent"} // 订单创建失败,商品不存在
|
CodeErrOrderCreatProductAbsent = &StatusResponse{5303, "create order failed, product is absent"} // 订单创建失败,商品不存在
|
||||||
CodeErrOrderCreatProductPriceAbsent = &StatusResponse{5304, "create order failed, price of product is absent"} // 订单创建失败,商品价格不存在
|
CodeErrOrderCreatProductPriceAbsent = &StatusResponse{5304, "create order failed, price of product is absent"} // 订单创建失败,商品价格不存在
|
||||||
CodeErrOrderCreatProductAccessoryAbsent = &StatusResponse{5305, "create order failed, accessory of product is absent"} // 订单创建失败,商品配件不存在
|
CodeErrOrderCreatProductAccessoryAbsent = &StatusResponse{5305, "create order failed, accessory of product is absent"} // 订单创建失败,商品配件不存在
|
||||||
|
CodeErrOrderCreatePrePaymentParam = &StatusResponse{5306, "create payment failed, the shipping address is illegal"} // 订单创建失败,商品配件不存在
|
||||||
|
CodeErrOrderCreatePrePaymentInfoNoFound = &StatusResponse{5307, "create payment failed, order info not found"}
|
||||||
|
CodeErrOrderCreatePrePaymentPaidDeposit = &StatusResponse{5308, "create payment failed, order is paid"}
|
||||||
|
CodeErrOrderCreatePrePaymentTimeout = &StatusResponse{5309, "create payment failed, timeout"}
|
||||||
)
|
)
|
||||||
|
|
||||||
type Response struct {
|
type Response struct {
|
||||||
|
|
|
@ -58,7 +58,7 @@ func MetadataModulePATCH(tx *gorm.DB, module string, tableStructPointer any, upd
|
||||||
WHEN metadata IS NULL THEN ?
|
WHEN metadata IS NULL THEN ?
|
||||||
ELSE JSON_MERGE_PATCH(metadata, ?)
|
ELSE JSON_MERGE_PATCH(metadata, ?)
|
||||||
END
|
END
|
||||||
WHERE module = '%s' and %s;`
|
WHERE order_sn = '%s' and %s;`
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
var metadata []byte
|
var metadata []byte
|
||||||
|
@ -147,3 +147,46 @@ func MetadataResourcePATCH(tx *gorm.DB, rid string, updateMetadata any, values .
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MetadataOrderPATCH(tx *gorm.DB, sql string, orderSn string, tableStructPointer any, updateMetadata any, WhereKeysCond string, values ...any) error {
|
||||||
|
stype := reflect.TypeOf(tableStructPointer)
|
||||||
|
if stype.Kind() == reflect.Pointer {
|
||||||
|
stype = stype.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
updatesql := `UPDATE %s
|
||||||
|
SET metadata = CASE
|
||||||
|
WHEN metadata IS NULL THEN ?
|
||||||
|
ELSE JSON_MERGE_PATCH(metadata, ?)
|
||||||
|
END%s
|
||||||
|
WHERE order_sn = '%s' and %s;`
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var metadata []byte
|
||||||
|
|
||||||
|
switch mdata := updateMetadata.(type) {
|
||||||
|
case []byte:
|
||||||
|
metadata = mdata
|
||||||
|
case string:
|
||||||
|
metadata = []byte(mdata)
|
||||||
|
default:
|
||||||
|
metadata, err = json.Marshal(updateMetadata)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var args []any
|
||||||
|
|
||||||
|
args = append(args, metadata, metadata)
|
||||||
|
args = append(args, values...)
|
||||||
|
|
||||||
|
updatesql = fmt.Sprintf(updatesql, tx.NamingStrategy.TableName(stype.Name()), sql, orderSn, WhereKeysCond)
|
||||||
|
// logx.Error(updatesql)
|
||||||
|
err = tx.Exec(updatesql, args...).Error
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -11,9 +11,9 @@ type Config struct {
|
||||||
func NewPayDriver(PayMethod int64, config *Config) Pay {
|
func NewPayDriver(PayMethod int64, config *Config) Pay {
|
||||||
switch PayMethod {
|
switch PayMethod {
|
||||||
case int64(constants.PAYMETHOD_STRIPE):
|
case int64(constants.PAYMETHOD_STRIPE):
|
||||||
return &Stripe{Key: config.Stripe.Key}
|
return &Stripe{Key: config.Stripe.Key, PayType: config.Stripe.PayType}
|
||||||
default:
|
default:
|
||||||
return &Stripe{Key: config.Stripe.Key}
|
return &Stripe{Key: config.Stripe.Key, PayType: config.Stripe.PayType}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,9 +81,6 @@ func (stripePay *Stripe) GeneratePrepayment(req *GeneratePrepaymentReq) (res *Ge
|
||||||
params := &stripe.PaymentIntentParams{
|
params := &stripe.PaymentIntentParams{
|
||||||
Amount: stripe.Int64(req.Amount),
|
Amount: stripe.Int64(req.Amount),
|
||||||
Currency: stripe.String(string(req.Currency)),
|
Currency: stripe.String(string(req.Currency)),
|
||||||
AutomaticPaymentMethods: &stripe.PaymentIntentAutomaticPaymentMethodsParams{
|
|
||||||
Enabled: stripe.Bool(true),
|
|
||||||
},
|
|
||||||
PaymentMethodTypes: stripe.StringSlice([]string{
|
PaymentMethodTypes: stripe.StringSlice([]string{
|
||||||
"card",
|
"card",
|
||||||
// "ideal",
|
// "ideal",
|
||||||
|
|
Loading…
Reference in New Issue
Block a user