小言_互联网的博客

SSM集成支付宝(沙箱环境)

276人阅读  评论(0)

1. 加入依赖


  
  1. <!--支付宝-->
  2. <dependency>
  3. <groupId>com.alipay.sdk </groupId>
  4. <artifactId>alipay-sdk-java </artifactId>
  5. <version>3.3.49.ALL </version>
  6. </dependency>

2. 加入AlipayConfig

使用官方Demo工程中的 AlipayConfig 类。内网穿透地址(内网穿透参考我的另一篇文NATAPP内网穿透服务使用,实现支付接口需要有一个可以外网访问的地址)需要根据当前运行时的实际情况调整。notify_url 和 return_url 需要编写对应的handler方法处理。(如果看到这有点懵,可以看看我的上一篇文沙箱环境使用支付宝,上一篇讲了如何把官方Demo运行起来,包括配置 AlipayConfig 类)

把 AlipayConfig 类复制到工程里面。


  
  1. /* *
  2. *类名:AlipayConfig
  3. *功能:基础配置类
  4. *详细:设置帐户有关信息及返回路径
  5. *修改日期:2017-04-05
  6. *说明:
  7. *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
  8. *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
  9. */
  10. public class AlipayConfig {
  11. //↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
  12. // 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
  13. public static String app_id = "2016111114435";
  14. // 商户私钥,您的PKCS8格式RSA2私钥
  15. public static String merchant_private_key = "MIIEvgIBADANBgkqhkiG9BgQDWR/khpebjBCsiZuHD4yGnD7S+AO1sV/W6MjVrsyXBJ4uLVNf9iemhcGlRpt+Ykh+Zg97iJ6BuJll482ZrtNxIQPRTDs1Lqy+PS5WWA5gOvQkpTKFNkAZWFx0YDiC6SlYXIjsilGC0AVXhFxhN4ayurP5RjYl8j8apAJH84efegwKBgHN2kYlqcHnoMu+ale2KEcEnmxoyVTvUz2HzI67QduuxIHGOst5iq2ytdhJ8t7N93ois6pDJ++Trqascp6srrlPOlPkV9wF1Fy8zJo+qok0+q3BySpYZYqMD42uq0mPWYWLD22MA31X7Ds2u0qXOGRYK5rkHVPvqmjkZ0KbguUsC";
  16. // 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
  17. public static String alipay_public_key = "MIIBIjANBgkqhkiG9w0lYpQpePDsTxIuiU4BQ96bvZ2DGjIM7D3joiJ3Gn+y9RLscFXHZ1dFMD0BtbxHhufd3GAwryasIlx/6rAxWwIdNTi+Rm6++7s0RLcs/JHUlaYvo7NOGSgZoxbNcj3u8G/5RKhBVzkIgcptzai9NwYep7uFNhGI/EZihcN7mNynTrbPdp13QIDAQAB";
  18. // 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问,efvya2.natappfree.cc 是我的外网穿透的地址;注意:payNotify 和 payReturn 是下面写的方法接口,一定要对应
  19. public static String notify_url = "http://efvya2.natappfree.cc/payNotify";
  20. // 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
  21. public static String return_url = "http://efvya2.natappfree.cc/payReturn";
  22. // 签名方式
  23. public static String sign_type = "RSA2";
  24. // 字符编码格式
  25. public static String charset = "utf-8";
  26. // 支付宝网关(这是是沙箱环境的网关)
  27. public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
  28. }

 

3. 创建PayController

调下面的“/doPayhtml”就可以成功支付:


  
  1.   @Controller
  2. public class PayController {
  3. @GetMapping(value= "/doPay.html")
  4. @ResponseBody
  5. public String doPay(String WIDout_trade_no, String WIDtotal_amount, String WIDsubject, String WIDbody, HttpServletRequest request) throws Exception {
  6. //获得初始化的AlipayClient
  7. AlipayClient alipayClient = new DefaultAlipayClient(
  8. AlipayConfig.gatewayUrl,
  9. AlipayConfig.app_id,
  10. AlipayConfig.merchant_private_key, "json",
  11. AlipayConfig.charset,
  12. AlipayConfig.alipay_public_key,
  13. AlipayConfig.sign_type);
  14. //设置请求参数
  15. AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
  16. alipayRequest.setReturnUrl(AlipayConfig.return_url);
  17. alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
  18. //商户订单号,商户网站订单系统中唯一订单号,必填
  19. String out_trade_no = new String(request.getParameter( "WIDout_trade_no").getBytes( "ISO-8859-1"), "UTF-8");
  20. //付款金额,必填
  21. String total_amount = new String(request.getParameter( "WIDtotal_amount").getBytes( "ISO-8859-1"), "UTF-8");
  22. //订单名称,必填
  23. String subject = new String(request.getParameter( "WIDsubject").getBytes( "ISO-8859-1"), "UTF-8");
  24. //商品描述,可空
  25. String body = new String(request.getParameter( "WIDbody").getBytes( "ISO-8859-1"), "UTF-8");
  26. alipayRequest.setBizContent( "{\"out_trade_no\":\""+ out_trade_no + "\","
  27. + "\"total_amount\":\""+ total_amount + "\","
  28. + "\"subject\":\""+ subject + "\","
  29. + "\"body\":\""+ body + "\","
  30. + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
  31. //若想给BizContent增加其他可选请求参数,以增加自定义超时时间参数timeout_express来举例说明
  32. //alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
  33. // + "\"total_amount\":\""+ total_amount +"\","
  34. // + "\"subject\":\""+ subject +"\","
  35. // + "\"body\":\""+ body +"\","
  36. // + "\"timeout_express\":\"10m\","
  37. // + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
  38. //请求参数可查阅【电脑网站支付的API文档-alipay.trade.page.pay-请求参数】章节
  39. //给支付宝发送请求进行支付操作
  40. return alipayClient.pageExecute(alipayRequest).getBody();
  41. }
  42. @RequestMapping( "/payReturn")
  43. @ResponseBody
  44. public String payReturn(HttpServletRequest request) throws Exception {
  45. // 获取支付宝GET过来反馈信息
  46. Map<String, String> params = new HashMap<String, String>();
  47. Map<String, String[]> requestParams = request.getParameterMap();
  48. for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
  49. String name = (String) iter.next();
  50. String[] values = (String[]) requestParams.get(name);
  51. String valueStr = "";
  52. for ( int i = 0; i < values.length; i++) {
  53. valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
  54. }
  55. // 乱码解决,这段代码在出现乱码时使用
  56. valueStr = new String(valueStr.getBytes( "ISO-8859-1"), "utf-8");
  57. params.put(name, valueStr);
  58. }
  59. boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset,
  60. AlipayConfig.sign_type); // 调用SDK验证签名
  61. // ——请在这里编写您的程序(以下代码仅作参考)——
  62. if (signVerified) {
  63. // 商户订单号
  64. String out_trade_no = new String(request.getParameter( "out_trade_no").getBytes( "ISO-8859-1"), "UTF-8");
  65. System.out.println( "商户订单号---------------------------"+out_trade_no);
  66. // 支付宝交易号
  67. String trade_no = new String(request.getParameter( "trade_no").getBytes( "ISO-8859-1"), "UTF-8");
  68. // 付款金额
  69. String total_amount = new String(request.getParameter( "total_amount").getBytes( "ISO-8859-1"), "UTF-8");
  70. return "trade_no:" + trade_no + "<br/>out_trade_no:" + out_trade_no + "<br/>total_amount:" + total_amount;
  71. } else {
  72. return "验签失败";
  73. }
  74. }
  75. @RequestMapping( "/payNotify")
  76. @ResponseBody
  77. public String payNotify(HttpServletRequest request) throws Exception {
  78. // 获取支付宝POST过来反馈信息
  79. Map<String, String> params = new HashMap<String, String>();
  80. Map<String, String[]> requestParams = request.getParameterMap();
  81. for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
  82. String name = (String) iter.next();
  83. String[] values = (String[]) requestParams.get(name);
  84. String valueStr = "";
  85. for ( int i = 0; i < values.length; i++) {
  86. valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
  87. }
  88. // 乱码解决,这段代码在出现乱码时使用
  89. valueStr = new String(valueStr.getBytes( "ISO-8859-1"), "utf-8");
  90. params.put(name, valueStr);
  91. }
  92. boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset,
  93. AlipayConfig.sign_type); // 调用SDK验证签名
  94. // ——请在这里编写您的程序(以下代码仅作参考)——
  95. /*
  96. * 实际验证过程建议商户务必添加以下校验: 1、需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
  97. * 2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额), 3、校验通知中的seller_id(或者seller_email)
  98. * 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)
  99. * 4、验证app_id是否为该商户本身。
  100. */
  101. if (signVerified) { // 验证成功
  102. // 商户订单号
  103. // String out_trade_no = new
  104. // String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
  105. // 支付宝交易号
  106. // String trade_no = new
  107. // String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
  108. // 交易状态
  109. String trade_status = new String(request.getParameter( "trade_status").getBytes( "ISO-8859-1"), "UTF-8");
  110. if (trade_status.equals( "TRADE_FINISHED")) {
  111. // 判断该笔订单是否在商户网站中已经做过处理
  112. // 如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
  113. // 如果有做过处理,不执行商户的业务程序
  114. // 注意:
  115. // 退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
  116. } else if (trade_status.equals( "TRADE_SUCCESS")) {
  117. // 判断该笔订单是否在商户网站中已经做过处理
  118. // 如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
  119. // 如果有做过处理,不执行商户的业务程序
  120. // 注意:
  121. // 付款完成后,支付宝系统发送该交易状态通知
  122. }
  123. return "success";
  124. } else { // 验证失败
  125. return "fail";
  126. // 调试用,写文本函数记录程序运行情况是否正常
  127. // String sWord = AlipaySignature.getSignCheckContentV1(params);
  128. // AlipayConfig.logResult(sWord);
  129. }
  130. }
  131. }

 


转载:https://blog.csdn.net/weixin_44210965/article/details/105239894
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场