admin管理员组文章数量:1415460
I’m working on a Next.js (15.1.6) app with React (19.0.0) and trying to integrate Stripe Identity Verification fully embedded within my UI—without redirecting to Stripe’s hosted page or opening a lightbox/modal via stripe.verifyIdentity. My goal is to capture photos (front ID, back ID, selfie) in my custom UI and submit them to Stripe seamlessly.
What I’ve Tried
Initially, I used [email protected] and uploaded files client-side via with purpose: 'identity_document'. After creating a VerificationSession server-side, I called stripe.verifyIdentity(clientSecret) from @stripe/stripe-js, but it opens a modal that restarts the photo capture process, ignoring my uploads.
I downgraded to [email protected] (and tested 10.17.0) hoping to use a server-side submit method to finalize the session with my uploaded files, but submit isn’t available in VerificationSessionsResource (only create, retrieve, update, list, cancel, redact). I also tried update with a hypothetical provided_documents param to link file IDs, but it’s not a valid property in VerificationSessionUpdateParams.
Here’s a simplified version of my current code with 16.12.0:
// src/lib/stripe.ts
import Stripe from 'stripe';
export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { apiVersion: '2024-08-01' });
// src/app/api/identity/create-verification-session/route.ts
import { NextResponse } from 'next/server';
import { stripe } from '@/lib/stripe';
export async function POST(req: Request) {
const { userId } = await req.json();
const session = await stripe.identity.verificationSessions.create({
type: 'document',
options: { document: { require_matching_selfie: true } },
metadata: { user_id: userId },
});
return NextResponse.json({ id: session.id, client_secret: session.client_secret });
}
// src/components/IdentityVerification.tsx
'use client';
import { useState, useRef, useEffect } from 'react';
import { loadStripe } from '@stripe/stripe-js';
const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!);
export default function IdentityVerification({ userId }: { userId: string }) {
const [session, setSession] = useState<{ id: string; client_secret: string } | null>(null);
const [step, setStep] = useState<'id_front' | 'id_back' | 'selfie'>('id_front');
const videoRef = useRef<HTMLVideoElement>(null);
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
fetch('/api/identity/create-verification-session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ userId }),
})
.then((res) => res.json())
.then(setSession);
}, [userId]);
const capturePhoto = async () => {
const context = canvasRef.current?.getContext('2d');
if (context && videoRef.current) {
context.drawImage(videoRef.current, 0, 0, 300, 225);
canvasRef.current?.toBlob(async (blob) => {
if (!blob) return;
const formData = new FormData();
formData.append('file', blob, `${step}.jpg`);
formData.append('purpose', 'identity_document');
const res = await fetch('', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY}` },
body: formData,
});
const data = await res.json();
if (step === 'id_front') setStep('id_back');
else if (step === 'id_back') setStep('selfie');
else if (step === 'selfie') submitVerification();
}, 'image/jpeg');
}
};
const submitVerification = async () => {
if (!session) return;
const stripe = await stripePromise;
await stripe?.verifyIdentity(session.client_secret); // Triggers modal
};
return (
<div>
<video ref={videoRef} autoPlay />
<canvas ref={canvasRef} width="300" height="225" className="hidden" />
<button onClick={capturePhoto}>Capture Photo</button>
</div>
);
}
The Problem
verifyIdentity opens a modal, duplicating the photo capture process.
No server-side submit or way to link files to the session without the modal.
The Stripe docs () suggest create and verifyIdentity, but nothing about embedding without a lightbox.
Questions
Is it possible to embed Stripe Identity Verification fully in my Next.js app without a modal/lightbox, using my own photo capture UI?
If submit was removed, is there an alternative server-side method in 16.12.0 (or any version) to finalize a session with custom-uploaded files?
Has anyone successfully bypassed verifyIdentity’s modal while still verifying files?
Any insights, workarounds, or confirmation that this isn’t possible would be greatly appreciated! I’d rather not downgrade further unless necessary, but I’m open to suggestions.
I’m working on a Next.js (15.1.6) app with React (19.0.0) and trying to integrate Stripe Identity Verification fully embedded within my UI—without redirecting to Stripe’s hosted page or opening a lightbox/modal via stripe.verifyIdentity. My goal is to capture photos (front ID, back ID, selfie) in my custom UI and submit them to Stripe seamlessly.
What I’ve Tried
Initially, I used [email protected] and uploaded files client-side via https://files.stripe/v1/files with purpose: 'identity_document'. After creating a VerificationSession server-side, I called stripe.verifyIdentity(clientSecret) from @stripe/stripe-js, but it opens a modal that restarts the photo capture process, ignoring my uploads.
I downgraded to [email protected] (and tested 10.17.0) hoping to use a server-side submit method to finalize the session with my uploaded files, but submit isn’t available in VerificationSessionsResource (only create, retrieve, update, list, cancel, redact). I also tried update with a hypothetical provided_documents param to link file IDs, but it’s not a valid property in VerificationSessionUpdateParams.
Here’s a simplified version of my current code with 16.12.0:
// src/lib/stripe.ts
import Stripe from 'stripe';
export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { apiVersion: '2024-08-01' });
// src/app/api/identity/create-verification-session/route.ts
import { NextResponse } from 'next/server';
import { stripe } from '@/lib/stripe';
export async function POST(req: Request) {
const { userId } = await req.json();
const session = await stripe.identity.verificationSessions.create({
type: 'document',
options: { document: { require_matching_selfie: true } },
metadata: { user_id: userId },
});
return NextResponse.json({ id: session.id, client_secret: session.client_secret });
}
// src/components/IdentityVerification.tsx
'use client';
import { useState, useRef, useEffect } from 'react';
import { loadStripe } from '@stripe/stripe-js';
const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!);
export default function IdentityVerification({ userId }: { userId: string }) {
const [session, setSession] = useState<{ id: string; client_secret: string } | null>(null);
const [step, setStep] = useState<'id_front' | 'id_back' | 'selfie'>('id_front');
const videoRef = useRef<HTMLVideoElement>(null);
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
fetch('/api/identity/create-verification-session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ userId }),
})
.then((res) => res.json())
.then(setSession);
}, [userId]);
const capturePhoto = async () => {
const context = canvasRef.current?.getContext('2d');
if (context && videoRef.current) {
context.drawImage(videoRef.current, 0, 0, 300, 225);
canvasRef.current?.toBlob(async (blob) => {
if (!blob) return;
const formData = new FormData();
formData.append('file', blob, `${step}.jpg`);
formData.append('purpose', 'identity_document');
const res = await fetch('https://files.stripe/v1/files', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY}` },
body: formData,
});
const data = await res.json();
if (step === 'id_front') setStep('id_back');
else if (step === 'id_back') setStep('selfie');
else if (step === 'selfie') submitVerification();
}, 'image/jpeg');
}
};
const submitVerification = async () => {
if (!session) return;
const stripe = await stripePromise;
await stripe?.verifyIdentity(session.client_secret); // Triggers modal
};
return (
<div>
<video ref={videoRef} autoPlay />
<canvas ref={canvasRef} width="300" height="225" className="hidden" />
<button onClick={capturePhoto}>Capture Photo</button>
</div>
);
}
The Problem
verifyIdentity opens a modal, duplicating the photo capture process.
No server-side submit or way to link files to the session without the modal.
The Stripe docs (https://docs.stripe/identity/verification-sessions) suggest create and verifyIdentity, but nothing about embedding without a lightbox.
Questions
Is it possible to embed Stripe Identity Verification fully in my Next.js app without a modal/lightbox, using my own photo capture UI?
If submit was removed, is there an alternative server-side method in 16.12.0 (or any version) to finalize a session with custom-uploaded files?
Has anyone successfully bypassed verifyIdentity’s modal while still verifying files?
Any insights, workarounds, or confirmation that this isn’t possible would be greatly appreciated! I’d rather not downgrade further unless necessary, but I’m open to suggestions.
Share Improve this question asked Feb 21 at 3:52 William HartmanWilliam Hartman 431 silver badge3 bronze badges1 Answer
Reset to default 1Stripe Identity does not allow you to use your own photo capture UI, or pass in your own files via the API to be verified.
本文标签:
版权声明:本文标题:reactjs - Embed Stripe Identity Verification instead of opening a lightbox with Stripe's designflow - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745167677a2645781.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论