Bläddra i källkod

Process and complete Stripe payments

master
Immanuel Onyeka 1 år sedan
förälder
incheckning
0ce1a066cc
5 ändrade filer med 107 tillägg och 19 borttagningar
  1. +33
    -3
      grav-admin/user/js/registration/billing.vue
  2. +19
    -0
      grav-admin/user/js/registration/completed.vue
  3. +23
    -6
      grav-admin/user/js/registration/registration.vue
  4. +1
    -0
      migrations/0_29092022_setup_tables.sql
  5. +31
    -10
      skouter.go

+ 33
- 3
grav-admin/user/js/registration/billing.vue Visa fil

@@ -1,13 +1,43 @@
<template> <template>
<div> <div>


<h4>hello</h4>
<h4>Billing</h4>
<div id="payment-element"></div>
<div id="message"></div>
<button @click="submit" class="btn btn-primary">Submit</button>


</div> </div>
</template> </template>


<script setup> <script setup>
import { ref } from "vue"
import { ref, onMounted } from "vue"


let stripe = Stripe(process.env.STRIPE_KEY)
const props = defineProps(["sub"])
const stripe = Stripe(process.env.STRIPE_KEY)
const options = { clientSecret: props.sub.clientSecret }
const elements = stripe.elements(options)
const payEl = elements.create("payment")

function submit() {
let result = stripe.confirmPayment({
//`Elements` instance that was used to create the Payment Element
elements,
confirmParams: {
return_url: "https://skouter.net/register",
}
})
}

onMounted(() => {
checkPayment()
payEl.mount("#payment-element")
})
</script> </script>

<style scoped>
button.btn {
margin: 10px auto;
display: block;
min-width: 90px;
}
</style>

+ 19
- 0
grav-admin/user/js/registration/completed.vue Visa fil

@@ -0,0 +1,19 @@
<template>
<section>
<h4 v-if="status == 'succeeded'">Payment succeeded!</h4>
<h4 v-if="status == 'processing'">Payment still processing. Try again later.</h4>
</section>
</template>

<script setup>
import { ref, onMounted } from "vue"

const props = defineProps(["status"])

</script>

<style>
h4 {
text-align: center;
}
</style>

+ 23
- 6
grav-admin/user/js/registration/registration.vue Visa fil

@@ -1,8 +1,9 @@
<template> <template>
<section class="shadowbox"> <section class="shadowbox">
<h2>Register</h2> <h2>Register</h2>
<account v-if="!step" :err="err" @submit="create" />
<billing v-if="step" :err="err" @submit="create" />
<account v-if="step == 1" :err="err" @submit="create" />
<billing v-if="step == 2" :err="err" :sub="sub"/>
<completed v-if="step == 3" :err="err" :status="sub.paymentStatus"/>
</section> </section>
</template> </template>


@@ -10,10 +11,18 @@
import { ref, onMounted } from "vue" import { ref, onMounted } from "vue"
import Account from "./account.vue" import Account from "./account.vue"
import Billing from "./billing.vue" import Billing from "./billing.vue"
import Completed from "./completed.vue"


let err = ref("") let err = ref("")
const step = ref(0)
const stripe = Stripe(process.env.STRIPE_KEY)
const step = ref(1)
const token = ref("") const token = ref("")
const user = ref(null)
const sub = ref(null)

const clientSecret = new URLSearchParams(window.location.search).get(
'payment_intent_client_secret'
);


function getCookie(name) { function getCookie(name) {
var re = new RegExp(name + "=([^;]+)") var re = new RegExp(name + "=([^;]+)")
@@ -68,9 +77,17 @@ function intent(user) {
}, },
}).then(resp => { }).then(resp => {
if (resp.ok) { if (resp.ok) {
return resp.json().then(u => {
resp.json().then(s => {
err.value = "" err.value = ""
console.log(u)
console.log(s)
sub.value = s
step.value++
if (["processing", "succeeded"].includes(s.paymentStatus) &&
clientSecret == s.clientSecret) {
step.value++
} else {
step.value = 0
}
}) })
} else { } else {
resp.text().then( e => err.value = e) resp.text().then( e => err.value = e)
@@ -80,7 +97,7 @@ function intent(user) {


onMounted(() => { onMounted(() => {
getUser().then( u => { getUser().then( u => {
if (u) intent(u)
if (u) { user.value = u; intent(u) }
}) })
}) })
</script> </script>


+ 1
- 0
migrations/0_29092022_setup_tables.sql Visa fil

@@ -64,6 +64,7 @@ CREATE TABLE subscription (
user_id INT, user_id INT,
customer_id VARCHAR(255) NOT NULL, customer_id VARCHAR(255) NOT NULL,
client_secret VARCHAR(255) NOT NULL, client_secret VARCHAR(255) NOT NULL,
payment_status VARCHAR(50) NOT NULL,
current_period_end INT DEFAULT 0, current_period_end INT DEFAULT 0,
current_period_start INT DEFAULT 0, current_period_start INT DEFAULT 0,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),


+ 31
- 10
skouter.go Visa fil

@@ -72,6 +72,7 @@ type Subscription struct {
Start int `json:"start"` Start int `json:"start"`
End int `json:"end"` End int `json:"end"`
ClientSecret string `json:"clientSecret,omitempty"` ClientSecret string `json:"clientSecret,omitempty"`
PaymentStatus string `json:"paymentStatus"`
} }


type User struct { type User struct {
@@ -1262,7 +1263,8 @@ func querySub(db *sql.DB, id int) (Subscription, error) {
customer_id, customer_id,
current_period_end, current_period_end,
current_period_start, current_period_start,
client_secret
client_secret,
payment_status
FROM subscription WHERE id = ? FROM subscription WHERE id = ?
` `
row := db.QueryRow(query, id) row := db.QueryRow(query, id)
@@ -1274,6 +1276,7 @@ func querySub(db *sql.DB, id int) (Subscription, error) {
&s.End, &s.End,
&s.Start, &s.Start,
&s.ClientSecret, &s.ClientSecret,
&s.PaymentStatus,
) )


return s, err return s, err
@@ -1290,7 +1293,8 @@ func (user *User) querySub(db *sql.DB) error {
customer_id, customer_id,
current_period_end, current_period_end,
current_period_start, current_period_start,
client_secret
client_secret,
payment_status
FROM subscription WHERE user_id = ? FROM subscription WHERE user_id = ?
` `
row := db.QueryRow(query, user.Id) row := db.QueryRow(query, user.Id)
@@ -1303,6 +1307,7 @@ func (user *User) querySub(db *sql.DB) error {
&user.Sub.End, &user.Sub.End,
&user.Sub.Start, &user.Sub.Start,
&user.Sub.ClientSecret, &user.Sub.ClientSecret,
&user.Sub.PaymentStatus,
) )


return err return err
@@ -1421,9 +1426,10 @@ func (sub *Subscription) insertSub(db *sql.DB) (error) {
customer_id, customer_id,
current_period_end, current_period_end,
current_period_start, current_period_start,
client_secret
client_secret,
payment_status
) )
VALUES (?, ?, ?, ?, ?, ?)
VALUES (?, ?, ?, ?, ?, ?, ?)
RETURNING id RETURNING id
` `
@@ -1434,18 +1440,19 @@ func (sub *Subscription) insertSub(db *sql.DB) (error) {
sub.End, sub.End,
sub.Start, sub.Start,
sub.ClientSecret, sub.ClientSecret,
sub.PaymentStatus,
) )


err = row.Scan(&sub.Id) err = row.Scan(&sub.Id)
return err return err
} }


func (sub *Subscription) updateSubSecret(db *sql.DB) error {
func (sub *Subscription) updateSub(db *sql.DB) error {
var query string var query string
var err error var err error


query = `UPDATE subscription SET
client_secret = ?
query = `UPDATE subscription
SET client_secret = ?, payment_status = ?
WHERE id = ? WHERE id = ?
` `
@@ -1459,11 +1466,15 @@ func (sub *Subscription) updateSubSecret(db *sql.DB) error {
&stripe.PaymentIntentParams{}) &stripe.PaymentIntentParams{})
if err != nil { return err } if err != nil { return err }

_, err = db.Exec(query, _, err = db.Exec(query,
p.ClientSecret, p.ClientSecret,
p.Status,
sub.Id, sub.Id,
) )
if err != nil { return err }
sub.ClientSecret = p.ClientSecret
sub.PaymentStatus = string(p.Status)


return err return err
} }
@@ -2972,7 +2983,7 @@ func subscribe(w http.ResponseWriter, db *sql.DB, r *http.Request) {
return return
} }
} }
if user.Sub.Id == 0 { if user.Sub.Id == 0 {
s, err := createSubscription(user.CustomerId) s, err := createSubscription(user.CustomerId)
if err != nil { if err != nil {
@@ -2986,10 +2997,20 @@ func subscribe(w http.ResponseWriter, db *sql.DB, r *http.Request) {
user.Sub.End = int(s.CurrentPeriodEnd) user.Sub.End = int(s.CurrentPeriodEnd)
user.Sub.Start = int(s.CurrentPeriodStart) user.Sub.Start = int(s.CurrentPeriodStart)
user.Sub.ClientSecret = s.LatestInvoice.PaymentIntent.ClientSecret user.Sub.ClientSecret = s.LatestInvoice.PaymentIntent.ClientSecret
user.Sub.PaymentStatus = string(s.LatestInvoice.PaymentIntent.Status)
user.Sub.insertSub(db)
err = user.Sub.insertSub(db)
if err != nil {
http.Error(w, err.Error(), 500)
return
}
json.NewEncoder(w).Encode(user.Sub) json.NewEncoder(w).Encode(user.Sub)
} else { } else {
err = user.Sub.updateSub(db)
if err != nil {
http.Error(w, err.Error(), 500)
return
}
json.NewEncoder(w).Encode(user.Sub) json.NewEncoder(w).Encode(user.Sub)
} }


Laddar…
Avbryt
Spara