Jade/Stripe.go

170 lines
4.6 KiB
Go

package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"github.com/flosch/pongo2"
"github.com/gofiber/fiber/v2"
"github.com/stripe/stripe-go"
"github.com/stripe/stripe-go/customer"
)
func PricingTableHandler(c *fiber.Ctx) error {
return c.SendString(generatePricingTableChatHTML())
}
func generatePricingTableChatHTML() string {
var result User
err := edgeClient.QuerySingle(edgeCtx, "SELECT global currentUser { stripe_id, email } LIMIT 1;", &result)
if err != nil {
panic(err)
}
clientSecretSession := CreateClientSecretSession()
// TODO Replace by live API call
stripeTable := `
<stripe-pricing-table
pricing-table-id="prctbl_1OxrazP2nW0okNQymYvskUk7"
publishable-key="pk_test_51OxXuWP2nW0okNQy2jyS70vx7WHZzDskvQazsitSDJQ3ifVHPqAkMv7orCePwRGRTarNn8uMuaxbVqD2Zg80oRc600epN4ycQ4"
customer-session-client-secret="` + clientSecretSession + `">
</stripe-pricing-table>`
closeBtn := `
<div class="is-flex is-justify-content-flex-end">
<a class="button is-small is-danger is-outlined" hx-get="/loadChat" hx-target="#chat-container" hx-swap="outerHTML"
hx-trigger="click">
<span class="icon">
<i class="fa-solid fa-xmark"></i>
</span>
</a>
</div>`
htmlString := "<div class='columns is-centered' id='chat-container'><div class='column is-12-mobile is-8-tablet is-6-desktop' id='chat-messages'>"
NextMessages := []TemplateMessage{}
nextMsg := TemplateMessage{
Icon: "icons/bouvai2.png", // Assuming Icon is a field you want to include from Message
Content: "<br>" + stripeTable + closeBtn,
Hidden: false, // Assuming Hidden is a field you want to include from Message
Id: "0",
Name: "JADE",
}
NextMessages = append(NextMessages, nextMsg)
botOut, err := botTmpl.Execute(pongo2.Context{"Messages": NextMessages, "ConversationAreaId": 0, "NotClickable": true, "notFlex": true})
if err != nil {
panic(err)
}
htmlString += botOut
htmlString += "<div style='height: 10px;'></div>"
htmlString += "</div></div>"
// Render the HTML template with the messages
return htmlString
}
func CreateNewStripeCustomer(name string, email string) string {
params := &stripe.CustomerParams{
Name: stripe.String(name),
Email: stripe.String(email),
}
result, err := customer.New(params)
if err != nil {
panic(err)
}
return result.ID
}
func IsCurrentUserSubscribed() bool {
var user User
err := edgeClient.QuerySingle(edgeCtx, "SELECT global currentUser { stripe_id } LIMIT 1;", &user)
if err != nil {
panic(err)
}
result, err := customer.Get(user.StripeID, nil)
if err != nil {
panic(err)
}
if result.Subscriptions.TotalCount == 0 {
return false
}
return result.Subscriptions.Data[0].Plan.Product.ID == "prod_PnDjBBwvQN36cQ" && result.Subscriptions.Data[0].Plan.Active
}
func IsCurrentUserLimiteReached() bool {
// Count the number of Usage for the current user
var count int64
err := edgeClient.QuerySingle(edgeCtx, `
WITH
U := (
SELECT Usage
FILTER .user = global currentUser
)
SELECT count(U)
`, &count)
if err != nil {
panic(err)
}
return count >= 500
}
func CreateClientSecretSession() string {
var user User
err := edgeClient.QuerySingle(edgeCtx, "SELECT global currentUser { stripe_id } LIMIT 1;", &user)
if err != nil {
panic(err)
}
url := "https://api.stripe.com/v1/customer_sessions"
method := "POST"
apiKey := stripe.Key
payload := []byte(fmt.Sprintf("customer=%s&components[pricing_table][enabled]=true", user.StripeID))
req, err := http.NewRequest(method, url, bytes.NewBuffer(payload))
if err != nil {
panic(fmt.Sprintf("failed to create request: %v", err))
}
req.Header.Add("Authorization", "Bearer "+apiKey)
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(fmt.Sprintf("failed to execute request: %v", err))
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
panic(fmt.Sprintf("failed to create customer session: status code %d, response: %s", resp.StatusCode, string(body)))
}
body, err := io.ReadAll(resp.Body)
if err != nil {
panic(fmt.Sprintf("failed to read response body: %v", err))
}
type CustomerSessionResponse struct {
ClientSecret string `json:"client_secret"`
CustomerID string `json:"customer"`
}
var customerSession CustomerSessionResponse
if err := json.Unmarshal(body, &customerSession); err != nil {
panic(fmt.Sprintf("failed to unmarshal response: %v", err))
}
if user.StripeID != customerSession.CustomerID {
panic(fmt.Sprintf("customer_id does not match: got %s, expected %s", customerSession.CustomerID, user.StripeID))
}
return customerSession.ClientSecret
}