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/ ;
技术提升在于沟通交流!