From 334ea4aa3f8f5363b81d5170720c4b5cdd68eb56 Mon Sep 17 00:00:00 2001 From: Hiven Date: Fri, 28 Jul 2023 11:15:42 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E4=BB=98=E6=88=90=E5=8A=9F=E5=9B=9E?= =?UTF-8?q?=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model/gmodel/fs_resource_gen.go | 27 ++++ model/gmodel/fs_resource_logic.go | 2 + model/gmodel/var_gen.go | 2 + server/pay/etc/pay.yaml | 2 + server/pay/internal/config/config.go | 7 +- server/pay/internal/handler/routes.go | 2 +- .../internal/handler/stripewebhookhandler.go | 19 ++- .../internal/logic/orderpaymentintentlogic.go | 7 +- .../pay/internal/logic/stripewebhooklogic.go | 139 +++++++++++++----- server/pay/internal/types/types.go | 5 +- server_api/pay.api | 7 +- utils/pay/pay.go | 7 +- utils/pay/stripe.go | 24 ++- 13 files changed, 199 insertions(+), 51 deletions(-) create mode 100644 model/gmodel/fs_resource_gen.go create mode 100644 model/gmodel/fs_resource_logic.go diff --git a/model/gmodel/fs_resource_gen.go b/model/gmodel/fs_resource_gen.go new file mode 100644 index 00000000..23623ee0 --- /dev/null +++ b/model/gmodel/fs_resource_gen.go @@ -0,0 +1,27 @@ +package gmodel + +import ( + "gorm.io/gorm" + "time" +) + +// fs_resource 资源表 +type FsResource struct { + ResourceId string `gorm:"primary_key;default:'';" json:"resource_id"` // 资源 ID + UserId *int64 `gorm:"index;default:0;" json:"user_id"` // 用户 ID + GuestId *int64 `gorm:"index;default:0;" json:"guest_id"` // 访客 ID + ResourceType *string `gorm:"index;default:'';" json:"resource_type"` // 资源类型 + ResourceUrl *string `gorm:"default:'';" json:"resource_url"` // 资源 URL + Version *string `gorm:"index;default:'0';" json:"version"` // 版本信息 + UploadedAt *time.Time `gorm:"index;default:'0000-00-00 00:00:00';" json:"uploaded_at"` // 上传时间 + Metadata *string `gorm:"default:'';" json:"metadata"` // 元数据,json格式,存储图像分率 + MetaKey1 *string `gorm:"index;default:'';" json:"meta_key1"` // 需要关键信息查询的自定义属性1,可以动态增加 +} +type FsResourceModel struct { + db *gorm.DB + name string +} + +func NewFsResourceModel(db *gorm.DB) *FsResourceModel { + return &FsResourceModel{db: db, name: "fs_resource"} +} diff --git a/model/gmodel/fs_resource_logic.go b/model/gmodel/fs_resource_logic.go new file mode 100644 index 00000000..e68225aa --- /dev/null +++ b/model/gmodel/fs_resource_logic.go @@ -0,0 +1,2 @@ +package gmodel +// TODO: 使用model的属性做你想做的 \ No newline at end of file diff --git a/model/gmodel/var_gen.go b/model/gmodel/var_gen.go index 2fac48a5..191a9898 100644 --- a/model/gmodel/var_gen.go +++ b/model/gmodel/var_gen.go @@ -79,6 +79,7 @@ type AllModelsGen struct { FsQuotationRemarkTemplate *FsQuotationRemarkTemplateModel // fs_quotation_remark_template 报价单备注模板 FsQuotationSaler *FsQuotationSalerModel // fs_quotation_saler 报价单业务员表 FsRefundReason *FsRefundReasonModel // fs_refund_reason + FsResource *FsResourceModel // fs_resource 资源表 FsResources *FsResourcesModel // fs_resources 资源表 FsStandardLogo *FsStandardLogoModel // fs_standard_logo 标准logo FsTags *FsTagsModel // fs_tags 产品分类表 @@ -170,6 +171,7 @@ func NewAllModels(gdb *gorm.DB) *AllModelsGen { FsQuotationRemarkTemplate: NewFsQuotationRemarkTemplateModel(gdb), FsQuotationSaler: NewFsQuotationSalerModel(gdb), FsRefundReason: NewFsRefundReasonModel(gdb), + FsResource: NewFsResourceModel(gdb), FsResources: NewFsResourcesModel(gdb), FsStandardLogo: NewFsStandardLogoModel(gdb), FsTags: NewFsTagsModel(gdb), diff --git a/server/pay/etc/pay.yaml b/server/pay/etc/pay.yaml index dcc6a6fe..841753e3 100644 --- a/server/pay/etc/pay.yaml +++ b/server/pay/etc/pay.yaml @@ -1,6 +1,7 @@ Name: pay Host: 0.0.0.0 Port: 9915 +Timeout: 15000 SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest Auth: AccessSecret: fusen2023 @@ -9,5 +10,6 @@ Auth: PayConfig: Stripe: Key: "sk_test_51IisojHygnIJZeghPVSBhkwySfcyDV4SoAduIxu3J7bvSJ9cZMD96LY1LO6SpdbYquLJX5oKvgEBB67KT9pecfCy00iEC4pp9y" + EndpointSecret: "whsec_f5f9a121d43af3789db7459352f08cf523eb9e0fbf3381f91ba6c97c324c174d" SuccessURL: "http://www.baidu.com" CancelURL: "http://www.baidu.com" \ No newline at end of file diff --git a/server/pay/internal/config/config.go b/server/pay/internal/config/config.go index 0b7a2dcb..6676984a 100644 --- a/server/pay/internal/config/config.go +++ b/server/pay/internal/config/config.go @@ -12,9 +12,10 @@ type Config struct { Auth types.Auth PayConfig struct { Stripe struct { - Key string - CancelURL string - SuccessURL string + EndpointSecret string + Key string + CancelURL string + SuccessURL string } } } diff --git a/server/pay/internal/handler/routes.go b/server/pay/internal/handler/routes.go index 454d6715..28292f5f 100644 --- a/server/pay/internal/handler/routes.go +++ b/server/pay/internal/handler/routes.go @@ -18,7 +18,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Handler: OrderPaymentIntentHandler(serverCtx), }, { - Method: http.MethodGet, + Method: http.MethodPost, Path: "/api/pay/stripe-webhook", Handler: StripeWebhookHandler(serverCtx), }, diff --git a/server/pay/internal/handler/stripewebhookhandler.go b/server/pay/internal/handler/stripewebhookhandler.go index 1e0da8fc..b4447ba7 100644 --- a/server/pay/internal/handler/stripewebhookhandler.go +++ b/server/pay/internal/handler/stripewebhookhandler.go @@ -1,6 +1,7 @@ package handler import ( + "io" "net/http" "reflect" @@ -14,19 +15,31 @@ import ( func StripeWebhookHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var req types.StripeWebhookReq - userinfo, err := basic.RequestParse(w, r, svcCtx, &req) + const MaxBodyBytes = int64(65536) + r.Body = http.MaxBytesReader(w, r.Body, MaxBodyBytes) + defer r.Body.Close() + payload, err := io.ReadAll(r.Body) if err != nil { return } + var req types.StripeWebhookReq + + // userinfo, err := basic.RequestParse(w, r, svcCtx, &req) + // if err != nil { + // return + // } + + req.Payload = payload + req.StripeSignature = r.Header.Get("Stripe-Signature") + // 创建一个业务逻辑层实例 l := logic.NewStripeWebhookLogic(r.Context(), svcCtx) rl := reflect.ValueOf(l) basic.BeforeLogic(w, r, rl) - resp := l.StripeWebhook(&req, userinfo) + resp := l.StripeWebhook(&req, nil) if !basic.AfterLogic(w, r, rl, resp) { basic.NormalAfterLogic(w, r, resp) diff --git a/server/pay/internal/logic/orderpaymentintentlogic.go b/server/pay/internal/logic/orderpaymentintentlogic.go index a9d13c22..a5cb71bc 100644 --- a/server/pay/internal/logic/orderpaymentintentlogic.go +++ b/server/pay/internal/logic/orderpaymentintentlogic.go @@ -97,6 +97,7 @@ func (l *OrderPaymentIntentLogic) OrderPaymentIntent(req *types.OrderPaymentInte payConfig := &pay.Config{} var generatePrepaymentReq = &pay.GeneratePrepaymentReq{ + OrderSn: req.Sn, ProductName: "支付标题", Amount: payAmount, Currency: "eur", @@ -142,7 +143,6 @@ func (l *OrderPaymentIntentLogic) OrderPaymentIntent(req *types.OrderPaymentInte if err != nil { return err } - resData.RedirectUrl = prepaymentRes.URL // 订单信息--修改 err = gmodel.NewFsOrderModel(connGorm).Update(ctx, orderInfo) @@ -161,7 +161,7 @@ func (l *OrderPaymentIntentLogic) OrderPaymentIntent(req *types.OrderPaymentInte } fspay.PayAmount = &payAmount fspay.PayStage = &payStage - fspay.TradeNo = &prepaymentRes.TradeNo + //fspay.TradeNo = &prepaymentRes.TradeNo fspay.PaymentMethod = &req.PayMethod fspay.OrderSource = &orderSource fspay.PayStatus = &payStatus @@ -171,6 +171,9 @@ func (l *OrderPaymentIntentLogic) OrderPaymentIntent(req *types.OrderPaymentInte return err } + resData.RedirectUrl = prepaymentRes.URL + resData.ClientSecret = prepaymentRes.ClientSecret + return nil }) diff --git a/server/pay/internal/logic/stripewebhooklogic.go b/server/pay/internal/logic/stripewebhooklogic.go index 82c5275b..048b78e7 100644 --- a/server/pay/internal/logic/stripewebhooklogic.go +++ b/server/pay/internal/logic/stripewebhooklogic.go @@ -7,8 +7,6 @@ import ( "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" - "io" - "net/http" "time" "context" @@ -17,15 +15,15 @@ import ( "fusenapi/server/pay/internal/types" "github.com/stripe/stripe-go/v74" + "github.com/stripe/stripe-go/v74/webhook" "github.com/zeromicro/go-zero/core/logx" "gorm.io/gorm" ) type StripeWebhookLogic struct { logx.Logger - ctx context.Context - svcCtx *svc.ServiceContext - Payload []byte + ctx context.Context + svcCtx *svc.ServiceContext } func NewStripeWebhookLogic(ctx context.Context, svcCtx *svc.ServiceContext) *StripeWebhookLogic { @@ -37,18 +35,9 @@ func NewStripeWebhookLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Str } // 处理进入前逻辑w,r -func (l *StripeWebhookLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { - const MaxBodyBytes = int64(65536) - r.Body = http.MaxBytesReader(w, r.Body, MaxBodyBytes) - defer r.Body.Close() - payload, err := io.ReadAll(r.Body) - if err != nil { - logx.Error(err) - w.WriteHeader(http.StatusServiceUnavailable) - return - } - l.Payload = payload -} +// func (l *StripeWebhookLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { + +// } // 处理逻辑后 w,r 如:重定向, resp 必须重新处理 // func (l *StripeWebhookLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { @@ -59,15 +48,45 @@ func (l *StripeWebhookLogic) StripeWebhook(req *types.StripeWebhookReq, userinfo // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // userinfo 传入值时, 一定不为null + stripe.Key = l.svcCtx.Config.PayConfig.Stripe.Key event := stripe.Event{} - if err := json.Unmarshal(l.Payload, &event); err != nil { + if err := json.Unmarshal(req.Payload, &event); err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail") } + endpointSecret := l.svcCtx.Config.PayConfig.Stripe.EndpointSecret + signatureHeader := req.StripeSignature + event, err := webhook.ConstructEvent(req.Payload, signatureHeader, endpointSecret) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "Webhook signature verification failed") + } + // Unmarshal the event data into an appropriate struct depending on its Type switch event.Type { + case "charge.succeeded": + // var charge stripe.Charge + // err := json.Unmarshal(event.Data.Raw, &charge) + // if err != nil { + // logx.Error(err) + // return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type charge.succeeded") + // } + + case "checkout.session.completed": + // checkout checkout.session.completed 处理逻辑 + // var session stripe.CheckoutSession + // err := json.Unmarshal(event.Data.Raw, &session) + // if err != nil { + // logx.Error(err) + // return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type payment_intent.succeeded") + // } + // fmt.Println("checkout.session.completed") + // err = l.handlePaymentSessionCompleted(session.ID, session.PaymentIntent.ID) + // if err != nil { + // return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "checkout.session.completed fail") + // } case "payment_intent.succeeded": var paymentIntent stripe.PaymentIntent err := json.Unmarshal(event.Data.Raw, &paymentIntent) @@ -95,13 +114,39 @@ func (l *StripeWebhookLogic) StripeWebhook(req *types.StripeWebhookReq, userinfo return resp.SetStatus(basic.CodeOK) } +// session完成 +// func (l *StripeWebhookLogic) handlePaymentSessionCompleted(sessionId string, tradeNo string) (err error) { +// // 查询支付记录 +// payModel := gmodel.NewFsPayModel(l.svcCtx.MysqlConn) +// rsbPay := payModel.RowSelectBuilder(nil) +// rsbPay = rsbPay.Where("session_id = ?", sessionId) +// payInfo, err := payModel.FindOneByQuery(l.ctx, rsbPay, nil) +// if err != nil { +// return err +// } +// if *payInfo.PayStatus == 0 { +// *payInfo.TradeNo = tradeNo +// _, err = payModel.CreateOrUpdate(l.ctx, payInfo) +// if err != nil { +// return err +// } +// } else { +// return errors.New("pay status 1") +// } +// return err +// } + // 成功的付款 func (l *StripeWebhookLogic) handlePaymentIntentSucceeded(paymentIntent *stripe.PaymentIntent) error { + orderSn, ok := paymentIntent.Metadata["order_sn"] + if !ok || orderSn == "" { + return errors.New("order_sn not found") + } // 查询支付记录 payModel := gmodel.NewFsPayModel(l.svcCtx.MysqlConn) rsbPay := payModel.RowSelectBuilder(nil) - rsbPay = rsbPay.Where("trade_no = ?", paymentIntent.ID) + rsbPay = rsbPay.Where("order_number = ?", orderSn) payInfo, err := payModel.FindOneByQuery(l.ctx, rsbPay, nil) if err != nil { return err @@ -112,22 +157,27 @@ func (l *StripeWebhookLogic) handlePaymentIntentSucceeded(paymentIntent *stripe. //订单信息 orderDetailTemplateModel := gmodel.NewFsOrderDetailTemplateModel(l.svcCtx.MysqlConn) orderModel := gmodel.NewFsOrderModel(l.svcCtx.MysqlConn) + fsOrderDetailModel := gmodel.NewFsOrderDetailModel(l.svcCtx.MysqlConn) + fsProductDesignModel := gmodel.NewFsProductDesignModel(l.svcCtx.MysqlConn) + rsbOrder := orderModel.RowSelectBuilder(nil) - rsbOrder = rsbOrder.Where("trade_no =?", paymentIntent.ID).Preload("FsOrderDetails") + rsbOrder = rsbOrder.Where("sn =?", orderSn).Preload("FsOrderDetails") rsbOrder = rsbOrder.Preload("FsOrderDetails", func(dbPreload *gorm.DB) *gorm.DB { - return dbPreload.Table(orderModel.TableName()).Preload("FsOrderDetailTemplateInfo", func(dbPreload *gorm.DB) *gorm.DB { - return dbPreload.Table(orderDetailTemplateModel.TableName()).Preload("FsProductDesignInfo") + return dbPreload.Table(fsOrderDetailModel.TableName()).Preload("FsOrderDetailTemplateInfo", func(dbPreload *gorm.DB) *gorm.DB { + return dbPreload.Table(orderDetailTemplateModel.TableName()).Preload("FsProductDesignInfo", func(dbPreload *gorm.DB) *gorm.DB { + return dbPreload.Table(fsProductDesignModel.TableName()) + }) }) }) - fsOrderRel, err := orderModel.FindOneByQuery(l.ctx, rsbOrder, nil) + fsOrderRelInfo, err := orderModel.FindOneByQuery(l.ctx, rsbOrder, nil) if err != nil { return err } var designIds []int64 var cartIds []int64 - if len(fsOrderRel.FsOrderDetails) > 0 { - for _, fsOrderDetail := range fsOrderRel.FsOrderDetails { + if len(fsOrderRelInfo.FsOrderDetails) > 0 { + for _, fsOrderDetail := range fsOrderRelInfo.FsOrderDetails { if fsOrderDetail.FsOrderDetailTemplateInfo.FsProductDesignInfo.Id != 0 { designIds = append(designIds, fsOrderDetail.FsOrderDetailTemplateInfo.FsProductDesignInfo.Id) } @@ -139,8 +189,18 @@ func (l *StripeWebhookLogic) handlePaymentIntentSucceeded(paymentIntent *stripe. // 支付成功 if paymentIntent.Status == "succeeded" { - var card string = paymentIntent.LatestCharge.PaymentMethodDetails.Card.Last4 - var brand string = string(paymentIntent.LatestCharge.PaymentMethodDetails.Card.Brand) + var card string + var brand string + 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) + } + } + } err = orderModel.Trans(l.ctx, func(ctx context.Context, connGorm *gorm.DB) (err error) { // 更新支付信息 @@ -163,12 +223,17 @@ func (l *StripeWebhookLogic) handlePaymentIntentSucceeded(paymentIntent *stripe. } var orderInfo = &gmodel.FsOrder{} - + var orderStatus int64 + var orderIsPartPay int64 + var orderPayedAmount int64 + var orderIsPayCompleted int64 // 支付记录是首款 if *payInfo.PayStage == int64(constants.PAYSTAGE_DEPOSIT) { - *orderInfo.Status = int64(constants.STATUS_NEW_PART_PAY) - *orderInfo.IsPartPay = 1 - *orderInfo.PayedAmount = paymentIntent.Amount + orderStatus = int64(constants.STATUS_NEW_PART_PAY) + orderIsPartPay = 1 + orderInfo.IsPartPay = &orderIsPartPay + orderPayedAmount = paymentIntent.Amount + // 删除购物车 cartModelT := gmodel.NewFsCartModel(connGorm) err = cartModelT.DeleteCartsByIds(ctx, cartIds) @@ -180,14 +245,18 @@ func (l *StripeWebhookLogic) handlePaymentIntentSucceeded(paymentIntent *stripe. // 支付记录是尾款 if *payInfo.PayStage == int64(constants.PAYSTAGE_REMAINING) { if *orderInfo.Status < int64(constants.STATUS_NEW_PAY_COMPLETED) { - *orderInfo.Status = int64(constants.STATUS_NEW_PAY_COMPLETED) + orderStatus = int64(constants.STATUS_NEW_PAY_COMPLETED) } - *orderInfo.IsPayCompleted = 1 - *orderInfo.PayedAmount = *orderInfo.PayedAmount + paymentIntent.Amount + orderIsPayCompleted = 1 + orderInfo.IsPayCompleted = &orderIsPayCompleted + orderPayedAmount = *orderInfo.PayedAmount + paymentIntent.Amount } // 更新订单信息 - *orderInfo.Ptime = nowTime + orderInfo.Id = fsOrderRelInfo.Id + orderInfo.Status = &orderStatus + orderInfo.Ptime = &nowTime + orderInfo.PayedAmount = &orderPayedAmount orderModelT := gmodel.NewFsOrderModel(connGorm) err = orderModelT.Update(ctx, orderInfo) if err != nil { diff --git a/server/pay/internal/types/types.go b/server/pay/internal/types/types.go index c070431b..76c0341e 100644 --- a/server/pay/internal/types/types.go +++ b/server/pay/internal/types/types.go @@ -13,10 +13,13 @@ type OrderPaymentIntentReq struct { } type OrderPaymentIntentRes struct { - RedirectUrl string `json:"redirect_url"` + RedirectUrl string `json:"redirect_url"` + ClientSecret string `json:"clientSecret"` } type StripeWebhookReq struct { + Payload []byte `json:"base_byte_slice,optional"` + StripeSignature string `json:"Stripe-Signature"` } type Request struct { diff --git a/server_api/pay.api b/server_api/pay.api index e110c5d4..b7a1b0d1 100644 --- a/server_api/pay.api +++ b/server_api/pay.api @@ -15,7 +15,7 @@ service pay { post /api/pay/payment-intent(OrderPaymentIntentReq) returns (response); @handler StripeWebhookHandler - get /api/pay/stripe-webhook(StripeWebhookReq) returns (response); + post /api/pay/stripe-webhook(StripeWebhookReq) returns (response); } // 生成预付款 @@ -27,12 +27,15 @@ type ( PayMethod int64 `form:"pay_method"` //支付方式 } OrderPaymentIntentRes { - RedirectUrl string `json:"redirect_url"` + RedirectUrl string `json:"redirect_url"` + ClientSecret string `json:"clientSecret"` } ) // StripeWebhook支付通知 type ( StripeWebhookReq { + Payload []byte `json:"base_byte_slice,optional"` + StripeSignature string `json:"Stripe-Signature"` } ) \ No newline at end of file diff --git a/utils/pay/pay.go b/utils/pay/pay.go index 005d700d..a378e4a8 100644 --- a/utils/pay/pay.go +++ b/utils/pay/pay.go @@ -24,6 +24,7 @@ type Pay interface { } type GeneratePrepaymentReq struct { + OrderSn string `json:"order_sn"` // 订单编号 Amount int64 `json:"amount"` // 支付金额 Currency string `json:"currency"` // 支付货币 ProductName string `json:"product_name"` // 商品名称 @@ -35,6 +36,8 @@ type GeneratePrepaymentReq struct { } type GeneratePrepaymentRes struct { - URL string `json:"url"` // 支付重定向地址 - TradeNo string `json:"trade_no"` //交易ID + URL string `json:"url"` // 支付重定向地址 + TradeNo string `json:"trade_no"` //交易ID + ClientSecret string `json:"clientSecret"` //交易密钥 + SessionId string `json:"session_id"` //SessionId } diff --git a/utils/pay/stripe.go b/utils/pay/stripe.go index 9dc5a2cf..cc8127f7 100644 --- a/utils/pay/stripe.go +++ b/utils/pay/stripe.go @@ -12,6 +12,7 @@ type Stripe struct { // 生成预付款 func (stripePay *Stripe) GeneratePrepayment(req *GeneratePrepaymentReq) (res *GeneratePrepaymentRes, err error) { var productData stripe.CheckoutSessionLineItemPriceDataProductDataParams + // productData.Metadata = map[string]string{"order_id": "33333333333333"} if req.ProductName != "" { productData.Name = stripe.String(req.ProductName) @@ -30,7 +31,14 @@ func (stripePay *Stripe) GeneratePrepayment(req *GeneratePrepaymentReq) (res *Ge // productData.Images = images stripe.Key = stripePay.Key + // session 方式 params := &stripe.CheckoutSessionParams{ + PaymentIntentData: &stripe.CheckoutSessionPaymentIntentDataParams{Metadata: map[string]string{"order_sn": req.OrderSn}}, + // Params: stripe.Params{Metadata: map[string]string{"order_id": "1111111111111"}}, + PaymentMethodTypes: stripe.StringSlice([]string{ + "card", + // "ideal", + }), LineItems: []*stripe.CheckoutSessionLineItemParams{ { PriceData: &stripe.CheckoutSessionLineItemPriceDataParams{ @@ -47,12 +55,24 @@ func (stripePay *Stripe) GeneratePrepayment(req *GeneratePrepaymentReq) (res *Ge } result, err := session.New(params) + // 密钥方式 + // params := &stripe.PaymentIntentParams{ + // Amount: stripe.Int64(req.Amount), + // Currency: stripe.String(string(req.Currency)), + // AutomaticPaymentMethods: &stripe.PaymentIntentAutomaticPaymentMethodsParams{ + // Enabled: stripe.Bool(true), + // }, + // } + // result, err := paymentintent.New(params) + if err != nil { return nil, err } return &GeneratePrepaymentRes{ - URL: result.URL, - TradeNo: result.ID, + URL: result.URL, + //TradeNo: result.ID, + SessionId: result.ID, + // ClientSecret: result.ClientSecret, }, err }