第一次订阅内容的时候,没有问题可以正常订阅成功。
但是等订阅到期或者取消后,第二次重新订阅总是失败。(测试中也没有弹出苹果订阅支付的弹窗)
代码中那一部分出错了?急,谢谢大神~
//
// TYPayManager.swift
// XiangXuniOS
//
//
import UIKit
import HandyJSON
import StoreKit
import SwiftDate
enum SIAPPurchType {
case Success // 购买成功
case Failed // 购买失败
case Cancle // 取消购买
case VerFailed // 订单校验失败
case VerSuccess // 订单校验成功
case NotAllow // 不允许内购
}
class TYPayManagerReceiptModel: HandyJSON {
var in_app: [TYPayManagerReceiptInAppModel] = []
required init() {}
}
class TYPayManagerReceiptInAppModel: HandyJSON{
/// 过期时间
var expires_date: Date?
/// 过期时间的时间戳
var expires_date_ms = 0
required init() {}
}
class TYPayManager: NSObject{
static let shared = TYPayManager()
var payOrderStatus: ((Int) -> ())?
var statusBlock: ((SIAPPurchType) -> ())?
var purchID: String!
/// 内购生成的订单号
var order_no = ""
var tips: QMUITips?
class var share: TYPayManager {
let obj = shared
obj.initAction()
return obj
}
/// 内购
func initAction() -> Void {
SKPaymentQueue.default().add(self)
}
func restore(order_no: String, view: UIView, completeHandle: @escaping ((SIAPPurchType) -> ())){
let tips = QMUITips.showLoading(in: view)
self.tips = tips
self.order_no = order_no
self.statusBlock = completeHandle
SKPaymentQueue.default().restoreCompletedTransactions()
}
// MARK: 开始内购
func startPurchWithID(purchID: String, order_no: String, view: UIView, completeHandle: @escaping ((SIAPPurchType) -> ())) {
let tips = QMUITips.showLoading(in: view)
self.tips = tips
print(message: purchID)
self.order_no = order_no
if SKPaymentQueue.canMakePayments() {
self.purchID = purchID
self.statusBlock = completeHandle
let request = SKProductsRequest.init(productIdentifiers: [purchID])
request.delegate = self
request.start()
} else {
completeHandle(.NotAllow)
}
}
// MARK: 交易失败
func failedTransaction(transaction: SKPaymentTransaction) {
if let tips = self.tips{
tips.hide(animated: true)
}
self.statusBlock?(.Failed)
SKPaymentQueue.default().finishTransaction(transaction)
}
// MARK: 交易结束
func completeTransaction(transaction: SKPaymentTransaction) {
let productIdentifier = transaction.payment.productIdentifier
if productIdentifier.count > 0 {
// 向自己的服务器验证购买凭证
}
self.verifyPurchaseWithPaymentTransaction(transaction: transaction, isTestServer: false)
}
// MARK: 验证交易
func verifyPurchaseWithPaymentTransaction(transaction: SKPaymentTransaction, isTestServer: Bool) {
let recepitURL = Bundle.main.appStoreReceiptURL
let receipt = try! Data(contentsOf: recepitURL!)
if let tips = self.tips{
tips.hide(animated: true)
}
self.toServiceVerifyPurchaseWithPaymentTransaction(receipt: receipt, transaction: transaction, isTestServer: false)
}
// MARK: 再次向服务器验证交易
func toServiceVerifyPurchaseWithPaymentTransaction(receipt: Data, transaction: SKPaymentTransaction, isTestServer: Bool) {
let para = ["receipt-data" : receipt.base64EncodedString(options: .endLineWithLineFeed), "password" : "7032ef52286840be8f2d32e7ee22b516"]
var appStoreUrl = "https://sandbox.itunes.apple.com/verifyReceipt"
if isProductServer {
appStoreUrl = "https://buy.itunes.apple.com/verifyReceipt"
}
var verTips: QMUITips?
if self.order_no.count > 0{
verTips = QMUITips.showLoading("加载中,请稍后", in: (QMUIHelper.visibleViewController()?.view)!, hideAfterDelay: 20)
}
HttpUtils.shared.postJson(url: appStoreUrl, parameters: para) { (result: TYPayManagerReceiptModel?) in
print(message: "应该是后台进行验证的")
if let tips = verTips{
tips.hide(animated: true)
}
if let in_app = result?.in_app{
for item in in_app{
let expires_date = Date(timeIntervalSince1970: TimeInterval(item.expires_date_ms / 1000))
Keychain.shared.expiresDate = expires_date.toString(.custom("yyyy年MM月dd号"))
Keychain.shared.expiresDateSecond = "\(item.expires_date_ms / 1000)"
SKPaymentQueue.default().finishTransaction(transaction)
}
}
SKPaymentQueue.default().finishTransaction(transaction)
self.statusBlock?(.VerSuccess)
} failure: { error in
SKPaymentQueue.default().finishTransaction(transaction)
if let tips = verTips{
tips.hide(animated: true)
}
self.statusBlock?(.VerFailed)
}
}
}
extension TYPayManager: SKPaymentTransactionObserver, SKProductsRequestDelegate{
// MARK: 交易状态
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transtion in transactions {
if transtion.transactionState == .purchased {
if let tips = self.tips{
tips.hide(animated: true)
}
// 购买成功
print(message: "购买成功")
self.completeTransaction(transaction: transtion)
break;
} else if transtion.transactionState == .purchasing {
// 正在购买
print(message: "正在购买")
break;
} else if transtion.transactionState == .restored {
// 恢复
print(message: "已经购买过商品")
self.completeTransaction(transaction: transtion)
SKPaymentQueue.default().finishTransaction(transtion)
break;
} else if transtion.transactionState == .failed {
// 购买失败
print(message: "购买失败")
self.failedTransaction(transaction: transtion)
SKPaymentQueue.default().finishTransaction(transtion)
break;
} else {
break;
}
}
}
// MARK: 请求查看存在的产品
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
let products = response.products
if products.count == 0 {
print("没有商品")
return
}
var product: SKProduct?
for item in products {
if item.productIdentifier == self.purchID {
product = item
break
}
}
if product != nil {
print("产品信息:")
print(product)
let payment = SKPayment.init(product: product!)
SKPaymentQueue.default().add(payment)
}
}
func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
if let tips = self.tips{
tips.hide(animated: true)
}
if queue.transactions.count > 0{
print(message: "有可恢复的购买项")
for item in queue.transactions{
print(message: item.original?.transactionDate)
print(message: item.original?.transactionIdentifier)
}
}else{
print(message: "没有可恢复的购买项")
QMUITips.show(withText: "没有可恢复的购买项", in: (QMUIHelper.visibleViewController()?.view)!)
}
}
func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: any Error) {
print(message: "恢复失败")
if let tips = self.tips{
tips.hide(animated: true)
}
QMUITips.show(withText: "没有可恢复的购买项", in: (QMUIHelper.visibleViewController()?.view)!)
}
}
根据你提供的代码和问题描述,有几个可能的原因和解决方案,导致订阅在第一次之后无法再次成功:
productsRequest
方法中,你为每个找到的产品添加了一个 SKPayment
到队列。如果 SKPaymentQueue
中已经有一个相同的交易在处理中(例如,用户之前尝试订阅但尚未完成),再次添加相同的交易可能会导致问题。paymentQueue
方法中,你检查了 .purchased
、.purchasing
、.restored
和 .failed
状态,但没有检查 .deferred
状态。在某些情况下,如等待用户确认付款时,交易可能会进入 .deferred
状态。SKPayment
到队列之前,检查 SKPaymentQueue
中是否已存在相同的交易。paymentQueue
方法中添加对 .deferred
状态的处理。以下是一个简单的示例,展示如何在添加 SKPayment
之前检查队列中是否已存在相同的交易:
func startPurchWithID(purchID: String, order_no: String, view: UIView, completeHandle: @escaping ((SIAPPurchType) -> ())) {
// ...(省略其他代码)
if SKPaymentQueue.canMakePayments() {
self.purchID = purchID
self.statusBlock = completeHandle
// 检查队列中是否已存在相同的交易
if !SKPaymentQueue.default().transactions.contains(where: { $0.payment.productIdentifier == purchID && $0.transactionState != .purchasing }) {
let request = SKProductsRequest(productIdentifiers: [purchID])
request.delegate = self
request.start()
} else {
// 处理已存在交易的情况,例如显示一个错误消息
completeHandle(.Failed)
}
} else {
completeHandle(.NotAllow)
}
}
注意:上面的代码片段只是一个示例,它假设如果队列中存在具有相同 productIdentifier
且不是 .purchasing
状态的交易,则认为该交易已存在。然而,这种方法可能不完全准确,因为 .purchasing
状态可能只是短暂的。你可能需要根据你的具体需求来调整这个逻辑。
问题描述:uniapp内部使用苹果内购(IAP),购买消耗类产品可以成功拉起支付并支付成功。支付订阅产品的时候首次可以支付成功,但是在App Store中手动取消产品订阅,再回到app内中复购则无法成功拉起支付,使怎么回事呢? 支付环境:沙盒环境
如题 能否开发?以及如何开发?
当我更新到RxJS 6时,我的应用程序坏了。我得到了它的大部分工作,但这一个方法难倒了我。 之前,我们有一组被平面映射的观测值,然后使用CombineTest,如下所示: 我可以订阅新观察,并从所有其他网站获得一系列最新的输出。 现在我试着做这样的事情: 这给了我一个很长很复杂的 类型为“(res:Observable)的参数 坦率地说,我的阅读障碍妨碍了我进行语法分析。 如果我只返回上面的res
我通读了RxJS文档,并希望确保我理解了< code > subscriber . unsubscribe()和< code > subscriber . complete()之间的区别。 假设我有一个有两个订阅者的可观察对象,订阅者1和订阅者2。如果订阅者1对其订阅调用取消订阅,它将不再接收来自可观察对象的通知,但订阅者2将继续接收它们。 <代码>的文档。complete(): 观察者回调,用于
我是新的数据流和发布子工具在GCP。 需要将prem过程中的电流迁移到GCP。 当前流程如下: 我们有两种类型的数据馈送 Full Feed–其adhoc作业–完整XML的大小约为100GB(单个XML–非常复杂的一个–完整的数据–ETL作业处理此XML并将其加载到约60个表中) 单独的ETL作业用于处理完整提要。ETL作业过程完全馈送并创建负载就绪文件,所有表将被截断并重新加载 源系统每30分钟
我试图回到IabHelper。OnIabPurchaseFinishedListener当购买结束时,我的订阅,但问题是它没有调用购买完成。 我已经尝试了onactive结果,但仍然不能在这里工作是我的代码块,我正在扩展下面的片段 我提到了这个链接