Skip to content

Commit

Permalink
✨ feat(pay): Automatically Create Stripe Webhook (#373)
Browse files Browse the repository at this point in the history
  • Loading branch information
thlz998 committed Sep 28, 2024
1 parent dcbe1ad commit 0525d0d
Show file tree
Hide file tree
Showing 13 changed files with 8,313 additions and 14 deletions.
26 changes: 22 additions & 4 deletions controller/payment.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package controller

import (
"log"
"net/http"
"one-api/common"
"one-api/model"
paymentService "one-api/payment"
"strconv"

"github.com/gin-gonic/gin"
Expand Down Expand Up @@ -61,15 +63,31 @@ func AddPayment(c *gin.Context) {
return
}

err = payment.Insert()
if err := payment.Insert(); err != nil {
common.APIRespondWithError(c, http.StatusInternalServerError, err)
return
}

ps, err := paymentService.NewPaymentService(payment.UUID)
if err != nil {
common.APIRespondWithError(c, http.StatusOK, err)
if deleteErr := payment.Delete(); deleteErr != nil {
log.Printf("Failed to delete payment after service creation error: %v", deleteErr)
}
common.APIRespondWithError(c, http.StatusInternalServerError, err)
return
}

c.JSON(http.StatusOK, gin.H{
if err := ps.CreatedPay(); err != nil {
if deleteErr := payment.Delete(); deleteErr != nil {
log.Printf("Failed to delete payment after creation error: %v", deleteErr)
}
common.APIRespondWithError(c, http.StatusInternalServerError, err)
return
}

c.JSON(http.StatusCreated, gin.H{
"success": true,
"message": "",
"message": "Payment added successfully",
"data": payment,
})
}
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ require (
github.com/smartwalle/alipay/v3 v3.2.21
github.com/spf13/viper v1.18.2
github.com/stretchr/testify v1.9.0
github.com/stripe/stripe-go/v72 v72.122.0
github.com/stripe/stripe-go/v79 v79.12.0
github.com/wechatpay-apiv3/wechatpay-go v0.2.18
github.com/wneessen/go-mail v0.4.1
Expand Down
3 changes: 0 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,6 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
Expand All @@ -452,8 +451,6 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stripe/stripe-go/v72 v72.122.0 h1:eRXWqnEwGny6dneQ5BsxGzUCED5n180u8n665JHlut8=
github.com/stripe/stripe-go/v72 v72.122.0/go.mod h1:QwqJQtduHubZht9mek5sds9CtQcKFdsykV9ZepRWwo0=
github.com/stripe/stripe-go/v79 v79.12.0 h1:HQs/kxNEB3gYA7FnkSFkp0kSOeez0fsmCWev6SxftYs=
github.com/stripe/stripe-go/v79 v79.12.0/go.mod h1:cuH6X0zC8peY6f1AubHwgJ/fJSn2dh5pfiCr6CjyKVU=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
Expand Down
16 changes: 16 additions & 0 deletions gowatch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
appname: "one-api"

debug: true

output: one-api

# 添加环境变量设置
env:
- CGO_ENABLED=0

build_args:
- -ldflags
- "-s -w -X 'one-api/common.Version=Dev-0'"

excluded_paths:
- web
Binary file added one-api
Binary file not shown.
8 changes: 7 additions & 1 deletion payment/gateway/alipay/payment.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import (
"encoding/json"
"errors"
"fmt"
"one-api/model"
"one-api/payment/types"

"github.com/gin-gonic/gin"
"github.com/smartwalle/alipay/v3"
"one-api/payment/types"
)

type Alipay struct{}
Expand Down Expand Up @@ -100,3 +102,7 @@ func getAlipayConfig(gatewayConfig string) (*AlipayConfig, error) {

return &alipayConfig, nil
}

func (a *Alipay) CreatedPay(notifyURL string, gatewayConfig *model.Payment) error {
return nil
}
4 changes: 4 additions & 0 deletions payment/gateway/epay/payment.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"net/http"
"one-api/model"
"one-api/payment/types"
"strconv"

Expand Down Expand Up @@ -89,3 +90,6 @@ func getEpayConfig(gatewayConfig string) (*EpayConfig, error) {

return &epayConfig, nil
}
func (e *Epay) CreatedPay(notifyURL string, gatewayConfig *model.Payment) error {
return nil
}
74 changes: 73 additions & 1 deletion payment/gateway/stripe/payment.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ import (
"encoding/json"
"fmt"
"math"
"one-api/model"
"one-api/payment/types"
"strconv"

sysconfig "one-api/common/config"

"github.com/gin-gonic/gin"
"github.com/stripe/stripe-go/v72/webhook"
"github.com/stripe/stripe-go/v79"
"github.com/stripe/stripe-go/v79/client"
"github.com/stripe/stripe-go/v79/webhook"
"github.com/stripe/stripe-go/v79/webhookendpoint"
)

// Stripe 结构体实现支付接口
Expand Down Expand Up @@ -76,6 +78,76 @@ func (e *Stripe) Pay(config *types.PayConfig, gatewayConfig string) (*types.PayR
return payRequest, nil
}

func (e *Stripe) CreatedPay(notifyURL string, gatewayConfig *model.Payment) error {
eventName := "checkout.session.completed"
var stripeConfig StripeConfig
err := json.Unmarshal([]byte(gatewayConfig.Config), &stripeConfig)
if err != nil {
fmt.Println("Error parsing JSON:", err)
return err
}
stripe.Key = stripeConfig.SecretKey
params := &stripe.WebhookEndpointListParams{}
params.Limit = stripe.Int64(100)
i := webhookendpoint.List(params)

var existingWebhook *stripe.WebhookEndpoint
for i.Next() {
webhook := i.WebhookEndpoint()
if webhook.URL == notifyURL && contains(webhook.EnabledEvents, eventName) {
existingWebhook = webhook
break
}
}

if err := i.Err(); err != nil {
return fmt.Errorf("error listing webhooks: %v", err)
}
// 如果不存在匹配的 Webhook,则创建新的
var wh *stripe.WebhookEndpoint

if existingWebhook == nil {
createParams := &stripe.WebhookEndpointParams{
URL: stripe.String(notifyURL),
EnabledEvents: []*string{
stripe.String(eventName),
},
}
newWebhook, err := webhookendpoint.New(createParams)
if err != nil {
return fmt.Errorf("error creating webhook: %v", err)
}
wh = newWebhook
fmt.Printf("Created new webhook: %s\n", newWebhook.ID)
} else {
fmt.Printf("Webhook already exists: %s\n", existingWebhook.ID)
wh = existingWebhook
}

stripeConfig.WebhookSecret = wh.Secret
config, err := json.Marshal(stripeConfig)
if err != nil {
return fmt.Errorf("error creating webhook: %v", err)
}

gatewayConfig.Config = string(config)
err = gatewayConfig.Update(true)
if err != nil {
return fmt.Errorf("error creating webhook: %v", err)
}
return nil
}

// 辅助函数来检查字符串切片中是否包含特定字符串
func contains(slice []string, str string) bool {
for _, v := range slice {
if v == str {
return true
}
}
return false
}

// HandleCallback 处理支付回调
func (e *Stripe) HandleCallback(c *gin.Context, gatewayConfig string) (*types.PayNotify, error) {
body, err := c.GetRawData()
Expand Down
12 changes: 9 additions & 3 deletions payment/gateway/wxpay/payment.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ import (
"encoding/json"
"errors"
"fmt"
"log"
"net/http"
"one-api/model"
"one-api/payment/types"

"github.com/gin-gonic/gin"
"github.com/wechatpay-apiv3/wechatpay-go/core"
"github.com/wechatpay-apiv3/wechatpay-go/core/auth/verifiers"
Expand All @@ -13,9 +18,6 @@ import (
"github.com/wechatpay-apiv3/wechatpay-go/core/option"
"github.com/wechatpay-apiv3/wechatpay-go/services/payments"
"github.com/wechatpay-apiv3/wechatpay-go/utils"
"log"
"net/http"
"one-api/payment/types"
)

type WeChatPay struct{}
Expand Down Expand Up @@ -122,3 +124,7 @@ func getWeChatConfig(gatewayConfig string) (*WeChatConfig, error) {

return &wechatConfig, nil
}

func (w *WeChatPay) CreatedPay(notifyURL string, gatewayConfig *model.Payment) error {
return nil
}
2 changes: 2 additions & 0 deletions payment/payment.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package payment

import (
"one-api/model"
"one-api/payment/gateway/alipay"
"one-api/payment/gateway/epay"
"one-api/payment/gateway/stripe"
Expand All @@ -13,6 +14,7 @@ import (
type PaymentProcessor interface {
Name() string
Pay(config *types.PayConfig, gatewayConfig string) (*types.PayRequest, error)
CreatedPay(notifyURL string, gatewayConfig *model.Payment) error
HandleCallback(c *gin.Context, gatewayConfig string) (*types.PayNotify, error)
}

Expand Down
5 changes: 5 additions & 0 deletions payment/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ func NewPaymentService(uuid string) (*PaymentService, error) {
}, nil
}

func (s *PaymentService) CreatedPay() error {
notifyURL := s.getNotifyURL()
return s.gateway.CreatedPay(notifyURL, s.Payment)
}

func (s *PaymentService) Pay(tradeNo string, amount float64, currency model.CurrencyType) (*types.PayRequest, error) {
config := &types.PayConfig{
Money: amount,
Expand Down
Loading

0 comments on commit 0525d0d

Please sign in to comment.