Java对接支付宝的支付、退款、提现

本篇主要是正对Java对接支付宝的常用功能,需要开通个人的沙箱环境和内网穿透(我用了阿里云服务器)。

集成前提:开发者在集成和开发前需要了解一下常用的接入方式和架构建议,如下图所示:

图片

1、登录网页版的个人支付宝

https://auth.alipay.com/login/ant_sso_index.htm

2、进入研发服务进入沙箱环境

3、通过开发平台去配置秘钥配置

https://opendocs.alipay.com/open/200/105311

4、配置yml文件和pom

alipay:
  appId: 2016110300790369 #在支付宝创建的应用的id
  notifyUrl: http://127.0.0.1/api/pay/notify   #支付宝会悄悄的给我们发送一个请求,告诉我们支付成功的信息
  returnUrl: http://127.0.0.1/api/page/success  #同步通知,支付成功,一般跳转到成功页 http://127.0.0.1/api/page/success?charset=utf-8&out_trade_no=6837ec3c-11b5-4290-b423-54515caf2fa5&method=alipay.trade.page.pay.return&total_amount=93.80&sign=c7jnEO8n6O%2BZXpk7dF3zYtIJb9lTMIM0%2B%2FmLm2JjPgdH5vEib7wp49%2F2%2FMB05YyKOxk6PYI5B2W0k%2FdHi%2Biyk083ZKcwL3a4ToXusG%2BZji66PaYe3tIe72N%2FgzpKcxF9lwF2%2FR0%2FbPhTDJpqem2v9Ej0d1yszLVeBQzU8IuQRglM4U6ev5gt%2Bslv8BViBkXWuy2OM6pA7k6CFptHWwXBYsdg9Ik%2BAIh0LD3rZobpzyn1w7y71Bu2Nj8XHev2gzmkxjyRSuERZJVVBSNNqtGY6xxlNqzh9L5k%2B4FcwEqNv5UPgWlCnvT9BI%2FB3cCUcAUTOxcdLwi1W8gTaqeI3rStyw%3D%3D&trade_no=2020122122001400320501115075&auth_app_id=2016110300790369&version=1.0&app_id=2016110300790369&sign_type=RSA2&seller_id=2088102181741856&timestamp=2020-12-21+11%3A53%3A05
  signType: RSA2 #签名方式
  charset: utf-8 #字符编码格式
  gatewayUrl: https://openapi.alipaydev.com/gateway.do  #沙箱环境
  timeoutExpress: 30m
  format: json
  merchantPrivateKey: # 商户私钥
  alipayPublicKey:  #支付宝公钥
        <!-- 支付宝-->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.9.28.ALL</version>
        </dependency>
        <dependency>
            <groupId>org.jdom</groupId>
            <artifactId>jdom2</artifactId>
            <version>2.0.6</version>
        </dependency>

5、包含网页支付(已测试)、APP支付、提现、退款、回调接口

5.1、请求入口代码

package com.example.mybaties.controller;

import com.example.mybaties.result.BaseResponse;
import com.example.mybaties.result.ResultGenerator;
import com.example.mybaties.service.AliPayService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @description: 支付宝下单支付
 * @author: lst
 * @date: 2020-12-01 16:58
 */
@RestController
@RequestMapping("/pay")
@Api(value = "AliPayController", tags = "支付宝下单支付")
public class AliPayController {

    @Autowired
    private AliPayService aliPayService;

    /**
     * @Description 支付宝下单支付
     * @author lst
     * @date 2020-12-1 17:27
     * @return com.example.mybaties.result.BaseResponse
     */
    @PostMapping(value = "/place-order", produces = "application/json; charset=utf-8")
    @ApiOperation(value = "支付宝下单支付", notes = "支付宝下单支付", produces = "application/json")
    public BaseResponse placeOrder() {
        return ResultGenerator.genSuccessResult(aliPayService.placeOrder());
    }

    /**
     * @Description 网页版支付宝下单支付
     * @author lst
     * @date 2020-12-2 14:16
     * @return com.example.mybaties.result.BaseResponse
     */
    @PostMapping(value = "/alipay-page", produces = "application/json; charset=utf-8")
    @ApiOperation(value = "网页版支付宝下单支付", notes = "网页版支付宝下单支付", produces = "application/json")
    public void alipayPage(HttpServletResponse response) {
         aliPayService.alipayPage(response);
    }

    /**
     * @Description  支付宝提现
     * @author lst
     * @date 2020-12-2 17:03
     * @param response
     */
    @PostMapping(value = "/alipay-withdraw", produces = "application/json; charset=utf-8")
    @ApiOperation(value = "支付宝提现", notes = "支付宝提现", produces = "application/json")
    public void withdraw(HttpServletResponse response) {
        aliPayService.withdraw(response);
    }

    /**
     * @Description  支付宝退款
     * @author lst
     * @date 2020-12-21 14:19
     * @param response
     */
    @PostMapping(value = "/alipay-refund", produces = "application/json; charset=utf-8")
    @ApiOperation(value = "支付宝退款", notes = "支付宝退款", produces = "application/json")
    public void refund(HttpServletResponse response) {
        aliPayService.refund(response);
    }

    /**
     * @Description 支付宝支付成功后,回调该接口
     * @author lst
     * @date 2020-12-1 17:27
     * @param request
     * @param response
     * @return java.lang.String
     */
    @RequestMapping(value="/notify",method={RequestMethod.POST,RequestMethod.GET})
    @ApiOperation(value = "支付宝支付成功后,回调该接口", notes = "支付宝支付成功后,回调该接口", produces = "application/json")
    public String notify(HttpServletRequest request, HttpServletResponse response) {
        return aliPayService.notifyData(request,response);
    }

}

5.2、实现层代码

package com.example.mybaties.service.impl;

import com.example.mybaties.form.AlipayBean;
import com.example.mybaties.form.AlipayRefundForm;
import com.example.mybaties.form.WithdrawBean;
import com.example.mybaties.service.AliPayService;
import com.example.mybaties.utils.AlipayUtil;
import com.example.mybaties.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.UUID;

/**
 * @description: 支付宝下单支付
 * @author: lst
 * @date: 2020-12-01 17:01
 */
@Service
@Slf4j
public class AliPayServiceImpl implements AliPayService {

    @Autowired
    private AlipayUtil alipayUtil;

    /**
     * @Description 支付宝下单支付
     * @author lst
     * @date 2020-12-1 17:27
     * @return java.lang.String
     */
    @Override
    public String placeOrder() {
        String body = alipayUtil.alipay();
        return body;
    }

    /**
     * @Description 支付宝支付成功后,回调该接口
     * @author lst
     * @date 2020-12-1 17:27
     * @param request
     * @param response
     * @return java.lang.String
     */
    @Override
    public String notifyData(HttpServletRequest request, HttpServletResponse response) {
        return alipayUtil.notifyData(request,response);
    }


    /**
     * @Description 网页版支付宝下单支付
     * @author lst
     * @date 2020-12-1 17:27
     * @param response
     * @return java.lang.String
     */
    @Override
    public void alipayPage(HttpServletResponse response) {
        AlipayBean alipayBean = new AlipayBean();
        //商户订单号,商户网站订单系统中唯一订单号,必填
        alipayBean.setOut_trade_no(UUID.randomUUID().toString());
        //付款金额,必填
        alipayBean.setTotal_amount("93.8");
        //订单名称,必填
        alipayBean.setSubject("商品名称:网页版支付测试Java");
        //商品描述,可空
        alipayBean.setBody("商品信息");
        String payResult = alipayUtil.alipayPage(alipayBean);

        response.setContentType("text/html;charset=utf-8");
        try {
            response.getWriter().write("<html>");
            response.getWriter().write("<head>");
            response.getWriter().write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">");
            response.getWriter().write("</head>");
            response.getWriter().write("<body>");
            response.getWriter().write(payResult);
            response.getWriter().write("</body>");
            response.getWriter().write("</html>");
            response.getWriter().flush();
            response.getWriter().close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * @Description  支付宝提现
     * @author lst
     * @date 2020-12-2 17:03
     * @param response
     * @return void
     */
    @Override
    public void withdraw(HttpServletResponse response) {
        WithdrawBean withdrawBean = new WithdrawBean();
        String payResult = alipayUtil.withdraw(withdrawBean);
        response.setContentType("text/html;charset=utf-8");
        try {
            response.getWriter().write("<html>");
            response.getWriter().write("<head>");
            response.getWriter().write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">");
            response.getWriter().write("<title>提现</title>");
            response.getWriter().write("</head>");
            response.getWriter().write("<body>");
            if("success".equals(payResult)){
                response.getWriter().write(" <div  style=\"color: red;font-size: 50px;margin: auto;\">恭喜提现成功</div>");
            }else{
                response.getWriter().write(" <div  style=\"color: red;font-size: 50px;margin: auto;\">提现失败</div>");
            }
            response.getWriter().write("</body>");
            response.getWriter().write("</html>");
            response.getWriter().flush();
            response.getWriter().close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void refund(HttpServletResponse response) {
        AlipayRefundForm alipayRefundForm = new AlipayRefundForm();
        String payResult = alipayUtil.alipayRefund(alipayRefundForm);
        response.setContentType("text/html;charset=utf-8");
        try {
            response.getWriter().write("<html>");
            response.getWriter().write("<head>");
            response.getWriter().write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">");
            response.getWriter().write("<title>退款</title>");
            response.getWriter().write("</head>");
            response.getWriter().write("<body>");
            if(StringUtil.isNotEmpty(payResult)){
                response.getWriter().write(" <div  style=\"color: red;font-size: 50px;margin: auto;\">恭喜退款成功</div>");
            }else{
                response.getWriter().write(" <div  style=\"color: red;font-size: 50px;margin: auto;\">退款失败</div>");
            }
            response.getWriter().write("</body>");
            response.getWriter().write("</html>");
            response.getWriter().flush();
            response.getWriter().close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

5.3、支付工具类

package com.example.mybaties.utils;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayFundTransToaccountTransferRequest;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayFundTransToaccountTransferResponse;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.example.mybaties.constants.AlipayProperties;
import com.example.mybaties.exceptionhandler.BaseException;
import com.example.mybaties.exceptionhandler.BaseExceptionEnum;
import com.example.mybaties.form.AlipayBean;
import com.example.mybaties.form.AlipayRefundForm;
import com.example.mybaties.form.WithdrawBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;

/**
 * @description: 支付宝支付工具
 * @author: lst
 * @date: 2020-12-01 15:57
 * 支付宝管理:https://open.alipay.com/platform/developerIndex.htm
 * 支付宝对接文档:https://opendocs.alipay.com/open/54/106370
 */
@Slf4j
@Component
public class AlipayUtil {

    @Autowired
    private  AlipayProperties alipayProperties;

    /**
     * @Description  APP支付宝下单支付
     * @author lst
     * @date 2020-12-1 17:28
     * @param
     * @return java.lang.String
     */
    public String alipay(){
        //TODO 1、实例化客户端
        AlipayClient  alipayClient = new DefaultAlipayClient(alipayProperties.getGatewayUrl(),
                alipayProperties.getAppId(), alipayProperties.getMerchantPrivateKey(), alipayProperties.getFormat(),
                alipayProperties.getCharset(), alipayProperties.getAlipayPublicKey(), alipayProperties.getSignType());
        //TODO 2、实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //TODO 3、SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        //商品信息
        model.setBody("商品信息");
        //商品名称
        model.setSubject("商品名称:App支付测试Java");
        //商品订单号(自动生成)
        model.setOutTradeNo(UUID.randomUUID().toString());
        //交易超时时间
        model.setTimeoutExpress(alipayProperties.getTimeoutExpress());
        //支付金额
        model.setTotalAmount("0.01");
        //销售产品码
        model.setProductCode("QUICK_MSECURITY_PAY");
        model.setTimeExpire("2020-12-21 17:52:00");
        request.setBizModel(model);
        //回调地址
        request.setNotifyUrl(alipayProperties.getNotifyUrl());
        log.info("请求数据:{},回调地址:{}",request.getBizModel(),request.getNotifyUrl());
        //这里和普通的接口调用不同,使用的是sdkExecute
        AlipayTradeAppPayResponse response = null;
        try {
            response = alipayClient.sdkExecute(request);
            //就是orderString 可以直接给客户端请求,无需再做处理。
            log.info("支付宝返回数据:{}",response.getBody());
        } catch (AlipayApiException e) {
            e.printStackTrace();
            throw new BaseException(BaseExceptionEnum.ALIPAY_MSG_ERROR);
        }
        return response.getBody();
    }

    /**
     * @Description APP支付宝支付成功后,回调该接口
     * @author lst
     * @date 2020-12-1 17:29
     * @param request
     * @param response
     * @return java.lang.String
     */
    public String notifyData(HttpServletRequest request, HttpServletResponse response){
        Map<String, String> params = new HashMap<String, String>();
        //TODO 1、从支付宝回调的request域中取值
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = iter.next();
            String[] values = 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);
        }
        for (Map.Entry<String, String> entry : params.entrySet()) {
            log.info("key:{}, value:{}",entry.getKey(),entry.getValue());
        }
        //TODO 2.封装必须参数  商户订单号   订单内容    交易状态(TRADE_SUCCESS)
        String outTradeNo = request.getParameter("out_trade_no");
        String orderType = request.getParameter("body");
        String tradeStatus = request.getParameter("trade_status");
        log.info("商户订单号:{},订单内容:{},交易状态:{}",outTradeNo,orderType,tradeStatus);
        //TODO 3.签名验证(对支付宝返回的数据验证,确定是支付宝返回的)
        try {
            boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayProperties.getAlipayPublicKey(), alipayProperties.getCharset(), alipayProperties.getSignType());
            if (signVerified) {
                //验签成功
               log.info("*******验签成功******");
                //TODO 业务处理逻辑

                return "success";
            } else {
                // 验签失败
                log.info("*******验签失败******");
                return "fail";
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return "fail";
        }
    }


    /**
     * @Description 网页版支付宝下单支付
     * @author lst
     * @date 2020-12-2 14:11
     * @param alipayBean
     * @return java.lang.String
     */
    public String alipayPage(AlipayBean alipayBean){
        //TODO 1、实例化客户端
        AlipayClient  alipayClient = new DefaultAlipayClient(alipayProperties.getGatewayUrl(),
                alipayProperties.getAppId(), alipayProperties.getMerchantPrivateKey(), alipayProperties.getFormat(),
                alipayProperties.getCharset(), alipayProperties.getAlipayPublicKey(), alipayProperties.getSignType());
        //TODO 2、实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
        //2、创建一个支付请求 //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(alipayProperties.getReturnUrl());
        alipayRequest.setNotifyUrl(alipayProperties.getNotifyUrl());

        alipayBean.setTimeout_express(alipayProperties.getTimeoutExpress());
        //绝对超时时间,格式为yyyy-MM-dd HH:mm:ss	2016-12-31 10:05:01
        //alipayBean.setTime_expire("2020-12-21 17:52:00");
        alipayRequest.setBizContent(JSONObject.toJSONString(alipayBean));

        String result = "";
        try {
            result = alipayClient.pageExecute(alipayRequest).getBody();
            //会收到支付宝的响应,响应的是一个页面,只要浏览器显示这个页面,就会自动来到支付宝的收银台页面
            log.info("支付宝的响应:{}",result);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            throw new BaseException(BaseExceptionEnum.ALIPAY_MSG_ERROR);
        }
        return result;
    }

    /**
     * @Description 支付宝提现
     * @author lst
     * @date 2020-12-2 17:04
     * @param withdrawBean
     * @return java.lang.String
     */
    public String withdraw(WithdrawBean withdrawBean){
        //提现
        //TODO 1、实例化客户端
        AlipayClient  alipayClient = new DefaultAlipayClient(alipayProperties.getGatewayUrl(),
                alipayProperties.getAppId(), alipayProperties.getMerchantPrivateKey(), alipayProperties.getFormat(),
                alipayProperties.getCharset(), alipayProperties.getAlipayPublicKey(), alipayProperties.getSignType());
        //TODO 2、实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
        AlipayFundTransToaccountTransferRequest alipayRequest = new AlipayFundTransToaccountTransferRequest();

        /* "\"out_biz_no\":\"3142321423432\"," +
         "\"payee_type\":\"ALIPAY_LOGONID\"," +
         "\"payee_account\":\"abc@sina.com\"," +
         "\"amount\":\"12.23\"," +
         "\"payer_show_name\":\"上海交通卡退款\"," +
         "\"payee_real_name\":\"张三\"," +
         "\"remark\":\"转账备注\"" +
         "  }"*/
        //商户转账唯一订单号
        withdrawBean.setOut_biz_no(DateUtil.getDateTime14());
        withdrawBean.setPayee_type("ALIPAY_LOGONID");
        withdrawBean.setPayee_account("ycknrb8604@sandbox.com");
        withdrawBean.setPayee_real_name("ycknrb8604");
        withdrawBean.setAmount("22.4");
        withdrawBean.setPayer_show_name("");
        withdrawBean.setRemark("推推提现");
        String jsonData = JSONObject.toJSONString(withdrawBean);
        log.info("支付宝提现请求数据:{}",jsonData);
        alipayRequest.setBizContent(jsonData);

        //TODO 3、转账/提现
        try {
            AlipayFundTransToaccountTransferResponse response = alipayClient.execute(alipayRequest);
            log.info("支付宝的响应:{}",JSONObject.toJSON(response));
            if(response.isSuccess()){
                //提现成功
                return "success";
            }else {
                throw new BaseException(BaseExceptionEnum.ALIPAY_WITHDRAW_ERROR);
            }

        } catch (AlipayApiException e) {
            e.printStackTrace();
            throw new BaseException(BaseExceptionEnum.ALIPAY_WITHDRAW_ERROR);
        }
    }

    /**
     * @Description 支付宝退款
     * @author lst
     * @date 2020-12-21 14:12
     * @param alipayRefundForm
     * @return java.lang.String
     */
    public String alipayRefund(AlipayRefundForm alipayRefundForm){
        //TODO 1、实例化客户端
        AlipayClient  alipayClient = new DefaultAlipayClient(alipayProperties.getGatewayUrl(),
                alipayProperties.getAppId(), alipayProperties.getMerchantPrivateKey(), alipayProperties.getFormat(),
                alipayProperties.getCharset(), alipayProperties.getAlipayPublicKey(), alipayProperties.getSignType());
        AlipayTradeRefundRequest aliPayRequest = new AlipayTradeRefundRequest();
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
        //订单支付时传入的商户订单号,不能和 trade_no同时为空
        model.setOutTradeNo("b87267c8-435b-449b-9ebb-e12efe06a1dd");
        //支付宝交易号,和商户订单号不能同时为空
        model.setTradeNo("2020122122001400320501115255");
        //需要退款的金额,该金额不能大于订单金额,单位为元,支持两位小数
        model.setRefundAmount("93.80");
        //退款的原因说明
        model.setRefundReason("正常退款");
        //标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传。
        model.setOutRequestNo(DateUtil.getDateTime14());
        aliPayRequest.setBizModel(model);
        try {
            AlipayTradeRefundResponse aliPayResponse = alipayClient.execute(aliPayRequest);
            log.debug("aliPayResponse:{}", aliPayResponse);
            if (!"10000".equals(aliPayResponse.getCode())) {
                log.info("支付宝退款失败,支付宝交易号:{},状态码:{}", "2020122122001400320501115254", aliPayResponse.getCode());
                throw new BaseException(aliPayResponse.getSubMsg());
            }
            return aliPayResponse.getMsg();
        } catch (AlipayApiException e) {
            e.printStackTrace();
            throw new BaseException("退款失败");
        }
    }
}

5.4、支付宝支付配置信息类

package com.example.mybaties.constants;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * @description: 支付宝支付配置信息
 * @author: lst
 * @date: 2020-12-01 15:50
 */
@Component
@ConfigurationProperties(prefix = "alipay")
@Data
public class AlipayProperties {

    /**
     * 在支付宝创建的应用的id
     */
    private String appId;

    /**
     * 商户私钥,您的PKCS8格式RSA2私钥
     */
    private String merchantPrivateKey;

    /**
     * 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
     */
    private String alipayPublicKey;

    /**
     * 服务器[异步通知]页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
     * 支付宝会悄悄的给我们发送一个请求,告诉我们支付成功的信息
     */
    private String notifyUrl;

    /**
     * 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
     * 同步通知,支付成功,一般跳转到成功页
     */
    private String returnUrl;

    /**
     * 签名方式
     */
    private String signType;

    /**
     * 字符编码格式
     */
    private String charset;

    /**
     * 支付宝网关; https://openapi.alipaydev.com/gateway.do  正式环境 https://openapi.alipay.com/gateway.do
     */
    private String gatewayUrl;

    /**
     * 该笔订单允许的最晚付款时间,逾期将关闭交易
     */
    private String timeoutExpress;

    /**
     * 请求的格式:json
     */
    private String format;

}

5.5、网页支付代码orderPage.html、下单成功代码success.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>网页下单</title>
    <script src="/static/js/jquery.min.js"></script>
    <script type="text/javascript">
        function placeOrder() {
            var url = "/pay/alipay-page";
            $.ajax({
                url: url,
                type: 'POST',
                dataType: 'JSON',
                success: function (data) {
                    console.log(data);
                    $('#orderPage').html(data)
                },
                error: function (msg) {

                }
            });
        }
    </script>


</head>


<body>
  <div>
     <!-- <span onclick="placeOrder()" id="orderPage" style="color: rgba(20,146,255,1);font-size: 50px;margin: auto;">网页下单</span>-->
      <form action="/api/pay/alipay-page" method="post">
          <input type="submit">
      </form>

  </div>


</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>成功页面</title>
    <script src="/static/js/jquery.min.js"></script>
    <script type="text/javascript">

    </script>


</head>


<body>
  <div>
      <div  style="color: red;font-size: 50px;margin: auto;">恭喜下单成功</div>
  </div>


</body>
</html>

6、打入服务器进行测试

输入网址点击‘提交’ 按钮,后端已经默认支付数据,我用沙箱APP支付成功后可以跳转到成功页面。

手机端也可以测试

HwVideoEditor

想要源码的小伙伴可以下方留言。

 

 

 

  • 0
    点赞
  • 0
    评论
  • 3
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 终极编程指南 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值