有图有派 2024-01-17 15:08 采纳率: 65.8%
浏览 3
已结题

Django实现的支付回调问题(有偿求解)

对支付的不熟悉导致如下问题:
1.如果只是打开二维码,不扫描(也就是用户不支付),当JS中的定时器走完,数据库已经改变了其状态值了.

2.如果扫描二维码并支付,前端没有卸载掉弹出层,也没有任何友好提示,同时 数据库里的数据改变了状态

3.当我手动关闭弹出层,回调还在执行
此问题价值20,当然是我成功测试后支付,谢谢大家!

#支付回调
def callback(request):
    mch_id="XXXXXXXX"#商户号
    out_trade_no=request.session.get("out_trade_no")
    param={"mch_id":mch_id,"out_trade_no":out_trade_no}
    sign=generate_sign(param)
    result=requests.get("https://api.pay.yungouos.com/api/system/order/getPayOrderInfo?out_trade_no={}&mch_id={}&sign={}".format(out_trade_no,mch_id,sign))
    res_obj=result.json()
    code=res_obj["code"]
    if code==0:
        data=res_obj["data"]
        money=data["money"]
        today = datetime.now().date()
        if money=="0.01":
            extime = "一个月"
            days = 30
            formatd = member_month()
            uid = request.session.get("user_info")
            ismember = Users.objects.get(UserPhone=uid)
            ismember.IsMember = "yes"
            ismember.MemberTime = days
            ismember.MemberExpirationDate = formatd
            ismember.save()
            info = Info()
            info.UserPhone = uid
            info.InfoContent = "同学,你于{}购买了{}会员".format(today, extime)
            info.save()
            success="success"
        elif money =="99.8":
            extime = "一年"
            days = 365
            formatd = member_year()
            uid = request.session.get("user_info")
            ismember = Users.objects.get(UserPhone=uid)
            ismember.IsMember = "yes"
            ismember.MemberTime = days
            ismember.MemberExpirationDate = formatd
            ismember.save()
            info = Info()
            info.UserPhone = uid
            info.InfoContent = "同学,你于{}购买了{}会员".format(today, extime)
            info.save()
            success="success"
        elif money =="79.8":
            extime = "3个月"
            days = 90
            formatd = member_3month()
            uid = request.session.get("user_info")
            ismember = Users.objects.get(UserPhone=uid)
            ismember.IsMember = "yes"
            ismember.MemberTime = days
            ismember.MemberExpirationDate = formatd
            ismember.save()
            info = Info()
            info.UserPhone = uid
            info.InfoContent = "同学,你于{}购买了{}会员".format(today, extime)
            success="success"
            data={"success":success}
            return JsonResponse(data=data)
    if code==1:
        data={"error":error}
        return JsonResponse(data=data)
    return render(request,'index/membershipprice.html')

<script type="text/javascript">
    $(".pay_member").click(function () {//点击购买按钮
        var member_price = $(this).val();//获取到价格
        var loadingLayer; // 定义加载层变量
        $.ajax({
            type: "GET",
            url: "/payformen/",
            data: { "member_price": member_price },
            beforeSend: function () {
                loadingLayer = layer.open({
                    type: 3,
                    shadeClose: false
                });
            },
            success: function (res) {
                layer.close(loadingLayer); // 关闭加载层
                if (res.code === 200) {//如果后台返回200,则将后台返回的二维码地址在Layer里打开,等待用户扫描二维码
                    var qrCodeLayer = layer.open({
                        type: 1,
                        area: ["250px", "300px"],//width*height
                        title: "等待支付",
                        shadeClose: false,
                        resize: false,
                        moveType: 1,
                        content: '<div><img src="' + res.pay_address + '"></div><div id="loadingText">请等待用户支付</div>',
                    });
                    // 使用定时器轮询支付状态
                    var interval = setInterval(function () {
                        $.ajax({
                            type: "GET",
                            url: "/callback/",
                            success: function (data) {
                                if (data == "success") {
                                    clearInterval(interval);
                                    layer.close(qrCodeLayer); // 关闭二维码弹出层
                                    weui.topTips("<span style='font-size: 20px;color:#ffffff'>购买成功!</span>");
                                }
                            },
                            error: function (data) {
                                if (data === "error") {
                                    clearInterval(interval);
                                    layer.close(qrCodeLayer); // 关闭二维码弹出层
                                    weui.topTips("<span style='font-size: 20px;color:#ffffff'>购买失败!</span>");
                                }
                            }
                        });
                    }, 11000);
                } else if (res.code === 500) {
                    weui.topTips("<span style='font-size: 20px;color:#ffffff'>同学,你还没登录.</span>")
                } else if (res.code == 300) {
                    weui.topTips("<span style='font-size: 20px;color:#ffffff'>同学,你已经是会员了.</span>")
                }
            },
            error: function (data) {
                layer.close(loadingLayer); // 关闭加载层
                weui.topTips("<span style='font-size: 20px;color:#ffffff'>请求失败</span>");
            }
        });
    });
</script>

  • 写回答

7条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-01-17 15:08
    关注

    引自免费微信小程序:皆我百晓生

    问题1:如果只是打开二维码,不扫描(也就是用户不支付),当JS中的定时器走完,数据库已经改变了其状态值了。

    • 问题原因: 当用户只是打开二维码而不扫描支付时,前端JS会启动一个定时器用以轮询支付状态,但没有处理用户不支付的情况,导致数据库的状态值被修改。
    • 解决方案: 在定时器回调函数中,应检查支付状态是否已经改变,如果未改变则不进行下一步处理。代码示例:
    var interval = setInterval(function () {
        $.ajax({
            type: "GET",
            url: "/callback/",
            success: function (data) {
                if (data == "success") {
                    clearInterval(interval);
                    layer.close(qrCodeLayer); // 关闭二维码弹出层
                    weui.topTips("<span style='font-size: 20px;color:#ffffff'>购买成功!</span>");
                } else if (data == "noChange") { // 新增处理未支付情况
                    clearInterval(interval);
                    layer.close(qrCodeLayer); // 关闭二维码弹出层
                    weui.topTips("<span style='font-size: 20px;color:#ffffff'>用户未支付!</span>");
                }
            },
            error: function (data) {
                if (data === "error") {
                    clearInterval(interval);
                    layer.close(qrCodeLayer); // 关闭二维码弹出层
                    weui.topTips("<span style='font-size: 20px;color:#ffffff'>购买失败!</span>");
                }
            }
        });
    }, 11000);
    

    问题2:如果扫描二维码并支付,前端没有卸载掉弹出层,也没有任何友好提示,同时数据库里的数据改变了状态。

    • 问题原因: 当用户扫描二维码并支付时,前端没有及时卸载弹出层,也没有提供友好提示,导致用户界面不友好。
    • 解决方案: 在支付成功后,应在前端代码中卸载弹出层并给出友好的提示。代码示例:
    success: function (data) {
        if (data == "success") {
            clearInterval(interval);
            layer.close(qrCodeLayer); // 关闭二维码弹出层
            weui.topTips("<span style='font-size: 20px;color:#ffffff'>购买成功!</span>");
        }
    }
    

    问题3:当我手动关闭弹出层,回调还在执行。

    • 问题原因: 当用户手动关闭弹出层时,回调函数仍在进行轮询支付状态的操作,没有停止。
    • 解决方案: 在手动关闭弹出层时,应停止定时器,即清除对应的interval。代码示例:
    layer.close(qrCodeLayer); // 关闭二维码弹出层
    clearInterval(interval); // 停止定时器
    

    综上所述,根据你提供的代码和问题,以上是对三个问题的解决方案。如果你有其他问题或需要进一步帮助,请随时告诉我。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 1月17日
  • 创建了问题 1月17日

悬赏问题

  • ¥15 想问一下树莓派接上显示屏后出现如图所示画面,是什么问题导致的
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号