在本教程中,我们将建立一个网站,使用Stripe创建一个结账系统,然后触发一个通过AWS Amplify提供的AWS Lambda函数,为购买者创建一个用户。然后,用户就可以登录并看到付费的内容了。这种模式适用于会员制或课程网站,你希望用户为访问内容付费。你也可以稍微修改代码,通过电子邮件向客户发送数字产品。
本教程假设有中级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可发布密钥作为参数。您可以在主页顶部的 "获取您的API密钥 "下找到您的Stripe可发布密钥。
然后,用你的信息运行Stripe的redirectToCheckout 方法 -- 首先是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'
})
}
在你的应用程序组件中渲染这个组件。
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
按回车键,接受建议的配置。然后,我们将初始化auth。
amplify add auth
对弹出的每个问题按回车键,接受默认的认证设置。现在我们将添加一个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函数中访问auth:
? 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
现在我们开始写逻辑了!
首先,在你的app.js 文件中删除Lambda函数的注释下面的所有内容,然后粘贴以下内容。其中大部分内容已经在文件中了。它将为你的无服务器应用程序设置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并使用它来创建一个具有管理API的用户。你可以在你的app.js 文件顶部的注释中获得你的UserPoolId 。它将与我代码中的略有不同。然后,我们将确保用户账户是通过电子邮件发送的,并使用该电子邮件来创建账户。
如果我们成功了,我们将发送一个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 关键。例如,我的看起来像这样"https://rw7cx5fyn3.execute-api.us-east-1.amazonaws.com/dev"。另外,在URL的末尾添加/webhook ,例如"https://rw7cx5fyn3.execute-api.us-east-1.amazonaws.com/dev/webhook"。
然后,进入您的Stripe控制面板,点击左侧导航中的 "开发人员"。然后点击下面的 "Webhooks"。点击右上方的 "+添加端点 "按钮。粘贴上面的URL,然后选择 "payment_intent.succed "作为要监听的事件。
你的事件应该工作了再次测试结账,然后检查你的电子邮件,看看是否有登录。
现在是展示代码--让我们添加一个登录表格,然后在他们登录后呈现一些付费内容
在你的<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 状态属性,一旦用户签到就会更新。如果用户签到了,我们将呈现付费内容,否则我们将显示签到表格。
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或本教程有任何反馈意见,请告诉我!


