Skip to content

Commit 7ab2173

Browse files
committed
Move to Alpha
1 parent 5794927 commit 7ab2173

4 files changed

Lines changed: 60 additions & 22 deletions

File tree

cmd/web/main.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ import (
1515
"github.com/stripe/stripe-go/v84"
1616
)
1717

18-
// TODO: 禁止重复订阅
1918
// TODO: 防止 /checkout/success 被滥用
20-
// TODO: 日志
2119
// TODO: 创建订阅集合迁移文件
2220
// TODO: 创建用户集合迁移文件
2321
// TODO: 用.env初始化SMTP和设置
@@ -64,6 +62,7 @@ func main() {
6462

6563
err := app.Start()
6664
if err != nil {
65+
app.Logger().Error("Web Server Error: ", err)
6766
panic(err)
6867
}
6968
}

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
services:
22
app:
3-
image: ghcr.io/pdnode-team/website:v1.0.0-dev.9
3+
image: ghcr.io/pdnode-team/website:v1.0.0-alpha
44
container_name: pdnode-website
55
ports:
66
- "8090:8090"

internal/subscriptions/handler.go

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"io"
99
"net/http"
1010

11-
"github.com/pocketbase/pocketbase/apis"
1211
"github.com/pocketbase/pocketbase/core"
1312
"github.com/stripe/stripe-go/v84"
1413
"github.com/stripe/stripe-go/v84/webhook"
@@ -20,9 +19,6 @@ type SubscriptionHandler struct {
2019

2120
func (h *SubscriptionHandler) Checkout(e *core.RequestEvent) error {
2221
user := e.Auth
23-
if user == nil {
24-
return apis.NewUnauthorizedError("Login first", nil)
25-
}
2622

2723
var data struct {
2824
Plan string `json:"plan"`
@@ -42,7 +38,18 @@ func (h *SubscriptionHandler) Checkout(e *core.RequestEvent) error {
4238

4339
url, err := h.service.CreateCheckoutSession(user, data.Plan, baseURL)
4440
if err != nil {
45-
return e.BadRequestError(err.Error(), nil)
41+
switch {
42+
case errors.Is(err, ErrPlanInvalid):
43+
return e.BadRequestError("The selected plan is invalid.", nil)
44+
45+
case errors.Is(err, ErrAlreadySubscribed):
46+
return e.BadRequestError("You already have an active subscription.", nil)
47+
48+
default:
49+
// 记录未知的系统错误
50+
h.service.app.Logger().Error("Checkout failed", "error", err)
51+
return e.InternalServerError("An unexpected error occurred.", nil)
52+
}
4653
}
4754

4855
return e.JSON(http.StatusOK, map[string]string{"url": url})
@@ -63,39 +70,51 @@ func (h *SubscriptionHandler) StripeWebhook(e *core.RequestEvent) error {
6370
},
6471
)
6572
if err != nil {
66-
fmt.Println(err)
73+
h.service.app.Logger().Debug("Invalid Stripe signature", "err", err)
6774
return e.BadRequestError("Invalid signature", nil)
6875
}
6976

77+
h.service.app.Logger().Info("Received Stripe Webhook",
78+
"type", event.Type,
79+
"id", event.ID,
80+
)
81+
7082
switch event.Type {
7183
case "checkout.session.completed":
7284
var session stripe.CheckoutSession
7385
err := json.Unmarshal(event.Data.Raw, &session)
7486
if err != nil {
75-
fmt.Println(err)
87+
h.service.app.Logger().Warn("Stripe webhook: JSON unmarshal failed", "err", err)
7688
return e.BadRequestError("JSON unmarshal failed", nil)
7789
}
7890

7991
// 🌟 调用 Service 层处理业务(如更新用户订阅状态、发货等)
8092
// 传入 e.App (PocketBase 实例) 以便在 Service 里操作数据库
8193
if err := h.service.HandleCheckoutCompleted(session); err != nil {
82-
fmt.Println(err)
94+
h.service.app.Logger().Error("Stripe webhook: checkout.session.completed processing failed",
95+
"error", err,
96+
"sessionId", session.ID,
97+
"userId", session.ClientReferenceID,
98+
)
8399

84-
return e.InternalServerError("Handle checkout failed", err)
100+
return e.InternalServerError("Handle checkout failed", nil)
85101
}
86102
case "invoice.paid":
87103

88104
var inv stripe.Invoice
89105
err := json.Unmarshal(event.Data.Raw, &inv)
90106
if err != nil {
91-
fmt.Println(err)
92-
return e.BadRequestError("Parsing invoice failed", err)
107+
108+
h.service.app.Logger().Warn("Stripe webhook: JSON unmarshal failed", "err", err)
109+
return e.BadRequestError("Parsing invoice failed", nil)
93110
}
94111

95112
err = h.service.HandleInvoicePaid(inv)
96113
if err != nil {
97-
fmt.Println(err)
98-
return e.InternalServerError("Handle checkout failed", err)
114+
h.service.app.Logger().Error("Stripe webhook: invoice.paid processing failed",
115+
"error", err,
116+
)
117+
return e.InternalServerError("Handle checkout failed", nil)
99118
}
100119

101120
}
@@ -108,12 +127,12 @@ func (h *SubscriptionHandler) CheckSubscription(e *core.RequestEvent) error {
108127

109128
if errors.Is(err, sql.ErrNoRows) {
110129

111-
return e.BadRequestError("No subscription", nil)
130+
return e.NotFoundError("No subscription", nil)
112131
}
113132

114133
if err != nil {
115-
116-
return e.InternalServerError("Check subscription failed", err)
134+
h.service.app.Logger().Warn("Failed to check subscription", "err", err)
135+
return e.InternalServerError("Check subscription failed", nil)
117136
}
118137

119138
return e.JSON(http.StatusOK, subscription)

internal/subscriptions/service.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package subscriptions
22

33
import (
4+
"database/sql"
45
"errors"
56
"fmt"
67
"time"
@@ -13,6 +14,11 @@ import (
1314
"github.com/stripe/stripe-go/v84/checkout/session"
1415
)
1516

17+
var (
18+
ErrAlreadySubscribed = errors.New("already_have_subscription")
19+
ErrPlanInvalid = errors.New("invalid_plan")
20+
)
21+
1622
type SubscriptionService struct {
1723
app *pocketbase.PocketBase
1824
cfg *config.Config
@@ -51,7 +57,19 @@ func (s *SubscriptionService) CheckValidSubscription(user *core.Record) (*core.R
5157
func (s *SubscriptionService) CreateCheckoutSession(user *core.Record, plan string, frontendURL string) (string, error) {
5258
priceID, exists := s.cfg.PlanToPrice[plan]
5359
if !exists || priceID == "" {
54-
return "", fmt.Errorf("invalid plan: %s", plan)
60+
return "", ErrPlanInvalid
61+
}
62+
63+
_, err := s.CheckValidSubscription(user.Original())
64+
65+
if !errors.Is(err, sql.ErrNoRows) {
66+
67+
return "", ErrAlreadySubscribed
68+
}
69+
70+
if err != nil {
71+
s.app.Logger().Warn("Failed to create checkout session", err)
72+
return "", errors.New("check subscription failed")
5573
}
5674

5775
params := &stripe.CheckoutSessionParams{
@@ -80,12 +98,12 @@ func (s *SubscriptionService) CreateCheckoutSession(user *core.Record, plan stri
8098
func (s *SubscriptionService) HandleInvoicePaid(inv stripe.Invoice) error {
8199

82100
if inv.Customer == nil {
83-
fmt.Println("invoice customer is nil")
101+
s.app.Logger().Warn("No customer found: ", inv)
84102
return errors.New("invoice customer is nil")
85103
}
86104

87105
if len(inv.Lines.Data) == 0 {
88-
fmt.Println("invoice has no lines")
106+
s.app.Logger().Warn("invoice has no lines: ", inv)
89107

90108
return errors.New("invoice has no lines")
91109
}
@@ -98,6 +116,7 @@ func (s *SubscriptionService) HandleInvoicePaid(inv stripe.Invoice) error {
98116

99117
collection, err := s.app.FindCollectionByNameOrId("subscriptions")
100118
if err != nil {
119+
s.app.Logger().Error("Failed to find collection: ", err)
101120
return errors.New("subscriptions collection not found")
102121
}
103122

@@ -111,6 +130,7 @@ func (s *SubscriptionService) HandleInvoicePaid(inv stripe.Invoice) error {
111130
fmt.Println(priceID)
112131

113132
if priceIDMap == "" {
133+
s.app.Logger().Warn("No prices found for invoice ", inv)
114134
return errors.New("invalid price")
115135
}
116136

0 commit comments

Comments
 (0)