V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Outshine
V2EX  ›  程序员

关于订单超时后用户却已支付的疑问

  •  1
     
  •   Outshine · 2023-03-03 16:00:44 +08:00 · 3774 次点击
    这是一个创建于 630 天前的主题,其中的信息可能已经有所发展或是发生改变。

    用户订单支付超时了,我现在需要:

    • 将订单标记为支付超时
    • 然后将订单库存恢复到商品库存
    • 告诉用户订单支付已经超时

    假如用户在超时前发起了支付但是在超时后才支付成功,或者因为支付回调通知等问题导致我上面流程已经跑了一部分或跑完了,这时候该如何处理?给用户退款?

    或者有啥办法能避免这个问题嘛?

    42 条回复    2023-03-23 16:46:50 +08:00
    Puteulanus
        1
    Puteulanus  
       2023-03-03 16:07:17 +08:00
    先将订单标记为支付超时,关闭支付的入口,但是留一点时间再进行库存这类的操作?
    这段时间如果他支付了,就回滚订单状态,还是算他成功下单了
    gam2046
        2
    gam2046  
       2023-03-03 16:11:38 +08:00
    一般第三方支付方的接入(支付宝、银联等)创建订单时,都是允许设置订单支付有效期的,所以原则上这口锅,第三方已经帮你解决了。

    对于超售问题,可以考虑事后的对账,然后对冲超期订单。
    T110E5
        3
    T110E5  
       2023-03-03 16:15:51 +08:00
    愚见:
    订单过期时间假设为 A ,发起支付上送时记录时间 B ,收到支付成功回调时间为 C ,
    如果 B 小于 A 时,可以发起支付,但是对于 C 是否必须小于 A ,可以看业务容忍度,有些就要求立即退款,走逆向流程,有些就认为 OK 。
    或者硬给 B 时间加一个偏移,作为支付回调通知延迟送达的修正。
    koloonps
        4
    koloonps  
       2023-03-03 16:20:05 +08:00
    你关闭订单的时候先锁定当前订单不让产生新的支付订单,然后关闭支付订单。最后再关闭订单
    Outshine
        5
    Outshine  
    OP
       2023-03-03 16:20:42 +08:00
    @gam2046 订单超时时间是自己系统的,但是支付超时时间,是发起支付成功才开始计算的,所以并不能解决我的问题。
    vibbow
        6
    vibbow  
       2023-03-03 16:20:49 +08:00
    你需要更新你自己的代码逻辑,支付成功回调后检查订单是否可用。
    如果不可用的话自动退款。
    zhou405x
        7
    zhou405x  
       2023-03-03 16:25:02 +08:00
    1.创建订单
    2.跳转第三方支付
    3.订单超时,状态修改
    4.第三方支付成功回调
    5.订单非待支付状态
    6.发起退款
    Outshine
        8
    Outshine  
    OP
       2023-03-03 16:30:24 +08:00
    @koloonps @zhou405x @koloonps 有个问题就是用户在我这边订单支付超时前发起了支付,但是并没有及时支付(支付宝有 15 分钟的支付时间),那我在订单支付超时时只锁定不让用户再发起支付,在支付超时 15 分钟后再之后退还库存等操作?
    Outshine
        9
    Outshine  
    OP
       2023-03-03 16:31:51 +08:00
    #8 的疑问同样适用于 #3 @T110E5 的回答
    monstervivi
        10
    monstervivi  
       2023-03-03 16:36:54 +08:00
    刚刚把 OP 问题,直接复制问了 ChatGPT
    以下是回答,OP 可以看看是否有参考价值
    ---------------------------------------------------------------------------------
    如果用户在超时前发起了支付但是在超时后才支付成功,或者因为支付回调通知等问题导致流程已经跑了一部分或跑完了,可以考虑以下解决方案:

    如果订单库存已经恢复到商品库存并且尚未发货,可以让用户继续购买,同时将已支付的金额转移到新订单中。

    如果订单库存已经恢复到商品库存并且已经发货,可以考虑给用户退款,同时要求用户退回商品。

    如果订单库存还没有恢复到商品库存,可以等待支付成功后再将库存恢复,或者让用户选择退款或继续购买其他商品。

    为了避免这个问题,可以在用户下单时设置支付超时时间,并在订单支付超时后自动取消订单,并将库存恢复到商品库存。同时,可以加强支付回调的监控和处理,确保订单状态的准确性。
    oxromantic
        11
    oxromantic  
       2023-03-03 16:38:24 +08:00
    支付超时的订单你们有需求要立刻释放库存?没有的话晚几分钟释放也没问题吧
    hhjswf
        12
    hhjswf  
       2023-03-03 16:45:54 +08:00 via Android
    @Outshine 你不可能不让他支付的。比如我就在摁密码界面不支付,等超时后再摁密码支付
    optional
        13
    optional  
       2023-03-03 16:49:08 +08:00 via iPhone
    你先把你的状态机画出来。
    按我看,订单超时了,可能 sku 都占用释放了,不一定能恢复订单了
    tudouxian
        14
    tudouxian  
       2023-03-03 16:58:30 +08:00
    用分布式锁吧能解决吧
    zhou405x
        15
    zhou405x  
       2023-03-03 17:05:16 +08:00
    @Outshine 不管什么时间什么状态 , 只要是支付成功回调的时候订单状态是正确的就 ok 了.
    改状态的时候加锁 ,然后那一套代码是一个事物里的 ,不管你是本地事物还是分布式事务
    Felldeadbird
        16
    Felldeadbird  
       2023-03-03 17:06:13 +08:00
    现实问题不应该程序解决,找领导决定流程,在开发修复这个问题。

    例如,产品超售时,一般钱直接退到客户的账户上。这样公司现金流多了。 如果你没有决定权,调用了退款接口。万一出错了,你要负担责任的。
    Felldeadbird
        17
    Felldeadbird  
       2023-03-03 17:08:28 +08:00
    我说一下我司的做法:
    1. 订单一般存活 4 小时,4 小时内支付成功就可以了。
    2. 超过 4 小时后才支付,一律不变状态。让对方找客服。财务确认后退款。
    Marinaaaa
        18
    Marinaaaa  
       2023-03-03 17:10:52 +08:00
    建议超时支付成功 自动退款。

    例如:用户支付的时候使用了优惠券,订单超时取消,优惠券退回。 如果这个时候用户支付成功,订单状态改成了成功,那么这个优惠券怎么算?
    DinnyXu
        19
    DinnyXu  
       2023-03-03 17:14:58 +08:00
    假如用户在超时前发起了支付但是在超时后才支付成功:
    OP 的这个问题是:用户在下单前发起的支付,这个时候订单还未超时,常见的手机支付,微信或支付宝在唤起支付时,付钱的那一刻,也就是输入密码或者面容识别,OP 的系统是无法感知的。

    举个例子:
    - OP 的订单设置为 10 分钟内必须支付完成。
    - 用户在 10 分钟内发起了支付,此时已经停留在输入密码的界面。
    - 用户停留在输入密码的界面超过 10 分钟,并且成功付钱了,OP 需要控制的是这个过程

    解决方案:在用户点击支付时(此次在输入密码的界面),进行预下单,这个时候会生成一笔订单,我对接过的支付宝和微信中有一个订单过期参数,OP 需要将这个参数设置为你的订单超时时间,这样用户停留在输入密码页面超过 10 分钟后,付钱的时候三方系统会通过你的这个超时参数判断,是不是已经超时了,从而拒绝该笔订单。
    Raw778
        20
    Raw778  
       2023-03-03 17:15:46 +08:00
    一般第三方支付方都会有个 close 订单的 api 的,在你系统订单超时的时候去调用 close,这样用户会支付失败.
    如果刚好卡时间点,用户支付成功回调的中途,你的系统订单超时回滚库存了,那么最好走退款流程(怕库存超卖).
    不过如果你能加上分布式锁的话,应该不会存在卡时间点的情况
    swulling
        21
    swulling  
       2023-03-03 17:16:25 +08:00   ❤️ 1
    最简单的方案:

    在订单支付页面增加提醒:请跳转到第三方支付系统后尽快支付,如超过支付时间(剩余 x 分 x 秒),您的支付将会原路退款,商品将会释放。


    复杂方案:

    比如订单超时时间 是 1 小时,那么当 1 小时超过后,订单转入“已超时关闭中”状态。
    这个状态内 sku 依然锁定,但是无法发起支付,但是可以接受第三方支付回调。状态持续时间比如 5 分钟或者 15 分钟都行。
    如果持续时间到了,就转入“关闭”状态,释放 sku ,优惠券等。此后再接收到任何支付回调,一律退款。
    wxw752
        22
    wxw752  
       2023-03-03 17:17:20 +08:00
    回调回来发现订单关闭了,会自动退款,我忘了用什么 APP 曾经遇到过。
    OldCarMan
        23
    OldCarMan  
       2023-03-03 17:20:04 +08:00
    个人看法:
    做电商的,人工处理流程基本是不可少的,极端情况下,比如你说的第三方支付延迟通知或第三方部分服务不可用导致你订单超时支付,建议走人工处理或半自动化处理(比如,自动退款同时短信通知),至于如何处理,是退款还是补偿,建议在商品规则的文案里写清楚,重点是让你们的处理方式公开透明,有理有据;

    非极端情况下,只能通过技术手段不断完善整个订单支付流程,尽量避免这类事情发生,比如规划好订单状态变化流程,理清整个订单闭环操作,包括无论是手动还是定时变化。总之处理原则是理清责任归属,把有理可依作为底线处理方式。
    git00ll
        24
    git00ll  
       2023-03-03 17:24:37 +08:00
    超时关单,关单后如果接到支付成功回调,则自动发起退款
    mnhkahn
        25
    mnhkahn  
       2023-03-03 17:30:30 +08:00
    搞个状态机订单状态需要按要求流转。收到付款消息时驱动订单状态,无法驱动就需要发起退款
    wu00
        26
    wu00  
       2023-03-03 17:35:16 +08:00
    - 超时关闭任务触发时,如果订单为支付成功状态,结束本次任务
    - 支付结果统一走回调处理,如果支付成功且订单为已关闭状态,走支付款原路返还流程。
    - 超时任务时间设置略大于第三方支付有效期,订单创建成功及时向第三方创建支付单(不要等用户手动触发支付),尽可能避免原路返款流程
    jaggle
        27
    jaggle  
       2023-03-03 18:42:39 +08:00 via iPhone
    @DinnyXu 你还没明白 op 的意思,op 是说支付完等待回调通知时,订单超时了,然后通知来了,这时该咋办
    edis0n0
        28
    edis0n0  
       2023-03-03 18:56:17 +08:00
    这种情况大公司也是经常出,要找人工客服退款
    bk201
        29
    bk201  
       2023-03-03 18:59:13 +08:00
    超时未支付,订单取消,订单取消订单系统通知给支付系统,发取消支付单指令,至于取消支付单后要做什么,压根不用订单系统去管,支付系统依据支付单的状态去做不同处理,比如支付中,那就发送取消支付单给第三方支付系统处理或者主动查询支付状态,成功就发起退款单流程,异常就发送给后台人工处理。
    WindProtect
        30
    WindProtect  
       2023-03-04 09:28:54 +08:00
    支付有回调的吧,回调查看订单状态,发现超时直接走退款。不过需要做好锁,不然也坑。
    DinnyXu
        31
    DinnyXu  
       2023-03-04 13:52:16 +08:00
    @jaggle 假设我订单有效时长设置 30 秒,回调回来的时候已经超过 30 秒了? 那就计算总体库存数量呗。不可能所有人的回调都超时了吧,没超时的就把订单库存买完了啊。超时那个运气不好,自动退款就行了。
    DinnyXu
        32
    DinnyXu  
       2023-03-04 13:53:21 +08:00
    @jaggle op 说了 2 种情况啊,我说的明显是解决第一种情况,回调超时的话处理更简单。
    markgor
        33
    markgor  
       2023-03-05 14:21:26 +08:00
    不太理解,为何支付渠道超时时间不能解决该问题?
    假设系统订单超时时间为 5 分钟;

    创建订单 09:00:00
    用户点支付
    判断当前时间是否超出 09:05:00 ,如果超过返回失败并 void 订单;
    如果没超过,则用 09:05:00 - 现在时间 作为支付时间传递给支付渠道;

    哪怕上面的操作有毫秒级的时间差,导致订单支付成功,但系统订单已经超时,此时回调时候判断下订单状态,如果是超时则走退款流程全款退还。
    Outshine
        34
    Outshine  
    OP
       2023-03-06 13:43:27 +08:00
    @Felldeadbird 那你们商品库存也是 4 小时候才释放回去?
    Outshine
        35
    Outshine  
    OP
       2023-03-06 13:44:28 +08:00
    @DinnyXu 那在订单快过期的时候去支付,用户的操作岂不是很极限?
    DinnyXu
        36
    DinnyXu  
       2023-03-06 14:03:34 +08:00
    @Outshine 微信唤起支付那个页面,系统是不可控的,你可以去试试
    Outshine
        37
    Outshine  
    OP
       2023-03-06 14:05:43 +08:00
    @markgor #33 你这个和 @DinnyXu 那个差不多,用户在订单快过期的时候去支付操作会很极限啊
    DinnyXu
        38
    DinnyXu  
       2023-03-06 14:12:03 +08:00
    @Outshine 你说的的订单过期用户操作很极限,我给你举例个场景,你看极限不。点击支付的时候,该笔订单需要在 5 秒内支付完成,5 秒内用户已经唤起支付了,但是输入密码最后一位的时候,已经超过 5 秒了,但是这个订单其实也属于超时了对不。
    DinnyXu
        39
    DinnyXu  
       2023-03-06 14:15:21 +08:00
    @Outshine 支付这一块,如果不想用户超时,第一个要规避的是唤起支付那用户输入密码可能会超时,还有一种是三方回调的时候可能会超时,因为根据你的说明是在回调后扣减库存,表示该笔订单已完成。回调这个地方你不能太依赖三方。特别是做这种限时的订单
    Felldeadbird
        40
    Felldeadbird  
       2023-03-06 16:19:47 +08:00
    @Outshine 是。因为我公司有一些特殊情况,客户会先下单,再过来取货。这时候店面的转 paid 。 而且这种订单锁了,再支付是一种极限状态。 不同公司有不同处理逻辑。所以我才说这个不应该程序解决,而是问上头用哪种方案。财务这玩意出问题了,你是要背锅的。
    markgor
        41
    markgor  
       2023-03-23 16:44:03 +08:00
    @Outshine 理解错题意,意思是支付结果回调时超时,而非支付前超时。
    支付结果回调一般都是秒级的,也会有特殊情况。
    这种方式没有高效避免,要么供货,要么取消订单。
    如果对稳定性要求高,可以申请专线,支付结果走专线通知,微信和支付宝有相应业务,找业务经理办理即可。
    markgor
        42
    markgor  
       2023-03-23 16:46:50 +08:00
    另外除了专线保证稳定外,还可以自己定时轮询取消单,
    比方你设置 10 秒超时时间,10 秒的时候主动发起订单结果查询,如果结果是成功的话那就供货,如果失败的话调用 void 单。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2501 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 01:32 · PVG 09:32 · LAX 17:32 · JFK 20:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.