Query for unfulfilled events stripe

main
Cameron Murphy Reikes 2 years ago
parent 381480873f
commit ba0fee6317

@ -658,8 +658,6 @@ void end_text_input(char *what_player_said)
return; return;
} }
player->state = CHARACTER_IDLE; player->state = CHARACTER_IDLE;
#ifdef WEB // hacky
#endif
size_t player_said_len = strlen(what_player_said); size_t player_said_len = strlen(what_player_said);
int actual_len = 0; int actual_len = 0;

@ -14,6 +14,7 @@ import (
"math/rand" "math/rand"
gogpt "github.com/sashabaranov/go-gpt3" gogpt "github.com/sashabaranov/go-gpt3"
"github.com/stripe/stripe-go/v74" "github.com/stripe/stripe-go/v74"
"github.com/stripe/stripe-go/v74/event"
"github.com/stripe/stripe-go/v74/webhook" "github.com/stripe/stripe-go/v74/webhook"
"github.com/stripe/stripe-go/v74/checkout/session" "github.com/stripe/stripe-go/v74/checkout/session"
@ -97,33 +98,12 @@ func clearOld(db *gorm.DB) {
} }
} }
func webhookResponse(w http.ResponseWriter, req *http.Request) { func handleEvent(event stripe.Event) error {
const MaxBodyBytes = int64(65536)
req.Body = http.MaxBytesReader(w, req.Body, MaxBodyBytes)
body, err := ioutil.ReadAll(req.Body)
if err != nil {
log.Printf("Error reading request body: %v\n", err)
w.WriteHeader(http.StatusServiceUnavailable)
return
}
endpointSecret := webhookSecret
event, err := webhook.ConstructEvent(body, req.Header.Get("Stripe-Signature"), endpointSecret)
if err != nil {
log.Printf("Error verifying webhook signature %s\n", err)
w.WriteHeader(http.StatusBadRequest) // Return a 400 error on a bad signature
return
}
if event.Type == "checkout.session.completed" { if event.Type == "checkout.session.completed" {
var session stripe.CheckoutSession var session stripe.CheckoutSession
err := json.Unmarshal(event.Data.Raw, &session) err := json.Unmarshal(event.Data.Raw, &session)
if err != nil { if err != nil {
log.Printf("Error parsing webhook JSON %s", err) return fmt.Errorf("Error parsing webhook JSON %s", err)
w.WriteHeader(http.StatusBadRequest)
return
} }
params := &stripe.CheckoutSessionParams{} params := &stripe.CheckoutSessionParams{}
@ -132,7 +112,6 @@ func webhookResponse(w http.ResponseWriter, req *http.Request) {
// Retrieve the session. If you require line items in the response, you may include them by expanding line_items. // Retrieve the session. If you require line items in the response, you may include them by expanding line_items.
// Fulfill the purchase... // Fulfill the purchase...
var toFulfill User var toFulfill User
found := false found := false
for trial := 0; trial < 5; trial++ { for trial := 0; trial < 5; trial++ {
@ -144,17 +123,50 @@ func webhookResponse(w http.ResponseWriter, req *http.Request) {
} }
} }
if !found { if !found {
log.Println("Error Failed to find user in database to fulfill: very bad! ID: " + session.ID) return fmt.Errorf("Error Failed to find user in database to fulfill: very bad! ID: " + session.ID)
} else { } else {
userString, err := codes.CodeToString(toFulfill.Code) userString, err := codes.CodeToString(toFulfill.Code)
if err != nil { if err != nil {
log.Printf("Error strange thing, saved user's code was unable to be converted to a string %s", err) return fmt.Errorf("Error strange thing, saved user's code was unable to be converted to a string %s", err)
} }
log.Printf("Fulfilling user with code %s number %d\n", userString, toFulfill.Code) log.Printf("Fulfilling user with code %s number %d\n", userString, toFulfill.Code)
if(toFulfill.IsFulfilled) {
log.Printf("User with code %s is already fulfilled, strange\n", userString)
}
toFulfill.IsFulfilled = true toFulfill.IsFulfilled = true
db.Save(&toFulfill) err = db.Save(&toFulfill).Error
if err != nil {
return fmt.Errorf("Failed to save fulfilled flag status to database: %s", err)
}
} }
} }
return nil
}
func webhookResponse(w http.ResponseWriter, req *http.Request) {
const MaxBodyBytes = int64(65536)
req.Body = http.MaxBytesReader(w, req.Body, MaxBodyBytes)
body, err := ioutil.ReadAll(req.Body)
if err != nil {
log.Printf("Error reading request body: %v\n", err)
w.WriteHeader(http.StatusServiceUnavailable)
return
}
endpointSecret := webhookSecret
event, err := webhook.ConstructEvent(body, req.Header.Get("Stripe-Signature"), endpointSecret)
if err != nil {
log.Printf("Error verifying webhook signature %s\n", err)
w.WriteHeader(http.StatusBadRequest) // Return a 400 error on a bad signature
return
}
err = handleEvent(event)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
}
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
} }
@ -285,12 +297,30 @@ func index(w http.ResponseWriter, req *http.Request) {
} else { } else {
// now have valid user, in the database, to be rate limit checked // now have valid user, in the database, to be rate limit checked
// rate limiting based on user token // rate limiting based on user token
_, exists := daypassTimedOut[thisUserCode] if !thisUser.IsFulfilled {
if exists { log.Println("Unfulfilled user trying to play, might've been unresponded to event. Retrieving backlog of unfulfilled events...\n")
rejected = true params := &stripe.EventListParams{}
params.Filters.AddFilter("delivery_success", "", "false")
i := event.List(params)
for i.Next() {
e := i.Event()
log.Println("Unfulfilled event! Of type %s. Handling...\n", e.Type)
err := handleEvent(*e)
if err != nil {
log.Println("Failed to fulfill unfulfilled event: %s\n", err)
}
}
}
if thisUser.IsFulfilled {
_, exists := daypassTimedOut[thisUserCode]
if exists {
rejected = true
} else {
rejected = false
daypassTimedOut[thisUserCode] = currentTime()
}
} else { } else {
rejected = false log.Println("User with code and existing entry in database was not fulfilled, and wanted to play... Very bad. Usercode: %s\n", thisUserCode)
daypassTimedOut[thisUserCode] = currentTime()
} }
} }
} }

Loading…
Cancel
Save