从零开始,到完全胜任alipay支付模块开发之项目集成alipay(第三篇)
首先复制Demo中配置文件 zfbinfo.properties
在项目工程WEB-INF 下新建lib 粘贴 下图alipay-xxx.jar
剩余jar不复制 而是在pom里面指定这些版本 版本号必须与下图一直
-
<!-- alipay --> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.10</version> </dependency> <dependency> <groupId>commons-configuration</groupId> <artifactId>commons-configuration</artifactId> <version>1.10</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>2.1</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-core</artifactId> <version>1.3</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency>
项目中创建根据Demo一样的包结构 复制两个类 是为了先在项目里把alipay跑通 然后集成
pom配置可以让maven 找到lib下的 jar
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> <encoding>UTF-8</encoding> <compilerArguments> <extdirs>${project.basedir}/src/main/webapp/WEB-INF/lib</extdirs> </compilerArguments> </configuration> </plugin>
复制Main 里面的 test_trade_precreate 方法放到自己的订单实现类里面 修改成自己的参数,都有注释很简单
简单看一下吧
public ServerResponse pay(Long orderNo,Integer userId,String path){ Map<String ,String> resultMap = Maps.newHashMap(); Order order = orderMapper.selectByUserIdAndOrderNo(userId,orderNo); if(order == null){ return ServerResponse.createByErrorMessage("用户没有该订单"); } resultMap.put("orderNo",String.valueOf(order.getOrderNo())); // (必填) 商户网站订单系统中唯一订单号,64个字符以内,只能包含字母、数字、下划线, // 需保证商户系统端不能重复,建议通过数据库sequence生成, String outTradeNo = order.getOrderNo().toString(); // (必填) 订单标题,粗略描述用户的支付目的。如“xxx品牌xxx门店当面付扫码消费” String subject = new StringBuilder().append("扫码支付,订单号:").append(outTradeNo).toString(); // (必填) 订单总金额,单位为元,不能超过1亿元 // 如果同时传入了【打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】 String totalAmount = order.getPayment().toString(); // (可选) 订单不可打折金额,可以配合商家平台配置折扣活动,如果酒水不参与打折,则将对应金额填写至此字段 // 如果该值未传入,但传入了【订单总金额】,【打折金额】,则该值默认为【订单总金额】-【打折金额】 String undiscountableAmount = "0"; // 卖家支付宝账号ID,用于支持一个签约账号下支持打款到不同的收款账号,(打款到sellerId对应的支付宝账号) // 如果该字段为空,则默认为与支付宝签约的商户的PID,也就是appid对应的PID String sellerId = ""; // 订单描述,可以对交易或商品进行一个详细地描述,比如填写"购买商品2件共15.00元" String body = new StringBuilder().append("订单").append(outTradeNo).append("购买商品共").append(totalAmount).append("元").toString(); // 商户操作员编号,添加此参数可以为商户操作员做销售统计 String operatorId = "test_operator_id"; // (必填) 商户门店编号,通过门店号和商家后台可以配置精准到门店的折扣信息,详询支付宝技术支持 String storeId = "test_store_id"; // 业务扩展参数,目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法),详情请咨询支付宝技术支持 ExtendParams extendParams = new ExtendParams(); extendParams.setSysServiceProviderId("2088100200300400500"); // 支付超时,定义为120分钟 String timeoutExpress = "120m"; // 商品明细列表,需填写购买商品详细信息, List<GoodsDetail> goodsDetailList = new ArrayList<GoodsDetail>(); List<OrderItem> orderItemList = orderItemMapper.getByOrderNoUserId(orderNo,userId); for(OrderItem orderItem : orderItemList){ GoodsDetail goods = GoodsDetail.newInstance(orderItem.getProductId().toString(), orderItem.getProductName(), BigDecimalUtil.mul(orderItem.getCurrentUnitPrice().doubleValue(),new Double(100).doubleValue()).longValue(), orderItem.getQuantity()); goodsDetailList.add(goods); } // 创建扫码支付请求builder,设置请求参数 AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder() .setSubject(subject).setTotalAmount(totalAmount).setOutTradeNo(outTradeNo) .setUndiscountableAmount(undiscountableAmount).setSellerId(sellerId).setBody(body) .setOperatorId(operatorId).setStoreId(storeId).setExtendParams(extendParams) .setTimeoutExpress(timeoutExpress) .setNotifyUrl(PropertiesUtil.getProperty("alipay.callback.url"))//支付宝服务器主动通知商户服务器里指定的页面http路径,根据需要设置 .setGoodsDetailList(goodsDetailList); AlipayF2FPrecreateResult result = tradeService.tradePrecreate(builder); switch (result.getTradeStatus()) { case SUCCESS: logger.info("支付宝预下单成功: )"); AlipayTradePrecreateResponse response = result.getResponse(); dumpResponse(response); File folder = new File(path); if(!folder.exists()){ folder.setWritable(true); folder.mkdirs(); } // 需要修改为运行机器上的路径 //细节细节细节 String qrPath = String.format(path+"/qr-%s.png",response.getOutTradeNo()); String qrFileName = String.format("qr-%s.png",response.getOutTradeNo()); ZxingUtils.getQRCodeImge(response.getQrCode(), 256, qrPath); File targetFile = new File(path,qrFileName); try { FTPUtil.uploadFile(Lists.newArrayList(targetFile)); } catch (IOException e) { logger.error("上传二维码异常",e); } logger.info("qrPath:" + qrPath); String qrUrl = PropertiesUtil.getProperty("ftp.server.http.prefix")+targetFile.getName(); resultMap.put("qrUrl",qrUrl); return ServerResponse.createBySuccess(resultMap); case FAILED: logger.error("支付宝预下单失败!!!"); return ServerResponse.createByErrorMessage("支付宝预下单失败!!!"); case UNKNOWN: logger.error("系统异常,预下单状态未知!!!"); return ServerResponse.createByErrorMessage("系统异常,预下单状态未知!!!"); default: logger.error("不支持的交易状态,交易返回异常!!!"); return ServerResponse.createByErrorMessage("不支持的交易状态,交易返回异常!!!"); } }
后续写一个支付的Demo会放到下面