Die Schaffung eines Marktplatzes wäre wahrscheinlich zu schwierig oder unmöglich, wenn man bedenkt, dass ihn nicht viele Zahlungsabwickler anbieten. Wenn sie ihn nicht anbieten, würden Sie wahrscheinlich von der Plattform gebootet, sobald sie Wind davon bekommen, und selbst ohne das Es ist riskant, einen Marktplatz zu schaffen, auf dem man keine solide Grundlage für die Abwicklung von Zahlungen, Rückerstattungen und Auszahlungen an die Verkäufer hat, die die Plattform nutzen.
Stripe Connect behebt diese Probleme und ermöglicht uns die Schaffung eines einfachen Marktplatzes, auf dem Sie sich als Verkäufer anmelden können und auf dem Kunden problemlos Artikel von diesen Verkäufern kaufen können. Als Plattformbesitzer können Sie auch Ihre Servicegebühr festlegen. Wenn also Benutzer
Einrichten des Projekts
// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model Store { id String @id // This will be the store's subdomain name String updated_at DateTime @default(now()) @updatedAt seller Seller? } model Seller { id Int @id @default(autoincrement()) email String password String store Store @relation(fields: [store_id], references: [id]) date_created DateTime @default(now()) date_updated DateTime @updatedAt store_id String @unique }
Außerdem werden wir ein Stripe-Modell hinzufügen, das Daten über das Connect-Konto des Verkäufers speichert.
model Stripe { account_id String @id is_onboarded Boolean @default(false) user Users @relation(fields: [user_id], references: [discord_id]) user_id String @unique created_at DateTime @default(now()) updated_at DateTime @updatedAt } model Seller { id Int @id @default(autoincrement()) email String password String store Store @relation(fields: [store_id], references: [id]) date_created DateTime @default(now()) date_updated DateTime @updatedAt store_id String @unique stripe Stripe? }
STRIPE_SK=your stripe secret key here
Dann müssen Sie eine neue Datei erstellen, die den Stripe-Client exportiert, damit er von unseren Routen verwendet werden kann
// app/libs/stripe.server.ts import Stripe from 'stripe'; export const stripe = new Stripe(process.env.STRIPE_SK)
// app/routes/onboarding.tsx export default function Onboarding() { const {stripe} = useLoaderData(); return <div className={'text-center pt-[6%]'}> <h1 className={'text-xl'}>Account onboarded: {stripe?.is_onboarded ? stripe?.account_id : '? Not connected'}</h1> <div className={'flex items-center text-white text-sm mt-5 justify-center gap-3'}> {!stripe ? <> <Form method={'post'}> <button type={'submit'} className={'bg-blue-600 hover:cursor-pointer rounded-[6px] px-4 py-1.5'}>Setup your seller account </button> </Form> </> : <> <div className={'bg-blue-600 rounded-[6px] px-4 py-1.5'}>Seller dashboard</div> </>} </div> </div> }
export async function loader({request}: LoaderFunctionArgs) { const user = await authenticator.isAuthenticated(request, { failureRedirect: '/login' }) const seller = await prisma.seller.findFirst({ where: { id: user.id }, include: { stripe: true } }) return { stripe: seller?.stripe } }
export async function action({request}: ActionFunctionArgs) { const authenticated = await authenticator.isAuthenticated(request, { failureRedirect: '/login' }) const seller = await prisma.seller.findFirst({ where: { id: authenticated.id }, include: { stripe: true } }) if (seller && seller.stripe?.is_onboarded) { return json({ message: 'User is onboarded already', error: true }, { status: 400 }) } const account = seller?.stripe?.account_id ? { id: seller.stripe?.account_id } : await stripe.accounts.create({ email: seller?.email, controller: { fees: { payer: 'application', }, losses: { payments: 'application', }, stripe_dashboard: { type: 'express', }, }, }); if (!seller?.stripe?.account_id) { await prisma.seller.update({ where: { id: authenticated.id }, data: { stripe: { create: { account_id: account.id } } }, include: { stripe: true } }) } const accountLink = await stripe.accountLinks.create({ account: account.id, refresh_url: 'http://localhost:5173/onboarding', return_url: 'http://localhost:5173/onboarding', type: 'account_onboarding', collection_options: { fields: 'eventually_due', }, }); console.debug(`[ACCOUNT ID = ${account.id}] CREATED ACCOUNT ONBOARDING LINK, REDIRECTING...`) return redirect(accountLink.url) }
Von dort aus gibt der Verkäufer seine E-Mail-/Telefonnummer ein und der Onboarding-Prozess beginnt. Stripe fragt den Verkäufer normalerweise nach dem Standort des Unternehmens, Geschäftsdaten, Bankkonten usw.
Jetzt können wir Webhooks für Stripe Connect-Ereignisse abhören. Wenn sich ein Verkäufer erfolgreich angemeldet hat, fügen wir diese Attribute dem Datensatz des Verkäufers in der Datenbank hinzu.
Zum Testen können Sie einfach Stripe CLI herunterladen und von dort aus alle Ereignisse an unsere neue Route /api/notifications weiterleiten, die wir jetzt erstellen werden
// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model Store { id String @id // This will be the store's subdomain name String updated_at DateTime @default(now()) @updatedAt seller Seller? } model Seller { id Int @id @default(autoincrement()) email String password String store Store @relation(fields: [store_id], references: [id]) date_created DateTime @default(now()) date_updated DateTime @updatedAt store_id String @unique }
Wenn Sie diesen Befehl ausführen, erhalten Sie eine Webhook-Signatur, damit wir die Integrität jedes von Stripe an uns gesendeten Webhooks überprüfen können. Wenn Sie im Entwicklerportal auf Stripe einen Webhook erstellen, verfügen Sie ebenfalls über ein Geheimnis .
model Stripe { account_id String @id is_onboarded Boolean @default(false) user Users @relation(fields: [user_id], references: [discord_id]) user_id String @unique created_at DateTime @default(now()) updated_at DateTime @updatedAt } model Seller { id Int @id @default(autoincrement()) email String password String store Store @relation(fields: [store_id], references: [id]) date_created DateTime @default(now()) date_updated DateTime @updatedAt store_id String @unique stripe Stripe? }
Wir werden auch eine neue Variable in der .env-Datei hinzufügen
STRIPE_SK=your stripe secret key here
Jetzt können wir den Code schreiben, um diese Ereignisse zu verarbeiten, die uns von Stripe gesendet werden
// app/libs/stripe.server.ts import Stripe from 'stripe'; export const stripe = new Stripe(process.env.STRIPE_SK)
Wir überprüfen, ob Stripe die Anfrage sendet. Ist dies der Fall, fahren wir fort. Das Ereignis, nach dem wir Ausschau halten möchten, ist „account.updated“. Dieses Ereignis hängt mit dem Konto zusammen, das wir vor der Weiterleitung des Verkäufers erstellt haben.
Wenn ein Verkäufer den Onboarding-Prozess startet, seine Telefonnummer hinzufügt oder die E-Mail-Adresse eingibt oder schließlich den Onboarding-Prozess abschließt, erhalten wir das Ereignis „account.updated“ und mit ihm wird dieses Array gesendet
account.requirements.currently_due
Wenn die Länge des Arrays „currently_due“ bei Null liegt, wissen wir, dass der Benutzer vollständig eingebunden ist und Zahlungen akzeptieren kann. Daher können wir von unserer Seite aus die Datenbank aktualisieren und dem Benutzer erlauben, Produkte zu erstellen, aber bevor wir das tun, fügen wir etwas hinzu diese Logik in der Aktion „/api/notifications“
// app/routes/onboarding.tsx export default function Onboarding() { const {stripe} = useLoaderData(); return <div className={'text-center pt-[6%]'}> <h1 className={'text-xl'}>Account onboarded: {stripe?.is_onboarded ? stripe?.account_id : '? Not connected'}</h1> <div className={'flex items-center text-white text-sm mt-5 justify-center gap-3'}> {!stripe ? <> <Form method={'post'}> <button type={'submit'} className={'bg-blue-600 hover:cursor-pointer rounded-[6px] px-4 py-1.5'}>Setup your seller account </button> </Form> </> : <> <div className={'bg-blue-600 rounded-[6px] px-4 py-1.5'}>Seller dashboard</div> </>} </div> </div> }
Sobald das eingerichtet ist, können wir das Onboarding ausprobieren und sehen, ob es funktioniert. Sobald Sie beispielsweise die Adresse eingeben, sehen Sie in der Konsole des Projekts eine Meldung wie
export async function loader({request}: LoaderFunctionArgs) { const user = await authenticator.isAuthenticated(request, { failureRedirect: '/login' }) const seller = await prisma.seller.findFirst({ where: { id: user.id }, include: { stripe: true } }) return { stripe: seller?.stripe } }
Das bedeutet also, dass der Körper validiert ist und wir erfolgreich Ereignisse von Stripe empfangen, aber mal sehen, ob das Onboarding funktioniert.
Sobald Sie zum letzten Schritt gelangen, wird Ihnen wahrscheinlich angezeigt, dass Ihre Kontodaten unvollständig sind. Der letzte Schritt ist die ID-Verifizierung, da es sich um einen Testmodus handelt, den wir simulieren können
Okay, sobald wir das erledigt haben, kehren wir zur vorherigen Seite zurück und können auf „Senden“ klicken. Drücken Sie auf „Senden“ und wir gelangen zur Konsole
export async function action({request}: ActionFunctionArgs) { const authenticated = await authenticator.isAuthenticated(request, { failureRedirect: '/login' }) const seller = await prisma.seller.findFirst({ where: { id: authenticated.id }, include: { stripe: true } }) if (seller && seller.stripe?.is_onboarded) { return json({ message: 'User is onboarded already', error: true }, { status: 400 }) } const account = seller?.stripe?.account_id ? { id: seller.stripe?.account_id } : await stripe.accounts.create({ email: seller?.email, controller: { fees: { payer: 'application', }, losses: { payments: 'application', }, stripe_dashboard: { type: 'express', }, }, }); if (!seller?.stripe?.account_id) { await prisma.seller.update({ where: { id: authenticated.id }, data: { stripe: { create: { account_id: account.id } } }, include: { stripe: true } }) } const accountLink = await stripe.accountLinks.create({ account: account.id, refresh_url: 'http://localhost:5173/onboarding', return_url: 'http://localhost:5173/onboarding', type: 'account_onboarding', collection_options: { fields: 'eventually_due', }, }); console.debug(`[ACCOUNT ID = ${account.id}] CREATED ACCOUNT ONBOARDING LINK, REDIRECTING...`) return redirect(accountLink.url) }
Das funktioniert, jetzt bringt uns Stripe zur Onboarding-Seite zurück und zeigt uns unsere Konto-ID an, was bedeutet, dass wir das Onboarding erfolgreich abgeschlossen haben und mit der Erstellung von Produkten beginnen können.
Okay, lasst uns einfach die Schaltfläche des Verkäufer-Dashboards funktionsfähig machen, bevor wir zu den Produkten übergehen, und eine neue Route erstellen, die sich unter /portal befindet
// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model Store { id String @id // This will be the store's subdomain name String updated_at DateTime @default(now()) @updatedAt seller Seller? } model Seller { id Int @id @default(autoincrement()) email String password String store Store @relation(fields: [store_id], references: [id]) date_created DateTime @default(now()) date_updated DateTime @updatedAt store_id String @unique }
Sehr einfache Funktion. Wenn Sie also nach dem Onboarding zu /portal gehen, werden Sie zu dem einmaligen Link weitergeleitet, den wir für das Stripe-Konto generieren.
In der Onboarding-Route sorgen wir dafür, dass das Verkäufer-Dashboard-Div mit einem Link umschlossen wird.
model Stripe { account_id String @id is_onboarded Boolean @default(false) user Users @relation(fields: [user_id], references: [discord_id]) user_id String @unique created_at DateTime @default(now()) updated_at DateTime @updatedAt } model Seller { id Int @id @default(autoincrement()) email String password String store Store @relation(fields: [store_id], references: [id]) date_created DateTime @default(now()) date_updated DateTime @updatedAt store_id String @unique stripe Stripe? }
Wenn wir /portal besuchen oder auf die Schaltfläche klicken, werden wir zum Stripe-Portal für Connect-Konten weitergeleitet, wo der Benutzer seine Analysen, Auszahlungen usw. sehen kann...
Dies markiert das Ende von Teil eins unserer Entwicklung eines Marktplatzes mit Stripe Connect, Teil zwei wird sich mit Produkten, Zahlungen und Auszahlungen befassen, Teil drei wird der letzte sein und dort werden wir uns mit der kundenorientierten Seite des Projekts befassen .
Sie können den Quellcode des Projekts unter https://github.com/ddm50/stripe-connect-howto-seller sehen
Das obige ist der detaillierte Inhalt vonMit Stripe Connect einen Marktplatz erstellen: Der Onboard-Prozess. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!