与 FastSpring 嵌入式店面集成,提供安全的应用程序内购买窗口。
提示
有关如何设置您自己的商店以及使用 FastSpring 准备应用程序的说明,请参阅我的书在 Mac App Store 之外赚钱。
与我的试用和许可包配合得非常好,该软件包基于 CocoaFob 用于生成许可证代码。
dependencies: [
.package(url: "https://github.com/CleanCocoa/FastSpringStore.git", .upToNextMajor(from: Version(1, 0, 0))),
]
通过 Xcode 使用以下 URL 添加软件包依赖项:https://github.com/CleanCocoa/FastSpringStore.git
此过程需要两个部分
如果您已经有一个嵌入式店面,则可以跳过此步骤。
嵌入式店面是商店 UI 的最小版本。 它们仅显示结帐详细信息,仅此而已。
要设置商店
请注意,新的店面以
我建议从“产品”开始:将要销售的应用添加到商店。
然后“将”您的网站列入白名单,以便您可以在下一步中将嵌入式商店置于在线状态。
您可以从嵌入式商店的“放置在您的网站上”操作中的模板开始,然后
data-popup-webhook-received="fsprg_dataPopupWebhookReceived"
属性设置为脚本,以及这是结果,所有大写字母都是占位符
<script
id="fsc-api"
src="https://sbl.onfastspring.com/sbl/0.9.6/fastspring-builder.min.js"
type="text/javascript"
data-storefront="STOREFRONT-ID"
data-popup-webhook-received="fsprg_dataPopupWebhookReceived"></script>
<div id="fsc-embedded-checkout-container"></div>
<script>fastspring.builder.add("PRODUCT-ID");</script>
这就是你真正需要的所有HTML。
替换占位符PRODUCT-ID
和 STOREFRONT-ID
,然后将其上传到您列入白名单的域。
在“离线”模式下,STOREFRONT-ID
将在 URL 的子域部分包含“test.onfastspring
”(例如,yourstore.test.onfastspring.com/embedded-test
)。您无法在“离线”模式下访问常规模式,但在您将嵌入式商店切换为“在线”后,您可以同时使用这两种模式。 我们将利用它进行调试。
当店面在您的应用程序中显示时,此软件包会将回调注入到 web view 中,fsprg_dataPopupWebhookReceived
以处理购买。 您无需在此处实现任何 JavaScript。
提示
我建议上传此模板的两个版本
myapp.com/embedded-store
DEBUG
构建的测试商店,例如位于 myapp.com/embedded-store/test
。这样,您就可以使用 FastSpring 的占位符信用卡详细信息来测试结帐流程。 测试商店顶部有一个突出的徽章。 单击它会显示您如何进行测试购买
检查嵌入式商店是否有效。 访问您在 Web 浏览器中准备的 HTML 文件。
如果它在浏览器中有效,它将在应用程序中有效。
因此,一旦您看到进行购买的结帐表格,您就可以开始了。 接下来我们将将其嵌入到应用程序中。
警告
您是否只看到占位符加载动画?
test
URL,<script>fastspring.builder.add("PRODUCT-ID");</script>
将此软件包导入到您的项目中。 然后使用 FastSpringStore
访问您的嵌入式店面 HTML。
以下代码示例将以下内容联系在一起
FastSpringStore
UI 以显示嵌入式商店,最后#if DEBUG
// Test store that accepts credit card placeholder values:
private let storeURL = URL(string: "https://myapp.com/embedded-store/test")!
#else
private let storeURL = URL(string: "https://myapp.com/embedded-store")!
#endif
class PurchaseLicense {
let store: FastSpringStore
init() {
self.store = FastSpringStore(
storeURL: storeURL,
purchaseCallback: { store, purchases in
// Could have multiple purchased items, e.g. if you
// offer in-app purchases of bundled features.
assert(purchases.count == 1)
guard let purchase = purchases.first else { return }
for license in purchase.licenses {
// Unlock via license.licenseName & license.licenseCode, e.g.
// using the https://github.com/CleanCocoa/TrialLicensing package:
//
// TrialLicensing.AppLicensing.register(
// name: license.licenseName,
// licenseCode: license.licenseCode
// )
}
})
}
func showStore() {
// Localize and customize the window title:
store.showStore(title: "Purchase MyApp")
}
}
将其添加到您的应用程序中,例如通过滥用流行的将所有内容放入 AppDelegate 反模式
// AppDelegate.swift
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
// ...
lazy var purchaseLicense = PurchaseLicense()
@IBAction func buyApp(_ sender: Any?) {
purchaseLicense.showStore()
}
// ...
}
当您调用 showStore()
时,您应该会看到一个小窗口出现,该窗口显示您的嵌入式店面,类似于 Web 浏览器。
警告
如果您只看到占位符加载动画,请首先验证您是否可以在 Web 浏览器中访问该 URL。
然后检查您是否使用了正确的商店 URL,例如 DEBUG
构建中的 test.onfastspring
子域,或者生产环境的实时 URL,以及您的嵌入式商店是否确实“在线”。
使用测试商店完成结帐流程,以验证购买是否有效以及您的应用程序是否已成功解锁。
从“debug”到“release”的切换是将嵌入式商店 HTML 中的 test.onfastspring
子域替换为 onfastspring
。 其余设置不会更改。 如果您遵循了我的建议,无论如何您都有两个 HTML 文件,因此您不需要更改 HTML 文件,只需更改商店 URL 即可。
data-popup-webhook-received
属性是否设置正确。 否则,您的商店可以正常工作,但您的应用程序不会自动解锁。因此,当您进行发布版本时,请务必至少测试一次自动解锁是否仍然有效。 我建议为此设置 100% 的折扣券,这样您就不会产生任何购买费用。
就架构而言,此软件包并没有太多的内容,但以下是最重要的部分
FastSpringStore
是您的入口点。 它管理商店窗口并转发购买回调。
简化后,API 为
class FastSpringStore {
init(
storeURL: URL,
purchaseCallback: @escaping (FastSpringStore, [FastSpringPurchase]) -> Void
)
func showStore(title: String)
func closeWindow()
}
FastSpringPurchase
是有效负载(数据传输对象),其中包含成功购买的所有信息。 您可以在商店中提供多个产品,也可以提供捆绑产品。 因此,您将获得一系列购买,并且每次购买可以包含多个 License
。
简化
struct FastSpringPurchase {
struct License: Equatable {
enum LicenseType { case cocoaFob }
let licenseCode: String
let licenseName: String
let licenseType: LicenseType
}
let product: String
let quantity: Int
let licenses: [License]
}
FastSpringStore
目标不收集或跟踪任何内容,并且您的应用程序负责存储购买的任何用户数据(请参阅上面的示例)。FastSpringClassicStore
目标在内部处理结帐流程。 它依赖于 TrialLicensing
将结果存储在 UserDefaults
中,并声明存储电子邮件和姓名。版权所有 (c) 2015 by Christian Tietze。 在 MIT 许可证下分发。 有关详细信息,请参见 LICENSE 文件。