搜尋
首頁web前端js教程使用 Stripe Connect 創建市場:上線流程

介紹

考慮到沒有太多支付處理商提供它,創建一個市場可能太難了,或者是不可能的,如果他們不提供它,那麼你很可能會在他們聽到風聲的那一刻就被踢出平台,即使沒有如果您沒有堅實的基礎來處理使用該平台的賣家的付款、退款和付款,那麼創建市場是有風險的。

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 並從那裡的賣家購買產品。
我們還將新增一個 Stripe 模型,它將儲存有關賣家 Connect 帳戶的資料。

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->
    <h1 id="Account-onboarded-stripe-is-onboarded-stripe-account-id-Not-connected">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- px-4 py-1.5>Setup your seller
                        account
                    </button>

                </form>
            > : 
                <div classname="{'bg-blue-600" rounded- 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 發送了請求,如果是,那麼我們繼續,現在我們要關注的事件是 account.updated,該事件與我們在重定向賣家之前創建的帳戶相關。

當賣家開始入職流程、新增電話號碼、輸入電子郵件或最終完成入職流程時,我們將收到「account.updated」事件,並且會發送此陣列

account.requirements.currently_due

當「currently_due」數組的長度為零時,我們知道用戶已完全註冊,能夠接受付款,因此從我們這邊我們可以更新資料庫並允許用戶創建產品,但在此之前讓我們添加'/api /notifications' 操作中的邏輯

// app/routes/onboarding.tsx

export default function Onboarding() {
    const {stripe} = useLoaderData();

    return <div classname="{'text-center" pt->
    <h1 id="Account-onboarded-stripe-is-onboarded-stripe-account-id-Not-connected">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- px-4 py-1.5>Setup your seller
                        account
                    </button>

                </form>
            > : 
                <div classname="{'bg-blue-600" rounded- 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 的事件,但讓我們看看加入是否有效。

一旦你到達最後一步,它可能會說你的帳戶詳細資料不完整,最後一步是身份驗證,因為這是測試模式,我們可以模擬

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 帳戶產生的一次性連結。

在入職路線中,我們將使用連結包裹賣家儀表板 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 創建市場的第一部分的結束,第二部分將處理產品、付款和支出,第三部分將是最終部分,我們將處理專案面向客戶的方面.

您可以在https://github.com/ddm50/stripe-connect-howto-seller查看該專案的原始碼

以上是使用 Stripe Connect 創建市場:上線流程的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
JavaScript的演變:當前的趨勢和未來前景JavaScript的演變:當前的趨勢和未來前景Apr 10, 2025 am 09:33 AM

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

神秘的JavaScript:它的作用以及為什麼重要神秘的JavaScript:它的作用以及為什麼重要Apr 09, 2025 am 12:07 AM

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

Python還是JavaScript更好?Python還是JavaScript更好?Apr 06, 2025 am 12:14 AM

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。1.Python以简洁语法和丰富库生态著称,适用于数据分析和Web开发。2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

如何安裝JavaScript?如何安裝JavaScript?Apr 05, 2025 am 12:16 AM

JavaScript不需要安裝,因為它已內置於現代瀏覽器中。你只需文本編輯器和瀏覽器即可開始使用。 1)在瀏覽器環境中,通過標籤嵌入HTML文件中運行。 2)在Node.js環境中,下載並安裝Node.js後,通過命令行運行JavaScript文件。

在Quartz中如何在任務開始前發送通知?在Quartz中如何在任務開始前發送通知?Apr 04, 2025 pm 09:24 PM

如何在Quartz中提前發送任務通知在使用Quartz定時器進行任務調度時,任務的執行時間是由cron表達式設定的。現�...

在JavaScript中,如何在構造函數中獲取原型鏈上函數的參數?在JavaScript中,如何在構造函數中獲取原型鏈上函數的參數?Apr 04, 2025 pm 09:21 PM

在JavaScript中如何獲取原型鏈上函數的參數在JavaScript編程中,理解和操作原型鏈上的函數參數是常見且重要的任�...

微信小程序webview中Vue.js動態style位移失效是什麼原因?微信小程序webview中Vue.js動態style位移失效是什麼原因?Apr 04, 2025 pm 09:18 PM

在微信小程序web-view中使用Vue.js動態style位移失效的原因分析在使用Vue.js...

在Tampermonkey中如何實現對多個鏈接的並發GET請求並依次判斷返回結果?在Tampermonkey中如何實現對多個鏈接的並發GET請求並依次判斷返回結果?Apr 04, 2025 pm 09:15 PM

在Tampermonkey中如何對多個鏈接進行並發GET請求並依次判斷返回結果?在Tampermonkey腳本中,我們經常需要對多個鏈...

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用