#zeke_ios-paymentsheet
1 messages · Page 1 of 1 (latest)
Below are links to other discussions we've had with you in the past week in case you want to review that information. If your question is related to one of these previous discussions, please provide a comprehensive summary of the current state and what you need help with now. We help many users simultaneously, so a summary allows us to resolve your issue as soon as possible.
- zeke_best-practices, 3 hours ago, 28 messages
- zeke_best-practices, 16 hours ago, 16 messages
- zeke_best-practices, 23 hours ago, 30 messages
- zeke_api, 1 day ago, 97 messages
- zeke_webhooks, 1 day ago, 16 messages
👋 Welcome to your new thread!
⏲️ We'll be here soon! We typically respond in a few minutes, but in some cases we might need a bit more time (e.g., server's busy, you've got a complex question, etc.).
⏱️ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can start a new thread if you have another question.
🔗 This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1260352757211201648
📝 Have more to share? Add details, code, screenshots, videos, etc. below.
import { Button } from "@/components/ui/button";
export default function CheckoutScreen() {
const { initPaymentSheet, presentPaymentSheet } = useStripe();
const [loading, setLoading] = useState(false);
const fetchPaymentSheetParams = async () => {
const response = await fetch(`${API_URL}/payment-sheet`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
});
const { paymentIntent, ephemeralKey, customer} = await response.json();
return {
paymentIntent,
ephemeralKey,
customer,
};
};
const initializePaymentSheet = async () => {
const {
paymentIntent,
ephemeralKey,
customer,
publishableKey,
} = await fetchPaymentSheetParams();
const { error } = await initPaymentSheet({
merchantDisplayName: "Example, Inc.",
customerId: customer,
customerEphemeralKeySecret: ephemeralKey,
paymentIntentClientSecret: paymentIntent,
// Set `allowsDelayedPaymentMethods` to true if your business can handle payment
//methods that complete payment after a delay, like SEPA Debit and Sofort.
allowsDelayedPaymentMethods: true,
defaultBillingDetails: {
name: 'Jane Doe',
}
});
if (!error) {
setLoading(true);
}
};
const openPaymentSheet = async () => {
// see below
const openPaymentSheet = async () => {
const { error } = await presentPaymentSheet();
if (error) {
Alert.alert(`Error code: ${error.code}`, error.message);
} else {
Alert.alert('Success', 'Your order is confirmed!');
}
};
return (
<Screen>
<Button
variant="primary"
disabled={!loading}
title="Checkout"
onPress={openPaymentSheet}
/>
</Screen>
)
};
useEffect(() => {
initializePaymentSheet();
}, []);
return (
<Screen>
<Button
variant="primary"
disabled={!loading}
title="Checkout"
onPress={openPaymentSheet}
/>
</Screen>
);
}
}
function useStripe(): { initPaymentSheet: any; presentPaymentSheet: any; } {
throw new Error("Function not implemented.");
}
function useState(arg0: boolean): [any, any] {
throw new Error("Function not implemented.");
}
function useEffect(arg0: () => void, arg1: never[]) {
throw new Error("Function not implemented.");
Im getting this error for {API_URL}/payment-sheet
Cannot find name 'API_URL'(2304)
Yep, your env variable
do i need to create another one with stripe or can I use one of pk_ sk_?
You can also try to hardcode that value to see if you're able to get past that error
Hold on a second. I don't think your API keys go on this line:
Im getting this error for {API_URL}/payment-sheet
What is ${API_URL} at the moment?
Nothing thats why there is an error🤔 I pulled this code from the guide I offered above! I was wondering how to put it in my env is it just my sk code and or pk code
heres what the surrounding code looks like
export default function CheckoutScreen() {
const { initPaymentSheet, presentPaymentSheet } = useStripe();
const [loading, setLoading] = useState(false);
const fetchPaymentSheetParams = async () => {
const response = await fetch(`${API_URL}/payment-sheet`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
});
const { paymentIntent, ephemeralKey, customer} = await response.json();
return {
paymentIntent,
ephemeralKey,
customer,
};
};
Or do I need to make another restricted key?!
Got it. No, no keys go in that section. I believe this is just a placeholder in our docs, give me a few minutes
All good take your time!
I also may have thought it was just asking me to replace it with my NEXT_PUBLIC_SERVER_URL
but I belive that was not the case
Okay, yep, this is just a placeholder. Further up in your code you can define API_URL=http://[insert your local test server address here] or you can hard code that line to const response = await fetch(`http://[insert your local test server address here]/payment-sheet`, {
Ok ill go test it Thanks!
zeke_ios-paymentsheet
@agile stag could you explain a little more one what roadrunner was saying?
not really sorry, I skimmed the thread but didn't really follow what you were asking or what was blocking you
Like right now your client-side code in your mobile app has to make a call to your server and as the developer you control both sides (the mobile app and the server) and you need to configure the code to hit the right URL for your server
@agile stag I need some help with somethin!
I get an ERR 400 on {{CONNECTED_ACCOUNT_ID}}
here the REQ
req_u6zdLpJbX7EMGi
this is just a placeholder, you're supposed to put a real account id
can I just use my own?
not really no. You are supposed to pass the id of a connected account, assuming you are a Connect platform. If you're not then you're reading the wrong docs
No im testing!
then you need to make sure you have a real connected account in Test mode and pass that id.
I just did how does it work when Im not on test mode and need to pass multible users?
I have no idea what that means I'm sorry
Ok another question for you @agile stag So I got it to work now were do I see the application fee in my dashboard?
req_SVpFDH9l7640Vq
You can search for the fee_123 in the Dashboard to get that answer in a few seconds. But https://dashboard.stripe.com/test/connect/application_fees
query of what? Please try to be crisp and provide actionable details, right now it looks more like thinking out loud 😦
O I just copied and pasted that msg
Thats what came up when I searched for fees in the dashboard sorry!
The example request you shared is associated with a Checkout Session creating in your platform without anything related to Connect
So there's no ApplicationFee that would be taken.
Interesting when I talked with some of the other helpers earlier they said to read this (zeke_best-practices) for connect so thats what I did
If you go to that thread you can see!
Hard to say, you have many threads spanning hours unfortunately but I think you got many things likely mixed up
What exact end to end documentation page are you following? What in your code makes you think you are using Stripe Connect and taking an ApplicationFee?
Sorry I dont mean to spam. I am just trying to accomplish something that is very important to me.
The file I am following is
okay so you aren't doing that. Or you have a bug in your code where you did not pass the id of a connected account. You also never passed parameters to configure an ApplicationFee
Also I'm... super confused. The example request you shared created a Checkout Session which has nothing to do with the doc you shared right? ReactNative doesn't support Checkout at all
im as confused as you are man😂
I think what is happening is I have two create checkout pages
and my checkout is still connected to the old one
not the new one
I just made of the doc I sent you
if that makes sense.
possibly! I highly recommend taking a step back, carefully reading the doc and your codem, adding clear logs around every call you make client-side and server-side to understand what you are doing
I get this matters a lot to you but you are rushing through so many things and I can see you don't really grasp a lot of those concepts yet
Like if you can use Checkout, just do that. It's fine to show Checkout in a webview/browser on mobile, you don't need an entire ReactNative integration for this.
I have to run but @narrow holly can help if you have follow up questions but after having taking some time to read your own code and the docs first
Ok. If you could just help me figure out how to take 10% from every product thats sold on my marketplace ill leave you guys alone for a few days😂
Bye!
Thats whats started all of this
👋 here in case you need more help!
Yes I do!
So ive been stuck on this problem were I cant take 10% away from every product sold on my marketplace and Ive read every file to the point I think Im getting them mixed up. is it ok if I show you my code?
give me one second
Here is my Payment-router.ts:
import { TRPCError } from "@trpc/server";
import { getPayloadClient } from "../get-payload";
import { stripe } from "../lib/stripe";
import type Stripe from "stripe";
import { z } from "zod";
import { privateProcedure, router } from "./trpc";
// Define the Product type
type Product = {
id: string;
priceId: string | null | undefined;
// other properties...
};
export const paymentRouter = router({
createSession: privateProcedure
.input(z.object({ productIds: z.array(z.string()) }))
.mutation(async ({ ctx, input }) => {
const { user } = ctx;
const { productIds } = input;
if (productIds.length === 0) {
throw new TRPCError({ code: "BAD_REQUEST" });
}
const payload = await getPayloadClient();
try {
const { docs: products } = await payload.find({
collection: "products",
where: {
id: {
in: productIds,
},
},
});
// Cast products to the Product type
const typedProducts: Product[] = products as Product[];
// Filter products that have priceId defined
const filteredProducts = typedProducts.filter((prod: Product) =>
Boolean(prod.priceId)
);
const order = await payload.create({
collection: "orders",
data: {
_isPaid: false,
products: filteredProducts.map((prod: Product) => prod.id), // Map to array of string IDs
user: user.id,
},
});
const line_items: Stripe.Checkout.SessionCreateParams.LineItem[] = [];
filteredProducts.forEach((product: Product) => {
line_items.push({
price: product.priceId!,
quantity: 1,
});
});
line_items.push({
price: "price_1PVJAM05fNcBdPQgDEu0sfqT",
quantity: 1,
adjustable_quantity: {
enabled: false,
},
});
const stripeSession = await stripe.checkout.sessions.create({
success_url: `${process.env.NEXT_PUBLIC_SERVER_URL}/thank-you?orderId=${order.id}`,
cancel_url: `${process.env.NEXT_PUBLIC_SERVER_URL}/cart`,
payment_method_types: ["card"],
mode: "payment",
metadata: {
userId: user.id,
orderId: order.id,
},
line_items,
});
console.log("Stripe session created successfully:", stripeSession);
return { url: stripeSession.url };
} catch (err) {
console.error("Error creating Stripe session:", err);
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "Failed to create Stripe session.",
});
}
}),
pollOrderStatus: privateProcedure
.input(z.object({ orderId: z.string() }))
.query(async ({ input }) => {
const { orderId } = input;
const payload = await getPayloadClient();
try {
const { docs: orders } = await payload.find({
collection: "orders",
where: {
id: {
equals: orderId,
},
},
});
if (!orders.length) {
throw new TRPCError({ code: "NOT_FOUND" });
}
const [order] = orders;
return { isPaid: order._isPaid };
} catch (err) {
console.error("Error polling order status:", err);
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "Failed to poll order status.",
});
}
}),
});
I think that the application fee should go right here under the line_items:
const stripeSession = await stripe.checkout.sessions.create({
success_url: ${process.env.NEXT_PUBLIC_SERVER_URL}/thank-you?orderId=${order.id},
cancel_url: ${process.env.NEXT_PUBLIC_SERVER_URL}/cart,
payment_method_types: ["card"],
mode: "payment",
metadata: {
userId: user.id,
orderId: order.id,
},
line_items,
});
I did not mean to post all the code sorry😂
it's alright, maybe my first question for you is, are you doing destination charges? https://docs.stripe.com/connect/destination-charges
No direct
okay, if that's the case, then when you create the Checkout Session, you should include a StripeAccount header : https://docs.stripe.com/connect/authentication#stripe-account-header. To be clear, Direct Charges mean creating the payment on the connected account, so you should start off with making sure that the Checkout Session is being successfully created on the connected account first. This also means that the Product and Prices used to create the Checkout Session need to also exist on the connected account
To take a application fee, you would need to include this parameter : https://docs.stripe.com/api/checkout/sessions/create#create_checkout_session-payment_intent_data-application_fee_amount
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.