spring boot项目接入支付宝支付

    科技2022-07-10  91

    流程

    应用私钥: 应用公钥: 支付宝公钥: 支付宝私钥(不需要知道):

    1.第三方应用给支付宝平台传送数据:第三方应用使用应用私钥对数据进行加密,支付宝使用应用公钥进行解密 2.支付宝平台给第三方应用传递数据:支付宝平台使用支付宝私钥对数据进行加密,第三方应用使用支付宝公钥对数据进行解密

    第三方应用需要配置的秘钥为:应用私钥、支付宝公钥

    接入依赖:

    <!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-easysdk --> <dependency> <groupId>com.alipay.sdk</groupId> <artifactId>alipay-easysdk</artifactId> <version>2.1.0</version> </dependency>

    步骤: 1.创建配置文件AlipayConfig

    package com.test.config; import com.alipay.easysdk.factory.Factory; import com.alipay.easysdk.kernel.Config; import com.alipay.easysdk.kernel.util.ResponseChecker; import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; import java.util.Map; @Component //添加 @Component 注解让 Component Scan 扫描到, @PropertySource("classpath:/zhifubao.properties") @ConfigurationProperties(prefix = "alipay") @Data public class AlipayConfig { private String protocol; private String gatewayHost; private String signType; private String appId; private String alipayPublicKey; //支付宝公钥 private String notifyUrl; //异步地址 private String returnUrl; //同步地址 private String merchantPrivateKey; //应用私钥 private String encryptKey; private String successUrl; public String toPay(String subject,String payNo,String amount) throws Exception { // 1. 设置参数(全局只需设置一次) String result=""; Factory.setOptions(getOptions()); try { // 2. 发起API调用(以创建当面付收款二维码为例) AlipayTradePagePayResponse response = Factory.Payment.Page().pay(subject,payNo,amount,returnUrl); // 3. 处理响应或异常 if (ResponseChecker.success(response)) { result=response.body; System.out.println("调用成功"); } else { result=response.body; System.err.println("调用失败,原因:" + response.body); } } catch (Exception e) { System.err.println("调用遭遇异常,原因:" + e.getMessage()); throw new RuntimeException(e.getMessage(), e); } System.out.println(result); return result; } //验证签名 public boolean validateSign(Map<String,String> parameters) throws Exception { return Factory.Payment.Common().verifyNotify(parameters); } private Config getOptions() { Config config = new Config(); config.protocol = getProtocol(); config.gatewayHost = getGatewayHost(); config.signType = getSignType(); config.appId = getAppId(); config.merchantPrivateKey = getMerchantPrivateKey(); // 为避免私钥随源码泄露,推荐从文件中读取私钥字符串而不是写入源码中 config.notifyUrl = getNotifyUrl(); //请填写您的支付类接口异步通知接收服务地址,例如:https://www.test.com/callback --> //可设置AES密钥,调用AES加解密相关接口时需要(可选) config.encryptKey = getEncryptKey(); config.alipayPublicKey=getAlipayPublicKey(); return config; } } //注:证书文件路径支持设置为文件系统中的路径或CLASS_PATH中的路径,优先从文件系统中加载,加载失败后会继续尝试从CLASS_PATH中加载 // config.merchantCertPath = "<-- 请填写您的应用公钥证书文件路径,例如:/foo/appCertPublicKey_2019051064521003.crt -->"; // config.alipayCertPath = "<-- 请填写您的支付宝公钥证书文件路径,例如:/foo/alipayCertPublicKey_RSA2.crt -->"; // config.alipayRootCertPath = "<-- 请填写您的支付宝根证书文件路径,例如:/foo/alipayRootCert.crt -->"; //注:如果采用非证书模式,则无需赋值上面的三个证书路径,改为赋值如下的支付宝公钥字符串即可 // config.alipayPublicKey = "<-- 请填写您的支付宝公钥,例如:MIIBIjANBg... -->";

    2.配置zhifubao.properties 注意此处网关的书写:

    alipay.gatewayHost=openapi.alipaydev.com #---------暂为沙盒测试ing------------ alipay.protocol=https #支付宝网关 alipay.gatewayHost=openapi.alipaydev.com #签名方式 alipay.signType=RSA2 #支付宝appid alipay.appId=testappId #支付宝公钥 alipay.alipayPublicKey=testalipayPublicKey alipay.notifyUrl=http://lmj.ngrok2.xiaomiqiu.cn/cd/pay/notify alipay.returnUrl=http://localhost:8081/cd/pay/returnDeal #应用私钥 alipay.merchantPrivateKey=testmerchantPrivateKey #密匙 alipay.encryptKey=test1 #字符编码格式 alipay.charset=utf-8 alipay.successUrl=http://localhost:8081/SuccessPay.html

    3.创建AliPayController 控制器

    package com.test.contoller; import com.alipay.easysdk.factory.Factory; import com.test.config.AlipayConfig; import com.test.utils.CommonUtils; import org.apache.catalina.servlet4preview.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; import java.util.Date; import java.util.HashMap; import java.util.Map; @Controller @RequestMapping("/cd/pay") public class AliPayController { @Autowired private AlipayConfig alipayConfig; @RequestMapping("/aliPay") @ResponseBody public String aliPay() throws Exception { Date date = new Date(); //订单号 String out_trade_no = CommonUtils.code()+date.getTime(); //商品名字 String subject="testshop1"; //总价 String sum_price="118.0"; //订单信息写入数据库 //调起支付 return alipayConfig.toPay(subject,out_trade_no,sum_price); } /** *同步返回方法 * @param request * @return * @throws Exception */ @GetMapping("/returnDeal") public String returnDeal(HttpServletRequest request) throws Exception { System.out.println("支付成功进入同步回调"); //1.验签 Map<String, String[]> params = request.getParameterMap(); Map<String,String> parameters=new HashMap<>(); params.entrySet(); //该方法返回值就是这个map中各个键值对映射关系的集合,可使用它对map进行遍历 for(Map.Entry<String,String[]> entry:params.entrySet()){ parameters.put(entry.getKey(),entry.getValue()[0]); } //调用方法验签 boolean flag=alipayConfig.validateSign(parameters); if(!flag){ return "/error.html"; } return "/return.html"; } /** * 异步返回方法 */ @RequestMapping("/notify") public void notify(HttpServletRequest request) throws Exception { System.out.println("支付成功进入异步回调"); //1.验签 Map<String, String[]> params = request.getParameterMap(); Map<String,String> parameters=new HashMap<>(); params.entrySet(); //该方法返回值就是这个map中各个键值对映射关系的集合,可使用它对map进行遍历 for(Map.Entry<String,String[]> entry:params.entrySet()){ parameters.put(entry.getKey(),entry.getValue()[0]); } //调用方法验签 boolean flag=alipayConfig.validateSign(parameters); if(!flag){ } //2.获取参数 String out_trade_no=parameters.get("out_trade_no"); //订单号 String trade_no=parameters.get("trade_no"); //订单号 String amount=parameters.get("total_amount"); //总金额 //3.修改本地数据库 } }

    4.前端测试页面

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css"> <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <style> div { text-align: center; margin-top: 45px; } </style> </head> <body> <!-- <div style="font-size: 28px;text-align: center"> ${name}欢迎页面4 </div> --> <div> <button onclick="topay()" style="width: 100px;height: 30px;">付款288</button> </div> <div id="paytest"> </div> </body> <script> function topay() { $.ajax({ url:'/cd/pay/aliPay', type:'post', // dataType:'json', success:function(data){ console.log(data); $('#paytest').replaceWith(data); } }); } </script> </html>

    5.返回页面

    Processed: 0.010, SQL: 8