重庆互联网,19年企业互联网解决经验,专业网站开发、移动端开发、微信端开发、小程序开发!
重庆网络推广公司

微信小游戏运营指南 — 虚拟支付篇(02)

作者:重庆互联网小徐 发布时间:2025-09-28 浏览:19634 赞(1850 收藏 评论(0)

3.小游戏支付最佳实践

对于首次接入支付能力的游戏,我们建议根据付费场景使用对应的支付能力去实现,即游戏币场景使用游戏币托管能力,道具直购场景使用道具直购能力

3.1.正确使用支付能力

首次接入支付能力或者有支付能力改造意愿的游戏,适用于该小节指南。

3.1.1.游戏币场景使用游戏币能力

此处所指游戏币场景,是上文2.1.1. 游戏币场景所提及场景, 游戏币的发货由平台负责,正常情况下扣费成功后,即可查询到游戏币余额,极端情况下可能有一定的到账延迟,需要在游戏客户端做好恰当的余额刷新机制。

游戏币扣除pay_v2.pay为了避免多扣、少扣,需要开发者实现正确的 bill_no 语义,即为每一次来自玩家的扣除意图(游戏币兑换道具)分配对应的唯一 id(传入 pay 接口的 bill_no 字段)。

必须实现
  • 相同扣除意图的请求不管调用多少次都需要使用相同的 bill_no:同样的扣除意图应保证多次重试时传入相同的 bill_no,平台侧保证48 小时传入同样的 billno 游戏不会币被多扣,开发者应在 48 小时内处理完本次扣除。

    反面教材举例:同样的一次兑换意图,如果第一次调用 pay 接口时使用的 bill_no_a1,因为网络原因超时或者微信侧接口返回-1(存在可能实际上平台侧已经执行成功,游戏币已扣除),开发者进行了重试,结果错误的换了新的 bill_no_a2 再次发起 pay 请求,则会造成两次扣除。

    pay 接口对相同的 bill_no 48 小时内只会扣除对应的游戏币一次,一旦扣除成功,后续同样 bill_no 的请求会返回 90012 表示 bill_no 同样的 pay 接口请求已扣除成功,如果开发者正确实现了 bill_no 的语义,可以把 90012 当成扣除成功。

  • 确保游戏币余额扣除成功,确保游戏币余额扣除成功后,再进行游戏内道具的发放。即“扣除游戏币-发放道具”的流程应该可以多次重入,结果上刚好只发放一次对应的道具。

建议实现

建议开发者有自己的服务端余额缓存。极端情况下平台的余额查询接口不可用,可以使用开发者自己的服务端缓存展示给玩家。只作为展示,真正扣除时仍然需要以平台返回的结果为准。

  • 游戏内的游戏币充值模块,在 wx.requestMidasPayment 返回后:

    • 不需要做任何失败的提示。即使前端接口返回失败,也不要提示用户充值失败:

      1. 对于确定充值失败的情况,平台已经做好了恰当的提示,比如:健康系统限制

      2. 极端情况下,存在接口返回失败实际上是充值成功的情况,比如:在 Windows 内的小游戏中充值,手机扫码支付后,Windows 网络断开,Windows 上接口会返回失败,实际上手机可以继续付费

    • 立刻查询一次游戏币余额:无论该接口返回成功,还是失败,都进行一次游戏币的余额查询pay_v2.getBalance,把最新余额展示给玩家。

    • 可接受游戏币发货事件通知,获取游戏币余额到账通知,主动刷新余额。

  • 若开发者做了余额缓存,建议在玩家进入商城模块、或者每天首次进入游戏时,可以主动调用查询余额接口获取最新余额

更详细的介绍参考:小游戏虚拟支付 2.0 开发指南(对外)

3.2.2.道具直购场景使用道具直购能力

道具直购能力发货由平台通知开发者,正常情况下扣费成功后,即会通过服务端消息推送通知到开发者,极端情况下可能有一定的通知延迟。 特别提醒

  1. 同样的发货请求(outTradeNo),可能因为网络原因,会请求多次。我们在有限时间内尽量保证触达一次,直到明确返回发货成功为止

  2. 针对重复的请求,开发者需要自行保证只发货一次,并且回包需要和第一次一样返回发货成功

  3. 通知周期:15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h

  4. 必须要开启道具发货推送才能收到回调请求

必须实现

  • 发货消息会尽可能及时、尽可能不漏的通知到开发者服务端,若出现网络异常或者非发货成功的应答,我们会进行重试,开发者的服务端可能会收到重复的发货消息,即相同的订单 id 被推送多次。开发者需要确保实现道具发货的幂等,相同的订单 id(outTradeNo)多次被通知发货时只发货一次。

  • 发货消息通道需要做好请求校验及相关密钥的妥善保管,避免因为密钥泄露导致请求来自恶意第三方。 建议实现

  1. 尽管我们会尽可能保证不漏的推送到开发者服务端,但是若开发者侧有故障,我们不可能一直重试。因此开发者可以增加一定频率的主动发货逻辑: a.下单后按一定间隔(比如 10s),定期查询订单状态(pay_v2.queryOrder),越往后间隔建议越大(比如后面可以按 1 分钟,10 分钟查询一次)  更详细的介绍参考:道具直购能力

3.2.3.使用游戏币托管能力实现道具直购场景的优化建议

对于使用了游戏币托管能力来实现道具直购场景的游戏,若考虑到兼容性、研发与运营成本,暂时不愿意切换到新的道具直购能力,我们也建议参考本小结说明进行优化。

游戏币托管能力原本的设计是用于游戏内有游戏币场景的游戏币购买、扣除、查询等操作,而通过游戏币托管能力实现道具直购,对玩家来说看不到“游戏币”账户,是直接花钱购买道具,实现层面则需要把 3 个步骤串起来,即:

  1. 购买游戏币wx.requestMidasPayment

  2. 扣除游戏币pay_v2.pay

  3. 道具发货

必须实现
  • 必须以游戏币扣除(pay_v2.pay)成功为道具发货的依据 目前购买游戏币的请求并没有要求开发者在服务端签名,所以完全可能被前端恶意篡改,比如 outTradeNo 对应的游戏币是 100 个,可以修改为 10 个,然后发起购买(wx.requestMidasPayment),购买成功后不能直接发放原订单(100 个游戏币)对应的道具,应该以扣除 100 个游戏币成功后再发放相应的道具

  • 扣除游戏币(pay_v2.pay)时为了避免多扣、少扣,需要开发者实现正确的 bill_no 语义,即为每一次来自玩家的扣除意图(游戏币兑换道具)分配对应的唯一 id(传入 pay 接口的 bill_no 字段)。这一步可以参考"3.1.1.游戏币场景使用游戏币能力"的说明。

建议实现
  • 游戏币实现道具直购主要问题:

    1. 极端情况下,wx.requestMidasPayment 返回失败,实际上也可能成功(参考“游戏币场景使用游戏币能力”的说明),也有可能会丢失回调。

    2. 游戏币到账会有延迟。

    3. 为了区分不同道具,zone_id 当成道具 ID 使用,导致遇到用户分区上限问题。

  • 建议措施: - 在 wx.requestMidasPayment 返回后: - 如上文所说不需要做任何失败的提示。即使前端接口返回失败,也不要提示用户充值失败。 - 若pay_v2.queryOrder查到用户已支付,但游戏币尚未到账,可提示用户稍等,平台侧会保证游戏币到账。 - 开发者服务端: - 开发者服务端通知游戏客户端 wx.requestMidasPayment 后便开启通知轮询定期查询游戏币余额pay_v2.getBalance或者查询订单状态pay_v2.queryOrder,下单后按一定间隔,至少间隔 10s,持续 5 分钟. - 收到wx.requestMidasPayment成功的回调后可以主动查询一下余额到账情况。 - 事件通知:订阅“小游戏支付类订阅事件 ”,有这个事件通知作为兜底,定期轮询可以在 5 分钟后停止,超过 5 分钟仍未到账的可以依赖事件通知。 - 开发者服务端可以直接用 out_trade_no 作为索引来存储订单相关信息,可以根据 out_trade_no 使用pay_v2.queryOrder查询微信侧订单状态,避免使用 zone_id 当成道具 ID 使用。

3.2.通用建议

3.2.1.微信服务端 API 域名选择

开发者可以根据自己的服务器部署情况,选择最佳的接入域名(延时更低,稳定性更高)。除此之外,可以将其他接入域名用作容灾用途,当网络链路发生故障时,可以考虑选择备用域名来接入。请开发者使用域名进行 API 接口请求,不要使用 IP 作为访问。  注意:该说明对所有“api.weixin.qq.com”下的 API 都适用,更多细节参考公众平台接口域名说明。 对于支付类业务而言,建议考虑就近接入以及做好异地容灾域名切换的策略。

3.2.2.接口调用凭证(access_token)的建议

  • 为了保证安全性,获取 access_token 的 AppSecret 以及 access_token 本身不要泄露到游戏客户端或者游戏服务端以外的其他地方

  • 建议统一切换到新接口:获取稳定版接口调用凭据 | 微信开放文档,对并发限制、调用频率都更为宽松,具体可以看接口说明。新接口与老接口(auth.getAccessToken | 微信开放文档)是互不影响的,切换期间可以同时存在

3.2.3.登录态与会话密钥 session_key(signature)的注意事项

支付相关 API 涉及用户签名的地方(signature 参数),都需要用到 session_key,session_key 是玩家在使用小游戏期间微信分配的用于微信服务端和游戏服务端之间验证身份、安全通信的一种凭据,是对用户数据进行加密签名的密钥。分别存储于微信服务端、游戏服务端,在调用 wx.login 时可能触发 session_key 的重新生成,为了保证游戏服务端存储的 session_key 和微信侧的一致,开发者需要使用 wx.login 获得的 code 去换最新的 session_key。

注意事项如下:

  • 开发者实现登录流程可参考小程序登录,session_key 主要用于微信服务端和游戏服务端之间验证身份。游戏客户端和游戏服务端之间的权限验证开发者应自己实现自定义登陆态。

  • 为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。

  • wx.login 调用时,用户的 session_key 可能会被更新而致使旧 session_key 失效(刷新机制存在最短周期,如果同一个用户短时间内多次调用 wx.login,并非每次调用都导致 session_key 刷新)。

  • session_key 目前 失效时间为天级别,用户可能会同时登录手机端和 PC 端,导致同一个用户重复 wx.login,开发者需要在服务端维护最新换取的 session_key。

  • wx.login 调用有频率限制游戏客户端应控制 wx.login 的调用频率,禁止短期内的多次自动重试,可以通过本地存储记录相关调用状态来实现),若检测到多次自动进入重新登录态流程,可以考虑交由玩家决策:弹出对话框提示玩家,重试、重启小程序或者清理缓存后再试。同时,开发者应该针对这类问题增加告警,排查代码逻辑是否有问题。以下任意条件满足则应触发重新登录(调用 wx.login)

    1. 首次登录

    2. 游戏服务端存储的 session_key 失效,例如:调用支付接口返回 90010(signature 签名错误)和 90016(sessionkey 过期)时,应通知游戏客户端重走 wx.login 流程。后台可以通过auth.checkSessionKey校验

    3. 进入游戏通过 wx.checkSession 检查 session_key 是否有效。

    4. 游戏自定义登陆态失效。

可以进一步参考session_key 相关注意事项

FAQ

Q: 如何测试虚拟支付相关的接口?

  • A: 使用沙箱环境,沙箱环境不结算,所有订单都可以直接退款

重庆互联网项目从2004年开始为各行各业提供互联网发展解决方案,专业从事网站、小程序、微信公众号、APP、电商平台、系统等互联网平台开发,帮助企业实现从传统行业到互联网的完美转型。截止目前,重庆互联网合作的企业遍布全国各地,21年的开发经验和完善的售后服务体系获得合作客户的高度认可!

关注重庆互联网官方公众号,即可获取粉丝专享福利!

重庆互联网公众号二维码.jpg

网友留言评论
我要评论
评论

欢迎广大用户为此页面进行评价,评价成功将获得积分奖励!

  • 赞(0
    踩(0
重庆网站定制建设
  • 重庆网站建设平台
  • 重庆网站优化公司
  • 重庆网络推广公司哪家好
  • 重庆APP制作公司
版权所有 ©2004-2024 重庆市渝中区圣灵科技信息有限公司 渝ICP备16004600号-14 渝公网安备50010802001420号 电子营业执照
重庆公众号制作哪家好
二维码
联系客服 重庆商城网站建设