news 2026/9/15 21:19:35

在 Encore.ts 中集成 Polar:支付、订阅与许可证密钥的完整接入指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
在 Encore.ts 中集成 Polar:支付、订阅与许可证密钥的完整接入指南

在 Encore.ts 中集成 Polar:支付、订阅与许可证密钥的完整接入指南

【免费下载链接】encoreThe infrastructure platform for the intelligence era项目地址: https://gitcode.com/GitHub_Trending/encor/encore

Polar 作为你的 Merchant of Record(记录商户),一站式处理支付、订阅与许可证密钥等商业化核心环节。本文将基于 Encore 开源仓库中的官方集成文档,完整演示如何在 Encore.ts 应用中接入 Polar:从 SDK 安装、Polar 后台配置、密钥管理、Checkout 会话创建,到 Webhook 事件处理与最终部署,并深入源码层讲解secret()api.rawENCORE_ENVIRONMENT等 Encore 运行时机制,帮助你构建一套可上线的支付与订阅闭环。

适用前提:本指南面向 TypeScript 语言版本的 Encore 应用。若尚未安装 Encore,请先参阅仓库内的 安装指南,再继续后续步骤。

快速开始:从官方示例创建应用

如果你希望跳过手工搭建、直接获得一份可运行的 Polar 集成范例,可以使用 Encore CLI 基于官方示例模板创建新应用:

$ encore app create --example=ts/polar

该命令会拉取一个已经配置好 Polar 客户端、Checkout 端点与 Webhook 处理的完整 TypeScript 示例项目。也可以按照下文步骤,把 Polar 逐步接入到已有的 Encore 应用中。

安装 Polar SDK

在 Encore.ts 项目根目录执行:

$ npm install @polar-sh/sdk

@polar-sh/sdk是 Polar 官方的 TypeScript/JavaScript SDK,封装了 Checkout 会话创建、Webhook 校验、订单与订阅查询等能力,后续所有 Polar 交互都通过它完成。

Polar 后台配置

编写代码之前,需要先在 Polar 控制台完成三件事(开发阶段请使用 sandbox 沙箱环境,避免影响真实计费数据):

  1. 创建 Access Token(访问令牌):进入 Settings > Developers > Personal Access Tokens,新建一个令牌,用于服务端鉴权。
  2. 创建商品(Product):进入 Products 页面创建至少一个商品,并复制其product ID。后续创建 Checkout 会话时需要用它指定用户要购买的商品。
  3. 配置 Webhook(本地开发可延后):进入 Settings > Webhooks,将回调地址指向你的 API 地址加上/webhooks/polar路径。本地开发时,可使用 ngrok 之类的隧道工具把本地服务暴露到公网,供 Polar 回调。

关于商品定价、订阅计划与 Webhook 事件类型的更多细节,可查阅 Polar 官方文档(本指南只介绍与 Encore 集成直接相关的部分)。

用 Encore Secrets 保存 Polar 凭据

Polar 的 Access Token 属于敏感凭据,绝不能硬编码进源码。Encore 提供内置的密钥管理机制,通过 CLI 设置:

$ encore secret set --type dev,local,pr,production PolarAccessToken

--type指定该密钥生效的环境集合:dev(开发云)、local(本地)、pr(预览环境)与production(生产)。Encore 会为每个环境独立加密存储,环境之间互不共享。

本地开发时,密钥直接保存在你的机器上,并在运行encore run时自动注入到应用中——无需任何.env文件,也避免了.env文件被误提交进 Git 仓库的风险。

在源码中通过 Encore 的secret()函数读取密钥。以仓库中 runtimes/js/encore.dev/config/secrets.ts 的实现为例:secret(name)从运行时配置中获取该密钥的实现,返回一个可调用对象;本地开发(runtime.CloudProvider.Local)且密钥未设置时,它会返回空字符串而不是直接抛错,方便调试;而在非本地环境中,若密钥缺失会抛出secret <name> is not set错误。此外,该对象重写了toString()输出为Secret<name>(*********),确保日志中不会泄露明文。密钥值会被 Encore 周期性刷新,这意味着它可以安全轮换而无需重启服务。

初始化 Polar 客户端

新建polar.ts,用 Encore 的secret()读取令牌,并根据运行环境在 Polar 的sandbox(沙箱)与production(生产)服务器之间切换:

-- polar.ts -- import { Polar } from "@polar-sh/sdk"; import { secret } from "encore.dev/config"; const polarAccessToken = secret("PolarAccessToken"); const server = process.env.ENCORE_ENVIRONMENT === "production" ? "production" : "sandbox"; export const polar = new Polar({ accessToken: polarAccessToken(), server, });

这里的ENCORE_ENVIRONMENT是 Encore 注入的环境变量:在生产环境部署时其值为production,其余情况(本地、预览、测试等)走 sandbox,从而保证开发与生产天然隔离。如果你需要更结构化的环境信息,Encore 还提供appMeta()API(见 runtimes/js/encore.dev/app_meta.ts),可读取environment.typeenvironment.cloudapiBaseUrl等元数据。

创建 Checkout 会话

Checkout 会话是用户完成支付的关键入口。下面通过一个需要认证的 Encore 端点,创建 Checkout 会话并返回支付跳转链接:

-- checkout.ts -- import { api } from "encore.dev/api"; import { polar } from "./polar"; import { getAuthData } from "~encore/auth"; interface CreateCheckoutRequest { productId: string; } interface CreateCheckoutResponse { checkoutUrl: string; } export const createCheckout = api( { auth: true, expose: true, method: "POST", path: "/checkout" }, async (req: CreateCheckoutRequest): Promise<CreateCheckoutResponse> => { const authData = getAuthData()!; const baseUrl = process.env.ENCORE_API_URL || "http://localhost:4000"; const session = await polar.checkouts.create({ products: [req.productId], customerEmail: authData.email, successUrl: `${baseUrl}/?success=true`, }); return { checkoutUrl: session.url || "" }; } );

对这段代码的要点拆解:

  • auth: truegetAuthData()auth: true声明该端点必须携带有效认证信息,否则 Encore 直接返回 401。认证数据通过~encore/authgetAuthData()获取(内部实现在 runtimes/js/encore.dev/internal/auth/mod.ts,从当前请求上下文中取出认证数据),因此可以把用户的邮箱直接传给 Polar 作为customerEmail,实现"登录即下单"的体验。
  • expose: true:把端点暴露到公网,使其可以被前端调用。未设置expose的端点默认只在服务内部网络可达。
  • path: "/checkout":自定义路由路径。Encore 的api()声明在 runtimes/js/encore.dev/api/mod.ts 中,支持methodpathexposeauthbodyLimitsensitive等选项;路径中还可使用:id单段参数与*path通配多段参数。
  • ENCORE_API_URL:Encore 注入的当前环境 API 基地址。本地开发时通常是http://localhost:4000,部署后则是对应环境的 API URL。这里用其拼接successUrl,保证用户在 Polar 完成支付后能正确跳回你的应用。

polar.checkouts.create()返回的session.url即用户在 Polar 侧完成支付的 Checkout 页面链接,前端拿到后直接跳转即可。

处理 Webhook:让支付事件驱动业务

支付是异步过程:用户可能在 Polar 侧完成支付或取消订阅,这些状态变化通过Webhook通知你的服务。Encore 的raw endpoint(原生端点)让你直接拿到 Node.js 风格的IncomingMessage请求对象,非常适合承接 Webhook 这类需要原始请求体的场景:

-- webhooks.ts -- import { api } from "encore.dev/api"; import log from "encore.dev/log"; export const handleWebhook = api.raw( { expose: true, path: "/webhooks/polar", method: "POST" }, async (req, res) => { const chunks: Buffer[] = []; for await (const chunk of req) { chunks.push(chunk); } const event = JSON.parse(Buffer.concat(chunks).toString()); log.info("Received Polar webhook", { type: event.type }); switch (event.type) { case "subscription.active": // Grant access to your product break; case "subscription.canceled": // Revoke access break; case "order.paid": // Fulfill the order break; } res.writeHead(200); res.end(); } );
  • api.raw:Encore 提供的原生端点声明。reqstream.Readable类型的请求对象(实现在 runtimes/js/encore.dev/api/node_http.ts),可以用异步迭代器逐块读取请求体;resServerResponse兼容的响应对象(同一文件 L115-L310),支持writeHeadwriteend等标准操作。由于完全兼容 Node.js HTTP 语义,它可以无缝对接 Express 等生态库。
  • 事件分发:示例按event.type分派三类典型事件——subscription.active(订阅激活,授予产品访问权限)、subscription.canceled(订阅取消,收回权限)、order.paid(订单支付成功,履行订单)。你可以在switch中补充实际的业务逻辑,例如调用数据库 API 更新用户权益,或给用户发放许可证密钥。
  • 确认响应:处理完成后返回 200,告知 Polar 事件已收到,避免 Polar 重复投递。

注册 Webhook 时,在 Polar 控制台的 Settings > Webhooks 中填写你的 Encore API URL 加/webhooks/polar,并勾选需要监听的事件(如subscription.activesubscription.canceledorder.paid)。

建议:生产环境务必校验 Webhook 请求的签名(Polar SDK 提供相应工具),并配合数据库做幂等处理,防止重复事件导致权益重复发放。

部署

当通过 Encore 部署应用时,Encore 会自动为应用提供并管理所需的全部基础设施:

  • Secrets(密钥):按环境(preview、staging、production)独立加密存储,环境之间绝不共享。
  • Databases(数据库):在 GCP 上自动预置为 Cloud SQL,在 AWS 上自动预置为 RDS。
  • Networking(网络):包含 TLS 证书、负载均衡与 DNS 解析,开箱即用。

自托管部署

如果你希望把应用部署到自有基础设施,可以构建 Docker 镜像:

$ encore build docker my-app:latest

构建产物是一个标准 Docker 镜像,可部署到任何支持 Docker 的环境。更详细的自托管说明见仓库内的 self-host 文档。

Encore Cloud

也可以直接推送到 Encore 的开发云,获得一个免费的 staging 环境:

$ git push encore main

如果你想部署到自己的 AWS 或 GCP 账号,连接云账号后,Encore 会自动预置基础设施并代为管理密钥。具体步骤参考 连接云账号指南。

小结

把 Polar 与 Encore.ts 集成,本质上是三个动作的组合:用 Encore Secrets 安全托管 Polar Access Token、用类型安全的api()端点创建 Checkout 会话、用api.raw原生端点接收 Webhook 事件并驱动业务。Polar 承担了商户记录、支付合规、订阅计费与许可证发放等重活,Encore 则负责运行时配置、密钥注入、环境区分与一键部署,二者互补后,你得到的是一套具备生产级基础设施的支付订阅能力。仓库内的encore app create --example=ts/polar示例是快速上手的最佳起点,可直接在此基础上扩展你自己的业务逻辑。

【免费下载链接】encoreThe infrastructure platform for the intelligence era项目地址: https://gitcode.com/GitHub_Trending/encor/encore

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 21:17:50

MATLAB声发射数据分析:滑动窗口计算b值、熵值、CV值等特征

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 21:17:43

2026届论文降AI率实战:六大工具实测与改写策略

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 21:15:16

AI驱动的列车制动系统气密性智能检测技术解析

1. 项目背景与核心价值列车制动系统作为轨道交通安全的最后一道防线&#xff0c;其气密性检测直接关系到整车的制动性能和运营安全。传统检测报告审核主要依赖人工目视检查&#xff0c;存在效率低&#xff08;单份报告平均审核耗时45分钟&#xff09;、漏检率高&#xff08;关键…

作者头像 李华
网站建设 2026/9/15 21:15:03

中小工厂MES选型对比:用友、金蝶、鼎捷哪家更合适?

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 21:14:56

在c盘做网站可以吗老手揭秘避坑指南

在c盘做网站可以吗老手揭秘避坑指南 昨天凌晨两点,我接到一个急电。电话那头声音颤抖:“我的网站被黑挂了马,打开全是赌博广告,客户全跑了,现在该怎么办?”…

作者头像 李华