经过长达八个小时以上的探索与实践,我成功在Manifest V3版本的Chrome Extensions中接入Striped的PricingTable功能。
先展示目前已成功实现的集成效果:
使用Plasmo
搭建Chrome Extensions
搭建一个Extensions,我这里通过使用Plasmo快速搭建了我自己的Extensions程序。通过创建
content.tsx
即可创建你自己的程序入口,我这里选择使用React进行开发。关于CSUI的具体原理可以了解官方文档:How does Plasmo CSUI work? 这里大致说一下,CSUI主要通过Shadow DOM实现的,这个要关注一下,后续有关联。
搭建Server并部署到Vercel
在搭建Server上面,我直接参考官方提供的Checkout single subscription例子,然后结合Vercel的官方文档,自己实现了一版:。你可以参考该repo自行实现。
express
notion-nice • Updated Mar 7, 2024
然后根据Using Express.js with Vercel进行部署即可。
入口文件api/index.js
源码解析
重点关注
/pay/:customer/:theme?
路由中的实现,这是一个基于ejs
实现的一个PricingTable
页面,通过官方SDK生成Sessions
并传递给PricingTable
组件,对应大的ejs文件在views/pay.ejs
。该路由请求呈现效果就是文章一开始演示的支付页面啦,源码中涉及的PRICING_TABLE_ID 参数,需要你自己在stripe
后台创建对应的PricingTable
中获取并替换 。关于 PricingTable
更多信息可以查阅官方教程:Embeddable pricing table for SaaS businesses把Server的页面嵌入到Chrome Extensions中
在集成方面,我写了一个组件进行操作,以下是部分实现代码:
// Upgrade.tsx import { useMount } from "ahooks" import React, { useContext, useState } from "react" import { Button } from "./ui/button" import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, type DialogContentProps } from "./ui/dialog" export const Upgrade = ({ portalProps }: Pick<DialogContentProps, "portalProps">) => { const [paymentUrl, setPaymentUrl] = useState("") useMount(async () => { const user = {} // TODO: 获取用户信息 const { customerId } = await axiosStripe .post("/create-payment", { userId, email: user.email, name: user.name }) .then((r) => r.data) setPaymentUrl(`${baseURL}/pay/${customerId}`) }) return ( <Dialog> <DialogTrigger asChild> <Button variant="link">升级到Plus</Button> </DialogTrigger> <DialogContent portalProps={portalProps}> <DialogHeader> <DialogTitle>升级到Plus</DialogTitle> </DialogHeader> <div className="nf-w-full nf-h-[460px]"> {paymentUrl && ( <iframe src={paymentUrl} allowTransparency className="nf-w-full nf-h-full nf-border-none" /> )} </div> </DialogContent> </Dialog> ) }
组件使用了shadcn/ui和Tailwind CSS进行开发,在这里通过iframe嵌入了我们Server中的支付页面,把customer放到Url上面传递给服务器。
实现原理
但是有一种情况是例外的:在沙盒化 iframe 中嵌入远程托管代码 ,而我们通过Plasmo创建的Extensions默认就已经通过Shadow DOM实现了,所以在
Upgrade.tsx
组件中可以直接通过iframe 嵌入我们自己搭建的Server页面啦~本文内容使用 Notion Nice 排版。