#nikivi
1 messages ยท Page 1 of 1 (latest)
let date = new Date() // get current date
date.setDate(date.getDate() + 31) // set day of month to current day + 30
let year = date.getFullYear()
let month = date.getMonth() + 1 // getMonth() is zero-indexed, so we add 1
let day = date.getDate()
// padStart(2, '0') ensures that day and month are two digits long, adding a leading zero if necessary
month = month.toString().padStart(2, "0")
day = day.toString().padStart(2, "0")
let dateString = `${year}-${month}-${day}` // template string to format in 'YYYY-MM-DD'
console.log(dateString)
we thought of doing this
but i think stripe should know
when end of subscription is
type UserDetails @model {
paidSubscriptionValidUntilDate: Date
in our case we want to update this value on user model
and check it on further actions that are supposed to be paid
or maybe there is another way to do it
The current_period_end is the timestamp for when the subscription will cycle again https://stripe.com/docs/api/subscriptions/object#subscription_object-current_period_end
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
It is a unix timestamp, but you can convert it in to the YYYY-MM-DD format https://www.unixtimestamp.com/
Epoch and unix timestamp converter for developers. Date and time function syntax reference for various programming languages.
Yes
Oh whoops I misread your code
That will not be on the Checkout Session, that is a completely different object.
can i get it there
thats my web hook code
case "checkout.session.completed":
when users pay
this gets triggered
You can get the ID of the subscription from the Checkout object and use that to retrieve the subscription object https://stripe.com/docs/api/checkout/sessions/object#checkout_session_object-subscription
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
You will also probably want to listen for customer.subscription.updated events to watch the subscription for when it renews so you can update how long the subscription in your system is valid for
oh great
forgot about that
thanks
btw can i type
the request in web hook
async (request, response) => {
in typescript
Yes I believe so, it is common to make API calls when receiving webhook info
where can i get the type
@types/stripe?
ok i see this
ok i got subscription id
console.log(details.subscription, "details.subscription")
use that to retrieve the subscription object
how do i do this
because i just have the id
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
stripe.subscription.retrieve(
details.subscription,
(err, subscription) => {
if (err) {
console.log(err)
return
}
console.log(subscription, "subscription")
}
)
didnt find it it in docs how to do it via stripe-node
hope this is ok
the err, part looks wrong to me
oh wait you could do this
neat
current_period_end: 1686839028
this right?
btw for some reason often times when i click the checkout link
that is test it just crashes
link like this
try {
const data = await stripe.checkout.sessions.create({
success_url: process.env.STRIPE_SUCCESS_URL!,
mode: "subscription",
metadata: {
userDetailsId: userDetailsId,
},
line_items: [
{
quantity: 1,
price: process.env.STRIPE_PRICE_ID!,
},
],
})
return {
suggestedTasks: null,
stripeCheckoutUrl: data.url,
}
} catch (error) {
console.log(error)
}
}
which i get from
i worry that in production same will happen
actually happens often ๐ฆ
hey @amber phoenix
i got it working
aside from stripe page breaking
i hope this doesn't happen in prod
also
case "customer.subscription.updated":
for this case
try {
const data = await stripe.checkout.sessions.create({
success_url: process.env.STRIPE_SUCCESS_URL!,
mode: "subscription",
metadata: {
userDetailsId: userDetailsId,
},
line_items: [
{
quantity: 1,
price: process.env.STRIPE_PRICE_ID!,
},
],
})
can I get access to userDetailsId
subscription.updated
because I am not manually triggering it
i assume stripe will trigger it when user pays again
So the code sets metadata on the Checkout Session object
customer.subscription.updated event payload is a subscription object
case "checkout.session.completed":
const details = event.data.object
if (details.status === "complete") {
const userDetailsId = details.metadata.userDetailsId.trim()
i do this
In order to see the metadata on the Checkout Session, you'd need to retrieve that object by calling the API
https://stripe.com/docs/api/checkout/sessions/list#list_checkout_sessions-subscription
Different events
Yup
case "customer.subscription.updated":
const details = event.data.object
if (details.status === "complete") {
stripe.checkout.sessions.retrieve(details.subscription)
}
if I get it right
there was no node example in docs
im not sure whats on the object
will log it and see
also not sure about details.status === "complete"
maybe no need for it
ohh
its actully redeclaring details
switch (event.type) {
case "checkout.session.completed":
let details = event.data.object
case "customer.subscription.updated":
console.log(event.data.object)
details = event.data.object
if (details.status === "complete") {
const subscription = stripe.checkout.sessions.retrieve(
details.subscription
)
console.log(subscription, "subscription")
}
trying this
try
subscription: ID,
});```
You'd get the ID from the webhook event
look at the details printed by event.data.object
not typed
so dont know whats inside
this is very worrying
is just test thats breaking?
or will it break for users who visit the payment page too?
try commenting out everything and only print event.data.object
is just test thats breaking?
What errors do you see in your console?
like it works 1 time out of 4
getting this
thats with this code
i stripped secret info
console.log(event.data.object, "event.data.object")
is not logged ๐ฆ
switch (event.type) {
case "checkout.session.completed":
let details = event.data.object
i should not call it details i think
i guess this is sessionDataObject
case "customer.subscription.updated":
const subscriptionObjectData = event.data.object
and this is like this
i guess
or im wrong
can you share the complete code you have under switch(event.type)?
You don't need
details.subscription
)
console.log(subscription, "subscription")```
gone
get this
case "customer.subscription.updated":
details = event.data.object
should be fine
i think
or wait
case "customer.subscription.updated":
let details = event.data.object
i guess i have to do this
case "checkout.session.completed":
let details = event.data.object
on both events
or rename
i was just not sure
You'll need to debug this on your own ๐ I guide you to fix your code but I fix it for you
Trial and error
customer.subscription.updated
for this event
event.data.object
returns subscriptionData
case "checkout.session.completed":
for this
event.data.object
is sessionData
i hope at least
going to name vars accordingly
so this
case "customer.subscription.updated":
let subscriptionData = event.data.object
if (subscriptionData.status === "complete") {
const sessions = await stripe.checkout.sessions.list({
subscription: subscriptionData.ID,
})
console.log(sessions, "sessions")
}
i assume you mean this
trying it out now
๐ glad you figured it out
ok now how to trigger it
because paying does not
case "customer.subscription.updated":
let subscriptionData = event.data.object
if (subscriptionData.status === "complete") {
const sessions = await stripe.checkout.sessions.list({
subscription: subscriptionData.ID,
})
console.log(sessions, "sessions")
}
there is log
got this
this is stripe listen --forward-to localhost:4242/webhook
I don't think you need this condition
if (subscriptionData.status === "complete")
ok getting this
but there is no metadata
that i can see
checking more
or wait
it returns all sessions
im confused
what do i do with sessions
const userDetailsId = sessionData.metadata.userDetailsId.trim()
const subscription = await stripe.subscriptions.retrieve(
sessionData.subscription
)
const endDateInUnix = subscription.current_period_end
i need this info
to do graphql call
I believe the list should be sorted, you can either pick the first session object OR the last session object (based on how its sorted)
last item has created: 1684161798
created: 1684162048
one before is this
one before is bigger
so last one is most recent
ok i get last session
but i dont see metadata
userDetailsId
can you share the event ID?
Can you share the complete Session object that you're seeing in the list?
{
id: 'cs_test_a1OVQAfGLJNoUfpXMyEnBMiMMZCM7o416S9d2N1jUaH2u8nyXOrzudpwfi',
object: 'checkout.session',
after_expiration: null,
allow_promotion_codes: null,
amount_subtotal: 1000,
amount_total: 1000,
automatic_tax: [Object],
billing_address_collection: null,
cancel_url: null,
client_reference_id: null,
consent: null,
consent_collection: null,
created: 1684161798,
currency: 'eur',
currency_conversion: null,
custom_fields: [],
custom_text: [Object],
customer: 'cus_NtqJJbygiImxeP',
customer_creation: 'always',
customer_details: [Object],
customer_email: null,
expires_at: 1684248198,
invoice: 'in_1N82ckKmRnbuc3WvF3ILNgrK',
invoice_creation: null,
livemode: false,
locale: null,
metadata: [Object],
mode: 'subscription',
payment_intent: null,
payment_link: null,
payment_method_collection: 'always',
payment_method_options: null,
payment_method_types: [Array],
payment_status: 'paid',
phone_number_collection: [Object],
recovered_from: null,
setup_intent: null,
shipping_address_collection: null,
shipping_cost: null,
shipping_details: null,
shipping_options: [],
status: 'complete',
submit_type: null,
subscription: 'sub_1N82ckKmRnbuc3WvE8ighWN0',
success_url: 'http://localhost:3000/payment-success',
total_details: [Object],
url: null
}
],
has_more: true,
url: '/v1/checkout/sessions'
} sessions
this is last one
can send more
metadata: [Object]
So there's a value
Can you try printing that?
console.log(sessions[sessions.length - 1].metadata, "metadata")
ok trying this
ahh
ok guess that was wrong
thought it'd get last session
oh its not array
fk
console.log(sessions.data[sessions.length - 1], "session")
console.log(sessions, "sessions")
console.log(sessions.data[sessions.data.length - 1], "session")
console.log(sessions.data[sessions.data.length - 1].metadata, "metadata")
this actually
{ userDetailsId: 'userdetails_01H08W9DMHGEZ41Q726XH2M414' } metadata
ok its there
amazing
thank you lots @amber phoenix
final q if I may
for my saas app
NP! ๐ Happy to help
Sure
case "checkout.session.completed":
case "customer.subscription.updated":
anything else needed?
i just want to process payments
nothing fancy yet
i guess I can do .rejected
Unhandled event type charge.succeeded.
Unhandled event type payment_method.attached.
Unhandled event type customer.created.
Unhandled event type customer.updated.
Unhandled event type invoice.created.
Unhandled event type invoice.finalized.
Unhandled event type customer.subscription.created.
Unhandled event type invoice.updated.
Unhandled event type invoice.paid.
Unhandled event type invoice.payment_succeeded.
Unhandled event type payment_intent.succeeded.
Unhandled event type payment_intent.created.
i don't see .rejected though