订单支付功能对接支付宝支付接口「建议收藏」

订单支付功能对接支付宝支付接口「建议收藏」求助:这张GIF的效果动图整了一个多小时,没找到好的编辑软件,都太难用了。如果恰巧看到这篇文章有好的GIF编辑或者录制软件,请推荐一个!万谢订单支付功能是购物的最后一个环节,本文将通过对接支付宝的接口,实现支付宝付款功能。蚂蚁金服开放平台专门为开发者的网站,包含了支付宝中涉及的很多功能接口,本文的功能实现是在沙箱环境中进行,蚂蚁沙箱环境(Beta)是协助开发者进行接口功能开发及主要功能联

大家好,又见面了,我是你们的朋友全栈君。

求助:这张GIF的效果动图整了一个多小时,没找到好的编辑软件,都太难用了。如果恰巧看到这篇文章有好的GIF编辑或者录制软件,请推荐一 个!万谢

订单支付功能对接支付宝支付接口「建议收藏」

订单支付功能是购物的最后一个环节,本文将通过对接支付宝的接口,实现支付宝付款功能。蚂蚁金服开放平台专门为开发者的网站,包含了支付宝中涉及的很多功能接口,本文的功能实现是在沙箱环境中进行,蚂蚁沙箱环境(Beta)是协助开发者进行接口功能开发及主要功能联调的辅助环境。沙箱环境模拟了开放平台部分产品的主要功能和主要逻辑。在开发者应用上线审核前,开发者可以根据自身需求,先在沙箱环境中了解、组合和调试各种开放接口,进行开发调通工作,从而帮助开发者在应用上线审核完成后,能更快速、更顺利的进行线上调试和验收工作。

开发文档中给出了电脑支付接口的过程图

订单支付功能对接支付宝支付接口「建议收藏」

一、配置密钥

下载SDK

为了帮助开发者调用开放接口,提供了开放平台服务端SDK,包含JAVA、PHP和.NET三个语言版本,封装了签名&验签、HTTP接口请求等基础功能。但是支付宝没有提供Python的SDK,我们使用GitHub中的Python工具包(链接中有Python具体的实现方式),SDK的作用就是为了减少生成签名时容易出错,安装Python-Alipay-SDK在doc中输入pip install python-alipay –upgrade

开发者调用接口前需要先生成RSA密钥,RSA密钥包含应用私钥(APP_PRIVATE_KEY)、应用公钥(APP_PUBLIC_KEY)。生成密钥后在开放平台管理中心进行密钥配置,配置完成后可以获取支付宝公钥(ALIPAY_PUBLIC_KEY)。

生成密钥文件

openssl
OpenSSL> genrsa -out app_private_key.pem   2048  # 私钥
OpenSSL> rsa -in app_private_key.pem -pubout -out app_public_key.pem # 导出公钥
OpenSSL>exit

将app_public_key中的内容复制到沙箱应用中

订单支付功能对接支付宝支付接口「建议收藏」

订单支付功能对接支付宝支付接口「建议收藏」

将刚刚生成的私钥和支付宝公钥放到项目目录下。

二、搭建和配置开发环境

调用接口

订单支付功能对接支付宝支付接口「建议收藏」

支付接口(alipay.trade.page.pay):

  1. 商户系统请求支付宝接口alipay.trade.page.pay,支付宝对商户请求参数进行校验,而后重定向至用户登录页面。
  2. 用户确认支付后,支付宝get请求returnUrl(商户入参传入),返回同步返回参数。
  3. 交易成功后,支付宝post请求notifyUrl(商户入参传入),返回异步通知参数。
  4. 若由于网络等问题异步通知没有到达,商户可自行调用alipay.trade.query接口进行查询,根据查询接口获取交易以及支付信息(商户也可以直接调用查询接口,不需要依赖异步通知)。

视图中的处理函数

# post
def order_pay(request):
    '''订单支付'''
    # 用户登录判断
    if not request.session.has_key('islogin'):
        return JsonResponse({'res':0, 'errmsg':'用户未登录'})

    # 接收订单id
    order_id = request.POST.get('order_id')

    # 数据校验
    if not order_id:
        return JsonResponse({'res':1, 'errmsg':'订单不存在'})

    try:
        order = OrderInfo.objects.get(order_id=order_id,
                                      status=1,
                                      pay_method=3)
    except OrderInfo.DoesNotExist:
        return JsonResponse({'res':2, 'errmsg':'订单信息出错'})

    # 和支付宝进行交互
    alipay = AliPay(
        appid="2016090800464202", # 应用id
        app_notify_url=None,  # 默认回调url
        app_private_key_path=os.path.join(settings.BASE_DIR, 'df_order/app_private_key.pem'),
        alipay_public_key_path=os.path.join(settings.BASE_DIR, 'df_order/alipay_public_key.pem'),  # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
        sign_type = "RSA2",  # RSA 或者 RSA2
        debug = True,  # 默认False
    )

    # 电脑网站支付,需要跳转到https://openapi.alipaydev.com/gateway.do? + order_string
    total_pay = order.total_price + order.transit_price # decimal
    order_string = alipay.api_alipay_trade_page_pay(
        out_trade_no=order_id, # 订单id
        total_amount=str(total_pay),
        subject='天天生鲜%s'%order_id,
        return_url=None,
        notify_url=None  # 可选, 不填则使用默认notify url
    )
    # 返回应答
    pay_url = settings.ALIPAY_URL + '?' + order_string
    return JsonResponse({'res':3, 'pay_url':pay_url, 'message':'OK'})

将支付结果通过查询接口返回

# post
def check_pay(request):
    '''获取用户支付的结果'''
    # 用户登录判断
    if not request.session.has_key('islogin'):
        return JsonResponse({'res': 0, 'errmsg': '用户未登录'})

    passport_id = request.session.get('passport_id')
    # 接收订单id
    order_id = request.POST.get('order_id')

    # 数据校验
    if not order_id:
        return JsonResponse({'res': 1, 'errmsg': '订单不存在'})

    try:
        order = OrderInfo.objects.get(order_id=order_id,
                                      passport_id=passport_id,
                                      pay_method=3)
    except OrderInfo.DoesNotExist:
        return JsonResponse({'res': 2, 'errmsg': '订单信息出错'})

    # 和支付宝进行交互
    alipay = AliPay(
        appid="2016090800464202",  # 应用id
        app_notify_url=None,  # 默认回调url
        app_private_key_path=os.path.join(settings.BASE_DIR, 'df_order/app_private_key.pem'),
        alipay_public_key_path=os.path.join(settings.BASE_DIR, 'df_order/alipay_public_key.pem'),
        # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
        sign_type="RSA2",  # RSA 或者 RSA2
        debug=True,  # 默认False
    )

    while True:
        # 进行支付结果查询
        result = alipay.api_alipay_trade_query(order_id)
        code = result.get('code')
        if code == '10000' and result.get('trade_status') == 'TRADE_SUCCESS':
            # 用户支付成功
            # 改变订单支付状态
            order.status = 2 # 待发货
            # 填写支付宝交易号
            order.trade_id = result.get('trade_no')
            order.save()
            # 返回数据
            return JsonResponse({'res':3, 'message':'支付成功'})
        elif code == '40004' or (code == '10000' and result.get('trade_status') == 'WAIT_BUYER_PAY'):
            # 支付订单还未生成,继续查询
            # 用户还未完成支付,继续查询
            time.sleep(5)
            continue
        else:
            # 支付出错
            return JsonResponse({'res':4, 'errmsg':'支付出错'})

前端的post提交 

 <script>
    $(function () {
        $('.oper_btn').click(function () {
            // 获取订单id和订单的状态
            order_id = $(this).attr('order_id')
            order_status = $(this).attr('order_status')   //attr获取自定义的选择器
            csrf = $('input[name="csrfmiddlewaretoken"]').val()   //csrf防御
            params = {'order_id':order_id, 'csrfmiddlewaretoken':csrf}
            if (order_status == 1){
                $.post('/order/pay/', params, function (data) {
                    if (data.res == 3){
                        // 把用户引导支付页面
                        window.open(data.pay_url)
                        // 查询用户的支付结果
                        $.post('/order/check_pay/', params, function (data) {
                            if (data.res == 3){
                                alert('支付成功')
                                // 重新刷新页面
                                location.reload()
                            }
                            else{
                                alert(data.errmsg)
                            }
                        })
                    }
                    else{
                        alert(data.errmsg)
                    }
                })
            }
        })
    })
    </script>

在setting配置alipay的沙箱网址URL

ALIPAY_URL='https://openapi.alipaydev.com/gateway.do'


总结:支付的过程其实大部分都是支付宝内部封装好的功能完成,我们只是调用了支付和查询接口,将参数通过接口传递进去,我们不需要知道支付宝内部怎么实现,就完成了支付收付款的功能。除了支付接口,支付宝还提供了很多免费的接口,如店铺、芝麻信用、生活服务等,通过这些接口我们可以做很多功能的实现,接口和文档链接:点击打开链接点击打开链接

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/134853.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • python程序化交易实例-用 Python 实现你的量化交易策略「建议收藏」

    python程序化交易实例-用 Python 实现你的量化交易策略「建议收藏」Python的学习者中,有相当一部分是冲着爬虫去的。因为爬虫可以帮你解决很多工作和生活中的问题,节约你的生命。不过Python还有一个神秘而有趣的应用领域,那就是量化交易。量化交易,就是以数学模型替代人的主观判断来制定交易策略。通常会借助计算机程序来进行策略的计算和验证,最终也常直接用程序根据策略设定的规则自动进行交易。Python由于开发方便,工具库丰富,尤其科学计算方面的支持很强大,所…

    2022年10月8日
    0
  • 原生JS 实现页面元素的拖动 拖拽

    原生JS 实现页面元素的拖动 拖拽原生JS实现页面元素的拖拽1.

    2022年6月22日
    84
  • 不止一个背包的背包问题_背包问题 java

    不止一个背包的背包问题_背包问题 java有 N 个物品和一个容量是 V 的背包。物品之间具有依赖关系,且依赖关系组成一棵树的形状。如果选择一个物品,则必须选择它的父节点。如下图所示:如果选择物品5,则必须选择物品1和2。这是因为2是5的父节点,1是2的父节点。每件物品的编号是 i,体积是 vi,价值是 wi,依赖的父节点编号是 pi。物品的下标范围是 1…N。求解将哪些物品装入背包,可使物品总体积不超过背包容量,且总价值最大。输出最大价值。输入格式第一行有两个整数 N,V,用空格隔开,分别表示物品个数和背包容量。接下来有 N

    2022年8月9日
    1
  • eplan激活码破解步骤 win10_通用破解码[通俗易懂]

    eplan激活码破解步骤 win10_通用破解码,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月16日
    441
  • eclipse+selenium谷歌浏览器驱动配置

    eclipse+selenium谷歌浏览器驱动配置1.各种Selenium-java的包都在此网址http://www.seleniumhq.org/download/2.各种浏览器驱动的下载地址:3.尤其注意浏览器驱动与浏览器版本之间的匹配情况,还有注意驱动与selenium之间的匹配情况火狐暂时还没有配置成功,这里记录谷歌的匹配情况1.查看谷歌浏览器版本2.谷歌驱动,见百度网盘3.将谷歌驱动放到谷歌浏览

    2022年5月31日
    58
  • aic准则和bic准则_用户故事准则

    aic准则和bic准则_用户故事准则aic准则和bic准则免责声明:这篇文章摘自内部Codurance文档,该文档用于帮助我们的学徒学习我们的工作方式。我们都知道每个项目都是不同的,而且我们绝不能在任何地方应用完全相同的技术和实践。但是,以下文字不仅作为基础,而且还是我们所有人涉及用户故事时的指南。有很多关于用户故事的好书和帖子。这篇文章绝不是该领域所有良好实践的总结。用户故事是收集需求,就需要完成的事情达成共识…

    2022年5月24日
    42

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号