海外支付(GooglePay)服务端设计方案

Google 支付方案设计

接入支付前期准备

主要是准备好Google开发者账号,创建项目,授权,获取密钥,创建商品等等。。。

前提说明

GooglePay 分为 Subscriptions (订阅) 和 In-App Purchases (内购)
官方文档在这里

In-App Purchases 内购

客户端代码流程(网上)

image.png

支付流程

  1. 向用户展示他们可以购买什么。
  2. 启动购买流程,以便用户接受购买交易。
  3. 在您的服务器上验证购买交易。
  4. 向用户提供内容。
  5. 确认内容已传送给用户。对于消耗型商品,请将购买的商品标记为消耗,以便用户能够再次购买商品。

服务端验证订单流程

image.png

  1. 接收客户端传递来的参数
  2. 根据客户端参数的订单ID(第三方订单ID)去库里查询是否存在订单
  3. 如果存在订单,检查订单状态,如果不是初始化状态,说明订单已经被处理过了,如果是初始化状态,则走步骤 5
  4. 如果不存在订单则创建订单
  5. 服务端调用 Google API 校验订单状态
  6. 如果链接不上 Google 服务器或者开启了本地校验
  7. 服务端本地 RSA 签名校验订单状态
  8. 订单校验失败,告知客户端,修改订单状态,记录订单失败信息
  9. 订单校验成功,更改订单状态,记录订单信息
  10. 发送 Kafka 消息,告知客户端处理成功

注意事项,校验订单时需要加分布式锁(按照订单号为锁),避免客户端多次重试出现并发问题

服务端校验订单方式

服务端校验订单,主要是校验订单的状态,可以分为两种验证方式:

  1. 服务端RAS签名验证
  2. 服务端调用Google API 验证

可以两种方式都做,原因是:

  1. Google api 方式需要连接Google服务器,如果谷歌服务器连接失败,此时可以退而求其次,使用本地签名验证
  2. 服务端RAS签名验证有一些风险,据说有些模拟器可以伪造数据

服务端签名验证

客户端返回参数大致情况:

signtureData:
{
    "orderId": "1111111111.111111111111", 
    "packageName": "com.abc.item", 
    "productId": "com.abc.item.1", 
    "purchaseTime": 1423197856877, 
    "purchaseState": 0, 
    "purchaseToken": "dccfjnioeeojanngnfspekea.AO-J1OzsBdFJhqhLtvtybnQbBMxELYL4M-wClITbJFd-rpnPzYWCOlHyK69xgXBYN8lx99XfMBhD8JPg6u3SsgNvPt2hhbvogszRxjtA15rP-qWBYv_Rytw"
}

signture:XCtoXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXy2Nyp047DV0f1VZ39CV7dCmLXouSFrYBxoS7NAVejgmHU+WXLLI61M4GjRrBMtEuW2HnUye8hfbsjlGfqI+MZDqAbfAi+3i6fPwIOwDS+tdAAU+VUz3cDyBubJhL+tZIa1uT6H0ifHN0KXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX7xpsZTctzf09XGKdqNktrFbNm4pqHqDttEg98xmiP/oKyitZpLoNyvrk7nEXxUstGJhKejPt9wyn3il+s7cT3TD4xyEznxeBuD+zVa/sCXAZw==
复制代码

服务端校验: publicKey , 谷歌后台提供

//result=true的话就成功了
boolean result = RSASignature.doCheck(signtureData, signture, publicKey);

复制代码

服务端调用Google API 验证订单状态

Google并未像Apple那样提供一个接口来校验订单的信息,但是提供了一个获取订单状态的接口,可以通过这个接口在GooglePlay服务器获取某个订单,查看其状态是否合法达到校验目的

服务端调用Google API验证订单也有两种方式:

  1. 一种是借助 Google SDK方式
  2. 另一种是使用Http请求,但是需要自己维护请求API时需要的 refreshToken、access_token(Auth2流程),个人感觉比较麻烦

建议使用 Google SDK接入方式

参考:www.cnblogs.com/kevin-zou/p…

支付表结构设计

  • 商品表
CREATE TABLE `goods` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT,
    `goods_code` varchar(20) NOT NULL COMMENT '商品code',
    `goods_name` varchar(20) NOT NULL COMMENT '商品名称',
    `type` tinyint(1) DEFAULT NULL COMMENT '虚拟币类型',
    `quantity` int(11) DEFAULT NULL COMMENT '数量',
    `price` bigint(20) NOT NULL DEFAULT 0 COMMENT '售价',
    `pay_channel` tinyint(1) DEFAULT NULL COMMENT '支付渠道:0 GooglePay 1 ApplePay 2 PayPal',
    `distribution_channel` varchar(200) NOT NULL COMMENT '分销渠道,多个逗号隔开',
    `create_time` datetime DEFAULT NULL COMMENT '创建时间',
    `update_time` datetime DEFAULT NULL COMMENT '更新时间',

    PRIMARY KEY (`id`),
    KEY `index_goods_code` (`goods_code`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4;
复制代码
  • 支付渠道表
CREATE TABLE `pay_channel` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT,
    `channel_name` varchar(20) DEFAULT NULL COMMENT '渠道名称',
    `link` varchar(100) DEFAULT NULL COMMENT '链接 H5类型下使用',
    `create_time` datetime DEFAULT NULL COMMENT '创建时间',
    `update_time` datetime DEFAULT NULL COMMENT '更新时间',

    PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4;
复制代码
  • 订单表
CREATE TABLE `order` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT,
    `order_sn` varchar(20) NOT NULL COMMENT '订单编号',
    `third_order_sn` varchar(20) NOT NULL COMMENT '第三方订单编号',
    `origin_order_sn` varchar(20) NOT NULL COMMENT '源订单号,发起退款时关联的订单',
    `user_id` bigint(20) DEFAULT NULL COMMENT '用户ID',
    `type` tinyint(1) NOT NULL COMMENT '订单类型 0 付款订单 1 退款订单',
    `goods_code` varchar(20) NOT NULL COMMENT '商品code',
    `price` bigint(20) NOT NULL DEFAULT 0 COMMENT '订单金额',
    `payment_method` tinyint(1) DEFAULT NULL COMMENT '付款方式:0 Google pay ',
    `status` tinyint(1) DEFAULT NULL COMMENT '订单状态:0:初始化 1:已完成 2 已经取消 3 已退款',
    `deliver_status` tinyint(1) DEFAULT NULL COMMENT '发货状态:0:发货失败 1:发货成功',
    `complete_time` datetime DEFAULT NULL COMMENT '订单完成时间',
    `refund_time` datetime DEFAULT NULL COMMENT '退款时间',
    `device` tinyint(1) DEFAULT NULL COMMENT '设备:0:IOS 1:安卓',
    `origin_info` varchar(500) DEFAULT NULL COMMENT '第三方支付信息',
    `remark` varchar(200) DEFAULT NULL COMMENT '备注',
    `refund_reason` varchar(200) DEFAULT NULL COMMENT '退款原因',
    `create_time` datetime DEFAULT NULL COMMENT '创建时间',
    `update_time` datetime DEFAULT NULL COMMENT '更新时间',

    PRIMARY KEY (`id`),
    KEY `index_order_sn` (`order_sn`) USING BTREE,
    KEY `index_third_order_sn` (`third_order_sn`) USING BTREE
    KEY `index_user_id` (`third_order_sn`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4;
复制代码

微服务设计

新加一个 order 服务? 现在有一个 ironman-service-commodity 服务,支付商品可以放这里

PayPal 支付设计方案

猜你喜欢

转载自juejin.im/post/7126780111268888583
今日推荐