Springboot集成手机网站支付

一:简介

手机网站支付常用于HTML5应用,常见于微信公众号上的应用。手机网站支付文档,其实当我们下载下来demo的时候,基本上所有的代码都已经有了,我们所要做的就是集成到自己的项目里面

二:集成步骤

创建应用、配置密钥,这些准备步骤请看我先前写的准备集成支付宝的准备工作
1.创建项目,集成依赖

	<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        
<!-- alipay begin -->
<dependency>
    <groupId>com.alipay</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>20170725114550</version>
</dependency>
<dependency>
    <groupId>com.alipay</groupId>
    <artifactId>alipay-trade-sdk</artifactId>
    <version>20161215</version>
</dependency>
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
</dependency>
<dependency>
    <groupId>commons-configuration</groupId>
    <artifactId>commons-configuration</artifactId>
    <version>1.10</version>
</dependency>
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.2.1</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
<!-- alipay end -->

这里有支付包的jar,我们首先需要将jar包添加到我们的maven中,这里可以查看Maven添加本地jar包,这里我再告诉大家一个方法,直接将jar包拷贝到resources中,新建lib,将jar包放入lib中,然后将jar导入
在这里插入图片描述

2.yml配置
这里的公钥私钥肯定是要换成你自己对应的,异步访问地址必须是外网可访问的,所以这里可以使用natapp,可以参考Natapp使用

# 沙箱账号
pay:
  alipay:
    gatewayUrl: https://openapi.alipaydev.com/gateway.do
    appid: 2016091500517039
    appPrivateKey: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCveherLJtuz6kaIpjqK5UoIjCru4jLeCx9rCYDFGN8FIQEh0iHEHbEvZ15zb50wkuhBEFEoRkPLrsg/CdaYl2qQly+OoPqNqFgQhcRu1qYAjO8aJAlajOYaJkcrC67DUlAIsU/yl8j5tc8Ik5RYzN9BjT2zNIXRoxhwytCX5STJT2ZEvQfkFdG0Hduud5eFLGFuC/mhJU+rdP2i6KZsDluf73VYmqC0JUs3pX+bVS1IV85cWpS/7F7mNR7t9hYCMZ9UJa7NLxJhh5JElwgZRozF0rLIkSN4K04VL9IHxwBQU6mFvnyxLzpF9P4HdPbq3w1AVEGUWcF3OGnOS7qCNBTAgMBAAECggEAMmNp1oJ5o6lH0rRqmpunOh4PQdEZJ+w7Ql8jjzDUnHW7rx01y2sD39zfEnHtJdQBKZxyLYXhD0YJACDIICEs6k4iGZHt/VxwnJZ9z16wVgQT3R9dfRDw/evTQ7OBu77F8P/LClVPWpzX43GqcZ5904HrxY7tKTfd6djEXEvb+yB00ErHisCLvaC2QNDq5kXBqNc9qNdULfWEvHOnALdgw39Qk5cIaGLSs/y9L67RtqN0SwdxZDViJkKsf9uhgHvjPfeGJvmT8nsOZpwT/9Woh0BdHPkbpiyocBUf/XVUSjqWzG8PS0Hj/FGac3M4y2yYN68a8LziapT7wUkoty3RsQKBgQDwP3YhPeWgMnXaa9vySUXVdT8O7b7Vv8XGrnfV6P4nlUmgLQaej2l8ju2YqnfbDXOMpWN8r6TSMhaUlwXFFhEL5yllcSFenk42O3VPYqOhkJK2YhIEkFC2+nH8DpXl7m1Tp8U0D/wxMddFccW+oiUHwGL72T0GZZiAvttBD5bGaQKBgQC6+3TOIHHcQUCQjpjuJXoLTOZ3ENY4p/qVbGuFWYHMfLHIPnZgpHkv8vum9H205Bo6XV9ybKVKdWU1uXZu/yEnkHhZGW8bgG+giB432efT2JQqA75IIo8frkuriJSL0ixfx59iJHGhks0N8ieLCKuqK8u35a2rrrxM6D7i7N7hWwKBgGq954BxfdqlUNOQ5JJLl+l1RGUfoJBbukXCMqAp+vIfVC0ElFJSqa2b21jfNI1w9ovg18kISRTTCFFQoFGmskA1nqDhmM/vShSyajaxPr6D+4tpG1RHwnTp5Ub2PAeC3bQzcFznVUeOO3UxTYibhhRhmBkJtiFndlCNe+D2SikxAoGAQFKahwJQSPXFkTUM1PfdeR+2NIV9PDZFFLwcbN4ysba/reQW8v4BloYfHfsDd4P0pdlTKVjIr8mczJOFc3+e1y5yyCvgtfRD8lSBGLOEdbMOnTl2bvg8hih+bX7powPlMfnJEYj58hw/ICoKgmC0NTElvphrWyEcM9S9NXFI5vsCgYEAxnYChqJ+4VXuNBF9wc6oebRYgGYWMEv0uhqa/7A0o6vsvXrd7QtQTdyeYxpBQLcsFJkKc1n5MFsrSY6FAFTVmBPMnYfQwH0OAYxKfytles3wMVxWbAwJwtxhZ1n3nGFHCES8rwPSa+5xZe6vzpYVUTgnjBfr4QL3dlQJKj51a+0=
    alipayPublicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtHjQ2gD1juu9F5Hxr1oy5c8So9EC7G6OlK4rJf98kvFj1GaDxUp9/WY7YMThC1VqTZn+T9FiEO7CI8/EXjiF/4n64NYtJFOtT7dplmQwoVHE5dOvprfR1ugUbeHLcQlUvbctKELCDrUHTe3/p2rCIH7TwKQoUOpP6yunyHardPOddUJEC4C7wZ11KwzTDaa1pU3kLb0Z/0DEte63aEq3fyt1M5UFD5sQgN7FZuW3s7sy5jaIJgkZbNTIl/lpcrNjPGXxZmK6qfiiA8LSFgQj2A0UPSNtDLdUnO0I211tWRfUVVDzviIdV1T9k+JhlPhLsYGRFTvsa9cRgwWL/lt7BQIDAQAB
    returnUrl: http://zhouguoqing.natapp1.cc/alipay/wap/returnUrl
    notifyUrl: http://zhouguoqing.natapp1.cc/alipay/notify


spring:
  thymeleaf:
    prefix: classpath:/templates/
    suffix: .html
    mode: HTML5
    encoding: UTF-8

3.AlipayProperties的基础文件
这是我们需要用到的基本参数,参数已经放在yml配置文件中,这里我们使用注解去获取,以及前面的注解Data,是使用了lombok插件,这里可以查看使用lombok

@Data
@Slf4j
@ConfigurationProperties(prefix = "pay.alipay")
public class AlipayProperties {

    /** 支付宝gatewayUrl */
    private String gatewayUrl;
    /** 商户应用id */
    private String appid;
    /** RSA私钥,用于对商户请求报文加签 */
    private String appPrivateKey;
    /** 支付宝RSA公钥,用于验签支付宝应答 */
    private String alipayPublicKey;
    /** 签名类型 */
    private String signType = "RSA2";

    /** 格式 */
    private String formate = "json";
    /** 编码 */
    private String charset = "UTF-8";

    /** 同步地址 */
    private String returnUrl;

    /** 异步地址 */
    private String notifyUrl;

    /** 最大查询次数 */
    private static int maxQueryRetry = 5;
    /** 查询间隔(毫秒) */
    private static long queryDuration = 5000;
    /** 最大撤销次数 */
    private static int maxCancelRetry = 3;
    /** 撤销间隔(毫秒) */
    private static long cancelDuration = 3000;

    private AlipayProperties() {}

    /**
     * PostContruct是spring框架的注解,在方法上加该注解会在项目启动的时候执行该方法,也可以理解为在spring容器初始化的时候执行该方法。
     */
    @PostConstruct
    public void init() {
        log.info(description());
    }

    public String description() {
        StringBuilder sb = new StringBuilder("\nConfigs{");
        sb.append("支付宝网关: ").append(gatewayUrl).append("\n");
        sb.append(", appid: ").append(appid).append("\n");
        sb.append(", 商户RSA私钥: ").append(getKeyDescription(appPrivateKey)).append("\n");
        sb.append(", 支付宝RSA公钥: ").append(getKeyDescription(alipayPublicKey)).append("\n");
        sb.append(", 签名类型: ").append(signType).append("\n");

        sb.append(", 查询重试次数: ").append(maxQueryRetry).append("\n");
        sb.append(", 查询间隔(毫秒): ").append(queryDuration).append("\n");
        sb.append(", 撤销尝试次数: ").append(maxCancelRetry).append("\n");
        sb.append(", 撤销重试间隔(毫秒): ").append(cancelDuration).append("\n");
        sb.append("}");
        return sb.toString();
    }

    private String getKeyDescription(String key) {
        int showLength = 6;
        if (StringUtils.isNotEmpty(key) && key.length() > showLength) {
            return new StringBuilder(key.substring(0, showLength)).append("******")
                    .append(key.substring(key.length() - showLength)).toString();
        }
        return null;
    }
}


4.将基础的配置文件加入到Spring的Bean容器中
创建AlipayConfiguration

@Configuration
@EnableConfigurationProperties(AlipayProperties.class)
public class AlipayConfiguration {

    @Autowired
    private AlipayProperties properties;

    @Bean
    public AlipayTradeService alipayTradeService() {
        return new AlipayTradeServiceImpl.ClientBuilder()
                .setGatewayUrl(properties.getGatewayUrl())
                .setAppid(properties.getAppid())
                .setPrivateKey(properties.getAppPrivateKey())
                .setAlipayPublicKey(properties.getAlipayPublicKey())
                .setSignType(properties.getSignType())
                .build();
    }

    @Bean
    public AlipayClient alipayClient(){
        return new DefaultAlipayClient(properties.getGatewayUrl(),
                properties.getAppid(),
                properties.getAppPrivateKey(),
                properties.getFormate(),
                properties.getCharset(),
                properties.getAlipayPublicKey(),
                properties.getSignType());
    }
}


5.创建支付需要的Controller层
新建AlipayWAPPayController,这里我们只使用付款功能,其实其他的功能都类似

/**
 * @ Author     :Zgq
 * @ Date       :Created in 9:47 2019/5/31
 * @ Description:手机网站支付
 * @ Modified By:
 * @Version: $
 */

@RequestMapping("/phone")
@Controller
public class PhonePayController {

    @Autowired
    private AlipayConfig properties;


    /**
     * 跳转到支付页面
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping("goPay")
    public void goPay(HttpServletRequest request, HttpServletResponse response) throws Exception{
        if(request.getParameter("WIDout_trade_no")!=null){
            // 商户订单号,商户网站订单系统中唯一订单号,必填
            String out_trade_no = new String(request.getParameter("WIDout_trade_no").getBytes("ISO-8859-1"),"UTF-8");
            // 订单名称,必填
            String subject = new String(request.getParameter("WIDsubject").getBytes("ISO-8859-1"),"UTF-8");
            System.out.println(subject);
            // 付款金额,必填
            String total_amount=new String(request.getParameter("WIDtotal_amount").getBytes("ISO-8859-1"),"UTF-8");
            // 商品描述,可空
            String body = new String(request.getParameter("WIDbody").getBytes("ISO-8859-1"),"UTF-8");
            // 超时时间 可空
            String timeout_express="2m";
            // 销售产品码 必填
            String product_code="QUICK_WAP_WAY";
            /**********************/
            // SDK 公共请求类,包含公共请求参数,以及封装了签名与验签,开发者无需关注签名与验签
            //调用RSA签名方式
            //获得初始化的AlipayClient
            AlipayClient client = new DefaultAlipayClient(properties.getGatewayUrl(), properties.getApp_id(), properties.getMerchant_private_key(), "json", properties.getCharset(), properties.getAlipay_public_key(), properties.getSign_type());


            AlipayTradeWapPayRequest alipay_request=new AlipayTradeWapPayRequest();

            // 封装请求支付信息
            AlipayTradeWapPayModel model=new AlipayTradeWapPayModel();
            model.setOutTradeNo(out_trade_no);
            model.setSubject(subject);
            model.setTotalAmount(total_amount);
            model.setBody(body);
            model.setTimeoutExpress(timeout_express);
            model.setProductCode(product_code);
            alipay_request.setBizModel(model);
            // 设置异步通知地址
            alipay_request.setNotifyUrl(properties.getNotify_url());
            // 设置同步地址
            alipay_request.setReturnUrl(properties.getReturn_url());

            // form表单生产
            String form = "";
            try {
                // 调用SDK生成表单
                form = client.pageExecute(alipay_request).getBody();
                response.setContentType("text/html;charset=" + properties.getCharset());
                response.getWriter().write(form);//直接将完整的表单html输出到页面
                response.getWriter().flush();
                response.getWriter().close();
            } catch (AlipayApiException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    /**
     * 交易查询
     * @param request
     * @param trade_no
     * @param out_trade_no
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("query")
    public String query(HttpServletRequest request,String trade_no,String out_trade_no) throws Exception{

            //商户订单号,商户网站订单系统中唯一订单号,必填
            String out_trade_no1 = new String(out_trade_no.getBytes("ISO-8859-1"),"UTF-8");
            //支付宝交易号
            String trade_no1 = new String(trade_no.getBytes("ISO-8859-1"),"UTF-8");
            /**********************/
            // SDK 公共请求类,包含公共请求参数,以及封装了签名与验签,开发者无需关注签名与验签
            //获得初始化的AlipayClient
            AlipayClient client = new DefaultAlipayClient(properties.getGatewayUrl(), properties.getApp_id(), properties.getMerchant_private_key(), "json", properties.getCharset(), properties.getAlipay_public_key(), properties.getSign_type());

            AlipayTradeQueryRequest alipay_request = new AlipayTradeQueryRequest();

            AlipayTradeQueryModel model=new AlipayTradeQueryModel();
            model.setOutTradeNo(out_trade_no1);
            model.setTradeNo(trade_no1);
            alipay_request.setBizModel(model);

            AlipayTradeQueryResponse alipay_response =client.execute(alipay_request);
            System.out.println(alipay_response.getBody());

        return alipay_response.getBody();
    }


    /**
     * 退款
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping("return")
    public String tui(HttpServletRequest request,
                      String out_trade_no,String trade_no
            ,String refund_amount, String refund_reason,
                      String out_request_no) throws Exception{

            //商户订单号和支付宝交易号不能同时为空。 trade_no、  out_trade_no如果同时存在优先取trade_no
            //商户订单号,和支付宝交易号二选一
            String out_trade_no1 = new String(out_trade_no.getBytes("ISO-8859-1"),"UTF-8");
            //支付宝交易号,和商户订单号二选一
            String trade_no1 = new String(trade_no.getBytes("ISO-8859-1"),"UTF-8");
            //退款金额,不能大于订单总金额
            String refund_amount1=new String(refund_amount.getBytes("ISO-8859-1"),"UTF-8");
            //退款的原因说明
            String refund_reason1=new String(refund_reason.getBytes("ISO-8859-1"),"UTF-8");
            //标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传。
            String  out_request_no1=new String(out_request_no.getBytes("ISO-8859-1"),"UTF-8");
            /**********************/
            // SDK 公共请求类,包含公共请求参数,以及封装了签名与验签,开发者无需关注签名与验签
            //获得初始化的AlipayClient
            AlipayClient client = new DefaultAlipayClient(properties.getGatewayUrl(), properties.getApp_id(), properties.getMerchant_private_key(), "json", properties.getCharset(), properties.getAlipay_public_key(), properties.getSign_type());

            AlipayTradeRefundRequest alipay_request = new AlipayTradeRefundRequest();

            AlipayTradeRefundModel model=new AlipayTradeRefundModel();
            model.setOutTradeNo(out_trade_no1);
            model.setTradeNo(trade_no1);
            model.setRefundAmount(refund_amount1);
            model.setRefundReason(refund_reason1);
            model.setOutRequestNo(out_request_no1);
            alipay_request.setBizModel(model);

            AlipayTradeRefundResponse alipay_response =client.execute(alipay_request);
            System.out.println(alipay_response.getBody());

            return alipay_response.getBody();
    }




    /**
     * 退款交易查询
     * @param request
     * @param trade_no
     * @param out_trade_no
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("Tkquery")
    public String Tkquery(HttpServletRequest request,String trade_no,
                          String out_trade_no,
                          String out_request_no) throws Exception{

            //商户订单号和支付宝交易号不能同时为空。 trade_no、  out_trade_no如果同时存在优先取trade_no
            //商户订单号,和支付宝交易号二选一
            String out_trade_no1 = new String(out_trade_no.getBytes("ISO-8859-1"),"UTF-8");
            //支付宝交易号,和商户订单号二选一
            String trade_no1 = new String(trade_no.getBytes("ISO-8859-1"),"UTF-8");
            //请求退款接口时,传入的退款请求号,如果在退款请求时未传入,则该值为创建交易时的外部交易号
            String out_request_no1 = new String(out_request_no.getBytes("ISO-8859-1"),"UTF-8");
            /**********************/
            // SDK 公共请求类,包含公共请求参数,以及封装了签名与验签,开发者无需关注签名与验签
            //获得初始化的AlipayClient
            AlipayClient client = new DefaultAlipayClient(properties.getGatewayUrl(), properties.getApp_id(), properties.getMerchant_private_key(), "json", properties.getCharset(), properties.getAlipay_public_key(), properties.getSign_type());


            AlipayTradeFastpayRefundQueryRequest alipay_request = new AlipayTradeFastpayRefundQueryRequest();

            AlipayTradeFastpayRefundQueryModel model=new AlipayTradeFastpayRefundQueryModel();
            model.setOutTradeNo(out_trade_no1);
            model.setTradeNo(trade_no1);
            model.setOutRequestNo(out_request_no1);
            alipay_request.setBizModel(model);

            AlipayTradeFastpayRefundQueryResponse alipay_response=client.execute(alipay_request);
            System.out.println(alipay_response.getBody());

            return alipay_response.getBody();

    }


    /**
     * 关闭交易
     * @param request
     * @param trade_no
     * @param out_trade_no
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("close")
    public String close(HttpServletRequest request,String trade_no,
                        String out_trade_no) throws Exception{

            //商户订单号和支付宝交易号不能同时为空。 trade_no、  out_trade_no如果同时存在优先取trade_no
            //商户订单号,和支付宝交易号二选一
            String out_trade_no1 = new String(out_trade_no.getBytes("ISO-8859-1"),"UTF-8");
            //支付宝交易号,和商户订单号二选一
            String trade_no1 = new String(trade_no.getBytes("ISO-8859-1"),"UTF-8");
            /**********************/
            // SDK 公共请求类,包
            // 含公共请求参数,以及封装了签名与验签,开发者无需关注签名与验签
            //获得初始化的AlipayClient
            AlipayClient client = new DefaultAlipayClient(properties.getGatewayUrl(), properties.getApp_id(), properties.getMerchant_private_key(), "json", properties.getCharset(), properties.getAlipay_public_key(), properties.getSign_type());

            AlipayTradeCloseRequest alipay_request=new AlipayTradeCloseRequest();

            AlipayTradeCloseModel model =new AlipayTradeCloseModel();
            model.setOutTradeNo(out_trade_no1);
            model.setTradeNo(trade_no1);
            alipay_request.setBizModel(model);

            AlipayTradeCloseResponse alipay_response=client.execute(alipay_request);
            System.out.println(alipay_response.getBody());

        return alipay_response.getBody();
    }



    @ResponseBody
    @RequestMapping("url")
    public String url(HttpServletRequest request,String bill_type,String bill_date) throws Exception{

            // 账单类型,商户通过接口或商户经开放平台授权后其所属服务商通过接口可以获取以下账单类型:trade、signcustomer;
            // trade指商户基于支付宝交易收单的业务账单;signcustomer是指基于商户支付宝余额收入及支出等资金变动的帐务账单;
            String bill_type1 = new String(bill_type.getBytes("ISO-8859-1"),"UTF-8");
            // 账单时间:日账单格式为yyyy-MM-dd,月账单格式为yyyy-MM。
            String bill_date1 = new String(bill_date.getBytes("ISO-8859-1"),"UTF-8");
            /**********************/
            // SDK 公共请求类,包含公共请求参数,以及封装了签名与验签,开发者无需关注签名与验签
            //获得初始化的AlipayClient
            AlipayClient client = new DefaultAlipayClient(properties.getGatewayUrl(), properties.getApp_id(), properties.getMerchant_private_key(), "json", properties.getCharset(), properties.getAlipay_public_key(), properties.getSign_type());
            AlipayDataDataserviceBillDownloadurlQueryRequest alipay_request = new AlipayDataDataserviceBillDownloadurlQueryRequest();

            AlipayDataDataserviceBillDownloadurlQueryModel model =new AlipayDataDataserviceBillDownloadurlQueryModel();
            model.setBillType(bill_type1);
            model.setBillDate(bill_date1);
            alipay_request.setBizModel(model);

            AlipayDataDataserviceBillDownloadurlQueryResponse alipay_response = client.execute(alipay_request);
            System.out.println(alipay_response.getBillDownloadUrl());

        return alipay_response.getBillDownloadUrl();
    }

6.新建一个同步异步回调地址

@RequestMapping("/callback")
@Controller
public class CallBackController {


    @Autowired
    private AlipayConfig properties;

    /**
     * 同步回调,展示页面
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping("/return")
    public ModelAndView returnUrl(HttpServletRequest request, HttpServletResponse response)throws Exception{
        ModelAndView mv = new ModelAndView();
        PrintWriter out = response.getWriter();

        //获取支付宝GET过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        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] + ",";
            }
            //乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        //获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
        //商户订单号

        String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");

        //支付宝交易号
        String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");

        //付款金额
        String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),"UTF-8");

        //获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
        //计算得出通知验证结果
        //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
        boolean verify_result = AlipaySignature.rsaCheckV1(params, properties.getAlipay_public_key(), properties.getCharset(), "RSA2");

        if(verify_result){//验证成功
            //
            //请在这里加上商户的业务逻辑程序代码
            //该页面可做页面美工编辑
            out.println("验证成功<br />");
            //——请根据您的业务逻辑来编写程序(以上代码仅作参考)——

            String result="trade_no:"+trade_no+"<br/>out_trade_no:"+out_trade_no+"<br/>total_amount:"+total_amount;
            mv.addObject("data",result);
            mv.addObject("msg","验签成功");
            mv.setViewName("/result");
            //
        }else{
            //该页面可做页面美工编辑
            out.println("验证失败");
        }

        return mv;
    }


    /**
     * 异步回调
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping("/notify")
    public void notifyUrl(HttpServletRequest request, HttpServletResponse response) throws Exception{

        PrintWriter out = response.getWriter();

        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        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] + ",";
            }
            //乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
            params.put(name, valueStr);
        }
        //获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
        //商户订单号

        String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
        //支付宝交易号

        String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");

        //交易状态
        String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");

        //获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
        //计算得出通知验证结果
        //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
        boolean verify_result = AlipaySignature.rsaCheckV1(params, properties.getAlipay_public_key(), properties.getCharset(), "RSA2");

        if(verify_result){//验证成功
            //
            //请在这里加上商户的业务逻辑程序代码

            //——请根据您的业务逻辑来编写程序(以下代码仅作参考)——

            if(trade_status.equals("TRADE_FINISHED")){
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
                //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
                //如果有做过处理,不执行商户的业务程序

                //注意:
                //如果签约的是可退款协议,退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
                //如果没有签约可退款协议,那么付款完成后,支付宝系统发送该交易状态通知。
            } else if (trade_status.equals("TRADE_SUCCESS")){
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
                //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
                //如果有做过处理,不执行商户的业务程序

                //注意:
                //如果签约的是可退款协议,那么付款完成后,支付宝系统发送该交易状态通知。
            }

            //——请根据您的业务逻辑来编写程序(以上代码仅作参考)——
            out.println("success");	//请不要修改或删除

            //
        }else{//验证失败
            out.println("fail");
        }
    }
}

7.新建一个全局地址的转换类
新建WebMvcConfiguration,其实这里也可以在控制层写跳转,不过这样更好

@Configuration
public class WebMvcConfiguration extends WebMvcConfigurationSupport {
    @Override
    protected void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/topay").setViewName("pay");
        registry.addViewController("/query").setViewName("query");
        registry.addViewController("/tk").setViewName("refund");
        registry.addViewController("/tkquery").setViewName("refundquery");
        registry.addViewController("/url").setViewName("downloadurl");
        super.addViewControllers(registry);
    }

    /**
     * @Description 静态资源路径
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
        super.addResourceHandlers(registry);
    }
}

8.页面
所有的页面都是可以直接使用demo中的样式

三.运行结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

备注:项目源码我放在github上
https://github.com/ZGQ1996/phonepay.git

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值