• 支付宝当面付源码讲解


      1 //测试当面付2.0生成支付二维码相关代码:
      2 /**
      3 当面付二维码其实只是支付宝接口付款的一个分支,N个分支都在Main中写着,包括当面支付、查询订单、退款、生成二维码什么的,每一个功能都是一个class类,我们实际开发的时候,基本上用不了那么
      4 全,这时候我们就需要把我们所需要的一部分代码copy进来,自己修改,自己写参数,但是我们复制的有些个别函数,都是在全局事先声明好的,这时候我们也要把我们所能用到事先声明好的函数copy进来,
      5 这样才可以继续进行下去
      6 
      7 比如说当面付二维码class类的“tradeService”方法,就是是Main中事先声明好的全局变量,在Main中的静态代码块中声明的
      8 
      9         /** 一定要在创建AlipayTradeService之前调用Configs.init()设置默认参数
     10          *  Configs会读取classpath下的zfbinfo.properties文件配置信息,如果找不到该文件则确认该文件是否在classpath目录
     11          */
     12         Configs.init("zfbinfo.properties");
     13 
     14         /** 使用Configs提供的默认参数
     15          *  AlipayTradeService可以使用单例或者为静态成员对象,不需要反复new
     16          */
     17         tradeService = new AlipayTradeServiceImpl.ClientBuilder().build();
     18 
     19 */
     20 
     21         //〓〓〓〓 简单打印应答方法,在最下面会用到的
     22     private void dumpResponse(AlipayResponse response) {
     23         if (response != null) {
     24             log.info(String.format("code:%s, msg:%s", response.getCode(), response.getMsg()));
     25             if (StringUtils.isNotEmpty(response.getSubCode())) {
     26                 log.info(String.format("subCode:%s, subMsg:%s", response.getSubCode(),
     27                     response.getSubMsg()));
     28             }
     29             log.info("body:" + response.getBody());
     30         }
     31     }
     32 
     33 
     34 
     35 // 测试当面付2.0生成支付二维码
     36     public void test_trade_precreate() {
     37         //〓〓〓〓〓在这里是一个方法,当我们做项目的时候,要把这个方法加载到一个自己设置的类中,然后现在的日志应该该成类名.class
     38         //〓〓〓〓〓这个去百度查查日志的创建书写什么的就知道了
     39         private static final Logger logger = LoggerFactory.getLogger(test_trade_precreate.class);
     40 
     41         
     42         
     43         // (必填) 商户网站订单系统中唯一订单号,64个字符以内,只能包含字母、数字、下划线,
     44         // 需保证商户系统端不能重复,建议通过数据库sequence生成,
     45         String outTradeNo = "tradeprecreate" + System.currentTimeMillis()
     46                             + (long) (Math.random() * 10000000L);
     47                             //〓〓〓〓〓order.getOrderNo().toString(); 在前面获取的订单号
     48                             
     49         // (必填) 订单标题,粗略描述用户的支付目的。如“xxx品牌xxx门店当面付扫码消费”
     50         String subject = "xxx品牌xxx门店当面付扫码消费";
     51                         //〓〓〓〓new StringBuilder.append("扫码支付,订单号:").append(outTradeNo).toString();
     52                         
     53         // (必填) 订单总金额,单位为元,不能超过1亿元
     54         // 如果同时传入了【打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】
     55         String totalAmount = "0.01";
     56                             //〓〓〓〓order.getPayment().toString();
     57         // (可选) 订单不可打折金额,可以配合商家平台配置折扣活动,如果酒水不参与打折,则将对应金额填写至此字段
     58         // 如果该值未传入,但传入了【订单总金额】,【打折金额】,则该值默认为【订单总金额】-【打折金额】
     59         String undiscountableAmount = "0";
     60 
     61         // 卖家支付宝账号ID,用于支持一个签约账号下支持打款到不同的收款账号,(打款到sellerId对应的支付宝账号)
     62         // 如果该字段为空,则默认为与支付宝签约的商户的PID,也就是appid对应的PID
     63         String sellerId = "";
     64                         //〓〓〓〓无所谓,空着就行。
     65         // 订单描述,可以对交易或商品进行一个详细地描述,比如填写"购买商品2件共15.00元"
     66         String body = "购买商品3件共20.00元";
     67                     //〓〓〓〓new StringBuilder().append("订单").append(outTradeNo).append("共卖商品共").append(totalAmount).append("元").toString();
     68         // 商户操作员编号,添加此参数可以为商户操作员做销售统计
     69         String operatorId = "test_operator_id";
     70 
     71         // (必填) 商户门店编号,通过门店号和商家后台可以配置精准到门店的折扣信息,详询支付宝技术支持
     72         String storeId = "test_store_id";
     73 
     74         // 业务扩展参数,目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法),详情请咨询支付宝技术支持
     75         ExtendParams extendParams = new ExtendParams();
     76         extendParams.setSysServiceProviderId("2088100200300400500");
     77 
     78         // 支付超时,定义为120分钟
     79         String timeoutExpress = "120m";
     80 
     81         // 商品明细列表,需填写购买商品详细信息,
     82         List<GoodsDetail> goodsDetailList = new ArrayList<GoodsDetail>();
     83         //〓〓〓〓〓在这里传过来一个方法, 用来查找商品订单表
     84 //〓〓〓〓〓        List<OrderItem> orderItemList = orderItemMapper.getByOrderNoUserID(orderNo,userID);
     85 //〓〓〓〓〓        for(OrderIter orderItem : orderItemList){
     86 //〓〓〓〓〓这个参数是商品的ID和名字          GoodsDetail goods1 = GoodsDetail.newInstance(orderItem.getProductId().toString(),orderItem.getProductNmame(), 
     87 //〓〓〓〓〓这个是单价,但是需要乘法运算,这里有Util工具      BigDecimalUtil.mul(orderItem.getCurrentUnitPrice().doubleValue(),new Double(100).doubleValue()).long(), 
     88 //〓〓〓〓〓这个是商品的是数量,直接获取就好          orderItem.getQuantity());
     89 //〓〓〓〓〓        }
     90 //〓〓〓〓〓这里把取到的数据,加到上面支付宝给出的集合里面就好        orderItemList.add(orderItem);
     91         // 创建一个商品信息,参数含义分别为商品id(使用国标)、名称、单价(单位为分)、数量,如果需要添加商品类别,详见GoodsDetail
     92 /**
     93       GoodsDetail goods1 = GoodsDetail.newInstance("goods_id001", "xxx小面包", 1000, 1);
     94         // 创建好一个商品后添加至商品明细列表
     95         goodsDetailList.add(goods1);
     96                             〓〓〓〓〓 这里都是系统给出的例子,在上面我们已经获取到商品的数据了,这两个我们就直接删除掉就好                
     97         // 继续创建并添加第一条商品信息,用户购买的产品为“黑人牙刷”,单价为5.00元,购买了两件
     98         GoodsDetail goods2 = GoodsDetail.newInstance("goods_id002", "xxx牙刷", 500, 2);
     99         goodsDetailList.add(goods2);
    100 */  
    101         // 创建扫码支付请求builder,设置请求参数
    102         AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder()
    103             .setSubject(subject).setTotalAmount(totalAmount).setOutTradeNo(outTradeNo)
    104             .setUndiscountableAmount(undiscountableAmount).setSellerId(sellerId).setBody(body)
    105             .setOperatorId(operatorId).setStoreId(storeId).setExtendParams(extendParams)
    106             .setTimeoutExpress(timeoutExpress)    //这就是回调地址
    107             .setNotifyUrl("http://www.test-notify-url.com")//〓〓〓〓〓这个回调地址在沙箱里面可以找到,直接复制到这里面就好
    108             //                .setNotifyUrl("http://www.test-notify-url.com")//支付宝服务器主动通知商户服务器里指定的页面http路径,根据需要设置
    109             .setGoodsDetailList(goodsDetailList);
    110 
    111                     /** 一定要在创建AlipayTradeService之前调用Configs.init()设置默认参数
    112          *  Configs会读取classpath下的zfbinfo.properties文件配置信息,如果找不到该文件则确认该文件是否在classpath目录
    113          */
    114    //〓〓〓〓〓     Configs.init("zfbinfo.properties");
    115           //这两句代码都是在静态代码块中声明的
    116         /** 使用Configs提供的默认参数
    117          *  AlipayTradeService可以使用单例或者为静态成员对象,不需要反复new
    118          */
    119     //〓〓〓〓〓    AlipayTradeService tradeService = new AlipayTradeServiceImpl.ClientBuilder().build();
    120             
    121             
    122             
    123             
    124             
    125             
    126         AlipayF2FPrecreateResult result = tradeService.tradePrecreate(builder);
    127         switch (result.getTradeStatus()) {
    128             case SUCCESS:
    129                 log.info("支付宝预下单成功: )");
    130         //〓〓〓〓 在这里,“log”是未声明的日志,我们需要在类上面需要设置一个日志,详情请看此类上面。
    131         //〓〓〓〓 在上面创建完成日志之后,我们就需要吧log改成我们创建的:“logger” 就ok了
    132                 AlipayTradePrecreateResponse response = result.getResponse();
    133                 
    134                 //〓〓〓〓这个是打印响应的方法,在Main类中有声明这个的方法,我们直接复制下来就好,如果想看的话,就去上面看吧
    135                 dumpResponse(response);
    136 
    137                 
    138                 //〓〓〓〓这里是下单成功,我们就要生成二维码了,把二维码传到服务器上面,然后二维码传输给前端,是一个比较关键的一点
    139                 //〓〓〓〓下面我们创建一个File,判断是否有文件夹,如果没有的话,我们就创建一个文件夹,否则二维码就不知道该生成到什么地方了
    140                 File folder = new File(path);
    141                 if(!folder.exists()){
    142                     folder.serWritable(true);
    143                     folder.mkdirs();
    144                 }
    145                     
    146                 
    147                 
    148                 // 需要修改为运行机器上的路径
    149                 String qrPath = String.format(path+"/qr-%s.png",response.getOutTradeNo());
    150                 //〓〓〓〓在这里我们就需要创建一个文件名了    后面跟着的那个就是订单号 
    151                 String qrFileName = String.format("qr-%s.png",response.getOutTradeNo());
    152                 //〓〓〓〓在这里我们就需要调用支付宝提供的一个方法了,把二维码生成的路径写上面 也有订单号码
    153                  ZxingUtils.getQRCodeImge(response.getQrCode(), 256, qrPath);
    154                  //〓〓〓〓这里需要用FTP把二维码上传到服务器,如果下面这段代码在eclipse中写的话会报异常,我们把异常抛出一下就好
    155                  //〓〓〓〓然后把抛出的错误打印个日志,说上传二维码异常
    156                  File targetFile = new File(path,qrFileName);
    157                  FTPUtil.uploadFile(Lists.newArrayList(targetFile));
    158                  //〓〓〓〓下面应该是把FTP的url地址放到map中
    159                  String qrUrl = PropertiesUtil.getProperty("这里是url地址,像数据库密码那样的文件")+targetFile.getName();
    160                  resuliMap.put("qrUrl",qrUrl);
    161                  return ServerResponse.creatBySuccess(resuliMap);
    162                  
    163                  
    164                 log.info("filePath:" + filePath);
    165                 //                ZxingUtils.getQRCodeImge(response.getQrCode(), 256, filePath);
    166                 break;
    167 
    168             case FAILED:
    169                 log.error("支付宝预下单失败!!!");
    170                 break;
    171 
    172             case UNKNOWN:
    173                 log.error("系统异常,预下单状态未知!!!");
    174                 break;
    175 
    176             default:
    177                 log.error("不支持的交易状态,交易返回异常!!!");
    178                 break;
    179         }
    180     }

     如果你感觉本文对你有帮助,欢迎进群一起探讨交流:点我加群

  • 相关阅读:
    基于 Docker 的 MySQL 主从复制搭建
    获取 Docker 容器的 IP 地址
    Maven 学习资料
    docker 中,修改了 mysql 配置,如何重启 mysql?
    TiDB 学习资料
    Sharding-JDBC 学习资料
    Druid(数据库连接池) 学习资料
    JWT 学习资料
    Maven 拥有三套相互独立的生命周期:clean、default、site
    Maven 生命周期的阶段与插件的目标之间的绑定关系
  • 原文地址:https://www.cnblogs.com/suiyisuixing/p/7453574.html
Copyright © 2020-2023  润新知