有没有接苹果内购(Apple In-App Purchase)的完美方案

目前 js->oc, 经常有丢单,掉单,的情况,还有就是无法对账,
玩家拿支付凭证,咱们不知道倒地这个支付凭证是否已经给过道具,给了哪个角色等,
咱们要解决 多账号,多角色,支付成功后的对账,丢单,有没有什么完美解决方案呀!

2赞

/**
检测未完成交易
*/

  • (BOOL)checkUncompleteTransaction:(NSString *)productId {
    NSLog(@"s, productId: @", FUNCTION, productId);

    BOOL ret = NO;
    NSArray *transactions = [SKPaymentQueue defaultQueue].transactions;
    if (transactions && transactions.count > 0) {
    NSLog(@"%s, 有未完成交易 transactions.count: %lu", FUNCTION, (unsigned long)transactions.count);

      for (SKPaymentTransaction *transaction in transactions) {
          if (transaction.transactionState == SKPaymentTransactionStatePurchased || transaction.transactionState == SKPaymentTransactionStateRestored) {
              if (productId == nil || !productId.length) {
                  [self onPurchaseSuccess:transaction];
                  ret = YES;
              } else {
                  if ([transaction.payment.productIdentifier isEqualToString:productId]) {
                      [self onPurchaseSuccess:transaction];
                      return YES;
                  }
              }
          }
      }
    

    }

    return ret;
    }

如果你说这个那我只能说你的支付流程整个就错了。
内购要先创建订单数据,其中要完整记录:内部订单号、交易项、账号、角色、时间。
而后才是拿着内部订单号,拉起APP或者平台的支付API

怎么可能会发生无法对账的情况?
网络及其不稳也只不过要么生成不了订单号无法发起交易,要么支付完毕后数据库没能记录完成状态。
但是这一条支付数据,必然存在。要对账也很简单

1赞

基本上是你说的这个,
我们要解决的是 游戏订单号 与 苹果的票据 无法对应的问题。
用户点击购买时:创建订单数据,其中要完整记录:内部订单号、交易项、账号、角色、时间等(这些信息暂且叫 订单号等信息),这些信息,等票据回来时,可以一一对应。这属于正常流程

如果 订单号生成,但等不到 票据回到,时间比较长的情况下
如果用户此时关闭了应用,下次启动应用时 票据回来了,怎么对应,按什么查找 订单号?

有人说 用个数据库之类的存储 订单号等信息,那么如何根据票据来找到订单号?按什么匹配?

如果这个数据库被删除了怎么办?比如用户觉得充值没到帐就卸载了应用,然后再安装应用,

如果 用户发现没充值没到帐, 拿苹果的支付账单来对账,怎么判断这个账单和游戏内的 某个角色是对应关系?也无法判断这个账单是否给过道具,这个账单只能证明用户确实支付过现金,但到底是哪个角色支付的?是否给过道具?这些都没法证明。

苹果支付流程建议看一下苹果开发者文档,最重要的一点是每个订单可以去苹果服务器验证是否有有效的,不过有一个问题是苹果支付订单无法透传字段,所以只能通过产品id区分游戏里的商品道具,所以要针对不同商品设置唯一id,以及账号A支付后由于掉单恢复到账号B上问题可处理也可以不处理毕竟都付费了道具到账了嘛哈哈

三天过去了,才回来找答案,你可真行。
所以综下所述,你会数据结构的设计么?

你的疑问点就很奇怪,难不成你把订单数据存在手机本地?服务器上的数据库被删了,就是你们公司安全有问题了

怎么会找不到角色和订单的对应关系,他能证明自己的角色的拥有者,角色对应有一张待完结的订单,他也能证明苹果支付到账了,做完结处理吧订单号绑定进去啊,这种掉单后台都没得么?

  1. 苹果内购不能透传数据,所以订单只能根据内购项ID来匹配。
  2. 玩家拿账单对账的话,你没有办法关联到游戏内角色ID,这个信息只能玩家自己提供,然后你根据金额和时间去你的订单库里匹配,确认是否真的有发过道具。

听你这么一说,你需要解决的不是苹果内购问题,而是你的服务代码逻辑就没对

  1. 苹果内购不能透传数据,所以订单只能根据内购项ID来匹配。

这个是指, 一个购买项没有完成的情况下,不能再次购买这个项目,但可以购买其他项目,以防止 找不到订单,可以用这个购买项id来匹配
是这个意思把,我们暂时也是这个方案。

  1. 玩家拿账单对账的话,你没有办法关联到游戏内角色ID,这个信息只能玩家自己提供,然后你根据金额和时间去你的订单库里匹配,确认是否真的有发过道具。

这个不行吧,时间相近会有好几笔,这样就没办法匹配了,

你先把付款流程图、泳道图画出来再分析吧。
貌似思维有点混乱呢。。

统一回复一下以免理解偏差

  1. 我这个游戏是 有多个分区,每个分区每个用户可以创建多个角色,的mmorpg。
  2. 游戏订单号,可以查找到 用户所在分区,角色id,这样才能给这个角色加他购买的道具物品。
  3. 每天有多笔充值,也不排除某个时间段有大量充值。(按时间比对恐怕不行)
  4. 如果某个票据验证没有游戏订单号,即便验证正确,也不知道道具物品该发给哪个玩家呀!
  5. 当不在购买流程时,比如重启游戏时发现有一个票据已经回来(可能是上次充值时没有回调,或者时间较长,用户关闭了游戏),这个票据如何对应一个游戏订单号?(这个可以做个记录,然后用购买项ID来匹配订单号,但如果这个数据被删除就找不到了,有人说可以用钥匙串,目前我用的是JSON字符串本地存储,所以会被删除)
  6. 对账,如果用户拿一个苹果账单(给角色A充值的账单)来找,说物品没到角色B的帐,
    角色B也和角色A同时充值,角色A正常完成充值,角色B中途通过杀进程关闭APP,并不支付,
    这种情况下,如何判别角色B该不该补发道具呢?(这个情况下,服务器记录角色B开始充值,但不知道角色B的充值支付是否成功)

其实也不乱,
正常支付 游戏订单号,随着流程走,怎么都是在的,
唯一有问题的是, 如果,刚启动游戏,就发现一个 上次没处理完的票据回来了,
(这种情况可能是 上次用户支付成功后,由于网络太慢 没等到票据回调、 关闭了游戏,总之是 支付成功,没等到票据回调 就关闭了游戏)
此时 只有一个票据,没有游戏订单号,怎么办?

用户点击购买–>服务端生成订单—>反馈APP–>客户端请求苹果支付–>
苹果返回购买结果—>APP本地存储购买记录(一长串的字符串)—>标记已支付未验证—>同时检查本地是否有未完成订单,同时发送给服务器验证(可能是多个订单,通常情况下不会).

启动APP时,检查本地数据库,是否有未验证订单数据,如果有发送给服务器验证,并返回结果。

–>客服端收到验证结果进行处理。

注意:
1、苹果和微信、支付宝不一样的是,他的原始购买订单是在购买完成的时候,由客户端发给服务端验证。而支付宝和微信,则是服务端先生成订单号。
2、每个平台的订单规范都不一样,你需要生成一个自己平台统一的订单号。

我是客户端开发者, 服务器端由我同事开发,票据验证在服务器端
我说的订单号 都是指游戏订单号,这个订单号能知道是哪个角色发起的支付,道具要发给哪个角色

如果没有这个游戏订单号, 服务器是不知道把道具发给谁的!

这就是我说的你要有一个统一的唯一订单号,这个是服务端根据你申请生成订单号的数据产生的。

难道你们没有主程吗?这个由你们主程设计好以后,你们按照做就可以了啊

现在是 订单号 和 票据 如何匹配的问题

你仔细看我上面写的文字,已经解决了你说的问题啊。如果你不明白,让你们服务端同事看看应该就明白了。。。


这个地方是 匹配 订单号和票据, 这是在 一个支付流程内的

主要是 启动APP时 有票据,此时如何匹配 订单号 与票据
这个是重点

之前生成的订单号和购买的票据成对存放在客户端本地数据库呀