ホームページ ウェブフロントエンド jsチュートリアル Stripe Connect を使用したマーケットプレイスの作成: オンボードプロセス

Stripe Connect を使用したマーケットプレイスの作成: オンボードプロセス

Nov 28, 2024 am 09:55 AM

導入

マーケットプレイスを提供している決済処理業者が多くないことを考えると、マーケットプレイスを作成するのはおそらく難しすぎるか不可能でしょう。もしマーケットプレイスが提供しなければ、その情報を知った瞬間にプラットフォームから強制終了される可能性が高く、それがなかったとしてもプラットフォームを使用して販売者への支払い、返金、支払いを処理するための強固な基盤がないマーケットプレイスを作成するのは危険です。

Stripe Connect はこれらの問題に対処し、販売者としてサインアップできる基本的なマーケットプレイスを作成し、顧客がこれらの販売者から商品を簡単に購入できるようにします。プラットフォーム所有者はサービス手数料を設定することもできるため、ユーザー X がストア Y から購入すると、その取引の X% が取り扱われますが、それについては後ほど説明します。

Creating a marketplace with Stripe Connect: The onboard process

プロジェクトのセットアップ

データベース接続の処理には Prisma を使用し、認証は remix-auth によって処理されます。この部分については、マーケットプレイスの販売者側のみを処理します。

// 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
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

これは schema.prisma ファイルの外観です。販売者モデルとそれに関連する店舗モデルがあります。「id」フィールドはサブドメインとして機能するため、購入者の側に到達すると、次のことが可能になります。 store.localhost.com にアクセスし、そこの販売者から製品を購入します。
また、販売者の Connect アカウントに関するデータを保存する Stripe モデルも追加します。

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?
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

これでユーザーのオンボーディングを処理できるようになったので、.env ファイルに別の変数を定義しましょう。

STRIPE_SK=your stripe secret key here
ログイン後にコピー
ログイン後にコピー

Stripe の開発ページで生成することで Stripe 秘密キーを取得できます。現時点では Stripe Connect の使用のみを許可する制限付きキーを作成することをお勧めします。

次に、Stripe クライアントをエクスポートしてルートで使用できるようにする新しいファイルを作成する必要があります

// app/libs/stripe.server.ts
import Stripe from 'stripe';
export const stripe = new Stripe(process.env.STRIPE_SK)
ログイン後にコピー
ログイン後にコピー

「/onboarding」に新しいルートを作成します

// 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
    }
}
ログイン後にコピー
ログイン後にコピー

ここで、/onboarding にアクセスすると、接続されていないことが表示され、ボタンを押してサインアップできるようになります。ここでアクション関数が登場します。

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)
}
ログイン後にコピー
ログイン後にコピー

販売者がボタンを押すと、登録に使用したメールアドレスでアカウントが作成され、販売者が既に Stripe アカウントを関連付けている場合は、オンボーディング ページにリダイレクトするアカウント リンクが作成されます。がオンボーディングされていない場合は、オンボーディング リンクにリダイレクトします。

Creating a marketplace with Stripe Connect: The onboard process

そこから販売者はメール/電話番号を入力し、オンボーディングプロセスが始まります。通常、Stripe は販売者にビジネスの場所、ビジネスの詳細、銀行口座などを尋ねます...

Stripe Connect イベントの Webhook をリッスンできるようになりました。そのため、販売者が正常にオンボーディングしたら、それらの属性をデータベース内の販売者のレコードに追加します。

テストの場合は、Stripe CLI をダウンロードするだけで、そこからイベントをこれから作成する新しいルート /api/notifications に転送できます

// 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
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

そのコマンドを実行すると、Webhook 署名が与えられます。これにより、Stripe から送信された各 Webhook の整合性を検証できるようになります。Stripe の開発者ポータルで Webhook を作成した場合も同様に、シークレットが得られます。 .

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?
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

.env ファイルに新しい変数も追加します

STRIPE_SK=your stripe secret key here
ログイン後にコピー
ログイン後にコピー

これで、Stripe から送信されるこれらのイベントを処理するコードを作成できます

// app/libs/stripe.server.ts
import Stripe from 'stripe';
export const stripe = new Stripe(process.env.STRIPE_SK)
ログイン後にコピー
ログイン後にコピー

Stripe がリクエストを送信していることを確認します。Stripe である場合は次に進みます。注目したいイベントは account.updated です。そのイベントは、販売者をリダイレクトする前に作成したアカウントに関連しています。

販売者がオンボーディング プロセスを開始したり、電話番号を追加したり、電子メールを入力したり、最終的にオンボーディング プロセスを完了すると、「account.updated」イベントが取得され、この配列が一緒に送信されます

アカウント.requirements.currently_due

'currently_due' 配列の長さが 0 の場合、ユーザーが完全にオンボーディングされ、支払いを受け入れることができることがわかります。そのため、データベースを更新してユーザーが商品を作成できるようにすることができますが、その前に以下を追加しましょう「/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>
}
ログイン後にコピー
ログイン後にコピー

それが整ったら、オンボーディングを試して、それが機能するかどうかを確認できます。たとえばアドレスを入力するとすぐに、プロジェクトのコンソールに
のようなメッセージが表示されます。

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
    }
}
ログイン後にコピー
ログイン後にコピー

これは、本文が検証され、Stripe からイベントを正常に受信していることを意味しますが、オンボーディングが機能するかどうかを見てみましょう。

最後のステップに到達すると、おそらくアカウントの詳細が不完全であることが表示されます。最後のステップは ID 確認です。これはテストモードなので、それをシミュレートできます

Creating a marketplace with Stripe Connect: The onboard process

それが完了したら、前のページに戻り、送信を押し、送信を押して、コンソールに入ります

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)
}
ログイン後にコピー
ログイン後にコピー

これでうまくいきました。Stripe はオンボーディング ページに戻り、アカウント ID が表示されます。これはオンボーディングが成功し、製品の作成を開始できることを意味します。

Creating a marketplace with Stripe Connect: The onboard process

それでは、商品に進む前に販売者ダッシュボード ボタンを機能させて、/portal に新しいルートを作成しましょう

// 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
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

非常に基本的な機能なので、オンボーディングしている場合に /portal にアクセスすると、Stripe アカウント用に生成された 1 回限りのリンクにリダイレクトされます。

オンボーディング ルートで、販売者ダッシュボード div をリンクでラップします。

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?
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

/portal にアクセスするかボタンを押すと、Stripe の Connect アカウント用ポータルにリダイレクトされ、ユーザーはそこで分析や支払いなどを確認できます...

Creating a marketplace with Stripe Connect: The onboard process

これで、Stripe Connect を使用してマーケットプレイスを作成するパート 1 が終了します。パート 2 は製品、支払い、支払いを扱います。パート 3 が最後で、そこでプロジェクトの顧客側の側面を扱います。 .

プロジェクトのソース コードは、https://github.com/ddm50/ Stripe-connect-howto-seller でご覧いただけます

以上がStripe Connect を使用したマーケットプレイスの作成: オンボードプロセスの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

javascriptの分解:それが何をするのか、なぜそれが重要なのか javascriptの分解:それが何をするのか、なぜそれが重要なのか Apr 09, 2025 am 12:07 AM

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

JavaScriptの進化:現在の傾向と将来の見通し JavaScriptの進化:現在の傾向と将来の見通し Apr 10, 2025 am 09:33 AM

JavaScriptの最新トレンドには、TypeScriptの台頭、最新のフレームワークとライブラリの人気、WebAssemblyの適用が含まれます。将来の見通しは、より強力なタイプシステム、サーバー側のJavaScriptの開発、人工知能と機械学習の拡大、およびIoTおよびEDGEコンピューティングの可能性をカバーしています。

JavaScriptエンジン:実装の比較 JavaScriptエンジン:実装の比較 Apr 13, 2025 am 12:05 AM

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

JavaScript:Web言語の汎用性の調査 JavaScript:Web言語の汎用性の調査 Apr 11, 2025 am 12:01 AM

JavaScriptは、現代のWeb開発のコア言語であり、その多様性と柔軟性に広く使用されています。 1)フロントエンド開発:DOM操作と最新のフレームワーク(React、Vue.JS、Angularなど)を通じて、動的なWebページとシングルページアプリケーションを構築します。 2)サーバー側の開発:node.jsは、非ブロッキングI/Oモデルを使用して、高い並行性とリアルタイムアプリケーションを処理します。 3)モバイルおよびデスクトップアプリケーション開発:クロスプラットフォーム開発は、反応および電子を通じて実現され、開発効率を向上させます。

Python vs. JavaScript:学習曲線と使いやすさ Python vs. JavaScript:学習曲線と使いやすさ Apr 16, 2025 am 12:12 AM

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合) next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合) Apr 11, 2025 am 08:22 AM

この記事では、許可によって保護されたバックエンドとのフロントエンド統合を示し、next.jsを使用して機能的なedtech SaaSアプリケーションを構築します。 FrontEndはユーザーのアクセス許可を取得してUIの可視性を制御し、APIリクエストがロールベースに付着することを保証します

C/CからJavaScriptへ:すべてがどのように機能するか C/CからJavaScriptへ:すべてがどのように機能するか Apr 14, 2025 am 12:05 AM

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

JavaScriptをインストールするにはどうすればよいですか? JavaScriptをインストールするにはどうすればよいですか? Apr 05, 2025 am 12:16 AM

JavaScriptは、最新のブラウザにすでに組み込まれているため、インストールを必要としません。開始するには、テキストエディターとブラウザのみが必要です。 1)ブラウザ環境では、タグを介してHTMLファイルを埋め込んで実行します。 2)node.js環境では、node.jsをダウンロードしてインストールした後、コマンドラインを介してJavaScriptファイルを実行します。

See all articles