IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 支付宝沙箱支付 -> 正文阅读

[开发测试]支付宝沙箱支付

注意区分支付宝同步通知和异步通知

同步通知:不能判断是否支付成功,用来支付完成后跳转页面
异步通知:需要外网可以访问,支付宝发送post请求的地址,可以判断是否支付成功,从而做业务上的持久层操作

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

AliPayConfig 支付宝参数配置类

public class AlipayConfig {
	// APPID
	public static String app_id = "";
	// 商户私钥
    public static String merchant_private_key ="";
    // 支付宝公钥
    public static String alipay_public_key ="";
    // 异步通知地址,这个地址需要外网可以访问,如果要本地调试则要进行内网穿透
	public static String notify_url = "ip+端口/notify_url";
	// 同步通知地址,不需要外网可以访问,只用来支付完成跳转页面,不能判断是否支付成功
	public static String return_url = "ip+端口/return_url";
	// 签名方式
	public static String sign_type = "RSA2";
	// 字符编码格式
	public static String charset = "utf-8";
	// 支付宝网关
	public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
}

AliPayUtil 工具类

@Slf4j
public class AliPayUtil {
    public static AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);

    /**
     * 转码
     * @param param
     * @return
     */
    public static String getByte(String param) {
        try {
            return new String(param.getBytes("ISO-8859-1"), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 校验签名
     * @param request
     * @return
     */
    public static boolean rsaCheckV1(HttpServletRequest request) {
        Map<String, String> params = new HashMap<>();
        Map requestParams = request.getParameterMap();
        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] + ",";
            }
            params.put(name, valueStr);
        }
        try {
            boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);
            return signVerified;
        } catch (AlipayApiException e) {
            log.debug("verify sigin error, exception is:{}", e);
            return false;
        }
    }
}

AliPayController 接口
这里没有写业务层和持久层,只是做了模拟操作

package com.yyx.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.request.*;

import com.yyx.config.AliPayConfig;
import com.yyx.utils.AliPayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@Slf4j
@RestController
public class AliPayController {


    /**
     * 调起支付
     * @return
     * @throws AlipayApiException
     */
    @GetMapping(value = "/toAlipay", produces = "text/html; charset=UTF-8")
    public String goAlipay() throws  AlipayApiException {
        AlipayClient alipayClient = AliPayUtil.alipayClient;
        // 订单模型
        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
        //本地订单号
        model.setOutTradeNo(String.valueOf(System.currentTimeMillis()));
        //订单标题
        model.setSubject("支付测试");
        //订单总价格
        model.setTotalAmount("0.01");
        //产品描述
        model.setBody("买不了吃亏买不了上当");
        //产品码,这个不变
        model.setProductCode("FAST_INSTANT_TRADE_PAY");

        AlipayTradePagePayRequest pagePayRequest = new AlipayTradePagePayRequest();
        //同步通知地址
        pagePayRequest.setReturnUrl(AliPayConfig.return_url);
        //异步通知地址
        pagePayRequest.setNotifyUrl(AliPayConfig.notify_url);
        pagePayRequest.setBizModel(model);
        //请求
        String result = alipayClient.pageExecute(pagePayRequest).getBody();
        return result;
    }

    /**
     * 同步回调,用来跳转页面
     * @param request
     * @return
     */
    @GetMapping("/return_url")
    public String return_url(HttpServletRequest request){
        log.info("=》》》》》进入同步通知接口------");
        // 验签
        boolean verifyResult = AliPayUtil.rsaCheckV1(request);
        if (verifyResult) {
            //商户订单号
            String out_trade_no = AliPayUtil.getByte(request.getParameter("out_trade_no"));
            //支付宝交易号
            String trade_no = AliPayUtil.getByte(request.getParameter("trade_no"));
            log.info("商户订单号,支付宝交易号", out_trade_no, trade_no);
            /*
            注意:这里并不能得到用户是否支付成功,而是在异步通知里判断是否支付成功,从而做业务处理调用持久层
             */
            return "支付成功页面";
        }
        return "支付失败页面";
    }

    /**
     * 异步回调,该接口需要外网可以访问
     * @param request
     * @return
     * @throws IOException
     * @throws AlipayApiException
     */
    @PostMapping("/notify_url")
    public String notify_url(HttpServletRequest request){
        log.info("=》》》》》支付成功, 进入异步通知接口------");
        // 一定要验签,防止黑客篡改参数
        boolean flag = AliPayUtil.rsaCheckV1(request);
        if (flag) {
            //交易状态
            String tradeStatus = AliPayUtil.getByte(request.getParameter("trade_status"));
            // 商户订单号
            String out_trade_no = AliPayUtil.getByte(request.getParameter("out_trade_no"));
            //支付宝交易号
            String trade_no = AliPayUtil.getByte(request.getParameter("trade_no"));
            //付款金额
            String total_amount = AliPayUtil.getByte(request.getParameter("total_amount"));
            log.info("交易状态,商户订单号,支付宝交易号,付款金额", tradeStatus, out_trade_no, trade_no, total_amount);
            if (tradeStatus.equals("TRADE_SUCCESS")) {
                /*
                支付成功,这里做业务上的持久层操作
                 */
            }
            //必须返回success和fail,这样支付宝才能判断异步回调接口是否调用成功,否则会一直向异步回调地址发请求直到收到响应
            return "success";
        }
        return "fail";
    }
}

访问接口测试

http://localhost:8080/goAlipay

观察日志信息,看是否成功调起同步通知和异步通知
在这里插入图片描述

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-08-22 13:48:14  更:2021-08-22 13:48:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 8:04:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码