fix:支付
This commit is contained in:
@@ -15,6 +15,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/stripe/stripe-go/v74"
|
||||
"github.com/zeromicro/go-zero/core/logc"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -40,6 +42,16 @@ type (
|
||||
List(ctx context.Context, in *ListReq) (res *ListRes, err error)
|
||||
// 详情
|
||||
Detail(ctx context.Context, in *DetailReq) (res *DetailRes, err error)
|
||||
// 支付成功
|
||||
PaymentSuccessful(ctx context.Context, in *PaymentSuccessfulReq) (res *PaymentSuccessfulRes, err error)
|
||||
}
|
||||
|
||||
PayInfo struct {
|
||||
PayMethod int64 `json:"pay_method"` // 交易方式
|
||||
PayTime time.Time `json:"pay_time"` // 支付时间
|
||||
Status gmodel.PayStatus `json:"status"` // 当前状态
|
||||
StatusLink []gmodel.PayStatus `json:"status_link"` // 状态链路
|
||||
TradeNo string `json:"trade_no"` // 支付交易号
|
||||
}
|
||||
|
||||
OrderAddress struct {
|
||||
@@ -63,6 +75,16 @@ type (
|
||||
Amount int64 `json:"amount"` // 金额
|
||||
Label string `json:"label"` // 标签
|
||||
}
|
||||
|
||||
/* 支付成功 */
|
||||
PaymentSuccessfulReq struct {
|
||||
EventId string
|
||||
PaymentMethod int64
|
||||
PaymentIntent *stripe.PaymentIntent
|
||||
}
|
||||
PaymentSuccessfulRes struct{}
|
||||
/* 支付成功 */
|
||||
|
||||
/* 预支付--定金 */
|
||||
CreatePrePaymentByDepositReq struct {
|
||||
StripeKey string `json:"stripe_key"`
|
||||
@@ -139,6 +161,175 @@ type (
|
||||
/* 列表 */
|
||||
)
|
||||
|
||||
// 支付成功
|
||||
func (d *defaultOrder) PaymentSuccessful(ctx context.Context, in *PaymentSuccessfulReq) (res *PaymentSuccessfulRes, err error) {
|
||||
var orderSn string
|
||||
var payStage string
|
||||
var ok bool
|
||||
var card string
|
||||
var brand string
|
||||
var country string
|
||||
var currency string
|
||||
var tradeSn string
|
||||
var payAmount int64
|
||||
var payTitle string
|
||||
var payTime time.Time
|
||||
if in.PaymentIntent != nil {
|
||||
paymentIntent := in.PaymentIntent
|
||||
orderSn, ok = paymentIntent.Metadata["order_sn"]
|
||||
if !ok || orderSn == "" {
|
||||
err = errors.New("order_sn is empty")
|
||||
logc.Errorf(ctx, "PaymentSuccessful failed param, eventId:%s,err:%v", in.EventId, err)
|
||||
return &PaymentSuccessfulRes{}, err
|
||||
}
|
||||
payStage, ok = paymentIntent.Metadata["pay_stage"]
|
||||
if !ok || payStage == "" {
|
||||
err = errors.New("pay_stage is empty")
|
||||
logc.Errorf(ctx, "PaymentSuccessful failed param, eventId:%s,err:%v", in.EventId, err)
|
||||
return &PaymentSuccessfulRes{}, err
|
||||
}
|
||||
country, ok = paymentIntent.Metadata["country"]
|
||||
if !ok || country == "" {
|
||||
err = errors.New("country is empty")
|
||||
logc.Errorf(ctx, "PaymentSuccessful failed param, eventId:%s,err:%v", in.EventId, err)
|
||||
return &PaymentSuccessfulRes{}, err
|
||||
}
|
||||
if paymentIntent.LatestCharge.PaymentMethodDetails != nil {
|
||||
if paymentIntent.LatestCharge.PaymentMethodDetails.Card != nil {
|
||||
if paymentIntent.LatestCharge.PaymentMethodDetails.Card.Last4 != "" {
|
||||
card = paymentIntent.LatestCharge.PaymentMethodDetails.Card.Last4
|
||||
}
|
||||
if paymentIntent.LatestCharge.PaymentMethodDetails.Card.Brand != "" {
|
||||
brand = string(paymentIntent.LatestCharge.PaymentMethodDetails.Card.Brand)
|
||||
}
|
||||
}
|
||||
}
|
||||
if paymentIntent.Currency != "" {
|
||||
currency = string(paymentIntent.Currency)
|
||||
}
|
||||
tradeSn = paymentIntent.ID
|
||||
payAmount = paymentIntent.Amount
|
||||
payTitle = paymentIntent.Description
|
||||
payTime = time.Unix(paymentIntent.Created, 0)
|
||||
}
|
||||
err = d.MysqlConn.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
var orderInfo gmodel.FsOrder
|
||||
result := tx.Where("is_del = ?", 0).Where("order_sn = ?", orderSn).Take(&orderInfo)
|
||||
err = result.Error
|
||||
if err != nil {
|
||||
logx.Errorf("PaymentSuccessful failed order Take, eventId:%s,err: %v", in.EventId, err)
|
||||
return err
|
||||
}
|
||||
ress, err := d.OrderDetailHandler(ctx, &orderInfo, 0)
|
||||
if err != nil {
|
||||
logx.Errorf("PaymentSuccessful failed DetailOrderDetailHandler,eventId:%s, err: %v", in.EventId, err)
|
||||
return err
|
||||
}
|
||||
var ntime = time.Now().UTC()
|
||||
if (payStage == "deposit" && *orderInfo.PayStatus == int64(constants.ORDERPAYSTATUSUNPAIDDEPOSIT)) || (payStage == "remaining_balance" && *orderInfo.PayStatus == int64(constants.ORDERPAYSTATUSPAIDDEPOSIT)) {
|
||||
var payStatus = int64(constants.PAYSTATUSPAID)
|
||||
var payStageInt int64
|
||||
var orderPayStatusCode constants.OrderPayStatusCode
|
||||
// 订单状态--当前
|
||||
var status gmodel.OrderStatus
|
||||
var statusLink []gmodel.OrderStatus
|
||||
var uOrderDetail = make(map[string]interface{})
|
||||
var payInfo PayInfo
|
||||
payInfo.PayMethod = in.PaymentMethod
|
||||
payInfo.PayTime = payTime
|
||||
payInfo.TradeNo = tradeSn
|
||||
|
||||
if payStage == "deposit" {
|
||||
payStageInt = 1
|
||||
orderPayStatusCode = constants.ORDERPAYSTATUSPAIDDEPOSIT
|
||||
status = gmodel.OrderStatus{
|
||||
Ctime: &ntime,
|
||||
Utime: &ntime,
|
||||
StatusCode: constants.ORDERSTATUSDIRECTMAILORDERED,
|
||||
StatusTitle: constants.OrderStatusMessage[constants.ORDERSTATUSDIRECTMAILORDERED],
|
||||
}
|
||||
statusLink = order.UpdateOrderStatusLink(ress.OrderDetailOriginal.OrderInfo.StatusLink, gmodel.OrderStatus{
|
||||
Utime: &ntime,
|
||||
StatusCode: constants.ORDERSTATUSDIRECTMAILORDERED,
|
||||
StatusTitle: constants.OrderStatusMessage[constants.ORDERSTATUSDIRECTMAILORDERED],
|
||||
})
|
||||
payInfo.Status = gmodel.PayStatus{
|
||||
StatusCode: int64(constants.PAYSTATUSPAID),
|
||||
StatusTitle: constants.PayStatusMessage[constants.PAYSTATUSPAID],
|
||||
}
|
||||
payInfo.StatusLink = append(ress.OrderDetail.OrderAmount.Deposit.StatusLink, payInfo.Status)
|
||||
uOrderDetail["order_amount"] = struct {
|
||||
Deposit PayInfo `json:"deposit"`
|
||||
}{
|
||||
Deposit: payInfo,
|
||||
}
|
||||
}
|
||||
if payStage == "remaining_balance" {
|
||||
payStageInt = 2
|
||||
orderPayStatusCode = constants.ORDERPAYSTATUSPAIDDREMAINING
|
||||
status = gmodel.OrderStatus{
|
||||
Ctime: &ntime,
|
||||
Utime: &ntime,
|
||||
StatusCode: constants.ORDERSTATUSCLOUDSTOREORDERED,
|
||||
StatusTitle: constants.OrderStatusMessage[constants.ORDERSTATUSCLOUDSTOREORDERED],
|
||||
}
|
||||
statusLink = order.UpdateOrderStatusLink(ress.OrderDetailOriginal.OrderInfo.StatusLink, gmodel.OrderStatus{
|
||||
Utime: &ntime,
|
||||
StatusCode: constants.ORDERSTATUSCLOUDSTOREORDERED,
|
||||
StatusTitle: constants.OrderStatusMessage[constants.ORDERSTATUSCLOUDSTOREORDERED],
|
||||
})
|
||||
payInfo.StatusLink = append(ress.OrderDetail.OrderAmount.RemainingBalance.StatusLink, payInfo.Status)
|
||||
uOrderDetail["order_amount"] = struct {
|
||||
RemainingBalance PayInfo `json:"remaining_balance"`
|
||||
}{
|
||||
RemainingBalance: payInfo,
|
||||
}
|
||||
}
|
||||
|
||||
// 新增交易信息
|
||||
tx.Create(&gmodel.FsOrderTrade{
|
||||
UserId: orderInfo.UserId,
|
||||
OrderSn: &orderSn,
|
||||
OrderSource: orderInfo.OrderSource,
|
||||
TradeSn: &tradeSn,
|
||||
PayAmount: &payAmount,
|
||||
PayStatus: &payStatus,
|
||||
PaymentMethod: &in.PaymentMethod,
|
||||
PayStage: &payStageInt,
|
||||
CardSn: &card,
|
||||
CardBrand: &brand,
|
||||
Country: &country,
|
||||
Currency: ¤cy,
|
||||
Ctime: &ntime,
|
||||
Utime: &ntime,
|
||||
PayTitle: &payTitle,
|
||||
})
|
||||
// 更新订单信息
|
||||
var sql string = fmt.Sprintf(", `utime` = '%s'", ntime)
|
||||
uOrderDetail["pay_status"] = orderPayStatusCode
|
||||
uOrderDetail["order_info"] = struct {
|
||||
Utime *time.Time `json:"utime"`
|
||||
Status gmodel.OrderStatus `json:"status"`
|
||||
StatusLink []gmodel.OrderStatus `json:"status_link"`
|
||||
}{
|
||||
Utime: &ntime,
|
||||
Status: status,
|
||||
StatusLink: statusLink,
|
||||
}
|
||||
if len(uOrderDetail) > 0 {
|
||||
err = fssql.MetadataOrderPATCH(d.MysqlConn, sql, orderSn, gmodel.FsOrder{}, uOrderDetail, "id = ?", orderInfo.Id)
|
||||
if err != nil {
|
||||
logx.Errorf("PaymentSuccessful failed MetadataOrderPATCH,eventId:%s, err: %v", in.EventId, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return &PaymentSuccessfulRes{}, nil
|
||||
}
|
||||
|
||||
// 预支付--尾款
|
||||
func (d *defaultOrder) CreatePrePaymentByBalance(ctx context.Context, in *CreatePrePaymentByBalanceReq) (res *CreatePrePaymentByBalanceRes, err error) {
|
||||
var errorCode basic.StatusResponse
|
||||
@@ -172,7 +363,7 @@ func (d *defaultOrder) CreatePrePaymentByBalance(ctx context.Context, in *Create
|
||||
}, err
|
||||
}
|
||||
|
||||
ress, err := d.OrderDetailHandler(ctx, &order)
|
||||
ress, err := d.OrderDetailHandler(ctx, &order, 1)
|
||||
if err != nil {
|
||||
logx.Errorf("create prePayment balance failed DetailOrderDetailHandler, err: %v", err)
|
||||
errorCode = *basic.CodeServiceErr
|
||||
@@ -185,8 +376,13 @@ func (d *defaultOrder) CreatePrePaymentByBalance(ctx context.Context, in *Create
|
||||
payConfig := &pay.Config{}
|
||||
payConfig.Stripe.PayType = "intent"
|
||||
payConfig.Stripe.Key = in.StripeKey
|
||||
var metadata = make(map[string]string, 2)
|
||||
metadata["model"] = "product_order"
|
||||
metadata["order_sn"] = in.OrderSn
|
||||
metadata["pay_stage"] = "remaining_balance"
|
||||
metadata["country"] = in.Country
|
||||
var generatePrepaymentReq = &pay.GeneratePrepaymentReq{
|
||||
OrderSn: in.OrderSn,
|
||||
Metadata: metadata,
|
||||
ProductName: "支付尾款后期统一调整",
|
||||
Amount: amount,
|
||||
Currency: "usd",
|
||||
@@ -270,7 +466,7 @@ func (d *defaultOrder) CreatePrePaymentByDeposit(ctx context.Context, in *Create
|
||||
}, err
|
||||
}
|
||||
|
||||
ress, err := d.OrderDetailHandler(ctx, &order)
|
||||
ress, err := d.OrderDetailHandler(ctx, &order, 0)
|
||||
if err != nil {
|
||||
logx.Errorf("create prePayment deposit failed DetailOrderDetailHandler, err: %v", err)
|
||||
errorCode = *basic.CodeServiceErr
|
||||
@@ -342,8 +538,13 @@ func (d *defaultOrder) CreatePrePaymentByDeposit(ctx context.Context, in *Create
|
||||
payConfig := &pay.Config{}
|
||||
payConfig.Stripe.PayType = "intent"
|
||||
payConfig.Stripe.Key = in.StripeKey
|
||||
var metadata = make(map[string]string, 2)
|
||||
metadata["model"] = "product_order"
|
||||
metadata["order_sn"] = in.OrderSn
|
||||
metadata["pay_stage"] = "deposit"
|
||||
metadata["country"] = in.Country
|
||||
var generatePrepaymentReq = &pay.GeneratePrepaymentReq{
|
||||
OrderSn: in.OrderSn,
|
||||
Metadata: metadata,
|
||||
ProductName: "支付首款",
|
||||
Amount: amount,
|
||||
Currency: "usd",
|
||||
@@ -417,7 +618,7 @@ func (d *defaultOrder) List(ctx context.Context, in *ListReq) (res *ListRes, err
|
||||
return nil, result.Error
|
||||
}
|
||||
for _, order := range orderList {
|
||||
ress, err := d.OrderDetailHandler(ctx, &order)
|
||||
ress, err := d.OrderDetailHandler(ctx, &order, 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -474,7 +675,7 @@ func (d *defaultOrder) Detail(ctx context.Context, in *DetailReq) (res *DetailRe
|
||||
}, err
|
||||
}
|
||||
|
||||
ress, err := d.OrderDetailHandler(ctx, &order)
|
||||
ress, err := d.OrderDetailHandler(ctx, &order, 1)
|
||||
if err != nil {
|
||||
logx.Errorf("order detail failed, err: %v", err)
|
||||
errorCode = *basic.CodeServiceErr
|
||||
@@ -718,6 +919,7 @@ func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRe
|
||||
StatusCode: int64(constants.PAYSTATUSUNPAID),
|
||||
StatusTitle: constants.PayStatusMessage[constants.PAYSTATUSUNPAID],
|
||||
},
|
||||
StatusLink: make([]gmodel.PayStatus, 0),
|
||||
PayAmount: order.GetAmountInfo(order.GetAmountInfoReq{
|
||||
ExchangeRate: in.ExchangeRate,
|
||||
Initiate: depositInt,
|
||||
@@ -734,6 +936,7 @@ func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRe
|
||||
StatusCode: int64(constants.PAYSTATUSUNPAID),
|
||||
StatusTitle: constants.PayStatusMessage[constants.PAYSTATUSUNPAID],
|
||||
},
|
||||
StatusLink: make([]gmodel.PayStatus, 0),
|
||||
PayAmount: order.GetAmountInfo(order.GetAmountInfoReq{
|
||||
ExchangeRate: in.ExchangeRate,
|
||||
Initiate: remainingBalanceInt,
|
||||
@@ -817,7 +1020,7 @@ func (d *defaultOrder) Create(ctx context.Context, in *CreateReq) (res *CreateRe
|
||||
}
|
||||
|
||||
// 详情处理
|
||||
func (d *defaultOrder) OrderDetailHandler(ctx context.Context, orderInfo *gmodel.FsOrder) (res *DetailRes, err error) {
|
||||
func (d *defaultOrder) OrderDetailHandler(ctx context.Context, orderInfo *gmodel.FsOrder, original int64) (res *DetailRes, err error) {
|
||||
var orderDetail gmodel.OrderDetail
|
||||
|
||||
err = json.Unmarshal(*orderInfo.Metadata, &orderDetail)
|
||||
@@ -826,18 +1029,21 @@ func (d *defaultOrder) OrderDetailHandler(ctx context.Context, orderInfo *gmodel
|
||||
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
|
||||
if original == 1 {
|
||||
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())
|
||||
|
||||
}
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user