前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >像微信支付一样处理苹果支付服务端回调

像微信支付一样处理苹果支付服务端回调

作者头像
seth-shi
发布2024-03-15 09:40:19
990
发布2024-03-15 09:40:19
举报
文章被收录于专栏:seth-shi的专栏seth-shi的专栏

客户端请使用StoreKit2, 服务端通知

数据库设计(省略不重要字段)

代码语言:javascript
复制
# 订单表
mysql> desc orders;
+------------------+---------------------+------+-----+---------+----------------+
| Field            | Type                | Null | Key | Default | Extra          |
+------------------+---------------------+------+-----+---------+----------------+
| id               | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| no               | varchar(255)        | NO   | UNI | NULL    |                |
| trade_no         | varchar(255)        | YES  |     | NULL    |                |
| status           | tinyint(4)          | NO   |     | NULL    |                |
| origin_no        | varchar(255)        | YES  |     | NULL    |                |
+------------------+---------------------+------+-----+---------+----------------+

# 用户签约表
mysql> desc member_contracts;
+-----------------+---------------------+------+-----+---------+-------+
| Field           | Type                | Null | Key | Default | Extra |
+-----------------+---------------------+------+-----+---------+-------+
| user_id         | bigint(20) unsigned | NO   | PRI | NULL    |       |
| status          | tinyint(4)          | NO   |     | NULL    |       |
| contract_id     | varchar(255)        | NO   | MUL | NULL    |       |
+-----------------+---------------------+------+-----+---------+-------+

服务端处理逻辑

  • 订阅到期重新订阅appAccountToken,originalTransactionId会变(订阅退订, 然后超过有效期后)
  • 订阅期内取消订阅, 然后又重新订阅appAccountToken,originalTransactionId不变

客户端下单

代码语言:javascript
复制
## 客户端请求创建订单接口生成订单号`$uuid`, 返回给客户端放入`appAccountToken`
INSERT INTO orders(no) VALUES('$uuid');

服务端事件回调-用户订阅

  • 苹果服务端notificationV2回调处理 && 客户端回调处理 (一个JWS字符串)
代码语言:javascript
复制
## 解析服务端回调, 确认`notificationType=SUBSCRIBED`且二级事件`subtype in INITIAL_BUY RESUBSCRIBE AUTO_RENEW_ENABLED`(根据自己要求处理事件, 验证商品`ID`和包名等是否符合条件)
## 重要的字段: appAccountToken,transactionId,originalTransactionId,expiresDate
## 1. 查询 appAccountToken 订单是否存在
select * from orders where no='{$appAccountToken}' limit 1 => $id;
## 2. 修改订单状态信息, 包括已付款
update orders set trace_no='$transactionId', origin_no='$originalTransactionId' where id=$id;
## 3. 修改用户订阅状态
update member_contracts set contract_id='$originalTransactionId';
## ... 赠送会员等等等

服务端事件回调-用户订阅

代码语言:javascript
复制
## notificationType=DID_RENEW
## 1. 通过`transactionId`查询订单是否存在, 如果存在直接返回已经通知过
select * from orders where trade_no='{$transactionId}' limit 1 => $id
## 2. 如果不存在, 那么通过 originalTransactionId 查询到订阅表, 得到订阅的创建订单信息;
select * from member_contracts where contract_id='$originalTransactionId' limit 1;
## 3. 通过订阅表信息直接插入一条已付款的订单信息
INSERT INTO orders(no, trade_no, origin_no) VALUES('$uuid', '$transactionId', '$originalTransactionId');
## ... 赠送会员等等等

退订事件

代码语言:javascript
复制
update member_contracts set status=xxx where contract_id='$originalTransactionId';

客户端回调

  • 客户端回调得到的JWS字符串解析出来的字段 === 苹果服务端回调的字段.Data.SignedTransactionInfo
  • 所以客户端把凭证串发给服务端, 服务端抽象出订阅事件的代码, 在苹果服务端回调和客户端验单共用就行
代码语言:javascript
复制
// 获取商品信息
products = try await Product.products(for: Set(productIds))

// 支付,先请求服务端创建订单接口获得 uuid
let uuid = Product.PurchaseOption.appAccountToken(UUID.init(uuidString: "$uuid")!)
let result = try await product.purchase(options: [uuid])

//处理支付结果,此时苹果内部已经进行了JWS校验
switch result {
    case .success(let verificationResult):
        // 把 verificationResult 发给服务端去校验, 防止苹果服务端回调慢
        // 把 verificationResult 发给服务端去校验, 防止苹果服务端回调慢
        // 把 verificationResult 发给服务端去校验, 防止苹果服务端回调慢
    case .userCancelled:
        //处理取消
    case .pending:
        //交易可能会在未来成功,通过Transaction.updates进行通知。
}

更多事件请按需处理

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-03-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 数据库设计(省略不重要字段)
  • 服务端处理逻辑
    • 客户端下单
      • 服务端事件回调-用户订阅
        • 服务端事件回调-用户订阅
          • 退订事件
            • 客户端回调
              • 更多事件请按需处理
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档