106 lines
2.7 KiB
Go
106 lines
2.7 KiB
Go
package httpx
|
|
|
|
import (
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type paymentIntentVerification struct {
|
|
PaymentIntentID string `json:"paymentIntentId"`
|
|
WebhookState string `json:"webhookState"`
|
|
WebhookEventID string `json:"webhookEventId,omitempty"`
|
|
WebhookEventType string `json:"webhookEventType,omitempty"`
|
|
Message string `json:"message"`
|
|
Verified bool `json:"verified"`
|
|
UpdatedAt time.Time `json:"updatedAt"`
|
|
CreatedAt time.Time `json:"createdAt"`
|
|
}
|
|
|
|
type paymentIntentStateStore struct {
|
|
mu sync.RWMutex
|
|
records map[string]paymentIntentVerification
|
|
}
|
|
|
|
func newPaymentIntentStateStore() *paymentIntentStateStore {
|
|
return &paymentIntentStateStore{records: make(map[string]paymentIntentVerification)}
|
|
}
|
|
|
|
func (s *paymentIntentStateStore) upsertCreated(paymentIntentID string) {
|
|
if strings.TrimSpace(paymentIntentID) == "" {
|
|
return
|
|
}
|
|
|
|
now := time.Now().UTC()
|
|
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
|
|
record, exists := s.records[paymentIntentID]
|
|
if !exists {
|
|
record = paymentIntentVerification{
|
|
PaymentIntentID: paymentIntentID,
|
|
CreatedAt: now,
|
|
}
|
|
}
|
|
|
|
record.WebhookState = "awaiting_webhook"
|
|
record.Message = "Waiting for Stripe webhook verification."
|
|
record.Verified = false
|
|
record.UpdatedAt = now
|
|
|
|
s.records[paymentIntentID] = record
|
|
}
|
|
|
|
func (s *paymentIntentStateStore) applyWebhook(result *stripeWebhookResult) {
|
|
if result == nil || strings.TrimSpace(result.PaymentIntentID) == "" {
|
|
return
|
|
}
|
|
|
|
now := time.Now().UTC()
|
|
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
|
|
record, exists := s.records[result.PaymentIntentID]
|
|
if !exists {
|
|
record = paymentIntentVerification{
|
|
PaymentIntentID: result.PaymentIntentID,
|
|
CreatedAt: now,
|
|
}
|
|
}
|
|
|
|
record.WebhookEventID = result.EventID
|
|
record.WebhookEventType = result.EventType
|
|
record.Message = result.Message
|
|
record.Verified = result.Verified
|
|
record.UpdatedAt = now
|
|
|
|
switch result.OrderState {
|
|
case "paid_verified_local_only", "paid_unrecorded":
|
|
record.WebhookState = "succeeded"
|
|
case "payment_failed_verified_local_only", "payment_failed_unrecorded":
|
|
record.WebhookState = "failed"
|
|
case "processing_verified_local_only", "processing_unrecorded":
|
|
record.WebhookState = "processing"
|
|
case "canceled_verified_local_only", "canceled_unrecorded":
|
|
record.WebhookState = "canceled"
|
|
case "ignored":
|
|
record.WebhookState = "ignored"
|
|
default:
|
|
record.WebhookState = "awaiting_webhook"
|
|
}
|
|
|
|
s.records[result.PaymentIntentID] = record
|
|
}
|
|
|
|
func (s *paymentIntentStateStore) get(paymentIntentID string) (paymentIntentVerification, bool) {
|
|
s.mu.RLock()
|
|
defer s.mu.RUnlock()
|
|
|
|
record, exists := s.records[paymentIntentID]
|
|
return record, exists
|
|
}
|
|
|
|
var paymentIntentStates = newPaymentIntentStateStore()
|