对接支付宝流程【网页支付,手机网页支付,APP支付】

支付的大体流程

在这里插入图片描述

配置应用、

在这里插入图片描述

APPID

注册完成以后添加应用就可以获得,没有可以使用沙箱模式中提供的测试应用
在这里插入图片描述

在这里插入图片描述
然后根据需求签约功能,开启使用,功能【添加能力】

支付宝网关(固定)

应用网关(可选)

回调地址

在这里插入图片描述

支付回调地址,支付以后,支付宝会将支付结果进行请求传达到我们定义的回调地址之上,这个地址必须是线上我们开发好的一个接口,用以接收支付结果;

商家私钥&支付宝公钥

支付宝采用RSA非对称性加密以保证数据的安全,这里我们可以使用支付宝提供的密钥生成工具进行生成
步骤如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如此便得到了应用公钥以及应用私钥
上面提到的商家私钥就是应用私钥这个参数了,两种称呼而已
支付宝公钥需要使用商家公钥(应用公钥)进行换取,
商家公钥换取流程:
网页与移动应用–>应用信息–>查看应用公钥–>验证信息
然后在此用我们刚才申请的应用公钥替换其中的内容,点击确认,此时会出现按钮查看支付宝公钥点击即可查看
在这里插入图片描述

业务对接

这里我们使用电脑pc网页支付以及app支付为例

pc网页支付

Controller部分

/**
 * 电脑网页支付
 * @throws IOException
 * @throws AlipayApiException
 */
@GetMapping("/pcPagePay")
public void pcPagePay() throws IOException, AlipayApiException {
    String oderId = UUID.randomUUID().toString();
    // 修改为以页面形式进行响应
    response.setContentType("text/html;charset=utf-8");
    // 获取响应目标
    PrintWriter writer = response.getWriter();
    // 将生成的支付页面展示给前端页面
    writer.write(pcPagePay.creatOder(oderId).getBody());
    // 执行关流
    flushAndClose(writer);
}

Service部分

/**
 * 获取支付页面
 */
public AlipayTradePagePayResponse creatOder(String oderId) throws AlipayApiException {
    // 填写基本信息
    AlipayClient alipayClient = new DefaultAlipayClient(
            payGetWay, // 支付宝网关,注意。沙箱环境的网关和正式环境有所不同,错误的当导致单号无效或者404
            appId, // appid就是我们注册应用的appid
            appPrivateKey, // app私钥
            "json", //
            charSet, // 字符集
            alipayPublicKey, // 阿里支付公钥
            "RSA2" // 加密方式
    );
    // 创建支付宝交易页面支付请求对象
    AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
    // 填入回调地址,支付成功以后支付结果将会响应到这里
    request.setNotifyUrl(notifyUrl);
    // 支付成功以后跳转的页面,页面跳转时同时也会携带支付结果参数,可填可不填
    request.setReturnUrl("https://www.baidu.com");
    // 创建请求体
    JSONObject bizContent = new JSONObject();
    // 填入商家方的唯一单号,稍后将用以保证订单不重复支付
    bizContent.put("out_trade_no", oderId);
    // 订单价格,精确到两位
    bizContent.put("total_amount", 0.01);
    // 商品标题
    bizContent.put("subject", "测试商品");
    // 产品代码
    bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
    //bizContent.put("time_expire", "2022-08-01 22:00:00");
     商品明细信息,按需传入
    //JSONArray goodsDetail = new JSONArray();
    //JSONObject goods1 = new JSONObject();
    //goods1.put("goods_id", "goodsNo1");
    //goods1.put("goods_name", "子商品1");
    //goods1.put("quantity", 1);
    //goods1.put("price", 0.01);
    //goodsDetail.add(goods1);
    //bizContent.put("goods_detail", goodsDetail);
     扩展信息,按需传入
    //JSONObject extendParams = new JSONObject();
    //extendParams.put("sys_service_provider_id", "2088511833207846");
    //bizContent.put("extend_params", extendParams);
    // 最后将信息写入请求对象
    request.setBizContent(bizContent.toString());
    // 执行请求创建支付页面
    AlipayTradePagePayResponse response = alipayClient.pageExecute(request);
    if (response.isSuccess()) {
        System.out.println("调用成功");
        // 调用成功则获得支付页面,其中的body即为页面信息,可以在这里get或者在用的时候再get。万万不可URL转码
        return response;
    } else {
        System.out.println("调用失败");
        throw new RuntimeException("支付调用失败");
    }
}

此时访问接口即可获取支付页面
在这里插入图片描述
在这里插入图片描述

APP支付

App支付的基本流程和网页支付差不多,区别就是不用响应页面到前端,我们将获取到的响应信息直接给前端进行响应,前端根据响应体中的包地址拉起支付宝。并附上参数,则可拉取支付信息
代码:
Controller部分

/**
 * app支付
 * @throws IOException
 * @throws AlipayApiException
 */
@GetMapping("/appPay")
public AlipayTradeAppPayResponse appPay() throws IOException, AlipayApiException {
    return appPay.creatOder(UUID.randomUUID().toString());
}

Service部分

public AlipayTradeAppPayResponse creatOder(String oderId) throws AlipayApiException {
    AlipayClient alipayClient = new DefaultAlipayClient(
            payGetWay,appId,appPrivateKey,"json",charSet,alipayPublicKey,"RSA2");
    AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
    request.setNotifyUrl(notifyUrl);
    JSONObject bizContent = new JSONObject();
    bizContent.put("out_trade_no", oderId);
    bizContent.put("total_amount", 0.01);
    bizContent.put("subject", "测试商品");
    bizContent.put("product_code", "QUICK_MSECURITY_PAY");
    //bizContent.put("time_expire", "2022-08-01 22:00:00");
     商品明细信息,按需传入
    //JSONArray goodsDetail = new JSONArray();
    //JSONObject goods1 = new JSONObject();
    //goods1.put("goods_id", "goodsNo1");
    //goods1.put("goods_name", "子商品1");
    //goods1.put("quantity", 1);
    //goods1.put("price", 0.01);
    //goodsDetail.add(goods1);
    //bizContent.put("goods_detail", goodsDetail);
     扩展信息,按需传入
    //JSONObject extendParams = new JSONObject();
    //extendParams.put("sys_service_provider_id", "2088511833207846");
    //bizContent.put("extend_params", extendParams);
    request.setBizContent(bizContent.toString());
    AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
    if(response.isSuccess()){
        System.out.println("调用成功");
        return response;
    } else {
        System.out.println("调用失败");
        throw new RuntimeException();
    }
}

参数都一样,就不做注释了,这里会获得一个AlipayTradeAppPayResponse将对象响应到前端即可完成后端流程;
前端可根据信息拉起支付宝进行支付

支付结果的回调通知

在用户完成支付以后,支付宝会对我们填写的回调地址进行通知请求,我们需要创建我们在回调中填写的接口进行接收参数
接口类型:POST
传参类型:FORMDATA
这里需要对请求进行验签,以保证支付结果的真实性;
验签代码

 @PostMapping("/notifyUr")
 public void notifyUr() throws AlipayApiException {
     // 创建结果集MAP
     Map<String, String> params = new HashMap<>();
     // 获取form表单参数
     Map requestParams = request.getParameterMap();
     log.info("回调触发了,请求体:{}", requestParams);
     // 遍历Map从新组合写入新Map
     for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
         String name = (String) iter.next();
         String[] values = (String[]) requestParams.get(name);
         String valueStr = "";
         // 不是最后一个就在结尾加个,号
         for (int i = 0; i < values.length; i++) {
             valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
         }
         //乱码解决,这段代码在出现乱码时使用。
         //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
         params.put(name, valueStr);
     }
     //切记alipaypublickey是支付宝的公钥,请去open.alipay.com对应应用下查看。
     //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
     boolean flag = AlipaySignature.rsaCheckV1
             (
                     params, // 取出的参数
                     alipayPublicKey, // 阿里支付公钥
                     charSet, // 字符集
                     "RSA2" // 加密方式 
             );
     if (!flag)
         throw new RuntimeException("验签未通过");
     log.info("验签通过");
     // 此时验签通过,params参数里包含了订单的所有参数,可以进行入库,
 }

支付完成时接口会被支付宝请求,
我们对其验签以后就可以执行自己的操作了

App支付包含一个同步通知,建议还是采用异步通知,同步通知仅作为支付结束的标志;
什么?你问我为啥?支付宝这么说的~
在这里插入图片描述

支付宝开放平台网站

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在uniapp对接支付宝,需要进行以下步骤: 1. 在支付宝开放平台创建应用并获取应用的APP_ID和私钥。 2. 在uniapp项目中引入支付宝JSAPI的SDK,可以使用支付宝官方提供的SDK或者第三方SDK。 3. 在uniapp项目中创建一个页面,用于发起支付请求。 4. 在发起支付请求的页面中,调用支付宝JSAPI的SDK进行支付。 以下是详细的流程: 1. 在支付宝开放平台创建应用并获取应用的APP_ID和私钥。 首先,你需要到支付宝开放平台注册并登录账号。 然后,创建一个应用并获取应用的APP_ID和私钥。在创建应用时,需要选择“移动应用”类型,并填写应用的基本信息。 创建完成后,可以在应用详情页中找到APP_ID和私钥。APP_ID是支付宝分配给应用的唯一标识符,私钥用于对支付请求进行签名。 2. 在uniapp项目中引入支付宝JSAPI的SDK。 支付宝官方提供了支付宝JSAPI的SDK,可以通过以下链接下载: https://docs.open.alipay.com/54/103419/ 第三方SDK也可以在GitHub等开源社区中找到。 将SDK文件拷贝到uniapp项目的static目录下,并在需要使用支付宝支付的页面中引入SDK。 例如,在页面的script标签中添加以下代码: ``` javascript import '@/static/alipay-sdk.js' ``` 3. 在uniapp项目中创建一个页面,用于发起支付请求。 在uniapp项目的pages目录下,创建一个新的页面,例如Pay.vue。这个页面用于展示订单信息和发起支付请求。 在Pay.vue中,需要定义一个支付按钮,点击按钮时触发支付请求。同时,需要将订单信息传递给支付宝SDK。 例如,可以在Pay.vue中添加以下代码: ``` html <template> <div> <div>订单金额:{{orderAmount}}</div> <div>订单描述:{{orderDesc}}</div> <button @click="goToPay">立即支付</button> </div> </template> <script> export default { data() { return { orderAmount: '100.00', orderDesc: '测试订单' } }, methods: { goToPay() { // TODO: 调用支付宝SDK进行支付 } } } </script> ``` 在goToPay方法中,需要调用支付宝SDK进行支付。具体实现方式见下一步。 4. 在发起支付请求的页面中,调用支付宝JSAPI的SDK进行支付。 在Pay.vue的goToPay方法中,需要调用支付宝SDK进行支付。 首先,需要将订单信息组装成一个JSON对象,并对该对象进行签名。签名过程需要使用应用的私钥。 例如,可以在goToPay方法中添加以下代码: ``` javascript goToPay() { const orderInfo = { app_id: '应用APP_ID', method: 'alipay.trade.app.pay', charset: 'utf-8', sign_type: 'RSA2', timestamp: new Date().toLocaleString(), version: '1.0', biz_content: JSON.stringify({ body: this.orderDesc, subject: this.orderDesc, out_trade_no: new Date().getTime().toString(), total_amount: this.orderAmount, product_code: 'QUICK_MSECURITY_PAY' }) } const sign = this.sign(orderInfo, '应用私钥') orderInfo.sign = sign } ``` 其中,sign方法用于对订单信息进行签名,具体实现可以参考支付宝官方文档。 接下来,需要调用支付宝SDK的pay方法,将签名后的订单信息作为参数传递给SDK。 例如,可以在goToPay方法中添加以下代码: ``` javascript goToPay() { // 组装订单信息并签名 const orderInfo = { app_id: '应用APP_ID', method: 'alipay.trade.app.pay', charset: 'utf-8', sign_type: 'RSA2', timestamp: new Date().toLocaleString(), version: '1.0', biz_content: JSON.stringify({ body: this.orderDesc, subject: this.orderDesc, out_trade_no: new Date().getTime().toString(), total_amount: this.orderAmount, product_code: 'QUICK_MSECURITY_PAY' }) } const sign = this.sign(orderInfo, '应用私钥') orderInfo.sign = sign // 调用支付宝SDK进行支付 window.AlipayJSBridge.call('tradePay', { orderStr: JSON.stringify(orderInfo) }, function(result) { // 支付结果处理 }) } ``` 其中,window.AlipayJSBridge.call方法用于调用支付宝SDK的pay方法,参数orderStr是签名后的订单信息。 支付结果通过回调函数返回,可以在回调函数中进行处理。 至此,uniapp对接支付宝流程就完成了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值