网站调用支付宝进行支付-Java后台调用支付宝支付

头像
码农笔录
2018-12-03阅读 4544

网站调用支付宝进行支付-Java后台调用支付宝支付

最近公司一个产品用到了打赏支付,其中一个是支付宝,记录一下java后台调用支付宝的过程付代码。本文讲的是使用沙箱环境(支付宝提供的一种开发专用模式,不要实际支付,可以走通整个流程)。

一、准备工作

1.首先要到 蚂蚁金服开发者中心 注册商家账户,并认证。
2.下载java版的sdk和demo sdk&demo下载地址
3.将sdk加入到项目中,在项目根路径下新建libs文件夹,将jar包复制进去,我这里使用的是gradle,如果各位使用的是maven,请自行修改。

compile fileTree(dir:'libs',include:['*.jar']) compile group: 'com.google.code.gson', name: 'gson', version: '2.8.0' //谷歌json相关的包,可以用其他的

4.公钥、私钥的生成。生成公钥、私钥官方教程 ,按照官网教程操作,很简单的,这里就不上图片了。生成完之后将你的公钥要上传上去,具体位置看图片。
这里写图片描述

二、开发接口

1、因为开发环境是使用沙箱环境,上线后会使用真实环境,所以支付宝的一些参数我们放到配置文件里 pay-dev.properties appid和支付宝公钥上面图片中有,直接在网页上复制就好。

注意: 支付宝回调接口一定要是公网可以访问到的,我这里用了花生壳内网穿透,你们可以自行解决,只要能实现公网访问即可

ALIPAY.PRIVATEKEY=你生成的私钥 ALIPAY.PUBLICKEY=支付宝的公钥 ALIPAY.APPID=2016080300156724 #沙箱环境下的appid ALIPAY.SERVER=https://openapi.alipaydev.com/gateway.do ALIPAY.NOTIFY_URL=http://sanqi.iask.in:31017/alipay/notify #公网可以访问的地址 ALIPAY.RETURNA_URL=http://sanqi.iask.in:31017/alipay/return ALIPAY.SIGN=RSA2 ALIPAY.LOG=C:\\alipaylog\\

2、加载配置文件,我的项目是基于springboot的,如果是基于xml配置的,请自行在xml中配置。

/** * @ClassName: PropertiesConfig * @Description: 读取配置文件 * @author nelson * @date 2018年3月21日 下午5:35:21 * */ @Configuration public class PropertiesConfig { @Bean public PropertySourcesPlaceholderConfigurer createPropertySourcesPlaceholderConfigurer() { ClassPathResource resource = new ClassPathResource("pay-dev.properties"); PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer(); propertyPlaceholderConfigurer.setLocation(resource); return propertyPlaceholderConfigurer; } }

3、开始编写写接口
这里支付宝要用的一些参数,我是通过@Value自动注入进来的,官方给的demo是,定义个AlipayConfig类,然后全部定义成静态变量,根据个人喜好问题选择,官方的demo中有,可以直接复制,然后修改为你自己的参数即可。

代码中适当的写了一些参数,但是并非全部参数,官网参数列表及解释

/** * @Title: AlipayController.java * @Package cn.trmap.tdcloud.pay * @Description: 支付宝后台接口 * @author nelson * @date 2018年3月21日 下午5:31:03 */ @RequestMapping("alipay") @RestController public class AlipayController { @Value("${ALIPAY.APPID}") private String app_id; @Value("${ALIPAY.PRIVATEKEY}") private String merchant_private_key; @Value("${ALIPAY.PUBLICKEY}") private String alipay_public_key; @Value("${ALIPAY.NOTIFY_URL}") private String notify_url; @Value("${ALIPAY.RETURNA_URL}") private String return_url; @Value("${ALIPAY.SIGN}") private String sign_type = "RSA2"; private String charset = "utf-8"; @Value("${ALIPAY.SERVER}") private String gatewayUrL; @GetMapping("pay") private String alipayPay() throws AlipayApiException { //这个应该是从前端端传过来的,这里为了测试就从后台写死了 AlipayVo vo = new AlipayVo(); vo.setOut_trade_no(UUID.randomUUID().toString().replace("-", "")); vo.setTotal_amount("0.01"); vo.setSubject("nelson-test-title"); vo.setProduct_code("FAST_INSTANT_TRADE_PAY"); //这个是固定的 String json = new Gson().toJson(vo); System.out.println(json); AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrL, app_id, merchant_private_key, "json",charset,alipay_public_key,sign_type); // 设置请求参数 AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest(); alipayRequest.setReturnUrl(return_url); alipayRequest.setNotifyUrl(notify_url); alipayRequest.setBizContent(json); String result = alipayClient.pageExecute(alipayRequest).getBody(); System.out.println(result); return result; //这里生成一个表单,会自动提交 }
/** * @Title: AlipayVo.java * @Package cn.trmap.tdcloud.pay.vo * @Description: 支付请求参数 * @author nelson * @date 2018年3月23日 上午9:00:02 */ public class AlipayVo implements Serializable{ private static final long serialVersionUID = 1L; /** * 订单名称 */ private String subject; /** * 商户网站唯一订单号 */ private String out_trade_no; /** * 该笔订单允许的最晚付款时间 */ private String timeout_express; /** * 付款金额 */ private String total_amount; /** * 销售产品码,与支付宝签约的产品码名称 */ private String product_code; ****此处省去get和set方法 }

4、支付宝异步通知回调接口

这个接口的请求方式只能是post,如果用get会拿不到数据,不支持。

/** * @Title: alipayNotify * @Description: 支付宝回调接口 * @author nelson * @param request * @param out_trade_no 商户订单号 * @param trade_no 支付宝交易凭证号 * @param trade_status 交易状态 * @throws AlipayApiException * @return String * @throws */ @PostMapping("notify") private String alipayNotify(HttpServletRequest request, String out_trade_no,String trade_no,String trade_status) throws AlipayApiException { Map<String, String> map = new HashMap<String, String>(); 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] + ","; System.out.println(valueStr); } map.put(name, valueStr); } boolean signVerified = false; try { signVerified = AlipaySignature.rsaCheckV1(map,alipay_public_key,charset,sign_type); } catch (AlipayApiException e) { e.printStackTrace(); return ("fail");// 验签发生异常,则直接返回失败 } if (signVerified) { //处理你的业务逻辑,更细订单状态等 return ("success"); } else { System.out.println("验证失败,不去更新状态"); return ("fail"); } }

5、支付宝回调接口 return url

/** * @Title: alipayReturn * @Description: 支付宝回调接口 * @author nelson * @param request * @param out_trade_no 商户订单号 * @param trade_no 支付宝交易凭证号 * @param trade_status 交易状态 * @throws AlipayApiException * @return String * @throws */ @GetMapping("return") private String alipayReturn(Map<String, String> params, HttpServletRequest request, String out_trade_no,String trade_no,String total_amount) throws AlipayApiException { Map<String, String> map = new HashMap<String, String>(); 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] + ","; System.out.println(valueStr); } map.put(name, valueStr); } boolean signVerified = false; try { signVerified = AlipaySignature.rsaCheckV1(map, alipay_public_key, charset, sign_type); } catch (AlipayApiException e) { e.printStackTrace(); return ("fail");// 验签发生异常,则直接返回失败 } if (signVerified) { return ("success"); } else { System.out.println("验证失败,不去更新状态"); return ("fail"); } }

三、测试接口

启动项目,访问接口地址 项目地址/alipay/pay 我的是 http://sanqi.iask.in:31017/alipay/pay

如果后台没有报错的话,他会自动重定向到,支付宝的付款页面,如下图所示。这时候我们下载安装沙箱版的app,然后使用官方提供的账户扫描然后直接付款,付款成功后会回调后面那两个接口,在通知的那个接口里处理你的业务逻辑。 查看沙箱app的登录帐户名和密码

这里写图片描述

四、关注

如果有问题,请在下方评论,或者加群讨论 200909980

关注下方微信公众号,可以及时获取到各种技术的干货哦,如果你有想推荐的帖子,也可以联系我们的。

码农笔录二维码