mirror of
https://github.com/rjNemo/rentease.git
synced 2026-06-06 02:36:49 +00:00
Upgrade Stripe SDK from v79 to v83 across the codebase. Update all imports to use github.com/stripe/stripe-go/v83 and refactor client usage to match the new API, including changes to PaymentIntents listing. Update documentation and plans to reference the new version. Remove references to the old version from go.mod and go.sum.
150 lines
4.1 KiB
Go
150 lines
4.1 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/labstack/echo/v4"
|
|
"github.com/stripe/stripe-go/v83"
|
|
"github.com/stripe/stripe-go/v83/webhook"
|
|
)
|
|
|
|
type stubStripeEventService struct {
|
|
intentCalled bool
|
|
chargeCalled bool
|
|
err error
|
|
}
|
|
|
|
func (s *stubStripeEventService) HandlePaymentIntentSucceeded(ctx context.Context, pi *stripe.PaymentIntent) error {
|
|
s.intentCalled = true
|
|
return s.err
|
|
}
|
|
|
|
func (s *stubStripeEventService) HandleChargeRefunded(ctx context.Context, ch *stripe.Charge) error {
|
|
s.chargeCalled = true
|
|
return s.err
|
|
}
|
|
|
|
func TestHandleStripeWebhookPaymentIntent(t *testing.T) {
|
|
secret := "whsec_test"
|
|
payload := map[string]any{
|
|
"id": "evt_test",
|
|
"type": "payment_intent.succeeded",
|
|
"api_version": stripe.APIVersion,
|
|
"data": map[string]any{
|
|
"object": map[string]any{
|
|
"id": "pi_123",
|
|
"amount": 10000,
|
|
"amount_received": 10000,
|
|
"currency": "eur",
|
|
"status": "succeeded",
|
|
"metadata": map[string]string{"booking_id": "42"},
|
|
"payment_method_types": []string{"card"},
|
|
},
|
|
},
|
|
}
|
|
|
|
payloadBytes, err := json.Marshal(payload)
|
|
if err != nil {
|
|
t.Fatalf("failed to marshal payload: %v", err)
|
|
}
|
|
|
|
ts := time.Now()
|
|
sig := webhook.ComputeSignature(ts, payloadBytes, secret)
|
|
sigHeader := fmt.Sprintf("t=%d,v1=%s", ts.Unix(), hex.EncodeToString(sig))
|
|
if _, err := webhook.ConstructEvent(payloadBytes, sigHeader, secret); err != nil {
|
|
t.Fatalf("signature validation failed in setup: %v", err)
|
|
}
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodPost, "/webhooks/stripe", strings.NewReader(string(payloadBytes)))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
|
req.Header.Set("Stripe-Signature", sigHeader)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
service := &stubStripeEventService{}
|
|
handler := handleStripeWebhook(service, secret)
|
|
|
|
if err := handler(c); err != nil {
|
|
t.Fatalf("handler returned error: %v", err)
|
|
}
|
|
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("expected 200, got %d", rec.Code)
|
|
}
|
|
|
|
if !service.intentCalled {
|
|
t.Fatalf("expected payment intent handler to be called")
|
|
}
|
|
}
|
|
|
|
func TestHandleStripeWebhookChargeRefunded(t *testing.T) {
|
|
secret := "whsec_test"
|
|
payload := map[string]any{
|
|
"id": "evt_charge",
|
|
"type": "charge.refunded",
|
|
"api_version": stripe.APIVersion,
|
|
"data": map[string]any{
|
|
"object": map[string]any{
|
|
"id": "ch_123",
|
|
"amount": 5000,
|
|
"amount_refunded": 5000,
|
|
"payment_intent": map[string]any{
|
|
"id": "pi_123",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
payloadBytes, _ := json.Marshal(payload)
|
|
ts := time.Now()
|
|
sig := webhook.ComputeSignature(ts, payloadBytes, secret)
|
|
sigHeader := fmt.Sprintf("t=%d,v1=%s", ts.Unix(), hex.EncodeToString(sig))
|
|
if _, err := webhook.ConstructEvent(payloadBytes, sigHeader, secret); err != nil {
|
|
t.Fatalf("signature validation failed in setup: %v", err)
|
|
}
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodPost, "/webhooks/stripe", strings.NewReader(string(payloadBytes)))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
|
req.Header.Set("Stripe-Signature", sigHeader)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
service := &stubStripeEventService{}
|
|
handler := handleStripeWebhook(service, secret)
|
|
|
|
if err := handler(c); err != nil {
|
|
t.Fatalf("handler returned error: %v", err)
|
|
}
|
|
|
|
if !service.chargeCalled {
|
|
t.Fatalf("expected charge handler to be called")
|
|
}
|
|
}
|
|
|
|
func TestHandleStripeWebhookInvalidSignature(t *testing.T) {
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodPost, "/webhooks/stripe", strings.NewReader("{}"))
|
|
req.Header.Set("Stripe-Signature", "invalid")
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
handler := handleStripeWebhook(&stubStripeEventService{}, "secret")
|
|
err := handler(c)
|
|
if err == nil {
|
|
t.Fatal("expected error for invalid signature")
|
|
}
|
|
|
|
if httpErr, ok := err.(*echo.HTTPError); !ok || httpErr.Code != http.StatusBadRequest {
|
|
t.Fatalf("expected 400 HTTP error, got %v", err)
|
|
}
|
|
}
|