Exploración del esquema y proceso de procesamiento de compras en la aplicación de iOS

prefacio

Las compras dentro de la aplicación, que están relacionadas con los ingresos reales, suelen ser la máxima prioridad de todas las empresas, y también la máxima prioridad de nuestros desarrolladores. Por lo tanto, hoy analizaremos el contenido de las compras dentro de la aplicación desde las más importantes. El proceso de compra en la aplicación se completa paso a paso a través del procesamiento de cada escena especial. Si crees que es demasiado largo, solo mira la parte final.

Compra básica en la aplicación

Al comienzo del artículo, simulamos un escenario de procesamiento de compras dentro de la aplicación más básico, es decir, para garantizar que el proceso normal se acredite en la cuenta, y luego realizamos optimizaciones posteriores de acuerdo con diferentes escenarios.

El proceso básico de compra en la aplicación es el siguiente:

Proceso del cliente:

graph LR
用户充值 --> 下单传递userId --> 下单成功 --> 充值 --> 苹果返回成功 --> 上报凭证传递userId --> 收到成功回调 --> 关闭交易事务

Proceso del lado del servidor:

Encargar:

graph LR
接收客户端下单信息 --> 订单信息入库 --> 返回订单号

Informes de documentos:

graph LR
接收客户端上报凭证 --> 找苹果校验成功 --> 返回客户端成功 --> 客户端关闭交易事务
找苹果校验成功 --> 通过userId查找对应的订单 --> 充值到账并写入凭证的transactionId 

Diagrama de interacción exitosa:

Debido al contenido excesivo del diagrama de interacción, solo se muestra temporalmente el proceso de interacción del proceso exitoso.

sequenceDiagram
用户->>客户端: 点击充值
客户端->>服务端: 下单(带userId)
服务端->>服务端: 订单入库
服务端-->>客户端: 下单成功
客户端->>苹果: 调用充值接口
苹果-->>用户: 充值操作
用户->>苹果: 充值完成
苹果-->>客户端: 回调充值成功
客户端->>服务端: 上报凭证(带userId)
服务端->>苹果: 调用凭证验证接口
苹果-->>服务端: 凭证验证合法
服务端-->>客户端: 上报成功
客户端-->>用户: 提示充值成功
服务端->>服务端: 通过userId查询订单信息
服务端->>服务端: 充值到账并写入凭证的transactionId 

problema y analisis

En el proceso de uso de compras básicas dentro de la aplicación, el problema más común es el problema anormal causado por el cambio de cuenta.

Escenario 1: cambiar de cuenta entre recargas

Entorno de la escena:

Un dispositivo, dos cuentas de inicio de sesión A y B.

Proceso de excepción:

La cuenta A realiza un pedido de recarga, y cuando se completa la recarga y Apple no regresa, cambia a la cuenta B y B informa el certificado.

situación real:

En el juego, los gerentes del sindicato necesitan cambiar de cuenta con frecuencia, o cambiar la cuenta de la trompeta para realizar diferentes operaciones.Después de la recarga normal, si el usuario no nota el estado de la cuenta y cambia directamente la cuenta, entonces esta situación puede ocurrir .

Rendimiento anormal:

  1. Si comprueba el registro del pedido en este momento. Es decir, consultará el pedido anterior realizado por el ID de usuario antes y luego encontrará que el pedido no se ha realizado antes y no se puede recibir, lo que resulta en un pedido perdido.
  2. Si el registro de pedidos no se verifica en este momento y la cuenta B se verifica directamente después de la verificación directa, habrá una serie de pedidos.

solución:

Con el esquema de bloqueo de ID de dispositivo (IDFV), solo puede existir un pedido para cada dispositivo y cada ID de producto en el proceso completo. Al informar el comprobante, el pedido se recupera de acuerdo con la ID del dispositivo y se acredita a la cuenta.

Actualizar escena de desbloqueo:

Desbloquear la escena
Apple devuelve el éxito e informa el éxito del certificado
Apple devuelve el fallo de recarga

Actualización del proceso:

Proceso del cliente:


graph LR
用户充值 --> 下单传递IDFV --> 下单成功 --> 充值 --> 苹果返回成功 --> 上报凭证传递IDFV --> 收到成功回调 --> 关闭交易事务
充值 --> 苹果返回失败 --> 上报失败信息(传递IDFV) --> 收到接收回调 --> 关闭交易事务

Proceso del lado del servidor:


Encargar:

graph LR
接收客户端下单信息 --> 查找订单列表中对应设备id是否存在加锁的订单
查找订单列表中对应设备id是否存在加锁的订单 --> 存在加锁订单 --> 返回锁单中
查找订单列表中对应设备id是否存在加锁的订单 --> 不存在加锁订单 --> 创建订单并入库 --> 订单置为锁单状态 -->  返回订单号

Informes de documentos:

graph LR
接收客户端上报凭证 --> 找苹果校验成功 --> 返回客户端成功 --> 客户端关闭交易事务
找苹果校验成功 --> 通过设备id查找对应的订单 --> 充值到账
通过设备id查找对应的订单 --> 订单解锁并写入凭证的transactionId 

Error al informar:

graph LR
接收客户端上报失败信息 --> 通过设备id查找对应的订单 --> 订单解锁 --> 返回接受成功
接收客户端上报失败信息 --> 失败信息写入日志

Diagrama interactivo de recarga exitosa:


sequenceDiagram
用户->>客户端: 点击充值
客户端->>服务端: 下单(带IDFV)
服务端->>服务端: 订单入库并加锁
服务端-->>客户端: 下单成功
客户端->>苹果: 调用充值接口
苹果-->>用户: 充值操作
用户->>苹果: 充值完成
苹果-->>客户端: 回调充值成功
客户端->>服务端: 上报凭证(带IDFV)
服务端->>苹果: 调用凭证验证接口
苹果-->>服务端: 凭证验证合法
服务端-->>客户端: 上报成功
客户端-->>用户: 提示充值成功
服务端->>服务端: 通过IDFV查询订单信息
服务端->>服务端: 订单解锁并写入凭证的transactionId 
服务端->>服务端: 充值到账

Escenario 2: excepción de desbloqueo

Entorno de la escena:

Durante el proceso de recarga, cierra la aplicación y cancela el pago

Proceso de excepción:

Después de que el usuario realice el pedido y el proceso de recarga, cierre la aplicación y cancele el pago. En este punto, Apple ya no devuelve ninguna información de pago.

Rendimiento anormal:

Como Apple no devolvió ninguna información, el servidor no ha desbloqueado el pedido, por lo que no se puede recargar antes de desinstalar y volver a instalar.

situación real:

El usuario puede simplemente hacer clic para recargar por error, para evitar que la recarga sea exitosa, la aplicación puede ser cerrada directamente y la recarga será cancelada, esta situación ocurrirá en este momento.

solución:

在唤起充值之后,如果未返回过充值成功,则在下次服务端返回充值失败时,可以假定用户充值失败,则直接进行解锁操作。

解锁场景更新:

解锁场景
苹果返回成功并上报凭证成功
苹果返回充值失败
重启应用后的首次下单返回锁定,且苹果未返回充值信息

流程更新:

客户端流程:


graph LR
用户充值 --> 下单传递IDFV --> 下单成功 --> 充值 --> 苹果返回成功 --> 上报凭证传递IDFV --> 收到成功回调 --> 关闭交易事务
充值 --> 苹果返回失败 --> 上报失败信息(传递IDFV) --> 收到接收回调 --> 关闭交易事务
下单传递IDFV --> 返回锁单中 --> 判断为打开应用后首次下单 --> 上报苹果未返回  --> 收到上报回调 --> 下单传递IDFV

其余流程无需更新

场景三:卸载重装无法到账

场景环境:

一台设备,充值过程中卸载重装应用

异常流程:

账号下单充值,充值完成且在苹果未返回的情况下,卸载重装应用,此时凭证上报时候的设备id发生了变化,导致无法找到设备ID对应的订单。(如果使用保存在 keychain 中的 idfv,则恢复出厂设置时也将无法获取到之前保存的 idfv)

现实场景:

用户在充值之后,可能由于网络问题,暂时无法到账,瞬间弃坑删除应用,再过一段时间的冷静期后,又重新继续下载应用,此时就会出现该情况

解决方案:

上报凭证时候有两种地方获取,一个是旧的直接通过 transactionData 获取, 一种是官方推荐的 NSBundle 中获取。我们需要优化的点在于两处内容同时上报,解析 transactionData 时,可以获取到 UniqueVendorIdentifier ,这个与发起充值时候的 IDFV 的值是相同的,我们就可以针对这点来做订单的关联,并使用bundle中的凭证信息做安全相关的检验。(实际上,直接使用 transactionData 中的数据也是可以的,目前通过苹果验证后的暂未发现异常情况)

流程更新:

服务端流程:


上报凭证:

graph LR
接收客户端上报凭证 --> 找苹果校验成功 --> 返回客户端成功 --> 客户端关闭交易事务
找苹果校验成功 --> 提取凭证中的UniqueVendorIdentifier --> 查找对应的订单 --> 充值到账并写入凭证的transactionId 
查找对应的订单 --> 订单解锁

其余流程无需更新

场景四:充值成功但是到账慢

情况有多种,但是表现类似,就放一起讨论 环境场景:

  1. 设备本身网络较慢
  2. 服务器与苹果链接慢
  3. 服务端异常导致入库失败

异常流程:

  1. 玩家本身网络慢,导致苹果返回充值成功之后,上报凭证服务端超时,按照正常流程则需要苹果再次下发充值成功才会再次上报,间隔时间长。
  2. 服务器找苹果校验凭证信息,接口调用时间过长导致超时,返回客户端失败,从而等待下次上报
  3. 服务器本身出现异常(内存满了、发布中等)导致入库异常,返回客户端失败等待重新上报

现实情况:

电梯中或者高铁上玩手机进行充值,时常会有信号不好的时候,此时即为该情况

解决方案:

  1. 客户端收到苹果下发的充值成功信息后,保存凭证到内存中再进行上报凭证到服务端的操作,上报成功后移除对应凭证信息,上报失败则进行延迟重试处理
  2. 服务端收到上报的凭证时,入库成功后则直接返回成功给客户端,然后再调用苹果接口校验凭证是否合法,如果发生超时情况,则延后进行重试。

更新的流程放在结尾处

结尾

以上为旧版 storekit 所使用的方案,在目前已知情况下除了苹果自身多次扣款,其余情况都能保证充值的正常到账。新版的 storeKit 可以直接使用 appAccountToken 进行关联。如果有其他情况,欢迎一起讨论

完整解锁场景

解锁场景
苹果返回成功并上报凭证成功
苹果返回充值失败
重启应用后的首次下单返回锁定,且苹果未返回充值信息

完整流程

客户端流程:


graph LR
用户充值 --> 下单传递IDFV --> 下单成功 --> 充值 --> 苹果返回成功 --> 保存凭证信息 --> 上报凭证 --> 收到成功回调 --> 关闭交易事务 --> 移除保存的凭证
上报凭证 --> 收到异常回调 --> 延时30s --> 上报凭证
充值 --> 苹果返回失败 --> 上报失败信息(传递IDFV) --> 收到接收回调 --> 关闭交易事务
下单传递IDFV --> 返回锁单中 --> 判断为打开应用后首次下单 --> 上报苹果未返回  --> 收到上报回调 --> 下单传递IDFV

服务端流程:


下单:

graph LR
接收客户端下单信息 --> 查找订单列表中对应设备id是否存在加锁的订单
查找订单列表中对应设备id是否存在加锁的订单 --> 存在加锁订单 --> 返回锁单中
查找订单列表中对应设备id是否存在加锁的订单 --> 不存在加锁订单 --> 创建订单并入库 --> 订单置为锁单状态 -->  返回订单号

上报凭证:

graph LR
接收客户端上报凭证 --> 请求苹果凭证校验接口 --> 苹果校验返回成功 --> 返回客户端成功 --> 客户端关闭交易事务
苹果校验返回成功 --> 提取凭证中的UniqueVendorIdentifier --> 查找对应的订单 --> 充值到账并写入凭证的transactionId 
查找对应的订单 --> 订单解锁
请求苹果凭证校验接口 --> 找苹果校验超时 --> 延时30s --> 请求苹果凭证校验接口

上报失败:

graph LR
接收客户端上报失败信息 --> 通过设备id查找对应的订单 --> 订单解锁 --> 返回接受成功
接收客户端上报失败信息 --> 失败信息写入日志

充值成功交互图:


sequenceDiagram
用户->>客户端: 点击充值
客户端->>服务端: 下单(带 IDFV)
服务端->>服务端: 订单入库并加锁
服务端-->>客户端: 下单成功
客户端->>苹果: 调用充值接口
苹果-->>用户: 充值操作
用户->>苹果: 充值完成
苹果-->>客户端: 回调充值成功
客户端->>服务端: 上报凭证
服务端->>苹果: 调用凭证验证接口
苹果-->>服务端: 凭证验证合法
服务端-->>客户端: 上报成功
客户端-->>用户: 提示充值成功
服务端->>服务端: 通过凭证获取的UniqueVendorIdentifier查询订单信息
服务端->>服务端: 订单解锁并写入凭证的transactionId 
服务端->>服务端: 充值到账

FAQ

  1. 多次扣款时如何补发给用户?

这种情况由于是极少数情况,只能定位到多次扣款的那个订单信息,并定位确认最近的订单,并跟用户确认后手动补发

  1. 如何验证重复上报凭证

上报凭证时候,先判断凭证的 transactionId 是否已存在,如果已存在则说明已上报过,直接返回成功即可

  1. 是否要做其他的限制

凭证验证成功后,查询订单时,查询凭证充值时间前的订单即可,并确认解析后的包名是否正确,如果需要的话,可以考虑查询到过早的订单时,不进行到账处理并预警该订单


Supongo que te gusta

Origin juejin.im/post/7118770506702012453
Recomendado
Clasificación