diff --git a/constants/order.go b/constants/order.go
index 79fa6497..a22fa9f3 100644
--- a/constants/order.go
+++ b/constants/order.go
@@ -126,7 +126,8 @@ type Day int64
 
 // 订单取消时间
 const (
-	CANCLE_ORDER_EXPIRE Day = 48 * 3600
+	CANCLE_ORDER_EXPIRE     Day = 48 * 3600
+	CANCLE_ORDER_EXPIRE_DAY Day = 2 // 2天
 )
 
 // 订单时间配置
diff --git a/model/gmodel/fs_cart_logic.go b/model/gmodel/fs_cart_logic.go
index b18f7672..d86b18be 100755
--- a/model/gmodel/fs_cart_logic.go
+++ b/model/gmodel/fs_cart_logic.go
@@ -92,5 +92,5 @@ func (c *FsCartModel) DeleteCartsByIds(ctx context.Context, ids []int64) ( err e
 	if len(ids) == 0 {
 		return
 	}
-	return c.db.WithContext(ctx).Model(&FsCart{}).Where("`id` in (?)", ids).Delete(&FsCart{}).Error
+	return c.db.Table(c.name).WithContext(ctx).Model(&FsCart{}).Where("`id` in (?)", ids).Update("status", 0).Error
 }
diff --git a/model/gmodel/fs_pay_event_gen.go b/model/gmodel/fs_pay_event_gen.go
new file mode 100644
index 00000000..38d6c56e
--- /dev/null
+++ b/model/gmodel/fs_pay_event_gen.go
@@ -0,0 +1,25 @@
+package gmodel
+
+import (
+	"gorm.io/gorm"
+)
+
+// fs_pay_event 支付回调事件日志
+type FsPayEvent struct {
+	Id           int64   `gorm:"primary_key;default:0;auto_increment;" json:"id"` //
+	PayMethod    *int64  `gorm:"default:0;" json:"pay_method"`                    // 支付方式  1 stripe  2 paypal
+	EventId      *string `gorm:"default:'';" json:"event_id"`                     // 事件ID
+	EventType    *string `gorm:"default:'';" json:"event_type"`                   // 事件类型
+	EventData    *string `gorm:"default:'';" json:"event_data"`                   // 事件数据
+	EventCreated *int64  `gorm:"default:0;" json:"event_created"`                 // 事件时间
+	Ip           *string `gorm:"default:'';" json:"ip"`                           // 请求IP
+	CreatedAt    *int64  `gorm:"default:0;" json:"created_at"`                    // 创建时间
+}
+type FsPayEventModel struct {
+	db   *gorm.DB
+	name string
+}
+
+func NewFsPayEventModel(db *gorm.DB) *FsPayEventModel {
+	return &FsPayEventModel{db: db, name: "fs_pay_event"}
+}
diff --git a/model/gmodel/fs_pay_event_logic.go b/model/gmodel/fs_pay_event_logic.go
new file mode 100644
index 00000000..8af36582
--- /dev/null
+++ b/model/gmodel/fs_pay_event_logic.go
@@ -0,0 +1,15 @@
+package gmodel
+
+import "context"
+
+// TODO: 使用model的属性做你想做的
+
+func (p *FsPayEventModel) CreateOrUpdate(ctx context.Context, req *FsPayEvent) (resp *FsPayEvent, err error) {
+	rowBuilder := p.db.Table(p.name).WithContext(ctx)
+	if req.Id > 0 {
+		err = rowBuilder.Save(req).Error
+	} else {
+		err = rowBuilder.Create(req).Error
+	}
+	return req, err
+}
diff --git a/model/gmodel/fs_pay_gen.go b/model/gmodel/fs_pay_gen.go
index e30685b6..0ee65802 100644
--- a/model/gmodel/fs_pay_gen.go
+++ b/model/gmodel/fs_pay_gen.go
@@ -7,7 +7,6 @@ import (
 // fs_pay 支付记录
 type FsPay struct {
 	Id            int64   `gorm:"primary_key;default:0;auto_increment;" json:"id"` //
-	PayNo         *string `gorm:"default:'';" json:"pay_no"`                       // 支付编号
 	UserId        *int64  `gorm:"index;default:0;" json:"user_id"`                 // 用户id
 	OrderNumber   *string `gorm:"default:'';" json:"order_number"`                 // 订单编号
 	TradeNo       *string `gorm:"index;default:'';" json:"trade_no"`               // 第三方支付编号
diff --git a/model/gmodel/fs_pay_logic.go b/model/gmodel/fs_pay_logic.go
index d470f2e9..fa4a6093 100644
--- a/model/gmodel/fs_pay_logic.go
+++ b/model/gmodel/fs_pay_logic.go
@@ -3,6 +3,7 @@ package gmodel
 import (
 	"context"
 	"fusenapi/utils/handler"
+	"reflect"
 
 	"gorm.io/gorm"
 )
@@ -80,6 +81,31 @@ func (m *FsPayModel) FindOneByQuery(ctx context.Context, rowBuilder *gorm.DB, fi
 	}
 }
 
+func (m *FsPayModel) FindAll(ctx context.Context, rowBuilder *gorm.DB, filterMap map[string]string, orderBy string) ([]*FsPay, error) {
+	var resp []*FsPay
+	// 过滤
+	if filterMap != nil {
+		rowBuilder = rowBuilder.Scopes(handler.FilterData(filterMap))
+	}
+
+	// 排序
+	if orderBy != "" {
+		var fieldsMap = make(map[string]struct{})
+		s := reflect.TypeOf(&FsOrder{}).Elem() //通过反射获取type定义
+		for i := 0; i < s.NumField(); i++ {
+			fieldsMap[s.Field(i).Tag.Get("json")] = struct{}{}
+		}
+		rowBuilder = rowBuilder.Scopes(handler.OrderCheck(orderBy, fieldsMap))
+	}
+
+	result := rowBuilder.WithContext(ctx).Find(&resp)
+	if result.Error != nil {
+		return nil, result.Error
+	} else {
+		return resp, nil
+	}
+}
+
 // 事务
 func (m *FsPayModel) Trans(ctx context.Context, fn func(ctx context.Context, connGorm *gorm.DB) error) error {
 	tx := m.db.Table(m.name).WithContext(ctx).Begin()
diff --git a/model/gmodel/fs_refund_reason_logic.go b/model/gmodel/fs_refund_reason_logic.go
index 88644fc4..76d6810b 100644
--- a/model/gmodel/fs_refund_reason_logic.go
+++ b/model/gmodel/fs_refund_reason_logic.go
@@ -24,3 +24,17 @@ func (m *FsRefundReasonModel) Update(ctx context.Context, obj *FsRefundReason) e
 func (m *FsRefundReasonModel) UpdateByRefundReasonId(ctx context.Context, obj *FsRefundReason) error {
 	return m.db.WithContext(ctx).Model(obj).Where("`refund_reason_id` = ?", obj.RefundReasonId).Updates(obj).Error
 }
+
+func (m *FsRefundReasonModel) CreateOrUpdate(ctx context.Context, req *FsRefundReason) (resp *FsRefundReason, err error) {
+	rowBuilder := m.db.Table(m.name).WithContext(ctx)
+	if req.Id > 0 {
+		err = rowBuilder.Save(req).Error
+	} else {
+		err = rowBuilder.Create(req).Error
+	}
+	return req, err
+}
+
+func (m *FsRefundReasonModel) TableName() string {
+	return m.name
+}
diff --git a/model/gmodel/var_gen.go b/model/gmodel/var_gen.go
index 191a9898..a90a6f7c 100644
--- a/model/gmodel/var_gen.go
+++ b/model/gmodel/var_gen.go
@@ -52,6 +52,7 @@ type AllModelsGen struct {
 	FsOrderDetailTemplate     *FsOrderDetailTemplateModel     // fs_order_detail_template 订单模板详细表
 	FsOrderRemark             *FsOrderRemarkModel             // fs_order_remark 订单备注表
 	FsPay                     *FsPayModel                     // fs_pay 支付记录
+	FsPayEvent                *FsPayEventModel                // fs_pay_event 支付回调事件日志
 	FsProduct                 *FsProductModel                 // fs_product 产品表
 	FsProductCopy1            *FsProductCopy1Model            // fs_product_copy1 产品表
 	FsProductDesign           *FsProductDesignModel           // fs_product_design 产品设计表
@@ -144,6 +145,7 @@ func NewAllModels(gdb *gorm.DB) *AllModelsGen {
 		FsOrderDetailTemplate:     NewFsOrderDetailTemplateModel(gdb),
 		FsOrderRemark:             NewFsOrderRemarkModel(gdb),
 		FsPay:                     NewFsPayModel(gdb),
+		FsPayEvent:                NewFsPayEventModel(gdb),
 		FsProduct:                 NewFsProductModel(gdb),
 		FsProductCopy1:            NewFsProductCopy1Model(gdb),
 		FsProductDesign:           NewFsProductDesignModel(gdb),
diff --git a/server/home-user-auth/etc/home-user-auth.yaml b/server/home-user-auth/etc/home-user-auth.yaml
index 7ef5a2c9..31722119 100644
--- a/server/home-user-auth/etc/home-user-auth.yaml
+++ b/server/home-user-auth/etc/home-user-auth.yaml
@@ -20,3 +20,10 @@ OAuth:
 
 Stripe:
   SK: "sk_test_51IisojHygnIJZeghPVSBhkwySfcyDV4SoAduIxu3J7bvSJ9cZMD96LY1LO6SpdbYquLJX5oKvgEBB67KT9pecfCy00iEC4pp9y"
+
+PayConfig:
+  Stripe:
+    Key: "sk_test_51IisojHygnIJZeghPVSBhkwySfcyDV4SoAduIxu3J7bvSJ9cZMD96LY1LO6SpdbYquLJX5oKvgEBB67KT9pecfCy00iEC4pp9y"
+    EndpointSecret: "whsec_f5f9a121d43af3789db7459352f08cf523eb9e0fbf3381f91ba6c97c324c174d"
+    SuccessURL: "http://www.baidu.com"
+    CancelURL: "http://www.baidu.com"
diff --git a/server/home-user-auth/internal/config/config.go b/server/home-user-auth/internal/config/config.go
index 19c515b1..fa7c3bf3 100644
--- a/server/home-user-auth/internal/config/config.go
+++ b/server/home-user-auth/internal/config/config.go
@@ -28,4 +28,13 @@ type Config struct {
 	Stripe struct {
 		SK string
 	}
+
+	PayConfig struct {
+		Stripe struct {
+			EndpointSecret string
+			Key            string
+			CancelURL      string
+			SuccessURL     string
+		}
+	}
 }
diff --git a/server/home-user-auth/internal/logic/userordercancellogic.go b/server/home-user-auth/internal/logic/userordercancellogic.go
index 56a9ab4a..0f23aa41 100644
--- a/server/home-user-auth/internal/logic/userordercancellogic.go
+++ b/server/home-user-auth/internal/logic/userordercancellogic.go
@@ -6,11 +6,13 @@ import (
 	"fusenapi/model/gmodel"
 	"fusenapi/utils/auth"
 	"fusenapi/utils/basic"
+	"time"
 
 	"context"
 
 	"fusenapi/server/home-user-auth/internal/svc"
 	"fusenapi/server/home-user-auth/internal/types"
+	handlerUtils "fusenapi/utils/handler"
 
 	"github.com/zeromicro/go-zero/core/logx"
 	"gorm.io/gorm"
@@ -50,11 +52,76 @@ func (l *UserOrderCancelLogic) UserOrderCancel(req *types.UserOrderCancelReq, us
 	}
 
 	// 判断订单状态
-	if *orderInfo.Status == int64(constants.STATUS_NEW_NOT_PAY) {
-
-	} else {
+	var notCancelStatusMap = make(map[constants.Order]struct{}, 3)
+	notCancelStatusMap[constants.STATUS_NEW_NOT_PAY] = struct{}{}
+	notCancelStatusMap[constants.STATUS_NEW_PART_PAY] = struct{}{}
+	notCancelStatusMap[constants.STATUS_NEW_PAY_COMPLETED] = struct{}{}
+	_, ok := notCancelStatusMap[constants.Order(*orderInfo.Status)]
+	if !ok {
 		return resp.SetStatusWithMessage(basic.CodeOrderNotCancelledErr, "the order status not cancle")
 	}
 
+	var cancelTime int64 = time.Now().Unix() - (*orderInfo.Ctime + int64(constants.CANCLE_ORDER_EXPIRE))
+	// 第一次支付成功后48小时后不能进行取消操作
+	if orderInfo.IsPayCompleted != nil && cancelTime > 0 {
+		return resp.SetStatusWithMessage(basic.CodeOrderNotCancelledErr, "The current order cannot be cancelled")
+	}
+
+	// 修改订单--取消状态和取消原因
+	*orderInfo.Status = int64(constants.STATUS_NEW_CANCEL)
+	*orderInfo.IsCancel = 1
+	orderInfo.RefundReasonId = &req.RefundReasonId
+	orderInfo.RefundReason = &req.RefundReason
+
+	var nowTime = time.Now().Unix()
+	var payList []handlerUtils.PayInfo
+	// 事务处理
+	err = orderModel.Trans(l.ctx, func(ctx context.Context, connGorm *gorm.DB) (err error) {
+		// 修改订单信息
+		orderModelTS := gmodel.NewFsOrderModel(connGorm)
+		err = orderModelTS.Update(ctx, orderInfo)
+		if err != nil {
+			return err
+		}
+		// 新增退款记录
+		var isRefund int64 = 0
+		refundReasonModelTS := gmodel.NewFsRefundReasonModel(connGorm)
+		refundReasonModelTS.CreateOrUpdate(ctx, &gmodel.FsRefundReason{
+			IsRefund:       &isRefund,
+			RefundReasonId: &req.RefundReasonId,
+			RefundReason:   &req.RefundReason,
+			OrderId:        &orderInfo.Id,
+			CreatedAt:      &nowTime,
+		})
+		// 退款申请
+		// 退款申请--查询支付信息
+		fsPayModelTS := gmodel.NewFsPayModel(connGorm)
+		rbFsPay := fsPayModelTS.RowSelectBuilder(nil).Where("order_number = ?", orderInfo.Sn).Where("pay_status =?", constants.PAYSTATUS_SUCCESS).Where("is_refund =?", 0)
+		payInfoList, err := fsPayModelTS.FindAll(ctx, rbFsPay, nil, "")
+		if err != nil {
+			return err
+		}
+		for _, payInfo := range payInfoList {
+			var key string
+			if *payInfo.PaymentMethod == int64(constants.PAYMETHOD_STRIPE) {
+				key = l.svcCtx.Config.PayConfig.Stripe.Key
+			}
+			payList = append(payList, handlerUtils.PayInfo{
+				TradeNo:       *payInfo.TradeNo,
+				PaymentMethod: *payInfo.PaymentMethod,
+				Key:           key,
+			})
+		}
+		return nil
+	})
+	// 退款申请--调取第三方接口发起退款
+	handlerUtils.PayRefundHandler(&handlerUtils.PayRefundHandlerReq{
+		PayInfoList: payList,
+	})
+	if err != nil {
+		logx.Error(err)
+		return resp.SetStatusWithMessage(basic.CodeOrderCancelledNotOk, "the order cancle failed")
+	}
+
 	return resp.SetStatus(basic.CodeOK)
 }
diff --git a/server/pay/etc/pay.yaml b/server/pay/etc/pay.yaml
index 841753e3..831292a9 100644
--- a/server/pay/etc/pay.yaml
+++ b/server/pay/etc/pay.yaml
@@ -1,7 +1,6 @@
 Name: pay
 Host: 0.0.0.0
 Port: 9915
-Timeout: 15000
 SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest
 Auth:
     AccessSecret: fusen2023
diff --git a/server/pay/internal/handler/orderrefundhandler.go b/server/pay/internal/handler/orderrefundhandler.go
new file mode 100644
index 00000000..3d7998ff
--- /dev/null
+++ b/server/pay/internal/handler/orderrefundhandler.go
@@ -0,0 +1,35 @@
+package handler
+
+import (
+	"net/http"
+	"reflect"
+
+	"fusenapi/utils/basic"
+
+	"fusenapi/server/pay/internal/logic"
+	"fusenapi/server/pay/internal/svc"
+	"fusenapi/server/pay/internal/types"
+)
+
+func OrderRefundHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+
+		var req types.OrderRefundReq
+		userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
+		if err != nil {
+			return
+		}
+
+		// 创建一个业务逻辑层实例
+		l := logic.NewOrderRefundLogic(r.Context(), svcCtx)
+
+		rl := reflect.ValueOf(l)
+		basic.BeforeLogic(w, r, rl)
+
+		resp := l.OrderRefund(&req, userinfo)
+
+		if !basic.AfterLogic(w, r, rl, resp) {
+			basic.NormalAfterLogic(w, r, resp)
+		}
+	}
+}
diff --git a/server/pay/internal/handler/routes.go b/server/pay/internal/handler/routes.go
index 28292f5f..f1295e35 100644
--- a/server/pay/internal/handler/routes.go
+++ b/server/pay/internal/handler/routes.go
@@ -17,6 +17,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
 				Path:    "/api/pay/payment-intent",
 				Handler: OrderPaymentIntentHandler(serverCtx),
 			},
+			{
+				Method:  http.MethodPost,
+				Path:    "/api/pay/refund",
+				Handler: OrderRefundHandler(serverCtx),
+			},
 			{
 				Method:  http.MethodPost,
 				Path:    "/api/pay/stripe-webhook",
diff --git a/server/pay/internal/handler/stripewebhookhandler.go b/server/pay/internal/handler/stripewebhookhandler.go
index b4447ba7..ca7689d0 100644
--- a/server/pay/internal/handler/stripewebhookhandler.go
+++ b/server/pay/internal/handler/stripewebhookhandler.go
@@ -30,6 +30,15 @@ func StripeWebhookHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
 		// 	return
 		// }
 
+		IPAddress := r.Header.Get("X-Real-Ip")
+		if IPAddress == "" {
+			IPAddress = r.Header.Get("X-Forwarded-For")
+		}
+		if IPAddress == "" {
+			IPAddress = r.RemoteAddr
+		}
+
+		req.RemoteAddr = IPAddress
 		req.Payload = payload
 		req.StripeSignature = r.Header.Get("Stripe-Signature")
 
diff --git a/server/pay/internal/logic/orderrefundlogic.go b/server/pay/internal/logic/orderrefundlogic.go
new file mode 100644
index 00000000..5f9e11db
--- /dev/null
+++ b/server/pay/internal/logic/orderrefundlogic.go
@@ -0,0 +1,43 @@
+package logic
+
+import (
+	"fusenapi/utils/auth"
+	"fusenapi/utils/basic"
+
+	"context"
+
+	"fusenapi/server/pay/internal/svc"
+	"fusenapi/server/pay/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type OrderRefundLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewOrderRefundLogic(ctx context.Context, svcCtx *svc.ServiceContext) *OrderRefundLogic {
+	return &OrderRefundLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx,
+	}
+}
+
+// 处理进入前逻辑w,r
+// func (l *OrderRefundLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
+// }
+
+// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
+// func (l *OrderRefundLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
+// // httpx.OkJsonCtx(r.Context(), w, resp)
+// }
+
+func (l *OrderRefundLogic) OrderRefund(req *types.OrderRefundReq, userinfo *auth.UserInfo) (resp *basic.Response) {
+	// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
+	// userinfo 传入值时, 一定不为null
+
+	return resp.SetStatus(basic.CodeOK)
+}
diff --git a/server/pay/internal/logic/stripewebhooklogic.go b/server/pay/internal/logic/stripewebhooklogic.go
index 048b78e7..8deaf2a6 100644
--- a/server/pay/internal/logic/stripewebhooklogic.go
+++ b/server/pay/internal/logic/stripewebhooklogic.go
@@ -64,6 +64,21 @@ func (l *StripeWebhookLogic) StripeWebhook(req *types.StripeWebhookReq, userinfo
 		return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "Webhook signature verification failed")
 	}
 
+	// 新增支付回调事件日志
+	var payMethod = int64(constants.PAYMETHOD_STRIPE)
+	var nowTime = time.Now().Unix()
+	var eventData = string(event.Data.Raw)
+	var fsPayEvent = &gmodel.FsPayEvent{
+		PayMethod:    &payMethod,
+		EventId:      &event.ID,
+		EventType:    &event.Type,
+		EventData:    &eventData,
+		EventCreated: &event.Created,
+		Ip:           &req.RemoteAddr,
+		CreatedAt:    &nowTime,
+	}
+	l.HandlePayEventCreate(fsPayEvent)
+
 	// Unmarshal the event data into an appropriate struct depending on its Type
 	switch event.Type {
 	case "charge.succeeded":
@@ -94,7 +109,7 @@ func (l *StripeWebhookLogic) StripeWebhook(req *types.StripeWebhookReq, userinfo
 			logx.Error(err)
 			return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type payment_intent.succeeded")
 		}
-		err = l.handlePaymentIntentSucceeded(&paymentIntent)
+		err = l.HandlePaymentIntentSucceeded(&paymentIntent)
 		if err != nil {
 			return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type Unhandled")
 		}
@@ -114,6 +129,12 @@ func (l *StripeWebhookLogic) StripeWebhook(req *types.StripeWebhookReq, userinfo
 	return resp.SetStatus(basic.CodeOK)
 }
 
+// 回调事件日志
+func (l *StripeWebhookLogic) HandlePayEventCreate(fsPayEvent *gmodel.FsPayEvent) error {
+	_, err := gmodel.NewFsPayEventModel(l.svcCtx.MysqlConn).CreateOrUpdate(l.ctx, fsPayEvent)
+	return err
+}
+
 // session完成
 // func (l *StripeWebhookLogic) handlePaymentSessionCompleted(sessionId string, tradeNo string) (err error) {
 // 	// 查询支付记录
@@ -137,7 +158,7 @@ func (l *StripeWebhookLogic) StripeWebhook(req *types.StripeWebhookReq, userinfo
 // }
 
 // 成功的付款
-func (l *StripeWebhookLogic) handlePaymentIntentSucceeded(paymentIntent *stripe.PaymentIntent) error {
+func (l *StripeWebhookLogic) HandlePaymentIntentSucceeded(paymentIntent *stripe.PaymentIntent) error {
 	orderSn, ok := paymentIntent.Metadata["order_sn"]
 	if !ok || orderSn == "" {
 		return errors.New("order_sn not found")
@@ -146,14 +167,12 @@ func (l *StripeWebhookLogic) handlePaymentIntentSucceeded(paymentIntent *stripe.
 	// 查询支付记录
 	payModel := gmodel.NewFsPayModel(l.svcCtx.MysqlConn)
 	rsbPay := payModel.RowSelectBuilder(nil)
-	rsbPay = rsbPay.Where("order_number = ?", orderSn)
+	rsbPay = rsbPay.Where("order_number = ?", orderSn).Where("pay_status = ?", constants.PAYSTATUS_UNSUCCESS)
 	payInfo, err := payModel.FindOneByQuery(l.ctx, rsbPay, nil)
 	if err != nil {
 		return err
 	}
-	if *payInfo.PayStatus == 1 {
-		return errors.New("pay status 1")
-	}
+
 	//订单信息
 	orderDetailTemplateModel := gmodel.NewFsOrderDetailTemplateModel(l.svcCtx.MysqlConn)
 	orderModel := gmodel.NewFsOrderModel(l.svcCtx.MysqlConn)
@@ -209,6 +228,7 @@ func (l *StripeWebhookLogic) handlePaymentIntentSucceeded(paymentIntent *stripe.
 			*payInfo.PayTime = nowTime
 			*payInfo.CardNo = card
 			*payInfo.Brand = brand
+			*payInfo.TradeNo = paymentIntent.ID
 			_, err = payModelT.CreateOrUpdate(ctx, payInfo)
 			if err != nil {
 				return err
@@ -244,12 +264,12 @@ func (l *StripeWebhookLogic) handlePaymentIntentSucceeded(paymentIntent *stripe.
 
 			// 支付记录是尾款
 			if *payInfo.PayStage == int64(constants.PAYSTAGE_REMAINING) {
-				if *orderInfo.Status < int64(constants.STATUS_NEW_PAY_COMPLETED) {
+				if *fsOrderRelInfo.Status < int64(constants.STATUS_NEW_PAY_COMPLETED) {
 					orderStatus = int64(constants.STATUS_NEW_PAY_COMPLETED)
 				}
 				orderIsPayCompleted = 1
 				orderInfo.IsPayCompleted = &orderIsPayCompleted
-				orderPayedAmount = *orderInfo.PayedAmount + paymentIntent.Amount
+				orderPayedAmount = *fsOrderRelInfo.PayedAmount + paymentIntent.Amount
 			}
 
 			// 更新订单信息
diff --git a/server/pay/internal/types/types.go b/server/pay/internal/types/types.go
index 76c0341e..fab57728 100644
--- a/server/pay/internal/types/types.go
+++ b/server/pay/internal/types/types.go
@@ -5,6 +5,12 @@ import (
 	"fusenapi/utils/basic"
 )
 
+type OrderRefundReq struct {
+}
+
+type OrderRefundRes struct {
+}
+
 type OrderPaymentIntentReq struct {
 	Sn             string `form:"sn"`              //订单编号
 	DeliveryMethod int64  `form:"delivery_method"` //发货方式
@@ -20,6 +26,7 @@ type OrderPaymentIntentRes struct {
 type StripeWebhookReq struct {
 	Payload         []byte `json:"base_byte_slice,optional"`
 	StripeSignature string `json:"Stripe-Signature"`
+	RemoteAddr      string `json:"remote_addr"`
 }
 
 type Request struct {
diff --git a/server_api/pay.api b/server_api/pay.api
index b7a1b0d1..4044c1e3 100644
--- a/server_api/pay.api
+++ b/server_api/pay.api
@@ -14,10 +14,20 @@ service pay {
 	@handler OrderPaymentIntentHandler
 	post /api/pay/payment-intent(OrderPaymentIntentReq) returns (response);
 
+	@handler OrderRefundHandler
+	post /api/pay/refund(OrderRefundReq) returns (response);
+
 	@handler StripeWebhookHandler
 	post /api/pay/stripe-webhook(StripeWebhookReq) returns (response);
+
 }
 
+// 退款
+type (
+	OrderRefundReq struct{}
+	OrderRefundRes struct{}
+)
+
 // 生成预付款
 type (
 	OrderPaymentIntentReq {
@@ -37,5 +47,6 @@ type (
 	StripeWebhookReq {
 		Payload         []byte `json:"base_byte_slice,optional"`
 		StripeSignature string `json:"Stripe-Signature"`
+		RemoteAddr      string `json:"remote_addr"`
 	}
 )
\ No newline at end of file
diff --git a/utils/basic/basic.go b/utils/basic/basic.go
index 7ec3d02f..66aaffc0 100644
--- a/utils/basic/basic.go
+++ b/utils/basic/basic.go
@@ -52,9 +52,11 @@ var (
 	CodeSafeValueRangeErr = &StatusResponse{5040, "value not in range"}    // 值不在范围内
 	CodeTemplateErr       = &StatusResponse{5040, "template parsed error"} // 模板解析错误
 
-	CodeOrderNotFoundErr      = &StatusResponse{5030, "order not found"}                   //未找到订单
-	CodeCloudOrderNotFoundErr = &StatusResponse{5031, "cloud order not found"}             //未找到云仓订单
-	CodeOrderNotCancelledErr  = &StatusResponse{5032, "current order cannot be cancelled"} // 当前订单无法取消
+	CodeOrderNotFoundErr      = &StatusResponse{5030, "order not found"}                    //未找到订单
+	CodeCloudOrderNotFoundErr = &StatusResponse{5031, "cloud order not found"}              //未找到云仓订单
+	CodeOrderNotCancelledErr  = &StatusResponse{5032, "current order cannot be cancelled"}  // 当前订单无法取消
+	CodeOrderCancelledNotOk   = &StatusResponse{5033, "current order cancelled failed"}     // 当前订单取消失败
+	CodeOrderCancelledOk      = &StatusResponse{5034, "current order cancelled successful"} // 当前订单取消成功
 
 	CodePayNotFoundErr = &StatusResponse{5020, "pay info not found"}      // 支付信息无法查询
 	CodePayCancelOk    = &StatusResponse{5021, "cancellation successful"} // 支付取消成功
diff --git a/utils/handler/payHandler.go b/utils/handler/payHandler.go
new file mode 100644
index 00000000..f69412b7
--- /dev/null
+++ b/utils/handler/payHandler.go
@@ -0,0 +1,64 @@
+package handler
+
+import (
+	"fusenapi/constants"
+	"fusenapi/utils/pay"
+
+	"github.com/zeromicro/go-zero/core/mr"
+)
+
+type (
+	PayInfo struct {
+		TradeNo       string `json:"trade_no"`
+		PaymentMethod int64  `json:"payment_method"`
+		Key           string `json:"key"`
+	}
+	PayRefundHandlerReq struct {
+		PayInfoList []PayInfo
+	}
+	PayRefundHandlerRes struct {
+	}
+)
+
+// 申请第三方退款
+func PayRefundHandler(req *PayRefundHandlerReq) (res PayRefundHandlerRes, err error) {
+
+	_, err = mr.MapReduce(func(source chan<- interface{}) {
+		for _, payInfo := range req.PayInfoList {
+			source <- payInfo
+		}
+	}, func(item interface{}, writer mr.Writer[interface{}], cancel func(error)) {
+		payConfig := new(pay.Config)
+		payInfo := item.(PayInfo)
+		switch payInfo.PaymentMethod {
+		case int64(constants.PAYMETHOD_STRIPE):
+			// stripe 支付
+			payConfig.Stripe.Key = payInfo.Key
+		}
+		payDriver := pay.NewPayDriver(payInfo.PaymentMethod, payConfig)
+		_, err = payDriver.PayRefund(&pay.PayRefundReq{
+			TradeNo: payInfo.TradeNo,
+		})
+
+		if err != nil {
+			// Notice 如果不加 cancel(err),会返回校验成功的id; 如果加上cancel(err),返回的结果会是一个空列表
+			// Notice 实际上,如果这里返回错误,其他协程直接就退出了!
+			// Notice 看实际中业务的需求情况来定了...
+			cancel(err)
+		}
+		// Notice 这个必须加!
+		writer.Write(payInfo)
+	}, func(pipe <-chan interface{}, writer mr.Writer[interface{}], cancel func(error)) {
+		var payInfoList []PayInfo
+		for p := range pipe {
+			payInfoList = append(payInfoList, p.(PayInfo))
+		}
+		// Notice 这个必须加!
+		writer.Write(payInfoList)
+	})
+	if err != nil {
+		return res, err
+	}
+
+	return res, nil
+}
diff --git a/utils/pay/pay.go b/utils/pay/pay.go
index a378e4a8..e982139e 100644
--- a/utils/pay/pay.go
+++ b/utils/pay/pay.go
@@ -20,7 +20,12 @@ func NewPayDriver(PayMethod int64, config *Config) Pay {
 
 // Pay 支付集成接口
 type Pay interface {
+
+	// 支付预处理
 	GeneratePrepayment(req *GeneratePrepaymentReq) (res *GeneratePrepaymentRes, err error)
+
+	// 支付退款申请
+	PayRefund(req *PayRefundReq) (res *PayRefundRes, err error)
 }
 
 type GeneratePrepaymentReq struct {
@@ -41,3 +46,10 @@ type GeneratePrepaymentRes struct {
 	ClientSecret string `json:"clientSecret"` //交易密钥
 	SessionId    string `json:"session_id"`   //SessionId
 }
+
+type PayRefundReq struct {
+	TradeNo string `json:"trade_no"` // 交易编号
+}
+
+type PayRefundRes struct {
+}
diff --git a/utils/pay/stripe.go b/utils/pay/stripe.go
index cc8127f7..e2e13799 100644
--- a/utils/pay/stripe.go
+++ b/utils/pay/stripe.go
@@ -3,12 +3,25 @@ package pay
 import (
 	"github.com/stripe/stripe-go/v74"
 	"github.com/stripe/stripe-go/v74/checkout/session"
+	"github.com/stripe/stripe-go/v74/refund"
+	"github.com/zeromicro/go-zero/core/logx"
 )
 
 type Stripe struct {
 	Key string `json:"key"`
 }
 
+// 生成退款
+func (stripePay *Stripe) PayRefund(req *PayRefundReq) (res *PayRefundRes, err error) {
+	stripe.Key = stripePay.Key
+	params := &stripe.RefundParams{PaymentIntent: stripe.String(req.TradeNo)}
+	_, err = refund.New(params)
+	if err != nil {
+		logx.Error(err)
+	}
+	return res, err
+}
+
 // 生成预付款
 func (stripePay *Stripe) GeneratePrepayment(req *GeneratePrepaymentReq) (res *GeneratePrepaymentRes, err error) {
 	var productData stripe.CheckoutSessionLineItemPriceDataProductDataParams