使用 Stripe 构建无服务器订阅网站
在本教程中,我们将构建一个网站,使用 Stripe 创建结账系统,然后触发通过 AWS Amplify 配置的 AWS Lambda 函数,为购买者创建用户。之后,用户可以登录并查看付费内容!这种模式适用于会员制或课程网站,用户需要付费才能访问内容。您也可以稍微修改代码,将数字产品通过电子邮件发送给客户!
请注意,我是 AWS Amplify 团队的开发倡导者,如果您对此有任何反馈或疑问,请联系我或在我们的 discord 上提问 - discord.gg/amplify!
本教程假设您具有中级React、AWS Amplify和 Node.js 知识,但您可以将 Node.js 代码与任何前端堆栈一起使用。
第一步是创建一个Stripe 帐户并确认您的邮箱地址。您需要用此邮箱地址来生成 API 密钥。此外,请在结账设置页面底部启用“仅限客户端结账”。如果您想自行构建表单等,可以实现全栈结账,但这会让您初期操作更快一些。
然后,使用 Stripe 仪表板创建产品。在左侧导航栏中,选择“产品”,然后选择“+ 添加产品”。填写表单!我选择的是每月 20 美元的订阅服务。
现在,创建一个 React 应用程序。
npx create-react-app membership-site
cd membership-site
然后安装 Amplify 库和 Stripe 的 JavaScript SDK。
npm i aws-amplify @stripe/stripe.js
清除 App.js 组件的return
语句,以便它<div>
现在只返回一个空的。
创建两个新的空 React 组件文件,一个名为SignIn.js
,一个名为Subscribe.js
。
让我们首先实现Subscribe.js
。从 Stripe SDK 导入 loadStripe。
import { loadStripe } from '@stripe/stripe-js'
创建一个在点击时触发事件监听器的按钮。
export default function Subscribe () {
const handleClick = async e => {
}
return <button onClick={handleClick}>Get Course Access</button>
}
在该事件监听器中,使用loadStripe
带有 Stripe Publishable 密钥作为参数的函数。您可以在主页顶部的“获取 API 密钥”下找到您的 Stripe Publishable 密钥。
redirectToCheckout
然后,使用您的信息(首先是 )运行 Stripe 的方法lineItems
。如果您有多个商品可供用户选择,您需要实现某种购物车结账功能,将商品及其数量添加到此数组中。在本例中,对于一个简单的应用,我们将数量设置为 1,并使用商品的价格键。您可以前往您的产品页面,然后复制价格旁边的 API ID 来找到价格键。
如果您将商品设置为订阅,请将其设置为模式,否则请使用“产品”或您创建的任何内容。然后设置成功和取消的 URL——如果成功,我会将他们重定向回主页!我没有实现错误页面,但您可以实现。
const handleClick = async e => {
const stripe = await loadStripe('your_stripe_publishable_key')
const { error } = await stripe.redirectToCheckout({
lineItems: [{
price: 'price_key',
quantity: 1
}],
mode: 'subscription',
successUrl: 'http://localhost:3000/',
cancelUrl: 'http://localhost:3000/cancel'
})
}
在您的 App 组件中呈现此组件。
import './App.css'
import Subscribe from './Subscribe'
function App () {
return (
<div className='App'>
<h1>My Fancy Subscription Site</h1>
<Subscribe />
</div>
)
}
export default App
试试看——你应该可以用这个表单“购买”一件商品了!你可以用信用卡号“4242 4242 4242 4242”来测试 Stripe,无需实际付款。现在我们已经实现了本教程的第一步:结账!
现在让我们转到 webhook 处理程序,一旦购买了商品,它就会创建一个新用户。
首先,为您的项目初始化 Amplify。
amplify init
按回车键接受建议的配置。然后我们将初始化身份验证。
amplify add auth
每次弹出问题时,按 Enter 键接受默认身份验证设置。现在,我们将添加一个 API,以便 Webhook 可以向 URL 发出请求。
amplify add api
像这样回答前几个问题:
? Please select from one of the below mentioned services: REST
? Would you like to add a new path to an existing REST API: No
? Provide a friendly name for your resource to be used as a label for this category in the project: apib104bfb8
? Provide a path (e.g., /book/{isbn}): /webhook
然后,我们还将创建一个 AWS Lambda 函数。请用以下方式回答这组问题:
? Choose a Lambda source Create a new Lambda function
? Provide an AWS Lambda function name: stripedemofunction
? Choose the runtime that you want to use: NodeJS
? Choose the function template that you want to use: Serverless ExpressJS function (Integration with
API Gateway)
我们确实想为该项目启用高级设置。请回答“是”。
? Do you want to configure advanced settings? Yes
首先,我们要从 Lambda 函数访问身份验证。
? Select the categories you want this function to have access to. auth
? Select the operations you want to permit on stripedemo: create, read, update, delete
对以下三个问题的回答都是“否”:
? Do you want to invoke this function on a recurring schedule? No
? Do you want to enable Lambda layers for this function? No
? Do you want to configure environment variables for this function? No
但是,我们会配置函数可以访问的密钥值。密钥名称请选择“stripe_key”,然后输入您的 Stripe 密钥。密钥位于您之前找到可发布密钥的位置——您必须点击“显示测试密钥”才能看到它。
? Enter a secret name (this is the key used to look up the secret value): stripe_key
? Enter the value for stripe_key: [hidden]
? What do you want to do? I'm done
然后运行amplify push
将所有配置的资源部署到云端!
更改为您的函数所在的目录并安装 AWS SDK 和 Stripe Node SDK。
cd /amplify/backend/function/stripedemofunction/src
npm i aws-sdk stripe
现在我们开始编写逻辑!
首先,删除Lambda 函数文件中注释下方的所有内容app.js
,然后粘贴以下内容。大部分内容已包含在文件中。它将为您的无服务器应用程序设置 Express。
const express = require('express')
const bodyParser = require('body-parser')
const awsServerlessExpressMiddleware = require('aws-serverless-express/middleware')
const aws = require('aws-sdk')
// declare a new express app
const app = express()
app.use(bodyParser.json({
verify: function (req, res, buf) {
req.rawBody = buf.toString()
}
}))
app.use(awsServerlessExpressMiddleware.eventContext())
// Enable CORS for all methods
app.use(function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Headers', '*')
next()
})
app.listen(3000, function () {
console.log('App started')
})
现在我们将编写一个函数来检索 Stripe 密钥。如果你查看文件顶部,app.js
你会发现它已经生成了!
const getStripeKey = async () => {
const { Parameters } = await (new aws.SSM())
.getParameters({
Names: ['stripe_key'].map(secretName => process.env[secretName]),
WithDecryption: true
})
.promise()
return Parameters[0].Value
}
现在我们将创建一条路线来处理我们设置的路线的发布请求/webhook
。
首先,我们需要获取 Stripe 密钥,然后配置 Stripe 来使用它。您还需要确保在生产应用中,该请求已由Stripe 正确签名。
我们将使用 Stripe 请求正文中发送给我们的客户 ID 来获取客户的电子邮件。
然后,我们将实例化 AWS Cognito SDK,并使用它通过 admin API 创建用户。您可以UserPoolId
在文件顶部的注释中获取您的代码app.js
。它与我的代码略有不同。然后,我们将确保通过电子邮件发送用户帐户,并使用该电子邮件创建帐户。
如果成功,我们将发送 200 响应。
app.post('/webhook', async function (req, res) {
const stripeKey = await getStripeKey()
const stripe = require('stripe')(stripeKey)
console.log(stripeKey)
const customer = await stripe.customers.retrieve(
req.body.data.object.customer
)
const userEmail = customer.email
const cognito = new aws.CognitoIdentityServiceProvider({ apiVersion: '2016-04-18' })
cognito.adminCreateUser({
UserPoolId: process.env.AUTH_STRIPEDEMO1C66A4D4_USERPOOLID,
Username: userEmail,
DesiredDeliveryMediums: [
'EMAIL'
],
UserAttributes: [
{
Name: 'email',
Value: userEmail
}],
ValidationData: [
{
Name: 'email',
Value: userEmail
}
]
}, function (err, data) {
if (err) console.log(err, err.stack) // an error occurred
else {
console.log(data)
res.sendStatus(200)
} // successful response
})
})
现在,我们需要在用户完成购买时触发 Lambda 函数。首先,我们需要获取应用的 URL。如果您进入目录aws-exports.js
中的文件src/
,会看到一个endpoint
键。例如,我的 URL 是这样的:“ https://rw7cx5fyn3.execute-api.us-east-1.amazonaws.com/dev ”/webhook
。此外,在 URL 末尾添加以下内容,例如:“ https://rw7cx5fyn3.execute-api.us-east-1.amazonaws.com/dev/webhook ”。
然后,进入Stripe 控制面板,点击左侧导航栏中的“开发者”。然后点击下方的“Webhooks”。点击右上角的“+ 添加端点”按钮。粘贴上面的 URL,然后选择“payment_intent.succeeded”作为要监听的事件。
您的活动应该可以正常进行!请再次测试结账功能,然后查看您的邮箱,获取登录信息!
现在来看看演示代码——让我们添加一个登录表单,然后在登录后呈现一些付费内容!
在您的<SignIn>
组件中,添加以下 React 表单,提交后将触发 Amplify 的登录方法。
import { useState } from 'react'
import { Auth } from 'aws-amplify'
export default function SignIn ({ setUser }) {
async function logIn (e) {
e.preventDefault()
try {
const user = await Auth.signIn(username, password)
setUser(user)
} catch (error) {
console.log('error signing in', error)
}
}
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
return (
<form onSubmit={logIn}>
<input type='text' placeholder='username' onChange={e => setUsername(e.target.value)} />
<input type='password' placeholder='password' onChange={e => setPassword(e.target.value)} />
<input type='submit' value='log in' />
</form>
)
}
现在我们来完善 App 组件!我们将创建一个user
state 属性,该属性会在用户登录后更新。如果用户已登录,我们将渲染付费墙内容;否则,我们将显示登录表单。
import './App.css'
import Subscribe from './Subscribe'
import SignIn from './SignIn'
import { Auth } from 'aws-amplify'
import { useState } from 'react'
function App () {
const [user, setUser] = useState(null)
return (
<div className='App'>
<h1>My Fancy Subscription Site</h1>
<Subscribe />
{user
? <h1>Paywalled content!</h1>
: <SignIn setUser={setUser} />}
</div>
)
}
export default App
如果要关闭此演示,您可以运行amplify delete
以取消配置云资源!
大功告成!在本教程中,我们创建了一个 Stripe 结账系统,它会触发账户创建。登录后,用户就可以查看付费内容了!如果您对 AWS Amplify 或本教程有任何反馈,请告诉我!
鏂囩珷鏉ユ簮锛�https://dev.to/aws/build-a-serverless-subscription-site-with-stripe-48h1