游戏商品限购支付的实现

流程图:

1
2
2
3
4
5
client
gs
de
sdk

其中gs(game server)是游戏逻辑服务器,可能有多个;sdk负责支付;de(delivery)分别连接gs和sdk。

流程简介:

  1. client到gs检查限购信息,通过的话,暂时占有限购名额,生成订单,必要字段有(timeoutstamp是订单超时时间戳)(每个账号的不同订单的orderid不能重复)
  2. gs将订单信息发给de,将可购买信息返回给client
  3. client发起支付,将orderid和productid传给SDK,并会透传给de
  4. 假定只有支付成功sdk才会通知de
  5. de收到支付成功通知后,校验userid、roleid、价格、是否超时等,如果校验通过,通知gs完成订单、扣减名额、发放商品

如果用户手动取消订单,client通知gs释放限购名额,gs可以不通知de,de等订单超时即可。

用户可能在支付时或支付完就下线了,所以流程5中,用户可能并不在gs中,所以直接将“完成订单、扣减名额、发放商品”封转起来委托给额外的服务,例如消息队列来实现,要保证:
1 如果用户在线,从de发出消息到gs处理消息要足够快,以防止在de还没超时,但到gs时却已经超时了,这样在刚超时的那一刻,玩家又能下单了,可能会超过限购次数。另外为减少这种意外,可以让de的订单超时时间戳减2秒,同时给client的超时时间也减2秒,只要从de发出消息到gs处理消息能在2秒内完成就不会有问题,但带来的另一个问题是,超时后2秒内玩家下单都会失败。
2 用户在登陆时,超时订单不能立即删除,因为消息队列中可能存在着已完成订单,但gs还没处理。
3 用户在登录后,要先处理完消息队列中之前的订单,才能接受新的订单。

购买失败的情况
如果用户卡在超时边缘支付,以及其他一些原因,流程4中de检查的时候可能已经超时了,就会出现支付成功,但购买失败的情况。此时de可通知sdk做退款处理,如果sdk不支持退款接口,只能加以记录,手动处理。上面让de和client的超时时间戳提前几秒也是为了减少购买失败的概率。

关于流程1中的productid
流程3中给sdk仅发送orderid,没有productid是不够的,考虑这样一种情况,首先生成了商品A的orderid,但用户不付款,然后购买商品B的时候在流程3中填入了商品A的orderid,如果de不校验productid,商品B就占用了商品A的名额。

你可能感兴趣的:(其他,游戏,网络,服务器)