#tarunmv30

1 messages ยท Page 1 of 1 (latest)

nimble badgerBOT
native verge
#

hey there, what exactly do you need help with?

charred sapphire
#
  const total = items.reduce((previous, current) => {
    return previous + current.price
  }, 0)

  // Check that the total price is greater than or equal to $0.50 USD
  if (total < 50) {
    throw new Error('Amount must be at least $0.50 USD')
  }
  
  const fee = Math.round(total * 0.1);
  const transferAmount = Math.round(total * 0.9);
  
  return {
    total: Math.round(total),
    fee: fee,
    transferAmount: transferAmount
  };
};

app.post("/create-payment-intent", async (req, res) => {
  const items = req.body;

  // Calculate the order amount, fee, and transfer amount
  const { total, fee } = calculateOrderAmount(items);

  // Create a PaymentIntent with the order amount and currency
  const paymentIntent = await stripe.paymentIntents.create({
    amount: total,
    currency: 'usd',
    application_fee_amount: fee,
  }, {
    stripeAccount: 'acct_1MsyJPCWAlRghLO7',
  });
  console.log("total:")
  console.log(total)
  console.log("application fee:")
  console.log(application_fee_amount)

  // Generate an ephemeral key for the customer
  const customer = await stripe.customers.create({
    email: 'customer@example.com'
  }, {
    stripeAccount: 'acct_1MsyJPCWAlRghLO7',
  });
  const ephemeralKey = await stripe.ephemeralKeys.create(
    { customer: customer.id },
    { apiVersion: '2020-08-27', stripeAccount: 'acct_1MsyJPCWAlRghLO7' }
  );

  // Return the necessary information to the client
  res.send({
    customer: customer.id,
    ephemeralKey: ephemeralKey.secret,
    paymentIntent: paymentIntent.client_secret,
    publishableKey: 'pk_test_51MSCbfJMYkCh6QmLjYSQLK5gPtmLvaUMn0KrXsbFVnqVROCRere3kLrAQnKOT2Uepb5fRqv34vjgNAArl8wzPwWd00OoOZlDFj' // replace with your own publishable key
  });
});

exports.stripe = functions.https.onRequest(app);
#

this is my server code

#
        let jsonData = try? JSONEncoder().encode(cart)

        var request = URLRequest(url: backendCheckoutUrl)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.httpBody = jsonData

        let task = URLSession.shared.dataTask(
            with: request,
            completionHandler: { (data, _, _) in
                guard let data = data,
                      let json = try? JSONSerialization.jsonObject(with: data, options: [])
                        as? [String: Any],
                      let customerId = json["customer"] as? String,
                      let customerEphemeralKeySecret = json["ephemeralKey"] as? String,
                      let paymentIntentClientSecret = json["paymentIntent"] as? String,
                      let publishableKey = json["publishableKey"] as? String
                else {
                    print("There was an error with the data")
                    return
                }
                STPAPIClient.shared.publishableKey = publishableKey

                // Create a PaymentSheet instance
                var configuration = PaymentSheet.Configuration()
                configuration.merchantDisplayName = "Your Merchant Name"
                configuration.customer = .init(
                    id: customerId,
                    ephemeralKeySecret: customerEphemeralKeySecret
                )
                configuration.returnURL = "your-app-url://stripe-redirect"
                configuration.allowsDelayedPaymentMethods = true

                DispatchQueue.main.async {
                    self.paymentSheet = PaymentSheet(
                        paymentIntentClientSecret: paymentIntentClientSecret,
                        configuration: configuration
                    )
                }
            }
        )
        task.resume()
    }```
#

this is my client code, the log is printing there was an error with the data (client side)

#

and then my console log is printing this error (server side)

#

Error: Amount must be at least $0.50 usd
at Function.generate (/workspace/node_modules/stripe/cjs/Error.js:10:20)
at res.toJSON.then.Error_js_1.StripeAPIError.message (/workspace/node_modules/stripe/cjs/RequestSender.js:105:54)
at processTicksAndRejections (node:internal/process/task_queues:96:5)

native verge
#

Ok, that seems like you're sending an amount that's too small then, regardless of everything else

#

what is total in amount: total?

charred sapphire
#

it depends on what the user adds to cart but the minimum price for an item is 10 dollars... so i dont know why im getting that error

#

is it because im not multiplying it by 100?

native verge
#

Possibly, amount is in cents, for USD

#

so USD $10 would be amount=1000

charred sapphire
#

let me try

#

Error: Amount must be at least $0.50 USD13.99
at calculateOrderAmount (/workspace/index.js:18:11)
at /workspace/index.js:35:26
at Layer.handle [as handle_request] (/workspace/node_modules/express/lib/router/layer.js:95:5)
at next (/workspace/node_modules/express/lib/router/route.js:144:13)
at Route.dispatch (/workspace/node_modules/express/lib/router/route.js:114:3)
at Layer.handle [as handle_request] (/workspace/node_modules/express/lib/rou

#

this is the error - i have it printing the error along with the amount being passed in

#

@native verge

#
  console.log("items:", items);
  const total = items.reduce((previous, current) => {
    console.log("previous:", previous, "current:", current);
    return previous + current.price;
  }, 0);
  console.log("total:", total);

  // Check that the total price is greater than or equal to $0.50 USD
  if (total < 50) {
    throw new Error('Amount must be at least $0.50 USD');
  }
  
  const fee = Math.round(total * 0.1);
  console.log("fee:", fee);
  const transferAmount = Math.round(total * 0.9);
  console.log("transferAmount:", transferAmount);
  
  return {
    total: Math.round(total) * 100,
    fee: fee * 100,
    transferAmount: transferAmount * 100
  };
};

app.post("/create-payment-intent", async (req, res) => {
  const items = req.body;

  // Calculate the order amount, fee, and transfer amount
  const { total, fee } = calculateOrderAmount(items);

  // Create a PaymentIntent with the order amount and currency
  const paymentIntent = await stripe.paymentIntents.create({
    amount: total,
    currency: 'usd',
    application_fee_amount: fee,
  }, {
    stripeAccount: 'acct_1MsyJPCWAlRghLO7',
  });
  console.log("total:")
  console.log(total)
  console.log("application fee:")
  console.log(application_fee_amount)

  // Generate an ephemeral key for the customer
  const customer = await stripe.customers.create({
    email: 'customer@example.com'
  }, {
    stripeAccount: 'acct_1MsyJPCWAlRghLO7',
  });
  const ephemeralKey = await stripe.ephemeralKeys.create(
    { customer: customer.id },
    { apiVersion: '2020-08-27', stripeAccount: 'acct_1MsyJPCWAlRghLO7' }
  );

  // Return the necessary information to the client
  res.send({
    customer: customer.id,
    ephemeralKey: ephemeralKey.secret,
    paymentIntent: paymentIntent.client_secret,
    publishableKey: 'pk_test_51MSCbfJMYkCh6QmLjYSQLK5gPtmLvaUMn0KrXsbFVnqVROCRere3kLrAQnKOT2Uepb5fRqv34vjgNAArl8wzPwWd00OoOZlDFj' // replace with your own publishable key
  });
});```
#

Is there anything that looks incorrect to you/

#

?

native verge
#

Yes it looks like your amount is still wrong based on the error. Can you share the exact request ID where you hit that?

#

eg req_123

charred sapphire
#

where would i find the request id?

#

req_XcZj5PsxMMH9UV

ebon smelt
#

Hi there ๐Ÿ‘‹ taking over, as my colleague needs to step away

Give me a few minutes to get caught up.

native verge
#

@charred sapphire notice you send amount: NaN

#

You need to review the total you calculate to ensure its a valid value

charred sapphire
#

let me check one second

#

Still not working, I cant seem to figure out why

ebon smelt
#

Somewhere your code is not setting an amount or an application_fee_amount. Keep in mind this has to be an integer and not a decimal or float type

charred sapphire
#

req_2pqunYdlJRwfb5

#

Would i need to set that on the client side?

ebon smelt
#

It needs to be set on the Payment Intent that you use on the client side. The Payment Intent is created on the server-side, so I would expect that's where it would be set

charred sapphire
#
  const amount = items.reduce((previous, current) => {
    return previous + current.price;
  }, 0);

  const total = amount * 100;

  // Check that the total price is greater than or equal to $0.05 USD for testing purposes
  if (total < 5) {
    throw new Error('Amount must be at least $0.05 USD' + total);
  }
  
  const fee = Math.round(total * 0.1);
  
  return {
    total: Math.round(total),
    fee: fee
  };
};

app.post("/create-payment-intent", async (req, res) => {
  const items = req.body;

  // Calculate the order amount, fee, and transfer amount
  const { total, fee } = calculateOrderAmount(items);

  // Create a PaymentIntent with the order amount and currency
  const paymentIntent = await stripe.paymentIntents.create({
    amount: total,
    currency: 'usd',
    application_fee_amount: fee,
  }, {
    stripeAccount: 'acct_1MsyJPCWAlRghLO7',
  });
  console.log("total:")
  console.log(total)
  console.log("application fee:")
  console.log(application_fee_amount)

  // Generate an ephemeral key for the customer
  const customer = await stripe.customers.create({
    email: 'customer@example.com'
  }, {
    stripeAccount: 'acct_1MsyJPCWAlRghLO7',
  });
  const ephemeralKey = await stripe.ephemeralKeys.create(
    { customer: customer.id },
    { apiVersion: '2020-08-27', stripeAccount: 'acct_1MsyJPCWAlRghLO7' }
  );

  // Return the necessary information to the client
  res.send({
    customer: customer.id,
    ephemeralKey: ephemeralKey.secret,
    paymentIntent: paymentIntent.client_secret,
    publishableKey: 'pk_test_51MSCbfJMYkCh6QmLjYSQLK5gPtmLvaUMn0KrXsbFVnqVROCRere3kLrAQnKOT2Uepb5fRqv34vjgNAArl8wzPwWd00OoOZlDFj' // replace with your own publishable key
  });
});```
#

req_zGxc7rOXvRR9sU

#

what does it mean when it says amount capturable is 0

ebon smelt
#

In this case, it looks like it's because there is no Payment Method attached to the Customer, so Stripe is essentially saying, "okay, this Payment Intent is created and ready for a payment method, but it cannot be charged until it has one"

charred sapphire
#

how would I use this customer for testing?

#

I dont want to attach a real payment on file I just want to set up and test multi party payments

#

I have an online food ordering app for a restaurant where I d like to take 10% of every transaction and then transfer the payments

#

to the connect account

#

req_RKCOmwSiQAwzVI

#

@ebon smelt

ebon smelt
#

Apologies for the wait. Taking a look now

charred sapphire
#

no worries youre good

ebon smelt
charred sapphire
#

i appreciate your help

#

let me try

#

do i need to add the card as a payment method to the connected accounts to test this?

#

or is connecting a connect account all I need to do

#

req_fnPMQFe9SVgDme

#

this is the error im getting currently

ebon smelt
#

It looks like you're passing

#

"{:fee=>\"90\", :total=>\"899\"}"

#

Instead of an integer

charred sapphire
#

where would I need to change it?

#

the same code worked when I was doing regular payment processing, but isnt working when I do multi part payments @ebon smelt

ebon smelt
#

Let's back up a little bit. Open the request you posted in the Dashboard. Notice that you're setting the application fee amount using a hash with fee and total, but both application_fee_amount and amount are supposed to be integers
application_fee_amount: {
fee: "90",
total: "899",
},
amount: {
fee: "90",
total: "899",
},

nimble badgerBOT
charred sapphire
#

yes

#

i dont get it tho?

stable sequoia
#

๐Ÿ‘‹ stepping in for my teammate who has to step out. request req_fnPMQFe9SVgDme is malformed. the values for application_fee_amount and amount should just be integers, not hashes. i'm assuming you want the application fee to be 90 and the total PaymentIntent amount to be 899

charred sapphire
#
  const amount = items.reduce((previous, current) => {
    return previous + current.price;
  }, 0);

  const total = Math.round(amount * 100);

  // Check that the total price is greater than or equal to $0.05 USD for testing purposes
  if (total < 5) {
    throw new Error('Amount must be at least $0.05 USD' + total);
  }
  
  const fee = Math.round(total * 0.1);
  
  return {
    total: total,
    fee: fee
  };
};

app.post("/create-payment-intent", async (req, res) => {
  const items = req.body;

  const { total, fee } = calculateOrderAmount(items);

  // Create a PaymentIntent with the order amount and currency
  const paymentIntent = await stripe.paymentIntents.create({
    amount: total,
    currency: 'usd',
    application_fee_amount: fee,
  }, {
    stripeAccount: 'acct_1MsyJPCWAlRghLO7',
  });
  
  // Generate an ephemeral key for the customer
  const customer = await stripe.customers.create({
    email: 'customer@example.com'
  }, {
    stripeAccount: 'acct_1MsyJPCWAlRghLO7',
  });

  const ephemeralKey = await stripe.ephemeralKeys.create(
    { customer: customer.id },
    { apiVersion: '2020-08-27', stripeAccount: 'acct_1MsyJPCWAlRghLO7' }
  );

  // Return the necessary information to the client
  res.send({
    customer: customer.id,
    ephemeralKey: ephemeralKey.secret,
    paymentIntent: paymentIntent.client_secret,
    publishableKey: 'pk_test_51MSCbfJMYkCh6QmLjYSQLK5gPtmLvaUMn0KrXsbFVnqVROCRere3kLrAQnKOT2Uepb5fRqv34vjgNAArl8wzPwWd00OoOZlDFj' // replace with your own publishable key
  });
});```
#

so does this look right?

#

with that code im getting this error

#

req_4tC5lTZYpWamtX

#

@stable sequoia

stable sequoia
#

that looks right. you could also try logging total and fee to confirm. in request req_4tC5lTZYpWamtX, I see your code passed application_fee_amount: 180 and amount: 1798.

#

the PaymentIntent was successfully created and is now waiting for payment details.

#

what exactly was your code trying to do when you received the error in the screenshot above?

charred sapphire
#

when i click buy to put card in it loads and then presents that error

#

so im not sure what is causing this

#

my cloud function log says completed successfully with status code 200

#

i sent the stripe dashboard log id so you could see

stable sequoia
#

when i click buy to put card in it loads and then presents that error
can you share more about this? as far as I can tell so far, your server side request to create a PaymentIntent was successful

charred sapphire
#
    
    let backendCheckoutUrl = URL(string: "https://us-central1-neilsurbanoven.cloudfunctions.net/stripe/create-payment-intent")!  // An example backend endpoint
    @Published var paymentSheet: PaymentSheet?
    @Published var paymentResult: PaymentSheetResult?
    
    
#
        let jsonData = try? JSONEncoder().encode(cart)

        var request = URLRequest(url: backendCheckoutUrl)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.httpBody = jsonData

        let task = URLSession.shared.dataTask(
            with: request,
            completionHandler: { (data, _, _) in
                guard let data = data,
                      let json = try? JSONSerialization.jsonObject(with: data, options: [])
                        as? [String: Any],
                      let customerId = json["customer"] as? String,
                      let customerEphemeralKeySecret = json["ephemeralKey"] as? String,
                      let paymentIntentClientSecret = json["paymentIntent"] as? String,
                      let publishableKey = json["publishableKey"] as? String
                else {
                    print("There was an error with the data")
                    return
                }

                STPAPIClient.shared.publishableKey = publishableKey

                var configuration = PaymentSheet.Configuration()
                configuration.merchantDisplayName = "Your Merchant Name"
                configuration.customer = .init(
                    id: customerId,
                    ephemeralKeySecret: customerEphemeralKeySecret
                )
                configuration.returnURL = "your-app-url://stripe-redirect"
                configuration.allowsDelayedPaymentMethods = true
                DispatchQueue.main.async {
                    self.paymentSheet = PaymentSheet(
                        paymentIntentClientSecret: paymentIntentClientSecret,
                        configuration: configuration
                    )
                }
            }
        )
        task.resume()
    }```
#
        self.paymentResult = result
        
        let cart = [MenuItem]()
        // MARK: Demo cleanup
        if case .completed = result {
            // A PaymentIntent can't be reused after a successful payment. Prepare a new one for the demo.
            self.paymentSheet = nil
            preparePaymentSheet(cart: cart)
        }
    }```
#

this is my client side code

#

which takes the response from the server

stable sequoia
#

Got it, give me a few minutes to review with my teammates

charred sapphire
#

No problem thank you so much for your help! Ive been beating my head up on this forever

void palm
#

๐Ÿ‘‹ sorry this is a multi-hour long thread so it's tough to even grasp the context and issue. What's the problem? which exact part of the code is erroring, what is that code doing, what details do you get in the error, what exact PaymentIntent are you using, etc.?

charred sapphire
#

The goal is to process payments for an online food ordering app where i take 10% and transfer the rest to the connected account

#

the server is set up correctly, and the payment intent is being correctly created

#

the code should be working, however when I press the payment button on the client side

#

instead of loading up the card input to make the payment it presents this error on the UI

#

Ive attached my client side code above and I can provide anything else you may need to help trouble shoot this

void palm
#

Can you share the exact PaymentIntent id?

charred sapphire
#

req_zGxc7rOXvRR9sU

void palm
#

thanks, looking

#

So the picture you shared is really really tough to read and grasp

#

Can you share a lot more details about the issue? Did you properly log all the values you pass in that code and made sure they are what you expect like the customerEphemeralKeySecret and paymentIntentClientSecret are those properly initialized?

charred sapphire
#

req_IREi43auPP1GPQ -> ephirmal intent log

#

req_Q6KEiAmNFQu98H -> Post/V1/Customer

void palm
#

that's not really my question

#

Right now you have a lot of lines of code getting this from your server to your iOS app and then passing this to the Stripe iOS SDK

#

Can you make sure to log those values in your app before using them and confirm they are exactly what you expect

charred sapphire
#

yes give me a moment

#

my apoligies

void palm
#

all good. And just to be super clear: you are not trying to use Connect at all right? You're just creating a PaymentIntent on your main account?

charred sapphire
#

i believe i need to use connect

void palm
#

The PaymentIntent example you gave me was not Connect though?

charred sapphire
#

im processing orders for a restaurant

void palm
#

Is it possible you've been mixing everything up together a little bit?

charred sapphire
#

taking a 10% cut and then transferring the rest of the funds to the connect account

void palm
charred sapphire
#

im sure i could be mixing thinghs up

void palm
charred sapphire
#

yes

#

is my code completely off?

#

Creating destination charges on your platform
could also solve my problem

void palm
#

Hard to say, you've been at it for a while so yes it does look like you got things mixed up

charred sapphire
#

whichever one is easier to complete

void palm
#

Like step 1: have you made this work without Connect first?

charred sapphire
#

yes ive been able to successfully process payments without connect

#

its only after I tried to set up connect that things got wonky lol

void palm
#

Cool. So now the only difference is
1/ Pass the Stripe-Account header server-side when creating the PaymentIntent
2/ Properly set the Stripe-Account header client-side when displaying the PaymentSheet.

It looks like you haven't done both of those at the same time. And the example you gave me earlier is likely incorrect (created on your own account, no Connect, also never used in your app)

charred sapphire
#
  const items = req.body;

  const { total, fee } = calculateOrderAmount(items);

  // Create a PaymentIntent with the order amount and currency
  const paymentIntent = await stripe.paymentIntents.create({
    amount: total,
    currency: 'usd',
    application_fee_amount: fee,
  }, {
    stripeAccount: 'acct_1MsyJPCWAlRghLO7',
  });```
#

arent i passing that in here?

void palm
#

I mean you are. But this is absolutely not the code you used to create the Request id you gave me 20 minutes ago

void palm
charred sapphire
void palm
#

not sure what that picture is for ๐Ÿ˜…

charred sapphire
#

you see the id at the top

#

isnt that the ID i use for the stripe connected account?

#
    stripeAccount: 'acct_1MsyJPCWAlRghLO7',
  });```
void palm
#

yeah sorry, we're kinda talking a bit past each other

charred sapphire
#

youre good lol im trying to wrap my head around this please be patient with me as im normally just a front end developer

#

and im not very smart

void palm
#

Your server-side code is creating a PaymentIntent on the connected account acct_1MsyJPCWAlRghLO7. But when I asked you for an example PaymentIntent id pi_123, instead you gave me a request id req_ABC. That request id was req_zGxc7rOXvRR9sU and it created a different PaymentIntent (pi_3Mrva2JMYkCh6QmL1m1N9Uey) on your own account not the connected account.

I think you just got mixed up but all that was irrelevant

#

Mostly, you seem to have just forgotten to set the right connected account id when you initialize the stripe iOS SDK

charred sapphire
#
struct NeilsUrbanOvenApp: App {
    
    init() {
        FirebaseApp.configure()
        StripeAPI.defaultPublishableKey = "pk_test_51MSCbfJMYkCh6QmLjYSQLK5gPtmLvaUMn0KrXsbFVnqVROCRere3kLrAQnKOT2Uepb5fRqv34vjgNAArl8wzPwWd00OoOZlDFj"
    }
    
    @StateObject var vm = EnvironmentViewModel()
    
    var body: some Scene {
        WindowGroup {
                TabBarView()
                     .environmentObject(vm)
        }
        
    }
}
void palm
#

yes, here, you never set the connected account id. So it does all requests on your own account

charred sapphire
#

so how would i set the connect ID in the app.main file?

void palm
#

did you read the doc I pointed you to?

charred sapphire
#

got it doing that now lets see

#

thank you

#
struct NeilsUrbanOvenApp: App {
    
    init() {
        FirebaseApp.configure()
        StripeAPI.defaultPublishableKey = "pk_test_51MSCbfJMYkCh6QmLjYSQLK5gPtmLvaUMn0KrXsbFVnqVROCRere3kLrAQnKOT2Uepb5fRqv34vjgNAArl8wzPwWd00OoOZlDFj"
        STPAPIClient.shared.stripeAccount = "acct_1MsyJPCWAlRghLO7"
    }
    
    @StateObject var vm = EnvironmentViewModel()
    
    var body: some Scene {
        WindowGroup {
                TabBarView()
                     .environmentObject(vm)
        }
        
    }
}
void palm
#

yep try that

charred sapphire
#

let me see

#

it worked thank you!

#

last question, i serioulsy want to thank you tho youve been amazing

#

is there anyway i can leave a review on your customer service?

#

but my last question is after i successfully complete the payment in continues to show a progress ring (loading) and then in the print statement shows there was an error with the data

void palm
#

Hard to say without again a lot more details

#

you've been rushing from problem to problem to problem a bit for the past few hours and so everytime you just say "oh doesn't work"

#

but you should be able to add clear debugging steps to the code to figure out which step is failing

#

the code you had earlier was else { print("There was an error with the data") return } and that's when fetching the PI secret and other info. That seems totally unrelated with the PI confirmation

#

So add clear logs to your code to figure out which part is even crashing right now first

charred sapphire
#

will do thank you!

void palm
#

let me know once you have clear logs

charred sapphire
#

will do! is there a way to clear the stripe test mode dashboard?>

nimble badgerBOT
charred sapphire
#

so that all the balances are set back to 0

void palm
#

not really. I mean there is but you'd lose all your connected accounts. And there shouldn't really be any reason to want to reset balances to 0

charred sapphire
#

thanks