java实现支付宝支付及退款(二)

紧跟上篇博客,本篇将书写具体的代码实现

开发环境:SSM、maven、JDK8.0

1.Maven坐标

 

<!--阿里支付-->
<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>3.4.49.ALL</version>
</dependency>

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.56</version>
</dependency>
<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>

 

2.AliOrderDTO 实体

public class UPOrder {
//get/set自己操作
    private String code;//商户订单号
    private String orderName;//订单名称
    private BigDecimal paymentAmount;//付款金额
    private String productDesc;//商品描述
    private String createBy;//创建人Code
    private Long createTime;//创建时间(时间戳)
    private Integer createByType;//创建人类型 1-专家 2-企业用户
    private Boolean status;//是否付款  true - 已付 false-未付
    private Long payTime;//订单支付时间-支付后才存在 (时间戳)
    public String getCode() {
        return code;
    }
}

  3.UPOrder 实体

public class AliOrderDTO {
//get/set自己操作
    private String code;//商户订单号
    private String aliTransactionNum;//支付宝交易号
    private BigDecimal paymentAmount;//退款金额
    private String refundCause;//退款原因
    private String refundNum;//退款请求号
}

  4.配置文件AlipayConfig

public class AlipayConfig {

//↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

	// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
	public static String APPID = "2016092700611035";

	// 商户私钥,您的PKCS8格式RSA2私钥
    public static String RSA_PRIVATE_KEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDP1hzPIGDA7XHmPpSIwvZVBGU1wsVYKactul5v4bJSV3Le0zGhV82GIP0ByX9tNzU+//kaxFgRsdZyPvR28iDbf9IaVZ+n+cZHA2rvevmntzoi3wMSEhfi8gHmY3+FuUALmICcK8a8rNV5qjpzRAyOb0IRLh1OxtCb64caKQivIt6OTEmLvyJ9BFdYbOSxHWpaOd6UMoXzG9gUzoRkMQiv9bGPkbOjxSXvYZXIXMF9OH+aHQ0oB94Od/Y/uc1xav23hPEq7HfaEMdNc3ZeRxC2JRGZm0HEn360hQ5fduE5QHnC0havpecvPNmmJv18KmYPICvK0WEONXQzZkd7ieWZAgMBAAECggEAPCPk6jqgRLNwxgNNz9U6mpdPAiN+H2jOK3lGYnGYvCL55miOb/WMT0e0bpPz/5J+IeDIIGq4YUZom16ENvcRcvKlxWEJdf3c1iezBeE75MAsXnLR3KTHrLACxLv95qAYXEKg1JAGTgplK3OKvlfumjivkXEaofT94GBjE7rT/HlBDUQd7fofu337fkVlzaluL9n6KwPyFoOhEoXz/ESANlcAzFxEdrHJ+41ywfivpCmPYipJ5RlPcvrxYPQVVcID9yxJmYl+yT+5zq+RENQw9UErKwufO27wMmlk8h9qnJ353Q5qzlI1XuziW27e+WcuCKA5KjPQDTW0FQX46+auAQKBgQDsM2A34G4bxF4FrKQMXYK+9AeN7jnOiObVigJWDQJdDmE6ajFJyjywSMJdJHFkt093jq1Q7GbFQratvXnsKw808gBqlUDHruHfQyAjB7Euwo/uj+Rf64wFSYeNyPz5Y4ZzTW/egp0+fNlwdQueF/ZxTix3Kveopju05OdP5LsDKQKBgQDhQhFWfLdhrzsmCbo1+FwI9XLQcijrwkDJcDCwjSw77Utdc7ZB9b47Qw8gPdGHsHUNST2SO0MUolxpcslhK0LCp2JH+jmyLvutCwJHge2ajEHr9UQNwqNT0VjfvLOCsqy1XjcT4UMkVbLuZfQVkuGeQMlZAz7vMwjnLHM5OWYM8QKBgQCx7+YtUfJBEsZt6efPtOZZKgdC4dNEhxe2iHhIERbVuY5/bh5hY2witT1O47RU1k+UVrS0QNMPCboK2rGtu6aCEUlFAdlCVLmt8qiUGyhcfI/nfRjjNdRO61yl8GK7EUHpPM3ox2bj+zPnJxWwbIboRqbywzi9ITXbiZHEOyCzOQKBgERWMMBWMaP27zDI/q7k27b0D5LhLzzmv5Tc7kiBa4v6n0SImCBGlyGPZIVZe7l4dOpE7+LvC5i08OgkpKdP4n7/HLfNV7eQvVVv448iAZ1DM7SLwcuS4s3I0vd9XdAmuHKFVJw5WI8rWI8uavAokT3bVbolW/BhQTAwsfwIR8dhAoGAOnxoALzuKX647N6k8AQEdNGr6CsDfwVR050vJHDbYVAxocGifiNE64/LJyzG0lO3mj4eiVwpikwPMx1oDhPuDURXrLK0TNzBV8LsGQvf+mTDgabAo8Jf/fYY3Ea8NOnE4Zrg6mEC93C0rUHEfsO8g+B2Skvw+8p6M6SHsmNsthw=";

	// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
    public static String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz9YczyBgwO1x5j6UiML2VQRlNcLFWCmnLbpeb+GyUldy3tMxoVfNhiD9Acl/bTc1Pv/5GsRYEbHWcj70dvIg23/SGlWfp/nGRwNq73r5p7c6It8DEhIX4vIB5mN/hblAC5iAnCvGvKzVeao6c0QMjm9CES4dTsbQm+uHGikIryLejkxJi78ifQRXWGzksR1qWjnelDKF8xvYFM6EZDEIr/Wxj5Gzo8Ul72GVyFzBfTh/mh0NKAfeDnf2P7nNcWr9t4TxKux32hDHTXN2XkcQtiURmZtBxJ9+tIUOX3bhOUB5wtIWr6XnLzzZpib9fCpmDyArytFhDjV0M2ZHe4nlmQIDAQAB";
    
	// 服务器异步通知页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
	public static String notify_url = "http://d9tc3e.natappfree.cc/alipay/notify_url.jsp";

	// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问,
//标红的域名为内网穿透工具生成的域名,没启动一次穿透工具,生成的域名都不一样,所有启动一次都需要进行修改 public static String return_url = "http://aa7xmz.natappfree.cc/alipay/return_url.jsp"; //请求网关地址 public static String URL="http://aa7xmz.natappfree.cc/gateway.do"; // 签名方式 public static String SIGNTYPE = "RSA2"; // 字符编码格式 public static String CHARSET = "utf-8"; //返回格式 public static String FORMAT="json"; // 支付宝网关 public static String gatewayUrl = "https://openapi.alipay.com/gateway.do"; // 支付宝网关 public static String log_path = "/log";

  5.控制层

@Controller
@RequestMapping("/pay/")
public class payCotroller {
   

       /**
     *@description: 生成充值余额订单(支付宝充值)
     *@author:cyb
     *@date: 2019-03-11 10:12
    *@param:
     *@return: net.sf.json.JSONArray
     */
    @RequestMapping("topUpBalance")
    public void topUpBalance(UPOrder order, HttpServletResponse response){
        //获得初始化的AlipayClient
        //参数: URL APPID  RSA_PRIVATE_KEY json ALI_CHARSET  ALIPAY_PUBLIC_KEY  SIGNTYPE
       AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);
        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(GetPayInfo.getProperyByFourthWay("ALI_RETURN_URL"));
        alipayRequest.setNotifyUrl(GetPayInfo.getProperyByFourthWay("ALI_NOTIFY_URL"));

        //商户订单号,商户网站订单系统中唯一订单号,必填
        String out_trade_no = new String(order.getCode());
        //付款金额,必填
        String total_amount = new String(order.getPaymentAmount().toString());
        //订单名称,必填
        String subject = new String(order.getOrderName());
        //商品描述,可空
        String body = new String(order.getProductDesc());
        alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
                + "\"total_amount\":\""+ total_amount +"\","
                + "\"subject\":\""+ subject +"\","
                + "\"body\":\""+ body +"\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        //请求
        String result;
        try {
            result = alipayClient.pageExecute(alipayRequest).getBody();
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write(result);// 直接将完整的表单html输出到页面
            response.getWriter().flush();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            response.setContentType("text/html;charset=utf-8");
            try {
                response.getWriter().flush();
                response.getWriter().write("1");// 直接将完整的表单html输出到页面
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    }

    /**
     *@description:支付宝退款
     *@author:cyb
     *@date: 2019-03-13 10:48
    *@param: response
    *@param: aliOrderDTO
     *@return: void
     */
    @RequestMapping("aliRefund")
    public void aliRefund(HttpServletResponse response, AliOrderDTO aliOrderDTO){
        try {
            //获得初始化的AlipayClient
            //URL APPID RSA_PRIVATE_KEY JSON CHARSET ALIPAY_PUBLIC_KEY  SIGNTYPE
           AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);
            //设置请求参数
            AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();
            //商户订单号,商户网站订单系统中唯一订单号
            String out_trade_no = aliOrderDTO.getCode();
            //支付宝交易号
            String trade_no =aliOrderDTO.getAliTransactionNum();
                    //请二选一设置
            //需要退款的金额,该金额不能大于订单金额,必填
            String refund_amount = aliOrderDTO.getPaymentAmount().toString();
                    //退款的原因说明
            String refund_reason = aliOrderDTO.getRefundCause();
                    //标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传
            String out_request_no = aliOrderDTO.getRefundNum();
            alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
                    + "\"trade_no\":\""+ trade_no +"\","
                    + "\"refund_amount\":\""+ refund_amount +"\","
                    + "\"refund_reason\":\""+ refund_reason +"\","
                    + "\"out_request_no\":\""+ out_request_no +"\"}");

            //请求
            String result = alipayClient.execute(alipayRequest).getBody();
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write(result);// 直接将完整的表单html输出到页面
            response.getWriter().flush();
        }catch (Exception e){
            e.printStackTrace();
            String result="1";
            response.setContentType("text/html;charset=utf-8");
            try {
                response.getWriter().write(result);// 直接将完整的表单html输出到页面
                response.getWriter().flush();
            } catch (IOException e1) {
                e1.printStackTrace();
            }

        }
    }


    /**
     *@description: 异步支付的回调
     *@author:cyb
     *@date: 2019-03-12 14:24
    *@param: request
     *@return: void
     */
    @RequestMapping("notify_url")
    @ResponseBody
    public JSONArray notify_url(HttpServletRequest request){
        System.out.println("异步回调");
     return msg200();
    }

/**
 *@description:同步的回调方法
 *@author:cyb
 *@date: 2019-03-12 14:23
*@param: request
 *@return: void
 */
@RequestMapping("return_url")
@ResponseBody
public JSONArray return_url(HttpServletRequest request){
    System.out.println("同步回调");
  return msg200();
}

 请求的效果:

1.支付宝支付:将返回的form表单写在一个HTML页面中运行,则会出现对应的支付页面让你进行支付

 

 

 

  支付成功后则会有个回调,回调的路径自己定义。

 

以上博客代码本人都亲测过,需要源码的可以联系本人,以上内容中有所不适的希望指出。另转载请说明出处,本人博客主页为:https://home.cnblogs.com/u/chenyuanbo/ ;

 

技术提升在于沟通交流!

 

 

 

posted @ 2019-03-13 16:55  陈远波  阅读(1691)  评论(0编辑  收藏  举报