Pārlūkot izejas kodu

Fix Stripe webhook errors

master
Immanuel Onyeka pirms 3 mēnešiem
vecāks
revīzija
33e71edc8e
5 mainītis faili ar 72 papildinājumiem un 77 dzēšanām
  1. +1
    -0
      components/settings.vue
  2. +4
    -2
      components/unsubscribe.vue
  3. +1
    -1
      grav-admin/user/js/registration/billing.vue
  4. +0
    -2
      grav-admin/user/js/registration/registration.vue
  5. +66
    -72
      skouter.go

+ 1
- 0
components/settings.vue Parādīt failu

@@ -84,6 +84,7 @@
</Dialog>

<UnsubPrompt v-if="unsubing" :token="token"
:cancelAtEnd="props.user.sub.cancelAtEnd"
@close="() => unsubing = false"
@cancelSub="() => { $emit('updateUser'); unsubing = false }"
/>


+ 4
- 2
components/unsubscribe.vue Parādīt failu

@@ -1,7 +1,9 @@
<template>

<Dialog @close="() => $emit('close')">
<h3>Are you sure you want to unsubscribe?</h3>
<h3>
Are you sure you want to {{cancelAtEnd ? "subscribe" : "unsubscribe"}}?
</h3>
<button @click="() => $emit('close')">Cancel</button>
<button @click="unsubscribe">Confirm</button>
</Dialog>
@@ -12,7 +14,7 @@
import Dialog from "./dialog.vue"

const emit = defineEmits(['close', 'cancelSub'])
const props = defineProps(['token'])
const props = defineProps(['token', 'cancelAtEnd'])

function unsubscribe() {
fetch(`/api/user/unsubscribe`,


+ 1
- 1
grav-admin/user/js/registration/billing.vue Parādīt failu

@@ -23,7 +23,7 @@ function submit() {
//`Elements` instance that was used to create the Payment Element
elements,
confirmParams: {
return_url: "https://skouter.net/register",
return_url: `https://${window.location.host}/app`,
}
})
}


+ 0
- 2
grav-admin/user/js/registration/registration.vue Parādīt failu

@@ -50,7 +50,6 @@ function getUser() {
}

function create(user) {
console.log(user)
fetch(`/api/user`,
{method: 'POST',
@@ -89,7 +88,6 @@ function intent(u) {
if (resp.ok) {
resp.json().then(s => {
err.value = ""
console.log(s)
sub.value = s
if (["processing", "succeeded"].includes(s.paymentStatus) &&


+ 66
- 72
skouter.go Parādīt failu

@@ -32,6 +32,8 @@ import (
"github.com/stripe/stripe-go/v76/customer"
"github.com/stripe/stripe-go/v76/subscription"
"github.com/stripe/stripe-go/v76/webhook"
"github.com/stripe/stripe-go/v76/invoice"
"github.com/stripe/stripe-go/v76/paymentintent"
"image"
_ "image/jpeg"
"image/png"
@@ -297,10 +299,10 @@ var feeTypes = []string{
}

var hookKeys = HookKeys{
InvoicePaid: "",
InvoicePaid: os.Getenv("STRIPE_SIGNING_SECRET_INVOICE_PAID"),
InvoiceFailed: "",
SubCreated: "",
SubUpdated: "",
SubCreated: os.Getenv("STRIPE_SIGNING_SECRET_SUB_CREATED"),
SubUpdated: os.Getenv("STRIPE_SIGNING_SECRET_SUB_UPDATED"),
SubDeleted: "",
}

@@ -1269,58 +1271,22 @@ func queryCustomer(db *sql.DB, id string) (User, error) {
var err error

query = `SELECT
u.id,
u.email,
u.first_name,
u.last_name,
coalesce(u.branch_id, 0),
u.country,
u.title,
coalesce(u.status, ''),
coalesce(u.customer_id, ''),
u.verified,
u.role,
u.address,
u.phone
u.id
FROM user u WHERE u.customer_id = ?
`
row := db.QueryRow(query, id)

if err != nil {
return user, err
}

err = row.Scan(
&user.Id,
&user.Email,
&user.FirstName,
&user.LastName,
&user.Branch.Id,
&user.Country,
&user.Title,
&user.Status,
&user.CustomerId,
&user.Verified,
&user.Role,
&user.Address.Id,
&user.Phone,
)

if err != nil {
return user, err
}

user.Address, err = queryAddress(db, user.Address.Id)
if err != nil {
return user, err
}

user.Branch, err = queryBranch(db, user.Branch.Id)
if err != nil {
return user, err
}
user, err = queryUser(db, user.Id)

return user, nil
return user, err
}

// Can probably be deleted.
@@ -1610,22 +1576,25 @@ func (sub *Subscription) updateSub(db *sql.DB) error {
var err error

query = `UPDATE subscription
SET client_secret = CASE @a := ? WHEN '' THEN client_secret ELSE @a END,
current_period_end = CASE
@b := ? WHEN 0 THEN current_period_end ELSE @b END,
current_period_start = CASE
@c := ? WHEN 0 THEN current_period_start ELSE @c END,
payment_status = CASE @d := ? WHEN '' THEN payment_status ELSE @d END,
status = CASE @e := ? WHEN '' THEN status ELSE @e END,
SET client_secret = IF(? = '', client_secret, ?),
current_period_end = IF(? = 0, current_period_end, ?),
current_period_start = IF(? = 0, current_period_start, ?),
payment_status = IF(? = '', payment_status, ?),
status = IF(? = '', status, ?),
cancel_at_end = ?
WHERE id = ?
`
_, err = db.Exec(query,
sub.ClientSecret,
sub.ClientSecret,
sub.End,
sub.End,
sub.Start,
sub.Start,
sub.PaymentStatus,
sub.PaymentStatus,
sub.Status,
sub.Status,
sub.CancelAtEnd,
sub.Id,
@@ -1691,7 +1660,8 @@ func (user *User) update(db *sql.DB) error {
first_name = CASE @fn := ? WHEN '' THEN first_name ELSE @fn END,
last_name = CASE @ln := ? WHEN '' THEN last_name ELSE @ln END,
role = CASE @r := ? WHEN '' THEN role ELSE @r END,
password = CASE @p := ? WHEN '' THEN password ELSE sha2(@p, 256) END
password = CASE @p := ? WHEN '' THEN password ELSE sha2(@p, 256) END,
verified = ?
WHERE id = ?
`

@@ -1701,6 +1671,7 @@ func (user *User) update(db *sql.DB) error {
user.LastName,
user.Role,
user.Password,
user.Verified,
user.Id,
)

@@ -3193,24 +3164,36 @@ func (sub *Subscription) CancelSubscription(cancel bool) (*stripe.Subscription,
return s, err
}

// Retrieves additional invoice information from Stripe
func ( user *User ) SyncSub( sub *stripe.Subscription, db *sql.DB ) error {
var err error
stripe.Key = os.Getenv("STRIPE_SECRET_KEY")
i, err := invoice.Get(sub.LatestInvoice.ID, &stripe.InvoiceParams{})
p, err := paymentintent.Get(i.PaymentIntent.ID,
&stripe.PaymentIntentParams{})
if err != nil {
return err
}

user.Sub.UserId = user.Id
user.Sub.StripeId = sub.ID
user.Sub.CustomerId = user.CustomerId
user.Sub.PriceId = standardPriceId
user.Sub.End = int(sub.CurrentPeriodEnd)
user.Sub.Start = int(sub.CurrentPeriodStart)
user.Sub.ClientSecret = sub.LatestInvoice.PaymentIntent.ClientSecret
user.Sub.PaymentStatus = string(sub.LatestInvoice.PaymentIntent.Status)
user.Sub.ClientSecret = p.ClientSecret
user.Sub.PaymentStatus = string(p.Status)
user.Sub.Status = string(sub.Status)
user.Sub.CancelAtEnd = sub.CancelAtPeriodEnd
log.Println("New status of sub:", sub.Status, p.Status, user.Sub.Id)
if user.Sub.Id != 0 {
if user.Sub.Id == 0 {
err = user.Sub.insertSub(db)
} else {
user.Sub.updateSub(db)
err = user.Sub.updateSub(db)
}
return err
@@ -3378,6 +3361,8 @@ func unsubscribe(w http.ResponseWriter, db *sql.DB, r *http.Request) {
// Updated through this hook.
func invoicePaid(w http.ResponseWriter, db *sql.DB, r *http.Request) {
var invoice stripe.Invoice
stripe.Key = os.Getenv("STRIPE_SECRET_KEY")
b, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
@@ -3416,7 +3401,13 @@ func invoicePaid(w http.ResponseWriter, db *sql.DB, r *http.Request) {
return
}
log.Println(user.Id, s.ID)
err = user.SyncSub(s, db)
if err != nil {
log.Printf("Could not sync subscription: %v", err)
return
}
log.Println("User's invoice paid: ", user.Id, s.ID)
}

func invoiceFailed(w http.ResponseWriter, db *sql.DB, r *http.Request) {
@@ -3479,7 +3470,8 @@ func subCreated(w http.ResponseWriter, db *sql.DB, r *http.Request) {
err = user.SyncSub(&sub, db)
if err != nil {
http.Error(w, err.Error(), 500)
log.Println("Could not create subscription due to error: ",
err.Error())
return
}
@@ -3518,20 +3510,21 @@ func subUpdated(w http.ResponseWriter, db *sql.DB, r *http.Request) {
if statuses[user.Status] < 5 && sub.Status == "trialing" {
user.Status = "Trial"
user.update(db)
err = user.update(db)
} else if sub.Status != "active" {
user.Status = "Unsubscribed"
user.update(db)
err = user.update(db)
}
err = user.SyncSub(&sub, db)
if err != nil {
http.Error(w, err.Error(), 500)
log.Println("Could not update subscription due to error: ",
err.Error())
return
}
log.Println("User subscription created:", user.Id, sub.ID)
log.Println("User subscription updated:", user.Id, sub.ID)
}

// Handles deleted subscriptions hooks sent by Stripe
@@ -3565,10 +3558,10 @@ func subDeleted(w http.ResponseWriter, db *sql.DB, r *http.Request) {
if statuses[user.Status] < 5 && sub.Status == "trialing" {
user.Status = "Trial"
user.update(db)
err = user.update(db)
} else if sub.Status != "active" {
user.Status = "Unsubscribed"
user.update(db)
err = user.update(db)
}
user.Sub.Status = "canceled"
@@ -3576,11 +3569,12 @@ func subDeleted(w http.ResponseWriter, db *sql.DB, r *http.Request) {
err = user.SyncSub(&sub, db)
if err != nil {
http.Error(w, err.Error(), 500)
log.Println("Could not delete subscription due to error: ",
err.Error())
return
}
log.Println("User subscription created:", user.Id, sub.ID)
log.Println("User subscription deleted:", user.Id, sub.ID)
}

func verificationToken(id int) (string, error) {
@@ -3626,6 +3620,13 @@ func verifyUser(w http.ResponseWriter, db *sql.DB, r *http.Request) {
log.Println("Verification claim invalid. ID:", claims.Id)
return
}
user, err := queryUser(db, claims.Id)
user.Verified = true
err = user.update(db)
log.Println("User verified:", user.Id, user.Email)
w.Write([]byte("Verification complete."))
}

func (user *User) sendVerificationEmail() {
@@ -3654,7 +3655,7 @@ func (user *User) sendVerificationEmail() {

message := `Welcome %s,
Click the link below to verify your email address
https://%s?verification_token=%s`
https://%s/api/user/verify?verification_token=%s`
t, err := verificationToken(user.Id)

@@ -4161,13 +4162,6 @@ func dbSeed(db *sql.DB) {
func dev(args []string) {
stripe.Key = os.Getenv("STRIPE_SECRET_KEY")
standardPriceId = "price_1OZLK9BPMoXn2pf9kuTAf8rs"
hookKeys = HookKeys{
InvoicePaid: os.Getenv("DEV_WEBHOOK_KEY"),
InvoiceFailed: os.Getenv("DEV_WEBHOOK_KEY"),
SubCreated: os.Getenv("DEV_WEBHOOK_KEY"),
SubUpdated: os.Getenv("DEV_WEBHOOK_KEY"),
SubDeleted: os.Getenv("DEV_WEBHOOK_KEY"),
}

db, err := sql.Open("mysql",
fmt.Sprintf("%s:%s@tcp(127.0.0.1:3306)/%s?multiStatements=true",


Notiek ielāde…
Atcelt
Saglabāt