#JCoDog-customer information

1 messages · Page 1 of 1 (latest)

minor void
#

👋 happy to help

#

the Customer Portal only concerns Billing/subscriptions

#

so if you need to display anything else you'd have to build your own

plain mica
#

Ok, well I want the user to be able to click a link or button when they select to view their stripe data and it shows their data… as you are an external provider…

#

Is there not a specific set of instructions to pull all customer data?

minor void
#

unfortunately there is no 1 API call you'd have to collect the data using multiple API endpoints, Customers, PaymentIntents, PaymentMethods, Invoices, Subscriptions, etc.

plain mica
#

I already record subscriptions and invoices and the users can view that in another option. The stripe one is meant to show the GDPR data request as if they requested it from stripe directly.

#

Which is why I cannot display it I would assume…

minor void
plain mica
#

Would that show the data I need to provide in a GDPR request?

minor void
#

name, email, phone, shipping, etc...

plain mica
#

Ok thank you.

minor void
#

let me know if you need any more help

plain mica
#

I’ll take a look as it’s a node app I have to get it sorted and then test it but should be fine, thank you.

plain mica
#

is it expands default_source or is it listed another way in the retrieve expand?

minor void
#

what is?

plain mica
#

to get the card details of the customer

#

i know I expand default_source but int he expands request do I write it as that or another way?

#

I cannot see the returned card details of the customer

royal snow
#

Taking over here, catching up

#

Can you share that cus_xxx?

plain mica
#

third screenshot

#

cus_KEndsK8XykbkYC

#

its a test customer for obvious reasons

royal snow
#

Yeah I wasn't typing it out 😂

#

Taking a look

plain mica
#

No worries but you can see a payment method is set in the screenshot

#

I even changed it to be default payment method and it returned nothing.

royal snow
#

Yep, but it's a Payment Method object not a Source

#

You want to expand invoice_settings.default_payment_method

plain mica
#

ah...

#

thanks

#

yep that worked

#

do I have to also expand card and billing details?

royal snow
#

Hmm I don't think so

plain mica
#

it just shows as [object]

royal snow
#

Yeah, the field will be the full object. What code invokes that?

plain mica
#

Its a command that will be used by my bot users to perform gdpr requests to view all their data```js
const Discord = require('discord.js');

const Stripe = require('stripe');
let key;
if (process.env.env == 'prod') {
key = process.env.stripelive;
} else {
key = process.env.stripetest;
}
const stripe = Stripe(key);

module.exports = {
data: new Discord.SlashCommandBuilder()
.setName("mydata")
.setDescription("View the data we have on you saved in our database")
.setDefaultMemberPermissions(Discord.PermissionFlagsBits.SendMessages)
.setDMPermission(true)
.addStringOption(option =>
option.setName("data-type")
.setDescription("The type of data we have on you")
.setRequired(true)
.addChoices(
{ name: 'User Data', value: 'user' },
{ name: 'Payments Data', value: 'payment' },
{ name: 'Subscription Data', value: 'subs' },
{ name: 'Credits Data', value: 'creds' },
{ name: 'Support Tickets', value: 'ticket' },
{ name: 'Incident Reports', value: 'incidents' },
{ name: 'Threads Data', value: 'threads' },
{ name: 'Stripe Data (external company)', value: 'stripe' },
{ name: 'All Data', value: 'all' },
),
)
.addStringOption(option =>
option.setName("response-type")
.setDescription("Where would you like to recieve your data. Hidden replys can only be seen by you.")
.setRequired(true)
.addChoices(
{ name: 'Direct Message', value: 'dm' },
{ name: 'Hidden Reply', value: 'reply' },
{ name: 'Email', value: 'email' },
),
),

async execute (interaction) {
    let dataType = interaction.options.getString('data-type');
    let res = interaction.options.getString('response-type');

    let data;

    if (dataType == 'stripe') {
        let disclaimer =`We store and log nothing that we recieve from stripe on each request to their API, the only data we store from stripe is your customer ID that we use to make requests\n
        You requested the customer object so we have requested the full customer object from stipe including your payment card.\n
        This request returns a reponse and we have not logged nor stored this response anywhere.`;

        let result = await interaction.client.db.query('SELECT stripeID FROM customers WHERE ID='+interaction.member.id);
        let results = result[0];

        if (results.length > 0) {
            data = await stripe.customers.retrieve(results[0].stripeID, {
                expand: ['default_source', 'invoice_settings.default_payment_method'],
            });
        } else {
            data = "We have no customer ID linked to your discord account meaning there is no stripe data for this account.";
        }
    }

    console.log(data); // For testing only, delete before pushing to repo.
}

}```

royal snow
#

What is the output of your console.log

plain mica
#

Let me trigger it again.

#
{
  id: 'cus_KEndsK8XykbkYC',
  object: 'customer',
  address: {
    <removed by me>
  },
  balance: 0,
  created: 1631796616,
  currency: 'gbp',
  default_currency: 'gbp',
  default_source: null,
  delinquent: false,
  description: null,
  discount: null,
  email: <removed by me>,
  invoice_prefix: '11183186',
  invoice_settings: {
    custom_fields: null,
    default_payment_method: {
      id: 'pm_1JaK2dEOJsqRXL0RcDv47ma2',
      object: 'payment_method',
      billing_details: [Object],
      card: [Object],
      created: 1631796615,
      customer: 'cus_KEndsK8XykbkYC',
      livemode: false,
      metadata: {},
      type: 'card'
    },
    footer: null,
    rendering_options: null
  },
  livemode: false,
  metadata: {},
  name: 'Jay',
  phone: null,
  preferred_locales: [],
  shipping: null,
  tax_exempt: 'none',
  test_clock: null
}
royal snow
plain mica
#

ok that fixed it thanks. I assume when I parse the data into the reply pdf that is generated and sent to the user that it will show all data, thanks.

#

I wont be using it all clearly as its a lot of data they wont understand but thanks

royal snow
#

np!

plain mica
#

One last thing, for all payments made on a checkout there the user adds a payment method, will this set it as default automatically and will this always be an invoice default_payment_method?

royal snow
#

It depends on how you configured the Checkout Session. Can you share an example cs_xxx ID?

plain mica
#

let me find a test one...

#

"id": "cs_test_a1q5ab5snvt2eJs4fXhDMm8NOCWwqBewl6MUQ5L3FCAHx5omDytZNWOY2H",

#

I have the checkout setup to pass in a customer ID if a customer exists, if they dont, it passes in their email from our website to create a customer in the checkout and then return an ID for us to store on their user account on our end.

royal snow
#

Yep, mode: 'subscription will set default_payment_method on the Subscription object, not the Customer

plain mica
#

and what does mode: 'payment' do?

royal snow
#

Nothing, unless you pass payment_intent_data.setup_future_usage. But it won't set it as the default

#

You'd need to do that manually in a webhoo maybe, following checkout.session.completed

plain mica
#

cs_test_a1WEm7kl8CUALGfDBKs6bMuR1FSnEmgpTk8d1nJgZzUECX6aXsBA4VV4UH

#

So this wont set default?

royal snow
#

Not on the customer, no

plain mica
#

Ok, I can modify my webhooks to handle that... How do I set the default payment method to the card used in the checkout session?

royal snow
plain mica
#

Cool thanks. I assume its the same thing needed to get the default payment method and if it isnt set it returns NULL

royal snow
#

Correct

plain mica
#

great thanks

#

how do I get the last used card of the user from the checkout session?

river cairn
#

Hi! I'm taking over this thread.

#

Are you using a Checkout Session, and want to update the default payment method of the customer?

plain mica
#

Yes

#

So when the user gets returned to my site after any purchase I handle their customer object from a checkout anyways just incase they didnt have one created. So I would like to know how to retrieve their card and set it as default from their first purchase

#

I am assuming that the used card is in this part of the returned session object?

river cairn
#

Can you share the Checkout Session ID?

plain mica
#

For some reason I cannot view checkout sessions on the stripe test dashboard

#

cs_test_a1krVr1qrhsE8A0Vpg9nMouLO6pUGOhNVZQyeIg2GKjQq5uOkZeeEcA5ly or this.

river cairn
#

Thanks! Give me a few minutes to look into this.

plain mica
#

its expand payment intents then payment_intent->charges->data->payment_method_details->card

#

I comepletely forgot I had the stripe cli installed to test commands.

river cairn
#

Sorry for the delay

#

yes you are right, it looks like you figured it out!

plain mica
#

Cool, but to confirm if nothing is set as default, the default_payment_method on the customer object will be null when expanded?

river cairn
plain mica
#

This is what I meant

#

Would this work?

river cairn
#

It looks okay, but: you don't have to expand the invoice_settings.default_payment_method, this field should be included by default. And you could actually retrieve the customer from the checkout session directly by expanding both the payment_intent and the customer.

plain mica
#

It says its expandable but I guess you are right as because the check is only if it exists and it shows a payment intent then I dont need to.

river cairn
#

If you expand it you get the full payment method object. Here you need only the ID so no need to expend it.

plain mica
#

So this in effect.

#

Or do I need to turn $paymentMethod into a payment intent?

river cairn
#

Something like this, yes. However to update the customer I think your syntax has some issues. You may need to do something like this:
[ 'invoice_settings' => [ 'default_payment_method' => $paymentMethod ] ]

plain mica
#

ah thank you I did question the syntax...

minor void
#

👋 taking over for my colleague. Let me know if there's any follow-up Qs I can answer!

plain mica
#

The node stripe library is causing me an issue with date-fns

#

seems I need date-fns

minor void
#

could you please share the code that's generating this error?

plain mica
#
const Discord = require('discord.js');

const Stripe = require('stripe');
let key;
if (process.env.env == 'prod') {
    key = process.env.stripelive;
} else {
    key = process.env.stripetest;
}
const stripe = Stripe(key);

module.exports = {
    data: new Discord.SlashCommandBuilder()
        .setName("stripe")
        .setDescription("Get a GDPR request result for your Stripe data. (third party payment provider - No JCN Support)")
        .setDMPermission(true),

    async execute (interaction) {
        let data;
        data = getStripe(interaction, data);

        if (data != null) {
            let user = {
                "Stripe ID": data.id,
                "Email": data.email,
                "Address": data.address
            }
            let card = {
                "Card": data.invoice_settings.default_payment_method.card,
                "Billing Address": data.invoice_settings.default_payment_method.billing_details.address,
                "Billing Name": data.invoice_settings.default_payment_method.billing_details.name,
                "Billing Email": data.invoice_settings.default_payment_method.billing_details.email,
            }
    
            interaction.reply({
                content: `User: \`\`\`${user}\`\`\`Payment Method: \`\`\`${card}\`\`\`\n\nJCoNet never stores or logs any data returned by Stripe Requests such as this.`,
                ephemeral: true
            });
        } else {
            interaction.reply({
                content: `We are sorry ${interaction.member.user.username}, We were unable to find a customer ID tied to your discord ID of ${interaction.member.id}. This means you have not made a payment on our system and therefore Stripe has no customer related to you.`,
                ephemeral: true
            });
        }
    }
}

async function getStripe(interaction, data) {
    let result = await interaction.client.db.query('SELECT stripeID FROM customers WHERE ID='+interaction.member.id);
    let results = result[0];

    if (results.length > 0) {
        data = await stripe.customers.retrieve(results[0].stripeID, {
            expand: ['default_source', 'invoice_settings.default_payment_method'],
        });
    } else {
        data = null;
    }

    return data;
}```
minor void
#

I'm not sure if this is related to Stripe

plain mica
#

Ah thanks. I think it was an issue with a module that was removed in this version of the code. A type caused it to be imported when it was not needed.

minor void
#

👍