SubHub 对接 Apple 订阅完整教程(StoreKit 2)
0. 写在前面Apple 订阅的难点往往不在「调起支付」而在App Store Connect 商品、沙盒账号、Server Notifications客户端验单与服务端权益一致续费、换档、退款、试用等生命周期要持续同步SubHub 把StoreKit 2 购买 → 服务端验单 → 权益 → Webhook收成一条链路客户端用 iOS SDK商店差异由平台消化。资金仍走 App StoreSubHub不是支付网关也不抽应用流水。本文将按真实接入顺序写商店侧 → SubHub 控制台 → ASN → SDK → 沙盒验证 → 常见坑。1. 你将得到什么完成后你应能在 App Store Connect 建好自动续订订阅在 SubHub 配好 Apple API 密钥与商品映射配好 App Store Server Notifications V2ASN用 SubHub iOS SDK 完成configure→setUserId→purchase→hasEntitlement用沙盒账号买一笔在控制台看到购买与权益环境要求简述iOS 15StoreKit 2Xcode 16当前 iOS SDK 以 SPM 二进制分发版本以 iOS SDK 文档 为准撰写时常见为 1.0.xApp Store Connect 权限能建 IAP、能创建 API 密钥SubHub 账户可用免费版起步2. 整体架构用户点购买 → StoreKit 2 与 Apple 完成支付 → SubHub iOS SDK 把交易交给 SubHub 验单 → SubHub 调 App Store Server API / 订阅状态写入购买与权益 → 可选你的服务端收 Webhook更新自家业务库 → 客户端 hasEntitlement / entitlements 决定是否解锁 续费 / 退款 / 过期 … → Apple 推 ASN V2 到 SubHub → SubHub 更新权益并可选再推你的 Webhook要点商品 IDSKU必须与 App Store Connect 的 Product ID完全一致权益标识entitlement业务上的「有没有会员」同组多档可共用一个权益 ID换档只换 SKUSandbox / Production由验单时 Apple JWS 自动识别SDK 与控制台都不用选手动环境3. App Store Connect 侧准备3.1 创建自动续订订阅登录 App Store Connect进入对应 App →订阅/App 内购买项目创建订阅群组再创建自动续订订阅如周 / 月 / 年记下每个档位的产品 ID例如com.yourapp.premium.monthly建议同组多档月 / 年共用业务权益如premium在 SubHub 里也会这样配。3.2 沙盒测试账号用户与访问 →沙盒→ 测试账户新建 Sandbox Apple ID与日常 Apple ID 分开真机或模拟器登录该沙盒账号后再测购买3.3 创建 App Store Connect API 密钥.p8SubHub 验单与订阅状态依赖 Server API需要项在哪拿Issuer ID用户与访问 → 集成 → Issuer IDKey ID创建 API 密钥时显示Private Key (.p8)下载一次妥善保存权限建议能访问 App 内购买 / 相关 API按你账号角色选择合适访问权限。注意.p8 只显示/下载一次丢失需重新创建密钥。4. SubHub 控制台配置注册并登录https://subhub.com.cn4.1 创建应用控制台创建应用填写名称、Bundle ID须与 Xcode / ASC 一致、平台选 iOS记下应用 ID形如app_xxx后面 ASN URL、SDK 都要用说明应用创建后一般不可删除Bundle ID 创建后通常不可改。4.2 生成 API 密钥在API 密钥页生成Publishable Keypk_live_...→ 放客户端 SDKSecret Keysk_live_...→ 仅服务端 REST / 运维禁止打进 App 或提交 Git同一账户下多应用可共用一套密钥用X-App-Id/ SDK 的appId区分应用。4.3 填写 Apple 配置应用详情 →Apple 配置粘贴Issuer ID密钥 IDKey IDPrivate Key.p8 文件全文私钥在 SubHub 侧加密存储保存后一般不回显。环境以每次验单结果为准。4.4 配置商品映射 SKU → 权益在应用下创建商品例如SubHub 字段示例说明产品标识符com.yourapp.premium.monthly ASC Product ID类型订阅subscription自动续订选这个权益标识premium年档可填同一个premium要点标识符必须与商店逐字符一致无单独「权益菜单」——写在商品上即可验单成功后平台自动写成员权益刚建 SKU 立刻买可能productNotFound重启 App 或重新configure后再试5. 配置 App Store Server Notifications V2强烈建议必做未配 ASN 时往往只有首次客户端 verify 有效续费、退款、过期等不会自动进 SubHub。5.1 通知 URL每个 SubHub 应用一条独立地址把{app_id}换成你的app_xxxhttps://subhub.com.cn/api/v1/providers/apple/apps/{app_id}示例https://subhub.com.cn/api/v1/providers/apple/apps/app_abc1235.2 在 ASC 里填写App Store Connect → 你的 App →App 信息→App Store 服务器通知Server Notifications生产环境 URL填上面的地址沙盒 URL建议同样填或按 ASC 当前 UI 分别配置保存后可用沙盒续费/退款流程验证 SubHub 控制台是否出现对应事件也可在自有 Webhook 侧观察。6. 集成 SubHub iOS SDK6.1 安装Swift Package ManagerXcode → Package Dependencies添加https://github.com/MoYoDream/subhub-ios-sdk选与文档一致的版本如1.0.2以 Release 为准。6.2 初始化顺序务必记住推荐顺序注册onDeferredSyncFailure延迟同步失败回调configure(publishableKey:appId:)登录或首次安装后setUserId再purchase/hasEntitlement/entitlements/restore/syncTransactions未setUserId就买会报userIdRequired一类错误。setUserId传的是你业务侧的用户 IDexternal_user_id例如 Firebase UID。SubHub 用它关联成员与权益。6.3 最小代码importSubHubtrySubHubSDK.configure(publishableKey:pk_live_xxx,appId:app_xxx)tryawaitSubHubSDK.setUserId(firebase_uid_8a2b)lethasEntitlementtryawaitSubHubSDK.hasEntitlement(premium)6.4 SwiftUI 完整落点含回前台同步importSwiftUIimportSubHubmainstructMyApp:App{Environment(\.scenePhase)privatevarscenePhaseinit(){do{SubHubSDK.onDeferredSyncFailure{errorinprint(SubHub deferred sync:,error)}trySubHubSDK.configure(publishableKey:pk_live_xxx,appId:app_xxx)}catch{assertionFailure(SubHub configure failed:\(error))}}varbody:someScene{WindowGroup{ContentView()}.onChange(of:scenePhase){phaseinguardphase.activeelse{return}Task{try?awaitSubHubSDK.syncTransactions()}}}}structContentView:View{StateprivatevarisPremiumfalsevarbody:someView{VStack(spacing:16){Text(isPremium?已开通会员:免费用户)Button(购买月订阅){Task{awaitbuy()}}}.task{awaitbootstrap()}}funcbootstrap()async{do{tryawaitSubHubSDK.setUserId(user_123)isPremiumtryawaitSubHubSDK.hasEntitlement(premium)}catch{print(bootstrap:,error)}}funcbuy()async{do{// productId App Store Connect / SubHub 商品标识符_tryawaitSubHubSDK.purchase(productId:com.yourapp.premium.monthly,refreshEntitlements:true)isPremiumtryawaitSubHubSDK.hasEntitlement(premium)}catchSubHubError.userCancelled{// 用户取消}catchSubHubError.purchasePending{// Ask to Buy家长批准后依赖回前台 syncTransactions}catch{print(purchase:,error)}}}说明purchase默认不一定拉全量权益订阅场景建议refreshEntitlements: true或买后再调entitlements()同组升级 / 降级iOS 直接purchase(新 SKU)即可不必单独 upgrade APIrestore不是每次冷启动必调自购且服务端已有权益时setUserId→hasEntitlement即可家庭共享受益人首次、店外兑换促销码等才需要restore7. 可选你自己的服务端 Webhook若发货、开通权限以你服务器为准在 SubHub 控制台配置出站 Webhook监听如purchase.completed、权益变更、退款等事件。消耗型必须以 Webhook 驱动发货订阅 / 会员多数可用 SubHub 权益 客户端hasEntitlement复杂业务再叠加 Webhook。详见Webhook 文档8. 沙盒联调清单按顺序勾选ASC 订阅 Product ID 与 SubHub 商品标识符一致Apple Issuer / Key ID / .p8 已保存且无报错ASN V2 URL 含正确app_xxxSDKonDeferredSyncFailure→configure→setUserId→purchase使用Sandbox Apple ID且测试用独立external_user_id避免沙盒权益污染正式测试账号购买成功后hasEntitlement(premium) true控制台能看到对应购买Sandbox 交易会标store_environmentsandbox试用 / Introductory OfferASC 配好后沙盒购买写入记录Webhook enrichment 里关注isTrial/offerType不要只看 amount 0。9. 订阅换档与「productId 对不上」必读同组升级、降级「下周期再生效」时常出现某一笔 Transaction 的productId仍是旧档renewalInfo.productId才是当前应授予档autoRenewProductId是下周期档SubHub 在配置了 .p8、能打Subscription Status API时会以 Apple 订阅状态纠正入账商品客户端仍purchase(新 SKU)响应里的商品标识可能与你传入的 SKU 不一致以 Apple 为准。落地原则建议当前应发权益优先信订阅状态里的当前商品权益层用稳定的premium一类 ID不要把「有没有会员」绑死在某一个 SKU 字符串上更多排查思路见社区技术文与官方 订阅生命周期。10. 常见问题Q: 能买但 SubHub 一直验不过检查 .p8 / Issuer / Key IDBundle ID 是否一致商品是否已在 SubHub 创建。Q: 首次可以续费没反应几乎都是没配 ASN或 URL 里app_id错了。Q:productNotFound控制台商品 ID 与 ASC 不一致或新建后客户端缓存未刷新——重启 App / 重新 configure。Q: 要不要每次启动 restore一般不要。自购且服务端已有权益setUserIdhasEntitlement。例外家庭共享受益人首次、店外兑换等见何时调用哪个 API。Q: Ask to BuySDK 会走purchasePending批准后靠自动同步并在回前台再syncTransactions。Q: 非续期订阅季票ASC 的 Non-Renewing 在 SubHub 侧有单独约定expiresAt可能为空业务到期要自己算。自动续订请用本文的subscription路径。见文档 Apple 非续期订阅。11. 小结对接 Apple 订阅到 SubHub可以记成五步ASC 建订阅 沙盒账号 .p8SubHub 建应用、密钥、Apple 配置、商品SKU 权益映射配 ASN V2 到.../providers/apple/apps/{app_id}iOS SDKconfigure→setUserId→purchase/hasEntitlement沙盒买一笔核对控制台与权益官方入口官网https://subhub.com.cn文档https://subhub.com.cn/docsApple 专题https://subhub.com.cn/docs/apple快速开始https://subhub.com.cn/docs/quick-start有具体报错码如verificationFailed/quota_exceeded可以把控制台与 Xcode 日志打码后对照 错误码文档 排查。本文步骤以 SubHub 公开文档为准商店后台文案可能随 Apple 改版略有差异请以 App Store Connect 当前界面为准。

相关新闻

漏打一个下划线,无辜男子白坐 18 个月牢:一起由“打字失误”引发的荒谬冤案

漏打一个下划线,无辜男子白坐 18 个月牢:一起由“打字失误”引发的荒谬冤案

最新内容请微.信搜索公.众.号阅读 在数字化时代,一个字符的差距究竟有多大?对于生活在加拿大新斯科舍省的布兰登克莱姆(Brandon Klayme)来说,一个微不足道的下划线(_),直接剥夺了他整…

2026/10/12 1:12:40 阅读更多 →
近屿智能学员真实案例:淡季求职逆风翻盘,25 届应届生系统学 AI 拿下月薪过万开发岗

近屿智能学员真实案例:淡季求职逆风翻盘,25 届应届生系统学 AI 拿下月薪过万开发岗

2025 年 6 月,一名智能科学相关专业 25 届毕业生走出校园,在校期间虽对 AI 抱有浓厚兴趣,但仅靠课余零散自学,没有完整落地项目,技术底层知识不成体系。秋招、春招持续投递简历,屡屡在技术面试中因项目单薄…

2026/10/11 20:06:24 阅读更多 →
2027亚洲消费电子展官方预定!从芯片到整机全链条展示

2027亚洲消费电子展官方预定!从芯片到整机全链条展示

2027亚洲消费电子展(赛逸展)定档2027年6月26‑28日,北京亦创国际会展中心,官方预定火热推进。展会完整呈现芯片半导体、整机设备、智能软件、落地场景全链条创新成果,打造亚太智能科技产业协作枢纽。 消费电子产品的最…

2026/10/9 1:14:18 阅读更多 →

最新新闻

基于SSM+Vue的养老服务平台设计与实现——毕设项目技术全解析

基于SSM+Vue的养老服务平台设计与实现——毕设项目技术全解析

做 Java 后端、写 Vue 前端的这些年,SSMVUE这套组合我经手过不少项目,但要说最值得拿出来好好聊聊的,大概率还是这个老人养老服务平台。作为计算机毕业设计选题,它比普通的管理系统多了一层人文关怀,又比纯电商项目多了…

2026/10/12 8:50:01 阅读更多 →
Vibe Coding与Claw之争:AI时代编程范式与工程实践指南

Vibe Coding与Claw之争:AI时代编程范式与工程实践指南

不知道为什么,最近朋友圈里聊AI编程的人都在问同一个问题:“为什么会Vibe Coding的,不养Claw龙虾?”我第一次看到这个标题的时候也愣了几秒,然后反射性地笑出声。Vibe和Claw,读音押韵,意思却南辕…

2026/10/12 8:50:00 阅读更多 →
SpringBoot+Vue洗衣店管理系统开发实战:状态机与权限控制

SpringBoot+Vue洗衣店管理系统开发实战:状态机与权限控制

1. 项目概述与核心需求拆解1.1 这个毕业设计到底在做什么洗衣店管理系统,乍一听是个不起眼的管理系统,但真做起来你会发现它麻雀虽小五脏俱全。绝大部分同学做毕业设计时喜欢选图书管理、超市管理这类烂大街的题目,而洗衣店这个场景天然自带一…

2026/10/12 8:50:00 阅读更多 →
SYN Cookies原理与内核参数配置:从TCP三次握手到SYN Flood防御实战

SYN Cookies原理与内核参数配置:从TCP三次握手到SYN Flood防御实战

SYN Cookies这东西,搞网络和运维的兄弟应该都听过,但真正把它原理吃透、知道生产环境怎么配的人不算多。前阵子我帮一个业务团队排查连接超时问题,最后定位到是SYN Flood导致的半连接队列被打满,顺手把tcp_syncookies相关机制完整…

2026/10/12 8:50:00 阅读更多 →
基于Django的蔬菜销售分析与预测可视化系统毕设实战拆解

基于Django的蔬菜销售分析与预测可视化系统毕设实战拆解

1. 先看明白这个毕设到底要做什么打开标题里的关键词:“大数据毕设项目”、“基于django”、“蔬菜销售分析与预测可视化系统”、“源码文档,讲解、调试运行、定制”。一句话概括,这就是个面向毕业设计的典型全栈工程——用Django把“数据分析…

2026/10/12 8:50:00 阅读更多 →
ThinkPHP美食商城系统开发实践:路由、订单与库存事务处理

ThinkPHP美食商城系统开发实践:路由、订单与库存事务处理

真要做“ThinkPHP美食商城网站”这种课题,多数人第一反应是“又是个学生作业”。但真正动手把商城从零搭起来,并且能跑通下单、支付、库存扣减这一整套流程之后,你会发现这个“老框架”里头能挖的东西比想象中多。这篇文章就围绕我在开发这套…

2026/10/12 8:48:56 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/11 14:36:54 阅读更多 →