#Team Seeds - Customer Portal

1 messages · Page 1 of 1 (latest)

proper fable
#

I am a bit unclear on the specific issue that you are running in to at the moment. Are you getting an error when you try to retrieve the customer or create the Customer Portal session?>

silk bronze
#

I don't see a way to use the Stripe API to call a customer ID without already having that specific customer ID....we ideally need to be able to call it using their email address

#

and yes, there's an error when creating the portal session. you can see it live in the link i provided

proper fable
silk bronze
#

Or are there any video demos re: using the Stripe API to retrieve a specific customer using data other than their Customer ID? I wasn't able to find any

'List all customers' is going to call a lot of data that we wouldn't need so I figure there must be a more streamlined way

#

I can see that the docs say that 'Passing an optional email will result in filtering to customers with only that exact email address,' but is there code somewhere showing how to use that param/a video demo?

proper fable
#

That is the link I sent you. You will want to make that list Customers call and provide the email you are looking for in the email parameter

silk bronze
#

no, the link you sent me doesnt' specify this

#

which is why i'm asking

#

please take a quick look at the code i provided in index.js

proper fable
#

I have a lot of other threads I am looking at right now and am having trouble logging in. Can you please send the error you are getting to this channel?

silk bronze
#

there is no error being shown relating to this specific issue. i need to see how to add the email param

#

the reason i've shared the code in this manner is to reduce the time spent here in chat

proper fable
#

In the upper right of the doc I send you, you can select a language and the doc will show you how to make that call in that language

#

The email parameter works the same way as that limit parameter. Have you tried passing the email parameter in the way the limit parameter is passed in in the doc's example snippet?

proper fable
#

@silk bronze was that last bit of clarification helpful? Are you still running in to some issue with the syntax of the list call?

#

Pasting your code here ```//Stripe API: List customers
const stripe = require('stripe')('sk_test_51H...');

const customers = await stripe.customers.list({
email: 'test@example.com',
});

//How do we pass Customer ID from the API call above to the 'customer' param below?

const session = await stripe.billingPortal.sessions.create({
customer: '{{CUSTOMER_ID}}',
return_url: 'https://www.example.com',
});

res.redirect(session.url);
});```

tall vector
#

Also please don't open many threads for simiular questions

silk bronze
#

I would not have if you had not closed the threads

proper fable
#

Was this thread closed for you? I don't think I archived it

silk bronze
#

I believe it asy

#

was*

#

in any case just want to get this figured out

proper fable
#

As for the code, that list call will return a list of zero or more customer objects, each of them will have their own id property, that ID will be of the format cus_123 and that is what you want to pass to the second call.

#

This can get a bit complex if you might have multiple Customer objects with the same email.

silk bronze
tall vector
#

You want to look at customers.data.length to see how many result(s) you got. Assuming you only get one you'd pass customers.data[0].id since it's a list API, but you should be super careful with this really. It means anyone can enter someone else's email address and then access their personal information, subscription, charge their card on file, etc.
So in a normal integration you'd know already which Customer id cus_123 maps to the user logged into your application

silk bronze
#

but yeah i understand the security issue you describe

tall vector
#

the problem is we don't guarantee unique email addresses. So it's possible (and really common) for users to have more than 1 customer with the same email address

#

you'd have to enforce uniqueness in your own application and be resilient to people adding customers manually in the Dashboard, people changing their email address to an existing one, etc.

tall vector
#

But now that you know those caveats overall you would use customers.data[0].id assuming you get one result. Did that work for your code?

silk bronze
#

i haven't gotten it working yet, nope, so decided to try to makes sure i was first successfully able to create a portal session for a test customer i made.

in the logs it's giving me a 401 and telling me i didn't provide an API key.

i thought this may have to do with keeping the test API key in a .env, but had a similar problem when trying to run this without storing the test key in an .env.

here's the code:

`const express = require('express');
const app = express();
const { resolve } = require('path');
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

app.get('/', (req, res) => {
const path = resolve('./index.html');
res.sendFile(path);
});

app.post('/create-customer-portal-session', async (req, res) => {

const session = await stripe.billingPortal.sessions.create({
customer: 'cus_L9ViS4hk4UcCXi',
return_url: 'https://www.seedsgives.com/thanks-for-giving',
});

res.redirect(session.url);
});

app.listen(4242);/`

#

would appreciate thoughts

queen citrus
#

Hello! Taking over, give me a minute to catch up...

silk bronze
#

hello!

#

if helpful, this is actually running the code (and is editable):

queen citrus
#

If you log process.env.STRIPE_SECRET_KEY on your side do you see the secret key starting with sk_test that you expect? (Make sure you don't share your secret key here!)

silk bronze
#

hmm, the log then prints the test key accurately, but tells me it's not defined

queen citrus
#

Can you redact the secret key and provide the output you're seeing?

silk bronze
#

'ReferenceError: sk_test_51H... is not def'

queen citrus
#

That makes it sound like your key is a variable name.

silk bronze
#

you can also see this if you click the link i shared, may be easier

queen citrus
#

Two things: first you're exposing your secret test key in that linked code, so you should roll it.

silk bronze
#

right

queen citrus
#

Second, I'm unable to reproduce that issue in this code.

#

It logs the value as expected.

#

Are you sure the key is being specified in your .env file correctly?

silk bronze
#

ok awesome - i see it working for me as well

#

but it's still failing to create a portal session

queen citrus
#

Same error or new error?

silk bronze
#

same

queen citrus
#

Refused to connect? I thought you were getting a 401 before?

silk bronze
#

the logs said 401 before, yes. the webpage itself shows a broken icon with the 'billing.stripe.com refused to connect'

which i'm finding confusing

#

that's still a 401, no? i'm being denied access

#

anyway yes, i'm seeing the same issue i was having initially

queen citrus
#

I don't think so. It it literally saying billing.stripe.come with the e at the end?

silk bronze
#

yeah you can see it for yourself if you click the 'manage recurring giving' link

#

no sorry that's a typo

queen citrus
#

I'm not seeing that, I'm seeing it without the e

silk bronze
queen citrus
#

Let me look at the other parts of this code...

#

Oh, you're posting to a form that's then trying to redirect to that URL. I don't think that's going to work.

#

You need to send the actual user to that URL, not redirect the form submission to it.

#

You can't make a POST request to the Portal URL, in other words.

silk bronze
#

line 21 in index.js you mean?

queen citrus
#

No, in index.html you have this:

<form method="POST" action="/create-customer-portal-session">
  <button type="submit">Manage your recurring gift</button>
</form>
silk bronze
#

ah!

queen citrus
#

That's going to make a POST request to your server, and in your server code you're responding with a redirect to the Portal URL, which means the POST request is being sent to the Portal, which doesn't work.

silk bronze
#

hmm, can you help me understand why the stripe docs ask us to use this code then/how? this is copy-pasted from the client-side portion of the node docs

#

ok, that's super helpful info thanks

queen citrus
#

Huh.

#

That's interesting.

silk bronze
#

lol

queen citrus
#

Maybe I'm off base! Hang on...

#

It's replit doing something strange!

#

I guess replit is thrown off by the POST or redirect or something?

silk bronze
#

oh weird ok

#

hmm

#

but yay! thanks! i'm going to move on to the next part of troubleshooting the issue i shared above, so if you don't mind please don't close the thread

#

appreciate how helpful you're being

#

i think replit may be being weird re: the .env too somehow

queen citrus
#

So you're still experiencing some other issue outside of Replit?

silk bronze
#

yeah

#

the core problem to solve is that we didn't previously have a need to require user auth on our website

#

and just used stripe payment links

#

but now want to integrate customer portal to allow existing subscribers to manage their subs themselves, and update payment methods as necessary

#

ideally (assuming we're doing this in a secure manner) when an existing subscriber attempts to manage their subscription i think this means something like using the List All Customers call to the Stripe API and filtering for 'email,' and then creating a portal session for the Stripe Customer ID associated with that email (tho would need additional authentication we'd be responsible for on our side, like requiring that they click an email sent to them)

#

here's the code i have so far in an attempt to do that:

wary carbon
#

👋Hello again! @queen citrus has to head out soon so I'm hopping in

silk bronze
#

hello

wary carbon
#

Were you going to send over some code? Outside of the replit issues you were discussing, are you hitting other errors?

silk bronze
#

yes, i'm going to send over some code

#

i described the core issue immediately above

wary carbon
#

👍 I'll wait for you to send over the code then

silk bronze
#

cool, just testing something first

#

i guess it's most useful to just share this?

#

`//Stripe API: List customers
const customers = await stripe.customers.list({
email: '',
});

//How do we pass Customer ID from the API call above to the 'customer' param below?

const session = await stripe.billingPortal.sessions.create({
customer: '',
return_url: 'https://www.seedsgives.com/thanks-for-giving',
});

res.redirect(session.url);
});

app.listen(4242);`

#

and yeah what i'm not getting is commented therein

#

i don't know how to pass the customer ID retrieved when filtering List Customers by the email param into Create Portal Session

wary carbon
#

const customers is a list of Customer objects - you'd take one of those objects, get its ID, and then pass that into the billing portal creation request

silk bronze
wary carbon
#

I'll just leave a quick example here - you'd get the ID from the first returned customer like this:
customers.data[0].id

So something like this is prorbably what you want

const session = await stripe.billingPortal.sessions.create({
    customer: customers.data[0].id,
    return_url: 'https://www.seedsgives.com/thanks-for-giving',
  });
silk bronze
#

hmm ok

#

where customers.data[0].id can be replaced by email?

#

since that's the param we're using

wary carbon
#

No, that's not what I'm saying - you'd still continue to use email when retrieving the list of customers. From the list of customers you can then use the Customer ID to pass in to the billing portal session creation

silk bronze
#

can you help understand where/how the above code does that? it's harder me to get this outside of the context of what's already written. it'd be awesome if you could just drop it into the code at the link i shared and then we can test it there as well

#

hmm i think i got it working

#

just need to create a few more test customers to be sure

#

thanks - feel free to close this thread. i'll keep plugging away at this and will come back if needed