#tarunmv30
1 messages ยท Page 1 of 1 (latest)
hey there, what exactly do you need help with?
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)
Ok, that seems like you're sending an amount that's too small then, regardless of everything else
what is total in amount: total?
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?
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/
?
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
Hi there ๐ taking over, as my colleague needs to step away
Give me a few minutes to get caught up.
Sign in to the Stripe Dashboard to manage business payments and operations in your account. Manage payments and refunds, respond to disputes and more.
@charred sapphire notice you send amount: NaN
You need to review the total you calculate to ensure its a valid value
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
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
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
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"
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
Apologies for the wait. Taking a look now
no worries youre good
You can use any of our test cards for testing: https://stripe.com/docs/testing
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
It looks like you're passing
"{:fee=>\"90\", :total=>\"899\"}"
Instead of an integer
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
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",
},
๐ 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
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
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?
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
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
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
Got it, give me a few minutes to review with my teammates
No problem thank you so much for your help! Ive been beating my head up on this forever
๐ 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.?
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
Can you share the exact PaymentIntent id?
req_zGxc7rOXvRR9sU
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?
req_IREi43auPP1GPQ -> ephirmal intent log
req_Q6KEiAmNFQu98H -> Post/V1/Customer
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
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?
i believe i need to use connect
The PaymentIntent example you gave me was not Connect though?
im processing orders for a restaurant
Is it possible you've been mixing everything up together a little bit?
taking a 10% cut and then transferring the rest of the funds to the connect account
https://dashboard.stripe.com/test/logs/req_zGxc7rOXvRR9sU is a PaymentIntent creation on your main platform account
im sure i could be mixing thinghs up
Are you trying to implement the Direct Charges flow https://stripe.com/docs/connect/direct-charges?
yes
is my code completely off?
Creating destination charges on your platform
could also solve my problem
Hard to say, you've been at it for a while so yes it does look like you got things mixed up
whichever one is easier to complete
Like step 1: have you made this work without Connect first?
yes ive been able to successfully process payments without connect
its only after I tried to set up connect that things got wonky lol
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)
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?
Can you share the code where you initialize Stripe in your Mobile app and set the Publishable key? Are you properly setting the connected account id there too like we document in https://stripe.com/docs/connect/authentication#adding-the-connected-account-id-to-a-client-side-application
I mean you are. But this is absolutely not the code you used to create the Request id you gave me 20 minutes ago
this was on your account only
not sure what that picture is for ๐
you see the id at the top
isnt that the ID i use for the stripe connected account?
stripeAccount: 'acct_1MsyJPCWAlRghLO7',
});```
yeah sorry, we're kinda talking a bit past each other
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
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
struct NeilsUrbanOvenApp: App {
init() {
FirebaseApp.configure()
StripeAPI.defaultPublishableKey = "pk_test_51MSCbfJMYkCh6QmLjYSQLK5gPtmLvaUMn0KrXsbFVnqVROCRere3kLrAQnKOT2Uepb5fRqv34vjgNAArl8wzPwWd00OoOZlDFj"
}
@StateObject var vm = EnvironmentViewModel()
var body: some Scene {
WindowGroup {
TabBarView()
.environmentObject(vm)
}
}
}
yes, here, you never set the connected account id. So it does all requests on your own account
so how would i set the connect ID in the app.main file?
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)
}
}
}
yep try that
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
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
will do thank you!
let me know once you have clear logs
will do! is there a way to clear the stripe test mode dashboard?>
so that all the balances are set back to 0
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
thanks