使用Next.js开始使用Stripe Connect

许多卖家依靠市场和支付处理平台,如Stripe,来销售他们的商品。如果你正在创建一个市场,让卖家使用你的平台销售产品,如果你想从你平台上的每笔交易中赚取15%的利润,你就需要使用Stripe Connect,将用户的Stripe账户连接到你的Stripe账户。

在本教程中,您将学习如何使用Next.js和Stripe Connect将用户的Stripe账户连接到您的平台。您还将了解Stripe Connect的网络钩子是如何工作的。

什么是Stripe Connect?

Stripe Connect付款入职流程可以帮助开发人员访问他们用户的Stripe账户,以创建产品、编辑产品、销售产品等–同时向平台提供申请费。

Stripe Connect账户的类型

Stripe Connect账户主要有两种类型,即标准型和快速型。

Stripe Express是首屈一指的级别,因为它让平台对资金流有更多的控制,而且对平台来说更昂贵,因为他们的月费是每个活跃的连接账户2美元。MediumQuora和其他高级市场都使用这种Stripe连接实现。

Stripe Standard将Stripe账户连接到平台的Stripe账户,但为平台提供了有限的控制权。它是免费使用的,你不必为赚取的申请费支付Stripe费用。例如,Substack就使用了它。

还有一种Stripe Connect的实施方式叫Stripe Custom Connected Accounts,需要实施复杂和定制支付系统的公司使用这种方式。像Shopify和Lyft这样的公司用它来支付他们的用户和商户。Stripe自定义连接账户提供了对支付入职体验的细化控制。在这篇文章中,我们将不涉及自定义账户。

在这里了解更多关于这些账户之间的区别。

在本教程中,我们将专注于使用Stripe标准连接账户,但这个过程对于Stripe Express账户也是几乎相同的。

使用OAuth流程建立一个Stripe标准账户

下面是我们使用OAuth flow构建项目的一个快速演示

当你进入演示并点击与Stripe连接时,你会进入一个Stripe登录页面。在登录并以有效账户连接后,你会看到对Stripe账户的完整分析,就像这样。?

Dashboard Of Stripe Connect Demo

每当你为用户提供连接到你的Stripe账户的选项时,如果你想通过你的平台向他们付款,或者你想收取申请费,你将需要考虑以下几点。

  1. 该账户上是否启用了支付功能?
  2. 该账户能否向其客户收取费用?
  3. 是否提交了关于Stripe账户的所有细节?
  4. 如果关于Stripe账户的某些内容看起来不对,您将需要允许用户取消Stripe账户的链接,这样他们就可以尝试连接到另一个账户。如果一切看起来都是正确的,并且Stripe账户已经连接,您将需要确保用户不能取消Stripe账户的链接,以防止出现错误和冲突。是否允许取消链接取决于各种因素。我们将在后面讨论它们。

要使用连接Webhooks(文章后面的教程)与连接的账户合作,对连接的账户进行操作,你可能要检查上面提到的四点。

在开发服务器上测试Stripe

首先,我们需要让你的Stripe账户启动并运行。(你可以在这里查看完整的GitHub源代码)。

从你的Stripe仪表盘,获得一个Stripe可发布密钥和一个秘密密钥。如果你还没有一个有效的Stripe账户,你可以在测试模式下试试。确保你保存这些密钥–在下面的步骤中你会需要它们。

现在,转到 Stripe连接设置,滚动到最底部,并获得您的OAuth客户端ID

OAuth Client ID In Stripe Connect Settings

请确保添加 [https://localhost:3001](https://localhost:3001)作为重定向URL(你不需要让它成为默认的),或者,如果你使用其他URL进行开发和测试,则添加它。我提供给你的资源库使用开发port 3001

注意:确保所有这些密钥都是来自测试模式或来自实时模式;不要把它们混为一谈!

现在,克隆或下载这个资源库,然后复制并重命名.env.sample.env.development ,并填写这样的证书(替换密钥)。?

NEXT_PUBLIC_BASE_URL=http://localhost:3001
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_***
STRIPE_SECRET_KEY=sk_test_***
NEXT_PUBLIC_STRIPE_OAUTH_CLIENT_ID=ca_***

复制代码

接下来,运行npm install ,然后是npm run dev 。就这样,你现在有了它的工作!请确保用您的Stripe账户进行测试。

创建和验证Stripe账户ID

接下来,我们需要创建、连接和验证账户ID。

当你点击 “连接到Stripe “按钮时,你会被重定向到这个链接。

https://dashboard.stripe.com/oauth/authorize?response_type=code&client_id=<OAUTH_CLIENT_ID>&scope=read_write&redirect_uri=http://localhost:3001
复制代码

你可以自己访问这个链接,只要用你的OAuth客户ID替换<OAUTH_CLIENT_ID>

提示:如果您想指定另一个重定向URL(从您在Stripe Connect设置中的那个),您也可以这样做。

请注意,当用户用他们的Stripe账户在该特定链接上登录时,这意味着他们同意你将他们的Stripe连接到你的平台。

现在,您将需要在服务器端验证该同意。

当用户通过您的Stripe OAuth链接用Stripe登录时,他们会返回到指定的redirect_uri ,URL中的一些属性,像这样。

https://localhost:3001/?scope=read_write&code=ac_***
复制代码

因此,当用户同意将他们的Stripe账户连接到您的OAuth链接时,Stripe会向您发送带有code 的重定向URL,您现在需要在后台使用该URL来验证同意并成功连接该账户。

验证这个很容易。您只需要在后台发出这个小请求 –stripe.oauth.token 。如果请求给你一个账户ID,说明连接成功了。

现在您有了账户ID,您可以把它存储在任何地方,以便以后访问有关信息,并对该账户进行各种Stripe操作。现在,让我们来打好基础。

创建一个风格化的按钮

接下来,创建经典的Stripe风格的 “Stripe Connect “按钮。

我们使用的是styled-components这里是按钮的样式

现在,在该按钮的onClick 事件上将人们重定向到您的Stripe OAuth URL,像这样。

<button
  type="button"
  className="stripe-connect"
  onClick={() => {
    if (window) {
      const url = `https://dashboard.stripe.com/oauth/authorize?response_type=code&client_id=${
        process.env.NEXT_PUBLIC_STRIPE_OAUTH_CLIENT_ID
      }&scope=read_write&redirect_uri=${
        process.env.NEXT_PUBLIC_BASE_URL
      }`;
      window.document.location.href = url;
    }
  }}
>
  <span>Connect with Stripe</span>
</button>

复制代码

为了使其发挥作用,请确保你再次检查你的.env.development 文件,确保所有的凭证都是正确的,如果你遇到麻烦,请重新运行npm run dev

scope=read_write 条款让您同意对用户的Stripe账户进行写和读操作。

创建后端API端点

现在,让我们在后端制作一个API,在用户从您的OAuth页面返回后,验证Stripe在URL栏中发送的代码。你可以在资源库中参考这个文件的最终版本,它负责验证它在请求正文中收到的code

注意:主逻辑还使用了一些其他的实用函数,所以要让你在存储库中检查所有这些。

让我们从/pages/api/verifyStripe.ts 中的这段代码开始。

import { NextApiHandler } from 'next';
import handleErrors from '@/api/middlewares/handleErrors';
import createError from '@/api/utils/createError';

const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

const handler: NextApiHandler = async (req, res) => {
  const body = req.body;

  switch (req.method) {
    case 'POST':
      const result = await stripe.oauth
        .token({
          grant_type: 'authorization_code',
          code: body?.code,
        })
        .catch((err: unknown) => {
          throw createError(400, `${(err as any)?.message}`);
        });

      res
        .status(200)
        .json({ oauth: result });
      break;

    default:
      throw createError(405, 'Method Not Allowed');
  }
};

export const config = {
  api: {
    bodyParser: {
      sizeLimit: '1mb',
    },
  },
};

export default handleErrors(handler);

复制代码

在这里,如果在请求中提供了正确的code

const result = await stripe.oauth
  .token({
    grant_type: 'authorization_code',
    code: body?.code,
  })
  .catch((err: unknown) => {
    throw createError(400, `${(err as any)?.message}`);
  });
复制代码

…你会从Stripe得到这个结果。

{
  "token_type": "bearer",
  "stripe_publishable_key": "{PUBLISHABLE_KEY}",
  "scope": "read_write",
  "livemode": false,
  "stripe_user_id": "{ACCOUNT_ID}",
  "refresh_token": "{REFRESH_TOKEN}",
  "access_token": "{ACCESS_TOKEN}"
}
复制代码

如果向API提供了不正确或过期的代码,它也会反馈错误。

请记住,code 在几秒钟内就会过期,所以,当客户端收到这个代码时,在加载时立即验证它。

现在,你已经有了一个基本的API端点,准备好被Next.js客户端ping了!

使用React和Next.js在服务器端验证一个已连接的账户

让我们从Next.js主页上创建一个服务器端请求,如果它在URL中收到code 参数。

它应该看起来像这样的/pages/index.ts

import React from 'react';
import fetch from 'isomorphic-unfetch';

import HomeView from '@/views/Home';

const Home = (props) => {
  return <HomeView data={props} />;
};

export const getServerSideProps = async ({
  req,
}) => {
  const body = req?.__NEXT_INIT_QUERY;

  if (!body?.code) {
    return { props: { data: null, req: body } };
  }

  let response;
  try {
    response = await fetch(
      process.env.NEXT_PUBLIC_BASE_URL + '/api/verifyStripe',
      {
        method: 'POST',
        body: JSON.stringify(body),
        headers: {
          'Content-Type': 'application/json',
        },
      },
    ).then((res) => res.json());
  } catch (error) {
    return { props: { data: { error }, req: body } };
  }

  return { props: { data: response, req: body } };
};

export default Home;

复制代码

当你从Next.js页面文件导出一个getServerSideProps 函数时,Next.js会在服务器上运行该函数。你可以在getServerSideProps 函数中返回获取的数据,这样React组件就能以props的形式接收获取的数据。

你可以在这里了解更多关于Next.js SSR的工作方式。

注意:你也可以在useEffect() 中发出请求,然后在获取数据后更新客户端的状态。

如果你的URL有?code=ac_*** ,你就想从URL中获取该参数。Next.js为你提供了req?.__NEXT_INIT_QUERY 对象中的主体参数。

{
  code: "ac_***",
  scope: "read_write"
}

复制代码

使用isomorphic-unfetch ,我们通过在请求中提供给它code ,从我们的API中提取数据。

await fetch(
  process.env.NEXT_PUBLIC_BASE_URL + '/api/verifyStripe', // our API endpoint
  {
    method: 'POST',
    body: JSON.stringify(body), // '{"code": "ac_***", "scope": "read_write"}'
    headers: {
      'Content-Type': 'application/json',
    },
  },
).then((res) => res.json());
复制代码

如果您检查/pages/api/verifyStripe.ts ,您会看到API返回{ oauth: result }

这个结果包含了Stripe账户ID,我们现在可以在React组件的props ,通过在getServerSideProps 中返回这个响应,在/pages/index.ts

return { props: { data: response, req: body } };

复制代码

在上面的这行代码中,我们将所有从API获取的数据转储到datareq 道具提供了URL参数数据,现在你可以在React组件中访问这些数据。

现在,让我们使用通过React组件传递的data prop获取的数据。

const Home = (props) => {
  return <HomeView data={props} />;
};

const HomeView = ({ data }) => {
  return (
    <>
      <button
        type="button"
        className="stripe-connect"
        onClick={() => {
          if (window) {
            const url = `https://dashboard.stripe.com/oauth/authorize?response_type=code&client_id=${
              process.env.NEXT_PUBLIC_STRIPE_OAUTH_CLIENT_ID
            }&scope=read_write&redirect_uri=${
              process.env.NEXT_PUBLIC_BASE_URL
            }`;
            window.document.location.href = url;
          }
        }}
      >
        <span>Connect with Stripe</span>
      </button>

      {data?.req?.code?.startsWith('ac_') && (
        <>
          <div className="fetchedData">
            <h3>Fetched data</h3>
            <pre>{JSON.stringify(data, null, 2)}</pre>
          </div>
        </>
      )}
    </>
  );
};

复制代码

请注意,如果URL栏有以ac_ 开始的code 参数字符串,前端将在<pre> 元素中显示从后端获取的数据。

现在,试着点击Stripe按钮并注册。当你从Stripe OAuth页面被重定向到主页时,你应该看到打印的成功信息,类似这样。

{
  "data": {
    "oauth": {
      "access_token": "sk*****4m",
      "livemode": false,
      "refresh_token": "r*****Oib6W",
      "token_type": "bearer",
      "stripe_publishable_key": "pk_test_51***tfPe",
      "stripe_user_id": "acct_1******YHsmb",
      "scope": "read_write"
    }
  },
  "req": {
    "scope": "read_write",
    "state": "13.036056350529645",
    "code": "ac_JP8TFZTmFg1GUnPnJmTII2PTOJYaeBCD"
  }
}

复制代码

酷!现在,你已经从/api/verifyStripe 端点获取了前端的数据。

获取Stripe账户信息

你可能已经注意到缺少一些东西。你有账户ID,但你没有账户信息。

让我们也从/pages/api/verifyStripe.ts

import { NextApiHandler } from 'next';
import handleErrors from '@/api/middlewares/handleErrors';
import createError from '@/api/utils/createError';

const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

const handler: NextApiHandler = async (req, res) => {
  const body = req.body;

  switch (req.method) {
    case 'POST':
      const result = await stripe.oauth
        .token({
          grant_type: 'authorization_code',
          code: body?.code,
        })
        .catch((err) => {
          throw createError(400, `${err?.message}`);
        });

      // We get the Account ID from `result.stripe_user_id`, 
      // let's fetch more account details using the ID.
      const account = await stripe.accounts
        ?.retrieve(result?.stripe_user_id)
        ?.catch((err) => {
          throw createError(400, `${err?.message}`);
        });

      // Here we get the important details of the account.
      const accountAnalysis = {
        hasConnectedAccount: !!account?.id, // Check if account ID received is actually connected or exists.
        accountId: account?.id,
        hasCompletedProcess: account?.details_submitted,
        isValid: account?.charges_enabled && account?.payouts_enabled,
        displayName:
          account?.settings?.dashboard?.display_name ||
          account?.display_name ||
          null,
        country: account?.country,
        currency: account?.default_currency,
      };

      // boolean - Once the account is connected, should we let it unlink?
      const shouldAllowUnlink =
        accountAnalysis?.hasConnectedAccount &&
        (!accountAnalysis?.isValid ||
          !accountAnalysis?.hasCompletedProcess ||
          !accountAnalysis?.displayName);

      res
        .status(200)
        .json({ account, oauth: result, accountAnalysis, shouldAllowUnlink });

      break;

    default:
      throw createError(405, 'Method Not Allowed');
  }
};

export const config = {
  api: {
    bodyParser: {
      sizeLimit: '1mb',
    },
  },
};

export default handleErrors(handler);

复制代码

现在,刷新主页,再次登录Stripe,你会看到你现在拥有比以前更多的重要信息。

Updated Fetch Data In Stripe

让我们在前台使用获取的数据,用动态文本更新您的Stripe连接按钮。

<button
  type="button"
  className="stripe-connect"
  disabled={!data?.data?.shouldAllowUnlink}
  onClick={() => {
    if (window) {
      const url = `https://dashboard.stripe.com/oauth/authorize?response_type=code&client_id=${
        process.env.NEXT_PUBLIC_STRIPE_OAUTH_CLIENT_ID
      }&scope=read_write&state=${Math.random() * 100}&redirect_uri=${
        process.env.NEXT_PUBLIC_BASE_URL
      }`;
      window.document.location.href = url;
    }
  }}
>
  {data?.data?.account?.id ? (
    <span>Connected: {data?.data?.account?.display_name}</span>
  ) : (
    <span>Connect with Stripe</span>
  )}
</button>

复制代码

这将检查你是否在data 道具中拥有账户ID。如果您有,它将显示:Connected: Display Name ,否则,Connect with Stripe

在这里,我们也将disabled={!data?.data?.shouldAllowUnlink} 道具添加到按钮中。你将在本文的下一节中了解到什么是shouldAllowUnlink

我们也可以像这样显示账户信息。

const YES = <>✅&nbsp;&nbsp;Yes.</>;
const NO = <>❌&nbsp;&nbsp;No.</>;

const HomeView: React.FC<{
  data?;
}> = ({ data }) => {
  return (
    <>
      <h1>Stripe Connect Demo</h1>

      ...

      {data?.data?.account?.id && (
        <>
          <div className="accountAnalysis">
            <div>
              <h3>Payouts Enabled?</h3>
              <h2>{data?.data?.account?.payouts_enabled ? YES : NO}</h2>
            </div>
            <div>
              <h3>Charges Enabled?</h3>
              <h2>{data?.data?.account?.charges_enabled ? YES : NO}</h2>
            </div>
            <div>
              <h3>Details Submitted?</h3>
              <h2>{data?.data?.account?.details_submitted ? YES : NO}</h2>
            </div>
          </div>

          <div className="allowUnlink">
            <h3>Allow Unlink?</h3>
            <p>
              When users connect their Stripe account, and if it is incomplete
              or invalid, you might want to let them unlink.
            </p>
            <h2>{data?.data?.shouldAllowUnlink ? YES : NO}</h2>
          </div>
        </>
      )}

      ....

    </>
  );
}   

复制代码

这就是结果。

Dashboard Of Stripe Connect Demo

就这样,你成功实现了基本的Stripe OAuth!

确定和优化Stripe账户有效性的因素

这些因素对于确保更好的KYC流程是非常重要的。

1.我们是否应该允许取消Stripe账户的链接?

让我们了解一下 “解除Stripe账户的链接 “是什么意思。

当用户连接他们的Stripe账户时,您会得到账户ID,您可以将其存储在数据库中以便将来访问。

现在,想象一下,通过连接的账户,您有大量的产品、客户和订阅。

如果您的账户运行顺利,您不会希望您的用户能够通过您的账户(从您的平台用户界面)断开他们的Stripe连接。您也不希望他们改变他们的Stripe账户,否则就会出现问题。

然而,您_确实_希望他们能够断开并重新连接账户,如果该账户无效,如果支付被禁用,如果收费被禁用,或者如果该账户来自您不支持的国家或货币。

请记住。无论如何,用户总是可以从他们的Stripe仪表板上断开您的平台。但您仍然要决定是否要在您的平台上为用户提供这一选项。

在我们的演示例子中,我们检查一个账户是否应该能够自行解除连接,就像这样(检查verifyStripe.ts)?

const accountAnalysis = {
  hasConnectedAccount: !!account?.id,
  accountId: account?.id,
  hasCompletedProcess: account?.details_submitted,
  isValid: account?.charges_enabled && account?.payouts_enabled,
  displayName:
    account?.settings?.dashboard?.display_name ||
    account?.display_name ||
    null,
  country: account?.country,
  currency: account?.default_currency,
};

// @type boolean
const shouldAllowUnlink =
  accountAnalysis?.hasConnectedAccount &&
  (!accountAnalysis?.isValid ||
    !accountAnalysis?.hasCompletedProcess ||
    !accountAnalysis?.displayName);

复制代码

在我们的例子中,如果账户是连接的,并且以下任何一项是falsenull ,我们应该允许解开账户的链接。

  • account.charges_enabled
  • account.payouts_enabled
  • account.details_submitted
  • 帐户显示名称

注意:你是否允许取消链接取决于你的平台的需求。请确保你相应地调整逻辑。

2.是否启用了支付功能?

您的Stripe Connected账户用户是否能够从他们的Stripe余额中提取资金到他们的银行账户?

如果您得到account?.payouts_enabledfalse ,这意味着该账户没有与Stripe账户连接的有效银行账户。

有时,这不应该影响您的平台,因为即使您的用户的连接账户没有启用支付功能,您也可以提供您的服务。

这取决于您的使用情况。但理想情况下,你应该要求用户启用它。

3.是否启用了收费?

这是在问:你的连接账户用户能不能创建收费?

如果你得到account?.charges_enabled 作为false ,该账户不能创建收费。

如果用户没有启用收费功能,你将无法在他们的账户上创建收费。如果您的平台依赖于通过其用户的Stripe账户创建收费,您需要启用用户收费。

像订阅、计划和结账,都可能依赖于收费API。因此,在几乎所有的用例中,它都是绝对必要的。

所有的细节都提交了吗?

这一点应该很明显。

当您创建一个Stripe账户时,它会要求您提供很多信息:姓名、电子邮件、地址、税务信息、EIN代码、银行账户信息等。

为了使Stripe账户功能齐全,具备所有必要的功能,您希望您的用户的Stripe账户被Stripe完全验证,并正确提交其所有细节。

如果您得到account?.details_submittedfalse ,这意味着账户验证过程还没有完成,或者一些细节还不为Stripe所知。

一定要避免与此类账户进行交易。

4.检查是否有其他要求

当您验证一个Stripe Connected账户时,立即检查account?.requirements[currently_due] 。如果是null ,这意味着该连接账户的状况很好。

如果有到期的要求,如果用户没有及时遵守这些要求,关键的账户操作以后会被阻止。

因此,当你发现account?.requirements[currently_due] 中列出的要求时,一定要通知用户,让他们采取行动。

提示:坚持每四周对连接账户进行检查,并不断优化和收集连接的Stripe账户的有效性的数据。

对Stripe连接的账户进行操作

您可以使用Node.js和stripe node包轻松执行操作。

const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

await payment.products
  .create(
    {
      name: "New product",
      description: "Product created on a Connected Account",
      metadata: {
        userId: "<WHATEVER_CUSTOM_PLATFORM_USER_ID_YOU_HAVE>"
      }
    },
    // Just add the following object as a second parameter on any Stripe operation.
    { stripeAccount: account?.id }
  )
  .catch(async e => {
    throw new Error(e.message)
  })

复制代码

在上面的例子中,您可以在连接的账户上创建一个Stripe产品。要做到这一点,您只需要在Stripe Node API的可选第二个参数中提供一个stripeAccount ID的对象。请注意,如果您不提供Stripe账户ID,它将在您的Stripe账户而不是所需的连接账户上创建产品。

记住:如果一个连接账户通过Stripe仪表盘与您的平台断开连接,或者如果该账户不够有效,一些操作可能会失败。因此,我们建议您只对完全有效的连接账户进行操作。

您可以使用类似的方法对已连接的Stripe账户进行其他大部分操作。

使用Stripe Connect webhooks

什么是webhook?它是一个端点,专门用于在事件发生时接收来自(或通过)其他服务的事件。

Stripe webhooks的作用是什么?

每当Stripe账户发生事件时,例如创建发票,或者创建或更新订阅、收费或付款方式,Stripe都会向您的API端点发送适当的信息,以便您能够从您这边完成该事件。

下面是一个用例。

您的用户在您的Stripe结账页面上付款购买您的软件许可证。在用户从Stripe结账页面提交并返回到主页后,用户会看到一个 “支付成功 “的消息。

但是,你怎么知道用户是否向你付款呢?通过使用Stripe webhooks。当用户通过你的结账页面向你付款时,Stripe会ping你的webhook API端点,告诉你用户已经在某个特定时刻向你支付了某个产品的费用。现在,您可以通过电子邮件向他们发送许可证,并履行订单。

什么是Stripe Connect webhooks?

基本上,它们是Stripe的webhooks,每当所选的事件发生在一个连接的账户上时,它们就会向您的指定终端发出信号。

如果您有一个订阅或任何其他在连接账户上运行的事件,您将使用Stripe Connect webhooks。

创建一个简单的Stripe Connect webhook

首先,安装Stripe CLI。然后在终端运行stripe listen --forward-connect-to localhost:3001/api/connectWebhook

如果您是第一次运行,它会要求您登录。登录并再次运行该命令。

运行该命令会给你一个以whsec_ 开始的端点秘密。现在它正在监听您所有的Stripe连接账户中可能发生的所有事件。

每当它得到一个事件,它就会ping你的webhook在localhost:3001/api/connectWebhook

.env.development.env.production 文件中,保存您在运行CLI命令后收到的STRIPE_SECRET_KEY ,并重新启动服务器。

要创建webhook,请在/pages/api/connectWebhook.ts 创建一个文件。

import { NextApiHandler } from 'next';
import handleErrors from '@/api/middlewares/handleErrors';
import createError from '@/api/utils/createError';

const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

const handler: NextApiHandler = async (req, res) => {
  const body = req.body;

  switch (req.method) {
    case 'POST':
      // Refers to STRIPE_ENDPOINT_SECRET variable in .env.development file
      const endpointSecret: string = process.env.STRIPE_ENDPOINT_SECRET

      // This is to verify if the request is coming from Stripe indeed.
      const sig = req.headers["stripe-signature"]

      let event
      try {
        event = stripe.webhooks.constructEvent(req?.body, sig, endpointSecret)
      } catch (err) {
        console.log(err.message)
        return res.status(401).send(`Webhook Error: ${err.message}`)
      }

      // Handle the checkout.session.completed event
      if (event.type === "checkout.session.completed") {
        const session = event?.data?.object

        // Fulfill the purchase if payment_status is "paid".
        if (session.payment_status === "paid") {
          try {

            // Do whatever here to fulful the purchase.
            // await fulfilThePurchase()

            // Or just observe the Session object
            console.log(session)

          } catch (err) {
            return res.status(400).send({ received: true, error: `${err}`, event })
          }
        }
      }

      // Return a response to acknowledge receipt of the event
      res
        .status(200)
        .json({ received: true, event });
      break;

    default:
      throw createError(405, 'Method Not Allowed');
  }
};

export const config = {
  api: {
    bodyParser: {
      sizeLimit: '1mb',
    },
  },
};

export default handleErrors(handler);

复制代码

在上面的例子中,你监听的是checkout.session.completed 事件。您可以选择监听更多发生在您的Stripe账户或Stripe连接账户的事件。在这里可以看到所有事件的列表

您可以通过创建/编辑产品或更新订阅从您的仪表板上触发这些webhooks,这取决于您正在监听的事件。

为了在开发模式下进行测试,请使用Stripe Test Triggers

$ stripe trigger checkout.session.completed

复制代码

您现在已经了解了Stripe Connect Webhooks是如何工作的,以及如何在开发模式下测试它。

要在Stripe的生产中使用该Webhook,请到Stripe仪表板中的 “开发人员”>”Webhooks“部分。

接收来自Connect应用程序的事件的端点旁边,点击添加端点

Panel To Add A Webhook Endpoint

填写您想要监听的事件,并使用您在线托管的端点URL。

对于部署,我推荐Vercel,因为它是免费的,而且很容易使用 – 你只需在终端运行vercel 命令,就可以部署你的Next.js项目。

当你部署时,确保.env.production ,关于你的Stripe账户的变量都是正确的。你也应该从你的Vercel项目仪表盘上添加它们。

谢谢您的阅读!

The postGetting started with Stripe Connect using Next.jsappeared first onLogRocket Blog.

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享