第三方应用对接支付宝支付业务(详细版)

       在第三方应用里开发者的身份大多是服务商,需要代商家调用接口完成收款业务。之前我以为支付业务只需要传交易金额,订单号,交易双方的支付宝账号和在支付宝开放平台申请到的appId, 应用私钥, 支付宝公钥调用接口就可以了。仔细阅读过官方API文档后我发现订单交易并不是通过传入交易双方的支付宝账号。传入交易双方支付宝账号通常适用于支付宝双方转账场景(提现,分佣等)。商家自研应用需要传入appId实现收款,应用私钥和支付宝公钥在数据传输过程中对接口信息进行加解密(防止被人截获和篡改数据)。在第三方应用中存在一个非常重要的问题,相对于商家自研应用,服务商需要代商家调用支付接口,不能通过传入支付宝账号,怎么才能满足每个商家的支付需求,把款打到商家对应的账户上呢?支付宝开放平台给出了相关文档说明。

小程序文档 - 支付宝文档中心 通过用户授权获取用户信息以及拿到openId

                                                    图一  第三方应用邀请商家授权

                                                      图二 获取app_auth_token业务流程图

在找到上面的文档研究过后,我的思路清晰了很多,我们进入到第三方应用后台按照流程完整的进行一遍操作。

1.我们进入第三方应用后台依次点击"商家授权"->邀请商家授权按钮

2.点击后我们进入到"邀请商家授权"的页面,可以看到有通过二维码和链接的两种方式,我们可以把二维码和PC端链接渲染到我们应用当中,让商家扫码进行授权。这里我们以在浏览器输入PC端链接为例。

3.打开PC端链接,我们选择要授权应用,勾选服务条款,点击"确认处理代办"按钮

4.商家授权成功后会自动打开授权回调地址,app_auth_code会同时拼接到路由中。授权回调地址在第三方应用后台开发设置中进行配置,商家授权后会自动跳转到回调地址,并且以路由传参的方式把参数传过来。因此该授权回调地址必须存在且部署到服务器上。

5.在邀请商家授权后我们能看到app_auth_code已经传到了回调地址中。接下来我们需要写好程序在页面中拿到这些路径参数,页面打开时将这些参数传到后端换取app_auth_token。

下面附上我的页面源代码:

<script setup lang="ts">
import { useRoute } from 'vue-router'
import { onMounted, ref } from 'vue';

import request from '../utils/request'
let sellerId = ref('1807335124124164098')
const route = useRoute()
onMounted(() => {
    console.log('code:' +route.query.app_auth_code)
    console.log('appId:' +route.query.app_id)
    console.log('source:' +route.query.source)



    // 调用后端接口, 以app_auth_code换取app_auth_token
    request.get('/updateToken', { params: { authCode: route.query.app_auth_code, sellerId: sellerId.value } })
})
</script>

<template>
<div class="getCode">
    商家授权成功
</div>
</template>

<style scoped lang="scss">
.getCode {
    width: 100vw;
}
</style>

6.后端拿到app_auth_code后需要参照官方文档换取app_auth_token,拿到app_auth_token后我们还需要将app_auth_token存入数据库中便于调用支付接口。下面附上我的后端源代码:

6.1.Maven依赖:

        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.39.113.ALL</version>
        </dependency>

6.2.控制层代码

    /**
     * 
     * @param authCode
     * @param sellerId  对应我数据库中表的主键ID,便于更新app_auth_token到商家表中
     * @return
     * @throws AlipayApiException
     */
    @GetMapping("/updateToken")
    public Result updateToken (String authCode, Long sellerId) throws AlipayApiException {
        sellerService.updateToken(authCode, sellerId);
        return Result.success();
    }

6.3.业务层代码

public void updateToken(String authCode, Long sellerId) throws AlipayApiException {
        AliPayConfig aliPayConfig = new AliPayConfig();
        AlipayClient alipayClient = new             
        DefaultAlipayClient("https://openapi.alipay.com/gateway.do", aliPayConfig.getAppId(), aliPayConfig.getPrivateKey(), "json", "GBK", aliPayConfig.getPublicKey(), "RSA2");

        // 构造请求参数以调用接口
        AlipayOpenAuthTokenAppRequest request = new AlipayOpenAuthTokenAppRequest();
        AlipayOpenAuthTokenAppModel model = new AlipayOpenAuthTokenAppModel();

        // 设置授权方式
        model.setGrantType("authorization_code");

        // 设置应用授权码
        model.setCode(authCode);

        // 设置刷新令牌
//        model.setRefreshToken("201509BBdcba1e3347de4e75ba3fed2c9abebE36");

        request.setBizModel(model);
        // 第三方代调用模式下请设置app_auth_token
        // request.putOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->");

        AlipayOpenAuthTokenAppResponse response = alipayClient.execute(request);
        System.out.println(response.getBody());

        if (response.isSuccess()) {
            System.out.println("调用成功");
            sellerMapper.updateToken(response.getAppAuthToken(), response.getAuthAppId(), sellerId);
        } else {
            System.out.println("调用失败");
            // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
            // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
            // System.out.println(diagnosisUrl);
        }
    }

6.4.dao层代码

void updateToken(@Param("appAuthToken") String appAuthToken, @Param("authAppId") String authAppId, @Param("sellerId") Long sellerId);
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace= "com.example.springboot.mapper.SellerMapper">

    <update id="updateToken">
        update seller set auth_token = #{appAuthToken}, app_id = #{authAppId}
            where id = #{sellerId}
    </update>
</mapper>

7.通过上面的演示我们已经获取到了app_auth_token并且存到了数据库中。现在思考一个问题,为什么能把app_auth_token存到数据库里呢,这么重要的参数不会一直更新嘛?

                                                app_auth_token有效期说明

根据官方对app_auth_token的解释,可见把app_auth_token插入数据库是必要也是可行的。

有一种情况就是服务商向商家提供新的业务,需要商家再授予新的权限。商家再次扫码对应用重新授权,这个时候原来的app_auth_token会失效,生成一个新的app_auth_token。但是我们每次都能通过商家登录账号拿到商家ID,商家重新授权后也是可以马上对数据库进行更新的,只是把上面的流程重复走了一遍。

有了以上的铺垫我们就可以在代商家调用接口的时候通过设置入参app_auth_token完成业务需求啦。

         request.putOtherTextParam("app_auth_token", authToken);

      最后简单介绍一下我自己吧。我,是一名本科生。在暑期实习期间因为公司有支付业务的需求以服务商的身份学习了支付宝开放平台的相关文档,在实践中遇到了很多困惑也真正有了很多体会。发布这篇文章希望可以真正帮助到大家。同时如果有不严谨的地方也欢迎各位指正。

星光不负赶路人。不论梦想有多遥远,只要坚持不懈,就一定能实现自己的理想。加油!

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对接支付宝接口涉及到前后端的交互,具体步骤如下: 1. 在支付宝开放平台注册开发者账号,并创建应用获取应用的AppID、公钥、私钥等信息。 2. 后端(Spring Boot)部分: - 引入支付宝SDK,可以使用官方提供的SDK或者第三方封装的SDK。 - 在应用配置文件中配置支付宝相关参数,如AppID、公钥、私钥等。 - 编写接口用于生成支付宝订单信息,并将订单信息返回给前端。 - 编写接口用于接收支付宝异步通知,验证支付结果并处理业务逻辑。 - 编写接口用于查询订单状态等其他操作。 3. 前端(Vue)部分: - 使用支付宝提供的前端组件,如扫码支付组件、H5支付组件等。 - 在前端页面中引入支付宝提供的组件,并配置相关参数,如AppID、订单信息等。 - 编写逻辑处理用户支付成功或失败的回调方法,并提示用户支付结果。 4. 后端与前端通信: - 后端提供生成订单信息的接口,前端调用该接口获取订单信息。 - 前端将订单信息传递给支付宝前端组件,并完成支付操作。 - 支付宝将支付结果以异步通知的形式发送给后端,后端接收并验证支付结果。 - 后端处理支付结果,更新订单状态等业务逻辑。 需要注意的是,在实际操作中还需要考虑安全性、异常处理、日志记录等方面的内容,以确保支付流程的稳定和安全。同时,支付宝也提供了详细的开发文档和示例代码,可以参考官方文档进行具体操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值