| | |
| | | <version>4.4.3</version> |
| | | </dependency> |
| | | |
| | | <!--引入本地工行支付jar start--> |
| | | <!-- <dependency> |
| | | <groupId>com.icbc</groupId> |
| | | <artifactId>icbc</artifactId> |
| | | <version>v2</version> |
| | | <scope>system</scope> |
| | | <systemPath>${project.basedir}/lib/icbc-api-sdk-cop.jar</systemPath> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.icbc.api</groupId> |
| | | <artifactId>icbc</artifactId> |
| | | <version>v2</version> |
| | | <scope>system</scope> |
| | | <systemPath>${project.basedir}/lib/icbc-api-sdk-cop-io.jar</systemPath> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>cn.com.infosec</groupId> |
| | | <artifactId>icbc</artifactId> |
| | | <version>v2</version> |
| | | <scope>system</scope> |
| | | <systemPath>${project.basedir}/lib/icbc-ca.jar</systemPath> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>cn.com.infosecCrypto</groupId> |
| | | <artifactId>icbc</artifactId> |
| | | <version>v2</version> |
| | | <scope>system</scope> |
| | | <systemPath>${project.basedir}/lib/InfosecCrypto_Java1_02_JDK14+.jar</systemPath> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>proguard</groupId> |
| | | <artifactId>icbc</artifactId> |
| | | <version>v2</version> |
| | | <scope>system</scope> |
| | | <systemPath>${project.basedir}/lib/proguard.jar</systemPath> |
| | | </dependency>--> |
| | | <!--引入本地工行支付jar end--> |
| | | |
| | | <dependency> |
| | | <groupId>commons-codec</groupId> |
| | | <artifactId>commons-codec</artifactId> |
| | |
| | | <artifactId>spring-test</artifactId> |
| | | <version>5.1.3.RELEASE</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.qiniu</groupId> |
| | | <artifactId>qiniu-java-sdk</artifactId> |
| | | <version>[7.7.0, 7.10.99]</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.squareup.okhttp3</groupId> |
| | | <artifactId>okhttp</artifactId> |
| | | <version>3.14.4</version> |
| | | <scope>runtime</scope> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>cn.hutool</groupId> |
| | | <artifactId>hutool-all</artifactId> |
| | | <version>5.0.5</version> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | <build> |
| | |
| | | import com.stylefeng.guns.modular.system.service.*; |
| | | import com.stylefeng.guns.modular.system.util.ALiSendSms; |
| | | import com.stylefeng.guns.modular.system.util.ResultUtil; |
| | | import com.stylefeng.guns.modular.system.util.qiniuyun.QNYAuth; |
| | | import com.stylefeng.guns.modular.system.warpper.*; |
| | | import com.stylefeng.guns.modular.taxi.model.OrderTaxi; |
| | | import com.stylefeng.guns.modular.taxi.service.IOrderTaxiService; |
| | |
| | | return ResultUtil.runErr(); |
| | | } |
| | | } |
| | | |
| | | |
| | | @ResponseBody |
| | | @PostMapping("/base/driver/getQnyToken") |
| | | @ApiOperation(value = "获取七牛云token", tags = {"司机端-个人中心"}, notes = "") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(value = "上传key", name = "key", required = true, dataType = "string"), |
| | | }) |
| | | public ResultUtil getQnyToken(String key){ |
| | | try { |
| | | String s = QNYAuth.create("6DqM0CEdAVON3mL3C6E23Vuj--635Q1hdjOwnpXw", "q35tZkQjvBCRkDsfWksY3PCr3wqUuJlodE7EF5qg") |
| | | .uploadToken("rbkj-zycx", key); |
| | | return ResultUtil.success(s); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | return ResultUtil.runErr(); |
| | | } |
| | | } |
| | | } |
| | |
| | | //添加已收入明细 |
| | | Line line = lineService.selectById(orderCrossCity.getLineId()); |
| | | Double speMoney = Double.valueOf(line.getRakeRate()); |
| | | BigDecimal d = new BigDecimal(orderCrossCity.getOrderMoney()).multiply(new BigDecimal(speMoney).divide(new BigDecimal(100))).setScale(2, BigDecimal.ROUND_HALF_EVEN);//企业收入 |
| | | BigDecimal d = new BigDecimal(orderCrossCity.getOrderMoney()).multiply(new BigDecimal(speMoney).divide(new BigDecimal(100), new MathContext(2, RoundingMode.HALF_EVEN))).setScale(2, BigDecimal.ROUND_HALF_EVEN);//企业收入 |
| | | BigDecimal c = new BigDecimal(orderCrossCity.getOrderMoney()).subtract(d).setScale(2, BigDecimal.ROUND_HALF_EVEN);//司机收入 |
| | | incomeService.saveData(1, orderCrossCity.getCompanyId(), 2, orderCrossCity.getId(), 1, d.doubleValue()); |
| | | incomeService.saveData(2, orderCrossCity.getDriverId(), 2, orderCrossCity.getId(), 1, c.doubleValue()); |
| | |
| | | orderCrossCity.setCouponId(null); |
| | | |
| | | if(payType == 1){//微信支付 |
| | | ResultUtil resultUtil1 = payMoneyUtil.weixinpay("完成订单",orderId+"",orderId + ",3",orderMoney+"","/base/wxPayCrossCity","APP"); |
| | | //Map<String, String> map = icbcPayUtil.placeAnOrder(orderId + ",3", 9, 5, uid.toString(), "完成订单", orderMoney, callbackPath + "/base/wxPayCrossCity", "", type, null); |
| | | ResultUtil resultUtil1 = payMoneyUtil.weixinpay("完成订单",orderId+"",orderId + ",3",orderMoney+"","/base/wxPayCrossCity","APP", ""); |
| | | if(resultUtil1.getCode()==200){ |
| | | paymentRecordService.saveData(1, null, null, orderId, 3, 1, orderMoney, null, 1);//添加预支付数据 |
| | | resultUtil = resultUtil1; |
| | |
| | | } |
| | | } |
| | | if(payType == 2){//支付宝支付 |
| | | ResultUtil resultUtil1 = payMoneyUtil.alipay("完成订单","完成订单",orderId + ",3",orderMoney+"","/base/aliPayCrossCity"); |
| | | //Map<String, String> map = icbcPayUtil.placeAnOrder(orderId + ",3", 10, 5, uid.toString(), "完成订单", orderMoney, callbackPath + "/base/aliPayCrossCity", "", type, null); |
| | | ResultUtil resultUtil1 = payMoneyUtil.alipay("完成订单","完成订单",orderId + ",3",orderMoney+"","/base/aliPayCrossCity", ""); |
| | | if(resultUtil1.getCode()==200){ |
| | | paymentRecordService.saveData(1, null, null, orderId, 3, 2, orderMoney, null, 1);//添加预支付数据 |
| | | resultUtil = resultUtil1; |
| | |
| | | //添加已收入明细 |
| | | Line line = lineService.selectById(orderCrossCity.getLineId()); |
| | | Double speMoney = Double.valueOf(line.getRakeRate()); |
| | | BigDecimal d = new BigDecimal(orderCrossCity.getOrderMoney()).multiply(new BigDecimal(speMoney).divide(new BigDecimal(100))).setScale(2, BigDecimal.ROUND_HALF_EVEN);//企业收入 |
| | | BigDecimal d = new BigDecimal(orderCrossCity.getOrderMoney()).multiply(new BigDecimal(speMoney).divide(new BigDecimal(100), new MathContext(2, RoundingMode.HALF_EVEN))).setScale(2, BigDecimal.ROUND_HALF_EVEN);//企业收入 |
| | | BigDecimal c = new BigDecimal(orderCrossCity.getOrderMoney()).subtract(d).setScale(2, BigDecimal.ROUND_HALF_EVEN);//司机收入 |
| | | incomeService.saveData(1, orderCrossCity.getCompanyId(), 2, orderCrossCity.getId(), 3, d.doubleValue()); |
| | | incomeService.saveData(2, orderCrossCity.getDriverId(), 2, orderCrossCity.getId(), 3, c.doubleValue()); |
| | |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.math.BigDecimal; |
| | | import java.math.MathContext; |
| | | import java.math.RoundingMode; |
| | | import java.util.*; |
| | | |
| | | |
| | |
| | | } |
| | | if(company.getIsSpeFixedOrProportional() == 1){//比例 |
| | | Double price = orderLogistics.getTravelMoney(); |
| | | d = new BigDecimal(price).multiply(new BigDecimal(speMoney).divide(new BigDecimal(100))).setScale(2, BigDecimal.ROUND_HALF_EVEN); |
| | | d = new BigDecimal(price).multiply(new BigDecimal(speMoney).divide(new BigDecimal(100), new MathContext(2, RoundingMode.HALF_EVEN))).setScale(2, BigDecimal.ROUND_HALF_EVEN); |
| | | c = new BigDecimal(orderLogistics.getOrderMoney()).subtract(d).setScale(2, BigDecimal.ROUND_HALF_EVEN); |
| | | } |
| | | incomeService.saveData(1, orderLogistics.getCompanyId(), 2, orderLogistics.getId(), orderLogistics.getType(), d.doubleValue()); |
| | |
| | | import java.io.FileWriter; |
| | | import java.io.PrintWriter; |
| | | import java.math.BigDecimal; |
| | | import java.math.MathContext; |
| | | import java.math.RoundingMode; |
| | | import java.util.*; |
| | | |
| | | |
| | |
| | | } |
| | | if(company.getIsSpeFixedOrProportional() == 1){//比例 |
| | | Double price = orderPrivateCar.getStartMoney() + orderPrivateCar.getMileageMoney() + orderPrivateCar.getWaitMoney() + orderPrivateCar.getDurationMoney() + orderPrivateCar.getLongDistanceMoney(); |
| | | d = new BigDecimal(price).multiply(new BigDecimal(speMoney).divide(new BigDecimal(100))).setScale(2, BigDecimal.ROUND_HALF_EVEN); |
| | | d = new BigDecimal(price).multiply(new BigDecimal(speMoney).divide(new BigDecimal(100), new MathContext(2, RoundingMode.HALF_EVEN))).setScale(2, BigDecimal.ROUND_HALF_EVEN); |
| | | c = new BigDecimal(orderPrivateCar.getOrderMoney()).subtract(d).setScale(2, BigDecimal.ROUND_HALF_EVEN); |
| | | } |
| | | incomeService.saveData(1, orderPrivateCar.getCompanyId(), 2, orderPrivateCar.getId(), 1, d.doubleValue()); |
| | |
| | | package com.stylefeng.guns.modular.system.service.impl; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.mapper.EntityWrapper; |
| | | import com.baomidou.mybatisplus.service.impl.ServiceImpl; |
| | |
| | | |
| | | @Autowired |
| | | private RedisUtil redisUtil; |
| | | |
| | | @Autowired |
| | | private ALiSendSms aLiSendSms; |
| | | |
| | | @Autowired |
| | | private SMSUtil smsUtil; |
| | | |
| | | @Autowired |
| | | private ICompanyCityService companyCityService; |
| | |
| | | templateCode = "SMS_207770039";//修改密码 |
| | | break; |
| | | } |
| | | Map<String, Object> map = new HashMap<>(); |
| | | map.put("code", authCode); |
| | | smsUtil.sendSmsTp(phone, 96596L, Arrays.asList(map)); |
| | | // String sData = aLiSendSms.sendSms(phone, templateCode, "{\"code\":\"" + authCode + "\"}"); |
| | | // JSONObject jsonObject = JSON.parseObject(sData); |
| | | // String message = jsonObject.getString("Message"); |
| | | // if(!"OK".equals(message)){ |
| | | // return ResultUtil.error(""); |
| | | // } |
| | | //发送记录集合 |
| | | JSONArray records = new JSONArray(); |
| | | JSONObject record = new JSONObject(); |
| | | //手机号 |
| | | record.put("mobile", phone); |
| | | //替换变量 |
| | | JSONObject param = new JSONObject(); |
| | | param.put("code", authCode); |
| | | record.put("tpContent", param); |
| | | records.add(record); |
| | | SMSUtil.sendSmsTp(96596L, records); |
| | | System.out.println(sms); |
| | | return ResultUtil.success(); |
| | | } |
| | |
| | | loginWarpper.setAppid(UUIDUtil.getRandomCode()); |
| | | |
| | | //创建高德猎鹰的终端数据 |
| | | String tid = gdFalconUtil.createTerminal(phone); |
| | | loginWarpper.setServerId(gdFalconUtil.getServerId()); |
| | | loginWarpper.setTerminalId(tid); |
| | | // String tid = gdFalconUtil.createTerminal(phone); |
| | | // loginWarpper.setServerId(gdFalconUtil.getServerId()); |
| | | // loginWarpper.setTerminalId(tid); |
| | | if(driver.getCompanyId()==null){ |
| | | loginWarpper.setJumpCode("100000"); |
| | | }else{ |
| | |
| | | if(null != reassign.getPayType()){ |
| | | if(reassign.getPayType() == 1){//微信支付 |
| | | reassign.setState(1); |
| | | ResultUtil resultUtil1 = payMoneyUtil.weixinpay("改派订单",reassign.getId()+"",reassign.getId() + "_" + reassign.getOrderType(),aDouble+"","/base/wxReassign","APP"); |
| | | ResultUtil resultUtil1 = payMoneyUtil.weixinpay("改派订单",reassign.getId()+"",reassign.getId() + "_" + reassign.getOrderType(),aDouble+"","/base/wxReassign","APP", ""); |
| | | //Map<String, String> map = icbcPayUtil.placeAnOrder(reassign.getId() + "_" + reassign.getOrderType(), 9, 5, uid.toString(), "改派订单", aDouble, callbackPath + "/base/wxReassign", "", type, driver.getAppletsOpenId()); |
| | | if(resultUtil1.getCode()==200){ |
| | | paymentRecordService.saveData(1, null, null, reassign.getOrderId(), reassign.getOrderType(), 1, aDouble, null, 1);//添加预支付数据 |
| | |
| | | } |
| | | if(reassign.getPayType() == 2){//支付宝 |
| | | reassign.setState(1); |
| | | ResultUtil resultUtil1 = payMoneyUtil.alipay("改派订单","改派订单",reassign.getId() + "_" + reassign.getOrderType(),aDouble+"","/base/aliReassign"); |
| | | ResultUtil resultUtil1 = payMoneyUtil.alipay("改派订单","改派订单",reassign.getId() + "_" + reassign.getOrderType(),aDouble+"","/base/aliReassign", ""); |
| | | //Map<String, String> map = icbcPayUtil.placeAnOrder(reassign.getId() + "_" + reassign.getOrderType(), 10, 5, uid.toString(), "改派订单", aDouble, callbackPath + "/base/aliReassign", "", 2, ""); |
| | | if(resultUtil1.getCode()==200){ |
| | | paymentRecordService.saveData(1, null, null, reassign.getOrderId(), reassign.getOrderType(), 2, aDouble, null, 1);//添加预支付数据 |
| | |
| | | if(null != reassign.getPayType()){ |
| | | if(reassign.getPayType() == 1){//微信支付 |
| | | String[] split1 = ids.split(","); |
| | | resultUtil = payMoneyUtil.weixinpay("改派订单",ids+"",ids + "_3",totalMoney+"","/base/wxReassign","APP"); |
| | | resultUtil = payMoneyUtil.weixinpay("改派订单",ids+"",ids + "_3",totalMoney+"","/base/wxReassign","APP", ""); |
| | | //Map<String, String> map = icbcPayUtil.placeAnOrder(ids + "_3", 9, 5, uid.toString(), "改派订单", totalMoney, callbackPath + "/base/wxReassign", "", type, driver.getAppletsOpenId()); |
| | | if(resultUtil.getCode()==200){ |
| | | for(String id : split1){ |
| | |
| | | } |
| | | if(reassign.getPayType() == 2){//支付宝 |
| | | String[] split1 = ids.split(","); |
| | | resultUtil = payMoneyUtil.alipay("改派订单","v",ids + "_3",totalMoney+"","/base/aliReassign"); |
| | | resultUtil = payMoneyUtil.alipay("改派订单","v",ids + "_3",totalMoney+"","/base/aliReassign", ""); |
| | | //Map<String, String> map = icbcPayUtil.placeAnOrder(ids + "_3", 10, 5, uid.toString(), "改派订单", totalMoney, callbackPath + "/base/aliReassign", "", 2, ""); |
| | | if(resultUtil.getCode()==200){ |
| | | for(String id : split1){ |
| | |
| | | package com.stylefeng.guns.modular.system.util; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import org.apache.http.NameValuePair; |
| | | import org.apache.http.client.config.RequestConfig; |
| | | import org.apache.http.client.entity.UrlEncodedFormEntity; |
| | | import org.apache.http.client.methods.CloseableHttpResponse; |
| | | import org.apache.http.client.methods.HttpGet; |
| | | import org.apache.http.client.methods.HttpPost; |
| | | import org.apache.http.entity.ContentType; |
| | | import org.apache.http.entity.EntityTemplate; |
| | | import org.apache.http.conn.ssl.SSLConnectionSocketFactory; |
| | | import org.apache.http.entity.StringEntity; |
| | | import org.apache.http.impl.client.CloseableHttpClient; |
| | | import org.apache.http.impl.client.HttpClients; |
| | | import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; |
| | | import org.apache.http.message.BasicNameValuePair; |
| | | import org.apache.http.ssl.SSLContexts; |
| | | import org.apache.http.util.EntityUtils; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.net.ssl.SSLContext; |
| | | import java.io.File; |
| | | import java.io.FileInputStream; |
| | | import java.io.IOException; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.io.InputStream; |
| | | import java.nio.charset.Charset; |
| | | import java.security.KeyStore; |
| | | import java.util.*; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * http工具类 |
| | |
| | | * 创建一个httpClient对象 |
| | | */ |
| | | private void getHttpCline(){ |
| | | this.httpClient = HttpClients.createDefault(); |
| | | //1.创建连接池管理器 |
| | | PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(60000, |
| | | TimeUnit.MILLISECONDS); |
| | | connectionManager.setMaxTotal(1000); |
| | | connectionManager.setDefaultMaxPerRoute(50); |
| | | |
| | | //2.创建httpclient对象 |
| | | this.httpClient = HttpClients.custom() |
| | | .setConnectionManager(connectionManager) |
| | | .disableAutomaticRetries() |
| | | .build(); |
| | | } |
| | | |
| | | private void setRequestConfig(){ |
| | | |
| | | private RequestConfig getRequestConfig(){ |
| | | return RequestConfig.custom() |
| | | .setConnectTimeout(60000) |
| | | .setSocketTimeout(60000) |
| | | .build(); |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | private void setPostHttpRequset(String url, Map<String, Object> params, Map<String, String> header, String contentType){ |
| | | HttpPost httpPost = new HttpPost(url); |
| | | httpPost.setConfig(this.getRequestConfig()); |
| | | if(null != header){ |
| | | for(String key : header.keySet()){ |
| | | httpPost.setHeader(key, header.get(key)); |
| | |
| | | try { |
| | | switch (contentType){ |
| | | case "form": |
| | | httpPost.setEntity(new UrlEncodedFormEntity(list)); |
| | | httpPost.setEntity(new UrlEncodedFormEntity(list, "UTF-8")); |
| | | break; |
| | | case "json": |
| | | String s = JSON.toJSONString(params); |
| | | ObjectMapper objectMapper = new ObjectMapper(); |
| | | String s =objectMapper.writeValueAsString(params); |
| | | System.err.println(s); |
| | | httpPost.setEntity(new StringEntity(s, ContentType.APPLICATION_JSON)); |
| | | httpPost.setEntity(new StringEntity(s, Charset.forName("UTF-8"))); |
| | | break; |
| | | } |
| | | this.getHttpCline(); |
| | | if(null == this.httpClient){ |
| | | this.getHttpCline(); |
| | | } |
| | | httpResponse = this.httpClient.execute(httpPost); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | |
| | | } |
| | | } |
| | | this.getHttpCline(); |
| | | if(null == this.httpClient){ |
| | | this.getHttpCline(); |
| | | } |
| | | try { |
| | | httpResponse = this.httpClient.execute(httpGet); |
| | | } catch (IOException e) { |
| | |
| | | if(httpResponse.getStatusLine().getStatusCode() == 200){ |
| | | try { |
| | | content = EntityUtils.toString(httpResponse.getEntity()); |
| | | this.close(); |
| | | return content; |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | this.close(); |
| | | } |
| | | } |
| | | if(httpResponse.getStatusLine().getStatusCode() == 201){ |
| | | content = "{\"status\":201}"; |
| | | this.close(); |
| | | return content; |
| | | }else{ |
| | | try { |
| | | content = "返回状态码:" + httpResponse.getStatusLine() + "。" + EntityUtils.toString(httpResponse.getEntity()); |
| | | System.err.println("返回状态码:" + httpResponse.getStatusLine() + "。"); |
| | | content = EntityUtils.toString(httpResponse.getEntity()); |
| | | this.close(); |
| | | return content; |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | this.close(); |
| | |
| | | try { |
| | | httpPost.setEntity(new StringEntity(xml, "UTF-8")); |
| | | this.getHttpCline(); |
| | | if(null == this.httpClient){ |
| | | this.getHttpCline(); |
| | | } |
| | | httpResponse = this.httpClient.execute(httpPost); |
| | | String content = null; |
| | | if(httpResponse.getStatusLine().getStatusCode() == 200){ |
| | | try { |
| | | content = EntityUtils.toString(httpResponse.getEntity(), "UTF-8"); |
| | | this.close(); |
| | | return content; |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | this.close(); |
| | | } |
| | | }else{ |
| | | try { |
| | | content = "返回状态码:" + httpResponse.getStatusLine() + "。" + EntityUtils.toString(httpResponse.getEntity()); |
| | | this.close(); |
| | | return content; |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | this.close(); |
| | | } |
| | | } |
| | | this.close(); |
| | | return content; |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | this.close(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 请求https发送XML请求 |
| | | * @param url 接口路径 |
| | | * @param xml 内容 |
| | | * @param header 请求头 |
| | | * @param certPassword 证书密码 |
| | | * @param certPath 证书路径 |
| | | * @param certType 证书类型 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public String pushHttpsRequsetXml(String url, String xml, Map<String, String> header, String certPassword, String certPath, String certType) throws Exception{ |
| | | HttpPost httpPost = new HttpPost(url); |
| | | for(String key : header.keySet()){ |
| | | httpPost.setHeader(key, header.get(key)); |
| | | } |
| | | httpPost.setHeader("Content-Type", "application/xml"); |
| | | try { |
| | | httpPost.setEntity(new StringEntity(xml, "UTF-8")); |
| | | this.getHttpCline(); |
| | | this.initCert(certPassword, certPath, certType); |
| | | httpResponse = this.httpClient.execute(httpPost); |
| | | String content = null; |
| | | if(httpResponse.getStatusLine().getStatusCode() == 200){ |
| | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 初始化https对象(带证书) |
| | | * @param key 证书密码 |
| | | * @param certPath 证书路径 |
| | | * @param certType 证书类型 |
| | | * @throws Exception |
| | | */ |
| | | private void initCert(String key, String certPath, String certType) throws Exception { |
| | | KeyStore keyStore = KeyStore.getInstance(certType); |
| | | // ClassPathResource cp = new ClassPathResource(certPath); |
| | | InputStream inputStream = new FileInputStream(new File(certPath)); |
| | | // InputStream instream = cp.getInputStream(); |
| | | try { |
| | | keyStore.load(inputStream, key.toCharArray()); |
| | | } finally { |
| | | inputStream.close(); |
| | | } |
| | | SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, key.toCharArray()).build(); |
| | | SSLConnectionSocketFactory sslsf = |
| | | new SSLConnectionSocketFactory(sslcontext, new String[] {"TLSv1"}, null, |
| | | SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); |
| | | this.httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 关闭资源 |
| | | */ |
| | | private void close(){ |
| | | try { |
| | | httpClient.close(); |
| | | httpResponse.close(); |
| | | if(null != httpClient){ |
| | | httpClient.close(); |
| | | } |
| | | if(null != httpResponse){ |
| | | httpResponse.close(); |
| | | } |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | }finally { |
| | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.alipay.api.AlipayApiException; |
| | | import com.alipay.api.AlipayClient; |
| | | import com.alipay.api.CertAlipayRequest; |
| | | import com.alipay.api.DefaultAlipayClient; |
| | | import com.alipay.api.domain.AlipayTradeAppPayModel; |
| | | import com.alipay.api.domain.AlipayTradeRefundModel; |
| | | import com.alipay.api.internal.util.AlipaySignature; |
| | | import com.alipay.api.request.AlipayTradeAppPayRequest; |
| | | import com.alipay.api.request.AlipayTradePrecreateRequest; |
| | | import com.alipay.api.request.AlipayTradeQueryRequest; |
| | | import com.alipay.api.request.AlipayTradeRefundRequest; |
| | | import com.alipay.api.response.AlipayTradeAppPayResponse; |
| | | import com.alipay.api.response.AlipayTradePrecreateResponse; |
| | | import com.alipay.api.response.AlipayTradeQueryResponse; |
| | | import com.alipay.api.response.AlipayTradeRefundResponse; |
| | | import com.alipay.api.request.*; |
| | | import com.alipay.api.response.*; |
| | | import org.apache.commons.collections.map.HashedMap; |
| | | import org.bouncycastle.jce.provider.BouncyCastleProvider; |
| | | import org.dom4j.Document; |
| | |
| | | @Value("${wx.appid}") |
| | | private String appid;//微信appid |
| | | |
| | | @Value("${wx.appletsAppid}") |
| | | private String appletsAppid;//微信小程序appid |
| | | |
| | | @Value("${wx.mchId}") |
| | | private String mchId;//微信商户号 |
| | | |
| | |
| | | |
| | | @Value("${callbackPath}") |
| | | private String callbackPath;//支付回调网关地址 |
| | | |
| | | private String app_cert_path = "";//应用公钥证书路径 |
| | | |
| | | private String alipay_cert_path = "";//支付宝公钥证书文件路径 |
| | | |
| | | private String alipay_root_cert_path = "";//支付宝CA根证书文件路径 |
| | | |
| | | @Autowired |
| | | private HttpClientUtil httpClientUtil; |
| | |
| | | /** |
| | | * 支付宝支付 |
| | | */ |
| | | public ResultUtil alipay(String body, String subject, String outTradeNo, String amount, String notifyUrl){ |
| | | //实例化客户端 |
| | | AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", aliAppid, appPrivateKey, "json", "UTF-8", alipayPublicKey, "RSA2"); |
| | | //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay |
| | | AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest(); |
| | | //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。 |
| | | AlipayTradeAppPayModel model = new AlipayTradeAppPayModel(); |
| | | model.setBody(body);//对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body。 |
| | | model.setSubject(subject);//商品的标题/交易标题/订单标题/订单关键字等。 |
| | | model.setOutTradeNo(outTradeNo);//商户网站唯一订单号 |
| | | model.setTimeoutExpress("30m"); |
| | | model.setTotalAmount(amount);//付款金额 |
| | | model.setProductCode("QUICK_MSECURITY_PAY"); |
| | | request.setBizModel(model); |
| | | request.setNotifyUrl(callbackPath + notifyUrl); |
| | | public ResultUtil alipay(String body, String subject, String passbackParams, String outTradeNo, String amount, String notifyUrl){ |
| | | //构造client |
| | | CertAlipayRequest certAlipayRequest = new CertAlipayRequest (); |
| | | //设置网关地址 |
| | | certAlipayRequest.setServerUrl("https://openapi.alipay.com/gateway.do"); |
| | | //设置应用Id |
| | | certAlipayRequest.setAppId(aliAppid); |
| | | //设置应用私钥 |
| | | certAlipayRequest.setPrivateKey(appPrivateKey); |
| | | //设置请求格式,固定值json |
| | | certAlipayRequest.setFormat("json"); |
| | | //设置字符集 |
| | | certAlipayRequest.setCharset("UTF-8"); |
| | | //设置签名类型 |
| | | certAlipayRequest.setSignType("RSA2"); |
| | | //设置应用公钥证书路径 |
| | | certAlipayRequest.setCertPath(app_cert_path); |
| | | //设置支付宝公钥证书路径 |
| | | certAlipayRequest.setAlipayPublicCertPath(alipay_cert_path); |
| | | //设置支付宝根证书路径 |
| | | certAlipayRequest.setRootCertPath(alipay_root_cert_path); |
| | | //构造client |
| | | AlipayClient alipayClient = null; |
| | | try { |
| | | //这里和普通的接口调用不同,使用的是sdkExecute |
| | | AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request); |
| | | Map<String, String> map = new HashMap<>(); |
| | | map.put("orderString", response.getBody()); |
| | | System.out.println(map);//就是orderString 可以直接给客户端请求,无需再做处理。 |
| | | return ResultUtil.success(response.getBody()); |
| | | alipayClient = new DefaultAlipayClient(certAlipayRequest); |
| | | } catch (AlipayApiException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay |
| | | AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest (); |
| | | //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。 |
| | | AlipayTradeAppPayModel model = new AlipayTradeAppPayModel (); |
| | | model.setBody(body); |
| | | model.setSubject (subject); |
| | | model.setOutTradeNo (outTradeNo); |
| | | model.setTimeoutExpress ("30m" ); |
| | | model.setTotalAmount (amount); |
| | | model.setProductCode ( "QUICK_MSECURITY_PAY" ); |
| | | model.setPassbackParams(passbackParams);//自定义参数 |
| | | request.setBizModel ( model ); |
| | | request.setNotifyUrl (callbackPath + notifyUrl); |
| | | try { |
| | | //这里和普通的接口调用不同,使用的是sdkExecute |
| | | AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request); |
| | | System.out.println(response.getBody());//就是orderString 可以直接给客户端请求,无需再做处理。 |
| | | return ResultUtil.success(response.getBody()); |
| | | } catch (AlipayApiException e ) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | |
| | | // //实例化客户端 |
| | | // AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", aliAppid, appPrivateKey, "json", "UTF-8", alipay_public_key, "RSA2"); |
| | | // //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay |
| | | // AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest(); |
| | | // //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。 |
| | | // AlipayTradeAppPayModel model = new AlipayTradeAppPayModel(); |
| | | // model.setBody(body);//对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body。 |
| | | // model.setSubject(subject);//商品的标题/交易标题/订单标题/订单关键字等。 |
| | | // model.setOutTradeNo(outTradeNo);//商户网站唯一订单号 |
| | | // model.setTimeoutExpress("30m"); |
| | | // model.setTotalAmount(amount);//付款金额 |
| | | // model.setProductCode("QUICK_MSECURITY_PAY"); |
| | | // model.setPassbackParams(passbackParams);//自定义参数 |
| | | // request.setBizModel(model); |
| | | // request.setNotifyUrl(callbackPath + notifyUrl); |
| | | // try { |
| | | // //这里和普通的接口调用不同,使用的是sdkExecute |
| | | // AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request); |
| | | // Map<String, String> map = new HashMap<>(); |
| | | // map.put("orderString", response.getBody()); |
| | | // System.out.println(map);//就是orderString 可以直接给客户端请求,无需再做处理。 |
| | | // return ResultUtil.success(map); |
| | | // } catch (AlipayApiException e) { |
| | | // e.printStackTrace(); |
| | | // } |
| | | return null; |
| | | } |
| | | |
| | |
| | | String valueStr = ""; |
| | | for (int i = 0; i < values.length; i++) { |
| | | valueStr = (i == values.length - 1) ? valueStr + values[i] |
| | | : valueStr + values[i] + ","; |
| | | : valueStr + values[i] + "_"; |
| | | } |
| | | //乱码解决,这段代码在出现乱码时使用。 |
| | | //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8"); |
| | |
| | | } |
| | | //切记alipaypublickey是支付宝的公钥,请去open.alipay.com对应应用下查看。 |
| | | //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type) |
| | | try { |
| | | boolean flag = AlipaySignature.rsaCheckV1(params, alipayPublicKey, "UTF-8","RSA2"); |
| | | if(flag){ |
| | | Map<String, String> map = new HashMap<>(); |
| | | String out_trade_no = params.get("out_trade_no"); |
| | | String subject = params.get("subject"); |
| | | String total_amount = params.get("total_amount"); |
| | | String trade_no = params.get("trade_no"); |
| | | map.put("out_trade_no", out_trade_no);//商家订单号 |
| | | map.put("subject", subject); |
| | | map.put("total_amount", total_amount); |
| | | map.put("trade_no", trade_no);//支付宝交易号 |
| | | return map; |
| | | } |
| | | // try { |
| | | // boolean flag = AlipaySignature.rsaCheckV1(params, alipay_public_key, "UTF-8","RSA2"); |
| | | // if(flag){ |
| | | // Map<String, String> map = new HashMap<>(); |
| | | // String out_trade_no = params.get("out_trade_no"); |
| | | // String subject = params.get("subject"); |
| | | // String total_amount = params.get("total_amount"); |
| | | // String trade_no = params.get("trade_no"); |
| | | // String passback_params = params.get("passback_params"); |
| | | // map.put("out_trade_no", out_trade_no);//商家订单号 |
| | | // map.put("subject", subject); |
| | | // map.put("total_amount", total_amount); |
| | | // map.put("trade_no", trade_no);//支付宝交易号 |
| | | // map.put("passback_params", passback_params);//回传参数 |
| | | // return map; |
| | | // }else{ |
| | | // System.err.println("验签失败"); |
| | | // } |
| | | // |
| | | // } catch (AlipayApiException e) { |
| | | // e.printStackTrace(); |
| | | // } |
| | | // return null; |
| | | |
| | | } catch (AlipayApiException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return null; |
| | | |
| | | Map<String, String> map = new HashMap<>(); |
| | | String out_trade_no = params.get("out_trade_no"); |
| | | String subject = params.get("subject"); |
| | | String total_amount = params.get("total_amount"); |
| | | String trade_no = params.get("trade_no"); |
| | | String passback_params = params.get("passback_params"); |
| | | map.put("out_trade_no", out_trade_no);//商家订单号 |
| | | map.put("subject", subject); |
| | | map.put("total_amount", total_amount); |
| | | map.put("trade_no", trade_no);//支付宝交易号 |
| | | map.put("passback_params", passback_params);//回传参数 |
| | | return map; |
| | | } |
| | | |
| | | |
| | |
| | | * @param tradeType 交易类型 |
| | | * @return |
| | | */ |
| | | public ResultUtil weixinpay(String body, String attach, String out_trade_no, String total_fee, String notify_url, String tradeType) throws Exception{ |
| | | public ResultUtil weixinpay(String body, String attach, String out_trade_no, String total_fee, String notify_url, String tradeType, String openId) throws Exception{ |
| | | int i = new BigDecimal(total_fee).multiply(new BigDecimal("100")).intValue(); |
| | | String hostAddress = null; |
| | | try { |
| | |
| | | } |
| | | String nonce_str = UUIDUtil.getRandomCode(16); |
| | | Map<String, Object> map = new HashMap<>(); |
| | | map.put("appid", appid); |
| | | map.put("appid", "APP".equals(tradeType) ? appid : appletsAppid); |
| | | map.put("mch_id", mchId); |
| | | map.put("nonce_str", nonce_str); |
| | | map.put("body", body); |
| | |
| | | map.put("spbill_create_ip", hostAddress); |
| | | map.put("notify_url", callbackPath + notify_url); |
| | | map.put("trade_type", tradeType); |
| | | if("JSAPI".equals(tradeType)){ |
| | | map.put("openid", openId); |
| | | } |
| | | String s = this.weixinSignature(map); |
| | | map.put("sign", s); |
| | | |
| | |
| | | String result_code = map1.get("result_code"); |
| | | if("SUCCESS".equals(result_code)){ |
| | | String type = map1.get("trade_type"); |
| | | String prepay_id = map1.get("prepay_id"); |
| | | switch (type){ |
| | | case "JSAPI": |
| | | break; |
| | | //重新进行签名后返回给前端 |
| | | Map<String, Object> map2 = new HashMap<>(); |
| | | map2.put("appId", map1.get("appid")); |
| | | map2.put("nonceStr", map1.get("nonce_str")); |
| | | map2.put("package", "prepay_id=" + prepay_id); |
| | | map2.put("signType", "MD5"); |
| | | map2.put("timeStamp", new Date().getTime() + ""); |
| | | String s2 = this.weixinSignature(map2); |
| | | |
| | | map2.put("prepay_id", prepay_id); |
| | | map2.put("mch_id", map1.get("mch_id")); |
| | | map2.put("trade_type", map1.get("trade_type")); |
| | | |
| | | map2.put("sign", s2); |
| | | return ResultUtil.success(map2); |
| | | case "NATIVE": |
| | | String code_url = map1.get("code_url"); |
| | | return ResultUtil.success(code_url); |
| | | case "APP": |
| | | String prepay_id = map1.get("prepay_id"); |
| | | //重新进行签名后返回给前端 |
| | | Map<String, Object> map2 = new HashMap<>(); |
| | | map2.put("appid", appid); |
| | | map2.put("noncestr", nonce_str); |
| | | map2.put("package", "Sign=WXPay"); |
| | | map2.put("partnerid", mchId); |
| | | map2.put("prepayid", prepay_id); |
| | | map2.put("timestamp", new Date().getTime() / 1000); |
| | | String s1 = this.weixinSignature(map2); |
| | | map2.put("sign", s1); |
| | | System.err.println(map2); |
| | | return ResultUtil.success(map2); |
| | | Map<String, Object> map3 = new HashMap<>(); |
| | | map3.put("appid", appid); |
| | | map3.put("noncestr", nonce_str); |
| | | map3.put("package", "Sign=WXPay"); |
| | | map3.put("partnerid", mchId); |
| | | map3.put("prepayid", prepay_id); |
| | | map3.put("timestamp", new Date().getTime() / 1000); |
| | | String s1 = this.weixinSignature(map3); |
| | | map3.put("sign", s1); |
| | | System.err.println(map3); |
| | | return ResultUtil.success(map3); |
| | | } |
| | | return null; |
| | | }else{ |
| | |
| | | if("SUCCESS".equals(result_code)){ |
| | | Map<String, String> map1 = new HashedMap(); |
| | | map1.put("nonce_str", map.get("nonce_str")); |
| | | map1.put("out_trade_no", map.get("out_trade_no").split("_")[1]);//存储的订单code |
| | | map1.put("out_trade_no", map.get("out_trade_no"));//存储的订单code |
| | | map1.put("attach", map.get("attach"));//存储订单id |
| | | map1.put("total_fee", map.get("total_fee")); |
| | | map1.put("transaction_id", map.get("transaction_id"));//微信支付订单号 |
| | |
| | | map1.put("result", result); |
| | | return map1; |
| | | }else{ |
| | | // System.err.println(map.get("err_code_des")); |
| | | System.err.println(map.get("err_code_des")); |
| | | } |
| | | }else{ |
| | | // System.err.println(map.get("return_msg")); |
| | | System.err.println(map.get("return_msg")); |
| | | } |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | |
| | | map.put("total_fee", tf); |
| | | map.put("refund_fee", rf); |
| | | map.put("notify_url", callbackPath + notify_url); |
| | | String s = this.weixinSignature(map); |
| | | String s = this.weixinSignature(map, key); |
| | | map.put("sign", s); |
| | | |
| | | String url = "https://api.mch.weixin.qq.com/secapi/pay/refund"; |
| | |
| | | xmlString.append("</xml>"); |
| | | |
| | | Map<String, String> map1 = null; |
| | | String body1 = httpClientUtil.pushHttpRequsetXml(url, xmlString.toString(), new HashMap<>()); |
| | | String body1 = null; |
| | | try { |
| | | String certPath = "D:\\app\\cert\\weixin\\1487457552\\apiclient_cert.p12"; |
| | | body1 = httpClientUtil.pushHttpsRequsetXml(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | System.err.println(body1); |
| | | //将结果xml解析成map |
| | | body1 = body1.replaceAll("<!\\[CDATA\\[",""); |
| | | body1 = body1.replaceAll("]]>", ""); |
| | |
| | | Map<String, String> map1 = new HashMap<>(); |
| | | map1.put("refund_id", map.get("refund_id")); |
| | | map1.put("out_refund_no", map.get("out_refund_no")); |
| | | String result = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>"; |
| | | map1.put("result", result); |
| | | return map1; |
| | | }else{ |
| | | // System.err.println(map.get("return_msg")); |
| | |
| | | * @throws AlipayApiException |
| | | */ |
| | | public Map<String, String> aliRefund(String trade_no, String refund_amount) throws AlipayApiException { |
| | | AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", aliAppid, appPrivateKey,"json","UTF-8", alipay_public_key,"RSA2"); |
| | | AlipayTradeRefundRequest request = new AlipayTradeRefundRequest(); |
| | | JSONObject jsonObject = new JSONObject(); |
| | | jsonObject.put("trade_no", trade_no); |
| | | jsonObject.put("refund_amount", refund_amount); |
| | | request.setBizContent(jsonObject.toJSONString()); |
| | | AlipayTradeRefundResponse response = alipayClient.execute(request); |
| | | Map<String, String> map = new HashMap<>(); |
| | | if(response.isSuccess()){ |
| | | System.out.println("调用成功"); |
| | | String outTradeNo = response.getOutTradeNo(); |
| | | map.put("code", response.getCode());//10000 |
| | | map.put("trade_no", response.getTradeNo());//支付宝交易号 |
| | | map.put("out_trade_no", outTradeNo);//商户订单号 |
| | | } else { |
| | | System.out.println("调用失败"); |
| | | map.put("code", response.getCode()); |
| | | map.put("msg", response.getSubMsg()); |
| | | // AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", aliAppid, appPrivateKey,"json","UTF-8", alipay_public_key,"RSA2"); |
| | | // AlipayTradeRefundRequest request = new AlipayTradeRefundRequest(); |
| | | // JSONObject jsonObject = new JSONObject(); |
| | | // jsonObject.put("trade_no", trade_no); |
| | | // jsonObject.put("refund_amount", refund_amount); |
| | | // request.setBizContent(jsonObject.toJSONString()); |
| | | // AlipayTradeRefundResponse response = alipayClient.execute(request); |
| | | // Map<String, String> map = new HashMap<>(); |
| | | // if(response.isSuccess()){ |
| | | // System.out.println("调用成功"); |
| | | // String outTradeNo = response.getOutTradeNo(); |
| | | // map.put("code", response.getCode());//10000 |
| | | // map.put("trade_no", response.getTradeNo());//支付宝交易号 |
| | | // map.put("out_trade_no", outTradeNo);//商户订单号 |
| | | // } else { |
| | | // System.out.println("调用失败"); |
| | | // map.put("code", response.getCode()); |
| | | // map.put("msg", response.getSubMsg()); |
| | | // } |
| | | // return map; |
| | | |
| | | |
| | | //构造client |
| | | CertAlipayRequest certAlipayRequest = new CertAlipayRequest (); |
| | | //设置网关地址 |
| | | certAlipayRequest.setServerUrl("https://openapi.alipay.com/gateway.do"); |
| | | //设置应用Id |
| | | certAlipayRequest.setAppId(aliAppid); |
| | | //设置应用私钥 |
| | | certAlipayRequest.setPrivateKey(appPrivateKey); |
| | | //设置请求格式,固定值json |
| | | certAlipayRequest.setFormat("json"); |
| | | //设置字符集 |
| | | certAlipayRequest.setCharset("UTF-8"); |
| | | //设置签名类型 |
| | | certAlipayRequest.setSignType("RSA2"); |
| | | //设置应用公钥证书路径 |
| | | certAlipayRequest.setCertPath(app_cert_path); |
| | | //设置支付宝公钥证书路径 |
| | | certAlipayRequest.setAlipayPublicCertPath(alipay_cert_path); |
| | | //设置支付宝根证书路径 |
| | | certAlipayRequest.setRootCertPath(alipay_root_cert_path); |
| | | //构造client |
| | | AlipayClient alipayClient = null; |
| | | try { |
| | | alipayClient = new DefaultAlipayClient(certAlipayRequest); |
| | | } catch (AlipayApiException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return map; |
| | | //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay |
| | | AlipayTradeRefundRequest request = new AlipayTradeRefundRequest (); |
| | | //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。 |
| | | AlipayTradeRefundModel model = new AlipayTradeRefundModel (); |
| | | model.setTradeNo(trade_no); |
| | | model.setRefundAmount(refund_amount); |
| | | request.setBizModel ( model ); |
| | | try { |
| | | //这里和普通的接口调用不同,使用的是sdkExecute |
| | | AlipayTradeRefundResponse response = alipayClient.certificateExecute(request); |
| | | Map<String, String> map = new HashMap<>(); |
| | | if(response.isSuccess()){ |
| | | System.out.println("调用成功"); |
| | | String outTradeNo = response.getOutTradeNo(); |
| | | map.put("code", response.getCode());//10000 |
| | | map.put("trade_no", response.getTradeNo());//支付宝交易号 |
| | | map.put("out_trade_no", outTradeNo);//商户订单号 |
| | | } else { |
| | | System.out.println("调用失败"); |
| | | map.put("code", response.getCode()); |
| | | map.put("msg", response.getSubMsg()); |
| | | } |
| | | return map; |
| | | } catch (AlipayApiException e ) { |
| | | e.printStackTrace(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * 微信转账功能(企业付款到零钱) |
| | | * @param openid 商户appid下,某用户的openid |
| | | * @param desc 企业付款备注,必填。 |
| | | * @param total_fee 企业付款金额 |
| | | * @param partner_trade_no 商户订单号,需保持唯一性 |
| | | * @return |
| | | */ |
| | | public Map<String, String> wxTransfers(String openid, String desc, String total_fee, String partner_trade_no) throws Exception{ |
| | | int amount = new BigDecimal(total_fee).multiply(new BigDecimal("100")).intValue(); |
| | | String nonce_str = UUIDUtil.getRandomCode(); |
| | | Map<String, Object> map = new HashMap<>(); |
| | | map.put("mch_appid", appid);//申请商户号的appid或商户号绑定的appid |
| | | map.put("mchid", mchId);//微信支付分配的商户号 |
| | | map.put("nonce_str", nonce_str);//随机字符串,不长于32位 |
| | | map.put("partner_trade_no", partner_trade_no);//商户订单号,需保持唯一性 |
| | | map.put("openid", openid);//商户appid下,某用户的openid |
| | | map.put("check_name", "NO_CHECK");//NO_CHECK:不校验真实姓名 FORCE_CHECK:强校验真实姓名 |
| | | map.put("amount", amount);//企业付款金额,单位为分 |
| | | map.put("desc", desc);//企业付款备注,必填。 |
| | | String s = this.weixinSignature(map, key); |
| | | map.put("sign", s); |
| | | |
| | | String url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; |
| | | //设置请求头 |
| | | HttpHeaders headers = new HttpHeaders(); |
| | | headers.setContentType(MediaType.APPLICATION_XML); |
| | | StringBuffer xmlString = new StringBuffer(); |
| | | Set<String> strings = map.keySet(); |
| | | String[] keys = {}; |
| | | keys = strings.toArray(keys); |
| | | Arrays.sort(keys); |
| | | xmlString.append("<xml>"); |
| | | for(int l = 0; l < keys.length; l++){ |
| | | xmlString.append("<" + keys[l] + ">" + map.get(keys[l]) + "</" + keys[l] + ">"); |
| | | } |
| | | xmlString.append("</xml>"); |
| | | |
| | | Map<String, String> map1 = null; |
| | | String certPath = "D:\\app\\cert\\weixin\\1487457552\\apiclient_cert.p12";//证书地址 |
| | | String body1 = httpClientUtil.pushHttpsRequsetXml(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); |
| | | //将结果xml解析成map |
| | | body1 = body1.replaceAll("<!\\[CDATA\\[",""); |
| | | body1 = body1.replaceAll("]]>", ""); |
| | | try { |
| | | map1 = this.xmlToMap(body1, "UTF-8"); |
| | | } catch (UnsupportedEncodingException e) { |
| | | e.printStackTrace(); |
| | | } catch (DocumentException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | String return_code = map1.get("return_code"); |
| | | Map<String, String> map2 = new HashMap<>(); |
| | | if("SUCCESS".equals(return_code)){ |
| | | String result_code = map1.get("result_code"); |
| | | if("SUCCESS".equals(result_code)){ |
| | | map2.put("return_code", result_code); |
| | | map2.put("payment_no", String.valueOf(map1.get("payment_no")));//付款订单号 |
| | | map2.put("payment_time", String.valueOf(map1.get("payment_time")));//付款时间 |
| | | return map2; |
| | | }else{ |
| | | map2.put("return_code", result_code); |
| | | map2.put("err_code", map1.get("err_code")); |
| | | map2.put("err_code_des", map1.get("err_code_des")); |
| | | return map2; |
| | | } |
| | | }else{ |
| | | map2.put("return_code", return_code); |
| | | map2.put("return_msg", map1.get("return_msg")); |
| | | return map2; |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 微信转账功能(企业付款到银行卡) |
| | | * @param desc 备注信息 |
| | | * @param total_fee 转账金额 |
| | | * @param partner_trade_no 订单号 |
| | | * @param enc_bank_no 银行卡号 |
| | | * @param enc_true_name 收款方用户名 |
| | | * @param bankName 银行名称 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public Map<String, String> wxPayBank(String desc, String total_fee, String partner_trade_no, String enc_bank_no, String enc_true_name, String bankName) throws Exception{ |
| | | int amount = new BigDecimal(total_fee).multiply(new BigDecimal("100")).intValue(); |
| | | String nonce_str = UUIDUtil.getRandomCode(); |
| | | Map<String, Object> map = new HashMap<>(); |
| | | map.put("mch_id", mchId);//微信支付分配的商户号 |
| | | map.put("nonce_str", nonce_str);//随机字符串,不长于32位 |
| | | map.put("partner_trade_no", partner_trade_no);//商户订单号,需保持唯一性 |
| | | map.put("enc_bank_no", enc_bank_no);//收款方银行卡号(采用标准RSA算法,公钥由微信侧提供) |
| | | map.put("enc_true_name", enc_true_name);//收款方用户名(采用标准RSA算法,公钥由微信侧提供) |
| | | map.put("bank_code", findBankCode(bankName));// |
| | | map.put("amount", amount);//企业付款金额,单位为分 |
| | | map.put("desc", desc);//企业付款备注,必填。 |
| | | String s = this.weixinSignature(map, key); |
| | | map.put("sign", s); |
| | | |
| | | String url = "https://api.mch.weixin.qq.com/mmpaysptrans/pay_bank"; |
| | | //设置请求头 |
| | | HttpHeaders headers = new HttpHeaders(); |
| | | headers.setContentType(MediaType.APPLICATION_XML); |
| | | StringBuffer xmlString = new StringBuffer(); |
| | | Set<String> strings = map.keySet(); |
| | | String[] keys = {}; |
| | | keys = strings.toArray(keys); |
| | | Arrays.sort(keys); |
| | | xmlString.append("<xml>"); |
| | | for(int l = 0; l < keys.length; l++){ |
| | | xmlString.append("<" + keys[l] + ">" + map.get(keys[l]) + "</" + keys[l] + ">"); |
| | | } |
| | | xmlString.append("</xml>"); |
| | | |
| | | Map<String, String> map1 = null; |
| | | String certPath = "D:\\app\\cert\\weixin\\1487457552\\apiclient_cert.p12";//证书地址 |
| | | String body1 = httpClientUtil.pushHttpsRequsetXml(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); |
| | | //将结果xml解析成map |
| | | body1 = body1.replaceAll("<!\\[CDATA\\[",""); |
| | | body1 = body1.replaceAll("]]>", ""); |
| | | try { |
| | | map1 = this.xmlToMap(body1, "UTF-8"); |
| | | } catch (UnsupportedEncodingException e) { |
| | | e.printStackTrace(); |
| | | } catch (DocumentException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | String return_code = map1.get("return_code"); |
| | | Map<String, String> map2 = new HashMap<>(); |
| | | if("SUCCESS".equals(return_code)){ |
| | | String result_code = map1.get("result_code"); |
| | | if("SUCCESS".equals(result_code)){ |
| | | map2.put("return_code", result_code); |
| | | map2.put("payment_no", String.valueOf(map1.get("payment_no")));//付款订单号 |
| | | map2.put("cmms_amt", String.valueOf(map1.get("cmms_amt")));//手续费金额 RMB:分 |
| | | return map2; |
| | | }else{ |
| | | map2.put("return_code", result_code); |
| | | map2.put("err_code", map1.get("err_code")); |
| | | map2.put("err_code_des", map1.get("err_code_des")); |
| | | return map2; |
| | | } |
| | | }else{ |
| | | map2.put("return_code", return_code); |
| | | map2.put("return_msg", map1.get("return_msg")); |
| | | return map2; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 微信转账到银行卡不编号 |
| | | * @param bankName |
| | | * @return |
| | | */ |
| | | public String findBankCode(String bankName){ |
| | | String json = "{\"工商银行 \":1002,\"农业银行\":1005,\"建设银行\":1003,\"中国银行\":1026,\"交通银行 \":1020,\"招商银行 \":1001,\"邮储银行\":1066,\"民生银行 \":1006,\"平安银行 \":1010,\"中信银行\":1021,\"浦发银行 \":1004,\"兴业银行 \":1009,\"光大银行 \":1022,\"广发银行\":1027,\"华夏银行\":1025,\"宁波银行\":1056,\"北京银行\":4836,\"上海银行\":1024,\"南京银行\":1054,\"长子县融汇村镇银行\":4755,\"长沙银行\":4216,\"浙江泰隆商业银行\":4051,\"中原银行 \":4753,\"企业银行(中国)\":4761,\"顺德农商银行 \":4036,\"衡水银行\":4752,\"长治银行\":4756,\"大同银行\":4767,\"河南省农村信用社\":4115,\"宁夏黄河农村商业银行\":4150,\"山西省农村信用社\":4156,\"安徽省农村信用社\":4166,\"甘肃省农村信用社\":4157,\"天津农村商业银行\":4153,\"广西壮族自治区农村信用社\":4113,\"陕西省农村信用社\":4108,\"深圳农村商业银行\":4076,\"宁波鄞州农村商业银行\":4052,\"浙江省农村信用社联合社\":4764,\"江苏省农村信用社联合社\":4217,\"江苏紫金农村商业银行股份有限公司 \":4072,\"北京中关村银行股份有限公司 \":4769,\"星展银行( 中国) 有限公司 \":4778,\"枣庄银行股份有限公司 \":4766,\"海口联合农村商业银行股份有限公司 \":4758,\"南洋商业银行( 中国) 有限公司 \":4763}"; |
| | | JSONObject jsonObject = JSON.parseObject(json); |
| | | Set<String> strings = jsonObject.keySet(); |
| | | for(String key : strings){ |
| | | if(key.indexOf(bankName) >= 0){ |
| | | return jsonObject.getString(key); |
| | | } |
| | | } |
| | | return ""; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 支付宝转账 |
| | | * @param out_biz_no 商家侧唯一订单号,由商家自定义。对于不同转账请求,商家需保证该订单号在自身系统唯一。 |
| | | * @param trans_amount 订单总金额,单位为元,精确到小数点后两位 |
| | | * @param order_title 转账业务的标题,用于在支付宝用户的账单里显示 |
| | | * @param identity 参与方的唯一标识(收款方支付宝账号) |
| | | * @param name 参与方真实姓名,如果非空,将校验收款支付宝账号姓名一致性。 |
| | | * @param remark 业务备注 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public Map<String, Object> aliTransfer(String out_biz_no, Double trans_amount, String order_title, String identity, String name, String remark) throws Exception{ |
| | | CertAlipayRequest certAlipayRequest = new CertAlipayRequest(); |
| | | certAlipayRequest.setServerUrl("https://openapi.alipay.com/gateway.do"); //gateway:支付宝网关(固定)https://openapi.alipay.com/gateway.do |
| | | certAlipayRequest.setAppId(aliAppid); //APPID 即创建应用后生成,详情见创建应用并获取 APPID |
| | | certAlipayRequest.setPrivateKey(appPrivateKey); //开发者应用私钥,由开发者自己生成 |
| | | certAlipayRequest.setFormat("json"); //参数返回格式,只支持 json 格式 |
| | | certAlipayRequest.setCharset("UTF-8"); //请求和签名使用的字符编码格式,支持 GBK和 UTF-8 |
| | | certAlipayRequest.setSignType("RSA2"); //商户生成签名字符串所使用的签名算法类型,目前支持 RSA2 和 RSA,推荐商家使用 RSA2。 |
| | | certAlipayRequest.setCertPath(app_cert_path); //应用公钥证书路径(app_cert_path 文件绝对路径) |
| | | certAlipayRequest.setAlipayPublicCertPath(alipay_cert_path); //支付宝公钥证书文件路径(alipay_cert_path 文件绝对路径) |
| | | certAlipayRequest.setRootCertPath(alipay_root_cert_path); //支付宝CA根证书文件路径(alipay_root_cert_path 文件绝对路径) |
| | | AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest); |
| | | AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest(); |
| | | request.setBizContent("{" + |
| | | "\"out_biz_no\":\"" + out_biz_no + "\"," + |
| | | "\"trans_amount\":" + trans_amount + "," + |
| | | "\"product_code\":\"TRANS_ACCOUNT_NO_PWD\"," + |
| | | "\"biz_scene\":\"DIRECT_TRANSFER\"," + |
| | | "\"order_title\":\"" + order_title + "\"," + |
| | | "\"payee_info\":{" + |
| | | "\"identity\":\"" + identity + "\"," + |
| | | "\"identity_type\":\"ALIPAY_USER_ID\"," + |
| | | "\"name\":\"" + name + "\"," + |
| | | "}," + |
| | | "\"remark\":\"" + remark + "\"" + |
| | | "}"); |
| | | AlipayFundTransUniTransferResponse response = alipayClient.certificateExecute(request); |
| | | Map<String, Object> map = new HashMap<>(); |
| | | if(response.isSuccess()){ |
| | | String status = response.getStatus(); |
| | | if(status.equals("SUCCESS")){//成功 |
| | | map.put("code", response.getCode()); |
| | | map.put("order_id", response.getOrderId());//支付宝订单号 |
| | | map.put("pay_fund_order_id", response.getPayFundOrderId());//支付宝流水号 |
| | | }else{ |
| | | map.put("code", response.getCode()); |
| | | map.put("sub_msg", response.getSubMsg()); |
| | | } |
| | | } else { |
| | | map.put("code", response.getSubCode()); |
| | | map.put("sub_msg", response.getSubMsg()); |
| | | } |
| | | return map; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取请求内容 |
| | | * @param request |
| | | * @return |
| | |
| | | |
| | | |
| | | /** |
| | | * 微信下单的签名算法 |
| | | * @param map |
| | | * @return |
| | | */ |
| | | private String weixinSignature(Map<String, Object> map, String key_){ |
| | | try { |
| | | Set<Map.Entry<String, Object>> entries = map.entrySet(); |
| | | List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(entries); |
| | | // 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序) |
| | | Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() { |
| | | public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) { |
| | | return (o1.getKey()).toString().compareTo(o2.getKey()); |
| | | } |
| | | }); |
| | | // 构造签名键值对的格式 |
| | | StringBuilder sb = new StringBuilder(); |
| | | for (Map.Entry<String, Object> item : infoIds) { |
| | | if (item.getKey() != null || item.getKey() != "") { |
| | | String key = item.getKey(); |
| | | Object val = item.getValue(); |
| | | if (!(val == "" || val == null)) { |
| | | sb.append(key + "=" + val + "&"); |
| | | } |
| | | } |
| | | } |
| | | sb.append("key=" + key_); |
| | | String sign = MD5AndKL.MD5Encode(sb.toString(), "UTF-8").toUpperCase(); //注:MD5签名方式 |
| | | return sign; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 微信退款成功后的解密 |
| | | * @param req_info |
| | | * @return |
| | |
| | | public static void main(String[] ages){ |
| | | // PayMoneyUtil payMoneyUtil = new PayMoneyUtil(); |
| | | // payMoneyUtil.weixinpay("测试", "123", "12.5", ""); |
| | | |
| | | } |
| | | |
| | | |
| | |
| | | import java.io.FileInputStream; |
| | | import java.io.InputStreamReader; |
| | | import java.math.BigDecimal; |
| | | import java.math.MathContext; |
| | | import java.math.RoundingMode; |
| | | import java.util.*; |
| | | |
| | | /** |
| | |
| | | System.err.println("查询距离出错了"); |
| | | return; |
| | | }else{ |
| | | d = new BigDecimal(distance.get("distance")).divide(new BigDecimal(1000)).setScale(2, BigDecimal.ROUND_HALF_EVEN).toString(); |
| | | t = new BigDecimal(distance.get("duration")).divide(new BigDecimal(60)).setScale(2, BigDecimal.ROUND_HALF_EVEN).intValue() + ""; |
| | | d = new BigDecimal(distance.get("distance")).divide(new BigDecimal(1000), new MathContext(2, RoundingMode.HALF_EVEN)).setScale(2, BigDecimal.ROUND_HALF_EVEN).toString(); |
| | | t = new BigDecimal(distance.get("duration")).divide(new BigDecimal(60), new MathContext(2, RoundingMode.HALF_EVEN)).setScale(2, BigDecimal.ROUND_HALF_EVEN).intValue() + ""; |
| | | } |
| | | map.put("reservationMileage", d);//当前位置距离预约点的剩余里程 |
| | | map.put("reservationTime", t);//当前位置距离预约点的剩余分钟 |
| | |
| | | if(null == distance){ |
| | | System.err.println("查询距离出错了"); |
| | | }else{ |
| | | d = new BigDecimal(distance.get("distance")).divide(new BigDecimal(1000)).setScale(2, BigDecimal.ROUND_HALF_EVEN).toString(); |
| | | t = new BigDecimal(distance.get("duration")).divide(new BigDecimal(60)).setScale(2, BigDecimal.ROUND_HALF_EVEN).intValue() + ""; |
| | | d = new BigDecimal(distance.get("distance")).divide(new BigDecimal(1000), new MathContext(2, RoundingMode.HALF_EVEN)).setScale(2, BigDecimal.ROUND_HALF_EVEN).toString(); |
| | | t = new BigDecimal(distance.get("duration")).divide(new BigDecimal(60), new MathContext(2, RoundingMode.HALF_EVEN)).setScale(2, BigDecimal.ROUND_HALF_EVEN).intValue() + ""; |
| | | } |
| | | map.put("laveMileage", d);//距离终点剩余未服务的里程数 |
| | | map.put("laveTime", t);//距离终端剩余未服务的预计时间 |
| | |
| | | package com.stylefeng.guns.modular.system.util; |
| | | |
| | | import cn.hutool.crypto.SecureUtil; |
| | | import cn.hutool.http.HttpRequest; |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.stylefeng.guns.core.util.MD5Util; |
| | | import com.stylefeng.guns.core.util.ToolUtil; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | |
| | | * @author zhibing.pu |
| | | * @Date 2023/3/31 10:05 |
| | | */ |
| | | @Component |
| | | public class SMSUtil { |
| | | |
| | | @Autowired |
| | | private HttpClientUtil httpClientUtil; |
| | | private static String username = "Ztrbkjhy"; |
| | | |
| | | private String username = "Ztrbkjhy"; |
| | | private static String password = "Zycx2023Rbkj"; |
| | | |
| | | private String password = "Zycx2023Rbkj"; |
| | | |
| | | private String signature = "【昭阳出行】"; |
| | | private static String signature = "【昭阳出行】"; |
| | | |
| | | |
| | | /** |
| | | * 模板短信发送 |
| | | * @param mobile 手机号 |
| | | * @param tpId 模板id |
| | | * @param records 模板变量[ |
| | | * @param records 模板变量 |
| | | * "records":[ |
| | | * { |
| | | * "mobile":"138****0000" |
| | | * "mobile":"138****0000", |
| | | * "tpContent":{ |
| | | * "var1":"变量1", |
| | | * "var2":"变量2" |
| | | * } |
| | | * }, |
| | | * { |
| | | * "mobile":"138****0001" |
| | | * "mobile":"138****0001", |
| | | * "tpContent":{ |
| | | * "var1":"变量2", |
| | | * "var2":"变量2" |
| | | * } |
| | | * } |
| | | * ] |
| | | */ |
| | | public void sendSmsTp(String mobile, Long tpId, List<Object> records){ |
| | | String url = "https://api.mix2.zthysms.com/v2/sendSmsTp"; |
| | | Map<String, Object> params = new HashMap<>(); |
| | | params.put("username", username); |
| | | params.put("password", password); |
| | | params.put("tKey", System.currentTimeMillis() / 1000); |
| | | params.put("signature", signature); |
| | | params.put("tpId", tpId); |
| | | params.put("mobile", mobile); |
| | | params.put("records", records); |
| | | String s = httpClientUtil.pushHttpRequset("POST", url, params, null, "json"); |
| | | if(ToolUtil.isEmpty(s)){ |
| | | return; |
| | | public static void sendSmsTp(Long tpId, JSONArray records){ |
| | | //地址 |
| | | String urls = "https://api.mix2.zthysms.com/v2/sendSmsTp"; |
| | | //请求入参 |
| | | JSONObject requestJson = new JSONObject(); |
| | | //账号 |
| | | requestJson.put("username", username); |
| | | //tKey |
| | | long tKey = System.currentTimeMillis() / 1000; |
| | | requestJson.put("tKey", tKey); |
| | | //明文密码 |
| | | requestJson.put("password", SecureUtil.md5(SecureUtil.md5(password) + tKey)); |
| | | //模板ID |
| | | requestJson.put("tpId", tpId); |
| | | //签名 |
| | | requestJson.put("signature", signature); |
| | | //扩展号 |
| | | requestJson.put("ext", ""); |
| | | //自定义参数 |
| | | requestJson.put("extend", ""); |
| | | requestJson.put("records", records); |
| | | String result = HttpRequest.post(urls) |
| | | .timeout(60000) |
| | | .body(requestJson.toJSONString(), MediaType.APPLICATION_JSON_UTF8_VALUE).execute().body(); |
| | | if(ToolUtil.isNotEmpty(result)){ |
| | | JSONObject jsonObject = JSON.parseObject(result); |
| | | int code = jsonObject.getIntValue("code"); |
| | | if(200 != code){ |
| | | System.err.println(jsonObject.getString("msg")); |
| | | } |
| | | }else{ |
| | | System.err.println("短信发送异常"); |
| | | } |
| | | } |
| | | |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.util.qiniuyun; |
| | | |
| | | import com.google.gson.Gson; |
| | | import com.qiniu.common.QiniuException; |
| | | import com.qiniu.http.Response; |
| | | import com.qiniu.storage.Configuration; |
| | | import com.qiniu.storage.Region; |
| | | import com.qiniu.storage.UploadManager; |
| | | import com.qiniu.storage.model.DefaultPutRet; |
| | | import com.qiniu.util.Auth; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.io.ByteArrayInputStream; |
| | | import java.io.IOException; |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.util.UUID; |
| | | |
| | | /** |
| | | * 对象存储 |
| | | * @author zhibing.pu |
| | | * @Date 2023/3/31 11:08 |
| | | */ |
| | | public class KodoUtil { |
| | | private static String accessKey = "6DqM0CEdAVON3mL3C6E23Vuj--635Q1hdjOwnpXw"; |
| | | private static String secretKey = "q35tZkQjvBCRkDsfWksY3PCr3wqUuJlodE7EF5qg"; |
| | | private static String bucketName = "rbkj-zycx"; |
| | | |
| | | |
| | | /** |
| | | * 普通上传 |
| | | * @param file |
| | | * @return |
| | | * @throws IOException |
| | | */ |
| | | public static String upload(MultipartFile file) throws IOException { |
| | | String originalFilename = file.getOriginalFilename(); |
| | | String fileName = UUID.randomUUID().toString().replaceAll("-","") + originalFilename.subSequence(originalFilename.lastIndexOf("."), originalFilename.length()); |
| | | |
| | | try { |
| | | //构造一个带指定 Region 对象的配置类 |
| | | Configuration cfg = new Configuration(Region.autoRegion()); |
| | | cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2;// 指定分片上传版本 |
| | | //...其他参数参考类注释 |
| | | UploadManager uploadManager = new UploadManager(cfg); |
| | | |
| | | byte[] uploadBytes = file.getBytes(); |
| | | ByteArrayInputStream byteInputStream=new ByteArrayInputStream(uploadBytes); |
| | | Auth auth = Auth.create(accessKey, secretKey); |
| | | String upToken = auth.uploadToken(bucketName); |
| | | try { |
| | | Response response = uploadManager.put(byteInputStream,fileName,upToken,null, null); |
| | | //解析上传成功的结果 |
| | | DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class); |
| | | // System.out.println(putRet.key); |
| | | // System.out.println(putRet.hash); |
| | | return "https://qiniu.cdn.zhaoyangchuxing.com/" + putRet.key; |
| | | } catch (QiniuException ex) { |
| | | Response r = ex.response; |
| | | System.err.println(r.toString()); |
| | | try { |
| | | System.err.println(r.bodyString()); |
| | | } catch (QiniuException ex2) { |
| | | ex2.printStackTrace(); |
| | | } |
| | | } |
| | | } catch (UnsupportedEncodingException ex) { |
| | | ex.printStackTrace(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | |
| | | |
| | | // 分片上传 v1 |
| | | public static String uploadv1(MultipartFile file){ |
| | | String originalFilename = file.getOriginalFilename(); |
| | | String fileName = UUID.randomUUID().toString().replaceAll("-","") + originalFilename.subSequence(originalFilename.lastIndexOf("."), originalFilename.length()); |
| | | Configuration cfg = new Configuration(); |
| | | UploadManager uploadManager = new UploadManager(cfg); |
| | | Auth auth = Auth.create(accessKey, secretKey); |
| | | String token = auth.uploadToken(bucketName); |
| | | Response r = null; |
| | | try { |
| | | r = uploadManager.put(file.getBytes(), fileName, token); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return r.address; |
| | | } |
| | | |
| | | // 分片上传 v2 |
| | | public static String uploadv2(MultipartFile file){ |
| | | String originalFilename = file.getOriginalFilename(); |
| | | String fileName = UUID.randomUUID().toString().replaceAll("-","") + originalFilename.subSequence(originalFilename.lastIndexOf("."), originalFilename.length()); |
| | | Configuration cfg = new Configuration(); |
| | | cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2; |
| | | UploadManager uploadManager = new UploadManager(cfg); |
| | | Auth auth = Auth.create(accessKey, secretKey); |
| | | String token = auth.uploadToken(bucketName); |
| | | Response r = null; |
| | | try { |
| | | r = uploadManager.put(file.getBytes(), fileName, token); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return r.address; |
| | | } |
| | | } |
New file |
| | |
| | | package com.stylefeng.guns.modular.system.util.qiniuyun; |
| | | |
| | | import com.google.gson.annotations.SerializedName; |
| | | import com.qiniu.common.Constants; |
| | | import com.qiniu.http.Client; |
| | | import com.qiniu.http.Headers; |
| | | import com.qiniu.util.Json; |
| | | import com.qiniu.util.StringMap; |
| | | import com.qiniu.util.StringUtils; |
| | | import com.qiniu.util.UrlSafeBase64; |
| | | |
| | | import javax.crypto.Mac; |
| | | import javax.crypto.spec.SecretKeySpec; |
| | | import java.net.URI; |
| | | import java.security.GeneralSecurityException; |
| | | import java.security.SecureRandom; |
| | | import java.text.DateFormat; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * @author zhibing.pu |
| | | * @Date 2023/4/3 15:15 |
| | | */ |
| | | public class QNYAuth { |
| | | |
| | | public static final String DISABLE_QINIU_TIMESTAMP_SIGNATURE_ENV_KEY = "DISABLE_QINIU_TIMESTAMP_SIGNATURE"; |
| | | public static final String DTOKEN_ACTION_VOD = "linking:vod"; |
| | | public static final String DTOKEN_ACTION_STATUS = "linking:status"; |
| | | public static final String DTOKEN_ACTION_TUTK = "linking:tutk"; |
| | | public static final String HTTP_HEADER_KEY_CONTENT_TYPE = "Content-Type"; |
| | | |
| | | private static final String QBOX_AUTHORIZATION_PREFIX = "QBox "; |
| | | private static final String QINIU_AUTHORIZATION_PREFIX = "Qiniu "; |
| | | |
| | | /** |
| | | * 上传策略 |
| | | * 参考文档:<a href="https://developer.qiniu.com/kodo/manual/put-policy">上传策略</a> |
| | | */ |
| | | private static final String[] policyFields = new String[]{ |
| | | "callbackUrl", |
| | | "callbackBody", |
| | | "callbackHost", |
| | | "callbackBodyType", |
| | | "callbackFetchKey", |
| | | |
| | | "returnUrl", |
| | | "returnBody", |
| | | |
| | | "endUser", |
| | | "saveKey", |
| | | "insertOnly", |
| | | "isPrefixalScope", |
| | | |
| | | "detectMime", |
| | | "mimeLimit", |
| | | "fsizeLimit", |
| | | "fsizeMin", |
| | | |
| | | "persistentOps", |
| | | "persistentNotifyUrl", |
| | | "persistentPipeline", |
| | | |
| | | "deleteAfterDays", |
| | | "fileType", |
| | | }; |
| | | private static final String[] deprecatedPolicyFields = new String[]{ |
| | | "asyncOps", |
| | | }; |
| | | private static final boolean[] isTokenTable = genTokenTable(); |
| | | private static final byte toLower = 'a' - 'A'; |
| | | public final String accessKey; |
| | | private final SecretKeySpec secretKey; |
| | | |
| | | private QNYAuth(String accessKey, SecretKeySpec secretKeySpec) { |
| | | this.accessKey = accessKey; |
| | | this.secretKey = secretKeySpec; |
| | | } |
| | | |
| | | public static QNYAuth create(String accessKey, String secretKey) { |
| | | if (StringUtils.isNullOrEmpty(accessKey) || StringUtils.isNullOrEmpty(secretKey)) { |
| | | throw new IllegalArgumentException("empty key"); |
| | | } |
| | | byte[] sk = StringUtils.utf8Bytes(secretKey); |
| | | SecretKeySpec secretKeySpec = new SecretKeySpec(sk, "HmacSHA1"); |
| | | return new QNYAuth(accessKey, secretKeySpec); |
| | | } |
| | | |
| | | private static void copyPolicy(final StringMap policy, StringMap originPolicy, final boolean strict) { |
| | | if (originPolicy == null) { |
| | | return; |
| | | } |
| | | originPolicy.forEach(new StringMap.Consumer() { |
| | | @Override |
| | | public void accept(String key, Object value) { |
| | | if (StringUtils.inStringArray(key, deprecatedPolicyFields)) { |
| | | throw new IllegalArgumentException(key + " is deprecated!"); |
| | | } |
| | | if (!strict || StringUtils.inStringArray(key, policyFields)) { |
| | | policy.put(key, value); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | |
| | | // https://github.com/golang/go/blob/master/src/net/textproto/reader.go#L596 |
| | | // CanonicalMIMEHeaderKey returns the canonical format of the |
| | | // MIME header key s. The canonicalization converts the first |
| | | // letter and any letter following a hyphen to upper case; |
| | | // the rest are converted to lowercase. For example, the |
| | | // canonical key for "accept-encoding" is "Accept-Encoding". |
| | | // MIME header keys are assumed to be ASCII only. |
| | | // If s contains a space or invalid header field bytes, it is |
| | | // returned without modifications. |
| | | private static String canonicalMIMEHeaderKey(String name) { |
| | | // com.qiniu.http.Headers 已确保 header name 字符的合法性,直接使用 byte ,否则要使用 char // |
| | | byte[] a = name.getBytes(Constants.UTF_8); |
| | | for (int i = 0; i < a.length; i++) { |
| | | byte c = a[i]; |
| | | if (!validHeaderFieldByte(c)) { |
| | | return name; |
| | | } |
| | | } |
| | | |
| | | boolean upper = true; |
| | | for (int i = 0; i < a.length; i++) { |
| | | byte c = a[i]; |
| | | if (upper && 'a' <= c && c <= 'z') { |
| | | c -= toLower; |
| | | } else if (!upper && 'A' <= c && c <= 'Z') { |
| | | c += toLower; |
| | | } |
| | | a[i] = c; |
| | | upper = c == '-'; // for next time |
| | | } |
| | | return new String(a, Constants.UTF_8); |
| | | } |
| | | |
| | | private static boolean validHeaderFieldByte(byte b) { |
| | | //byte: -128 ~ 127, char: 0 ~ 65535 |
| | | return 0 < b && b < isTokenTable.length && isTokenTable[b]; |
| | | } |
| | | |
| | | private static boolean[] genTokenTable() { |
| | | int[] idx = new int[]{ |
| | | '!', '#', '$', '%', '&', '\'', '*', '+', '-', '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', |
| | | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', |
| | | 'U', 'W', 'V', 'X', 'Y', 'Z', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', |
| | | 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '|', '~'}; |
| | | boolean[] tokenTable = new boolean[127]; |
| | | Arrays.fill(tokenTable, false); |
| | | for (int i : idx) { |
| | | tokenTable[i] = true; |
| | | } |
| | | return tokenTable; |
| | | } |
| | | |
| | | private Mac createMac() { |
| | | Mac mac; |
| | | try { |
| | | mac = javax.crypto.Mac.getInstance("HmacSHA1"); |
| | | mac.init(secretKey); |
| | | } catch (GeneralSecurityException e) { |
| | | e.printStackTrace(); |
| | | throw new IllegalArgumentException(e); |
| | | } |
| | | return mac; |
| | | } |
| | | |
| | | @Deprecated // private |
| | | public String sign(byte[] data) { |
| | | Mac mac = createMac(); |
| | | String encodedSign = UrlSafeBase64.encodeToString(mac.doFinal(data)); |
| | | return this.accessKey + ":" + encodedSign; |
| | | } |
| | | |
| | | @Deprecated // private |
| | | public String sign(String data) { |
| | | return sign(StringUtils.utf8Bytes(data)); |
| | | } |
| | | |
| | | @Deprecated // private |
| | | public String signWithData(byte[] data) { |
| | | String s = UrlSafeBase64.encodeToString(data); |
| | | return sign(StringUtils.utf8Bytes(s)) + ":" + s; |
| | | } |
| | | |
| | | @Deprecated // private |
| | | public String signWithData(String data) { |
| | | return signWithData(StringUtils.utf8Bytes(data)); |
| | | } |
| | | |
| | | /** |
| | | * 生成HTTP请求签名字符串 |
| | | * |
| | | * @param urlString 签名请求的 url |
| | | * @param body 签名请求的 body |
| | | * @param contentType 签名请求的 contentType |
| | | * @return 签名信息 |
| | | */ |
| | | @Deprecated // private |
| | | public String signRequest(String urlString, byte[] body, String contentType) { |
| | | URI uri = URI.create(urlString); |
| | | String path = uri.getRawPath(); |
| | | String query = uri.getRawQuery(); |
| | | |
| | | Mac mac = createMac(); |
| | | |
| | | mac.update(StringUtils.utf8Bytes(path)); |
| | | |
| | | if (query != null && query.length() != 0) { |
| | | mac.update((byte) ('?')); |
| | | mac.update(StringUtils.utf8Bytes(query)); |
| | | } |
| | | mac.update((byte) '\n'); |
| | | if (body != null && Client.FormMime.equalsIgnoreCase(contentType)) { |
| | | mac.update(body); |
| | | } |
| | | |
| | | String digest = UrlSafeBase64.encodeToString(mac.doFinal()); |
| | | |
| | | return this.accessKey + ":" + digest; |
| | | } |
| | | |
| | | /** |
| | | * 验证回调签名是否正确,此方法仅能验证 QBox 签名以及 GET 请求的 Qiniu 签名 |
| | | * |
| | | * @param originAuthorization 待验证签名字符串,以 "QBox " 作为起始字符,GET 请求支持 "Qiniu " 开头。 |
| | | * @param url 回调地址 |
| | | * @param body 回调请求体。原始请求体,不要解析后再封装成新的请求体--可能导致签名不一致。 |
| | | * @param contentType 回调 ContentType |
| | | * @return 签名是否正确 |
| | | */ |
| | | @Deprecated |
| | | public boolean isValidCallback(String originAuthorization, String url, byte[] body, String contentType) { |
| | | Headers header = null; |
| | | if (!StringUtils.isNullOrEmpty(contentType)) { |
| | | header = new Headers.Builder() |
| | | .add(HTTP_HEADER_KEY_CONTENT_TYPE, contentType) |
| | | .build(); |
| | | } |
| | | return isValidCallback(originAuthorization, new Request(url, "GET", header, body)); |
| | | } |
| | | |
| | | /** |
| | | * 验证回调签名是否正确,此方法支持验证 QBox 和 Qiniu 签名 |
| | | * |
| | | * @param originAuthorization 待验证签名字符串,以 "QBox " 或 "Qiniu " 作为起始字符 |
| | | * @param callback callback 请求信息 |
| | | * @return 签名是否正确 |
| | | */ |
| | | public boolean isValidCallback(String originAuthorization, Request callback) { |
| | | if (callback == null) { |
| | | return false; |
| | | } |
| | | |
| | | String authorization = ""; |
| | | if (originAuthorization.startsWith(QINIU_AUTHORIZATION_PREFIX)) { |
| | | authorization = QINIU_AUTHORIZATION_PREFIX + signQiniuAuthorization(callback.url, callback.method, callback.body, callback.header); |
| | | } else if (originAuthorization.startsWith(QBOX_AUTHORIZATION_PREFIX)) { |
| | | String contentType = null; |
| | | if (callback.header != null) { |
| | | contentType = callback.header.get(HTTP_HEADER_KEY_CONTENT_TYPE); |
| | | } |
| | | authorization = QBOX_AUTHORIZATION_PREFIX + signRequest(callback.url, callback.body, contentType); |
| | | } |
| | | return authorization.equals(originAuthorization); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 下载签名 |
| | | * |
| | | * @param baseUrl 待签名文件url,如 http://img.domain.com/u/3.jpg 、 |
| | | * http://img.domain.com/u/3.jpg?imageView2/1/w/120 |
| | | * @return 签名 |
| | | */ |
| | | public String privateDownloadUrl(String baseUrl) { |
| | | return privateDownloadUrl(baseUrl, 3600); |
| | | } |
| | | |
| | | /** |
| | | * 下载签名 |
| | | * |
| | | * @param baseUrl 待签名文件url,如 http://img.domain.com/u/3.jpg 、 |
| | | * http://img.domain.com/u/3.jpg?imageView2/1/w/120 |
| | | * @param expires 有效时长,单位秒。默认3600s |
| | | * @return 签名 |
| | | */ |
| | | public String privateDownloadUrl(String baseUrl, long expires) { |
| | | long deadline = System.currentTimeMillis() / 1000 + expires; |
| | | return privateDownloadUrlWithDeadline(baseUrl, deadline); |
| | | } |
| | | |
| | | public String privateDownloadUrlWithDeadline(String baseUrl, long deadline) { |
| | | StringBuilder b = new StringBuilder(); |
| | | b.append(baseUrl); |
| | | int pos = baseUrl.indexOf("?"); |
| | | if (pos > 0) { |
| | | b.append("&e="); |
| | | } else { |
| | | b.append("?e="); |
| | | } |
| | | b.append(deadline); |
| | | String token = sign(StringUtils.utf8Bytes(b.toString())); |
| | | b.append("&token="); |
| | | b.append(token); |
| | | return b.toString(); |
| | | } |
| | | |
| | | /** |
| | | * scope = bucket |
| | | * 一般情况下可通过此方法获取token |
| | | * |
| | | * @param bucket 空间名 |
| | | * @return 生成的上传token |
| | | */ |
| | | public String uploadToken(String bucket) { |
| | | return uploadToken(bucket, null, 3600, null, true); |
| | | } |
| | | |
| | | /** |
| | | * scope = bucket:key |
| | | * 同名文件覆盖操作、只能上传指定key的文件可以可通过此方法获取token |
| | | * |
| | | * @param bucket 空间名 |
| | | * @param key key,可为 null |
| | | * @return 生成的上传token |
| | | */ |
| | | public String uploadToken(String bucket, String key) { |
| | | return uploadToken(bucket, key, 3600, null, true); |
| | | } |
| | | |
| | | /** |
| | | * 生成上传token |
| | | * |
| | | * @param bucket 空间名 |
| | | * @param key key,可为 null |
| | | * @param expires 有效时长,单位秒 |
| | | * @param policy 上传策略的其它参数,如 new StringMap().put("endUser", "uid").putNotEmpty("returnBody", "")。 |
| | | * scope通过 bucket、key间接设置,deadline 通过 expires 间接设置 |
| | | * @return 生成的上传token |
| | | */ |
| | | public String uploadToken(String bucket, String key, long expires, StringMap policy) { |
| | | return uploadToken(bucket, key, expires, policy, true); |
| | | } |
| | | |
| | | /** |
| | | * 生成上传token |
| | | * |
| | | * @param bucket 空间名 |
| | | * @param key key,可为 null |
| | | * @param expires 有效时长,单位秒。默认3600s |
| | | * @param policy 上传策略的其它参数,如 new StringMap().put("endUser", "uid").putNotEmpty("returnBody", "")。 |
| | | * scope通过 bucket、key间接设置,deadline 通过 expires 间接设置 |
| | | * @param strict 是否去除非限定的策略字段,默认true |
| | | * @return 生成的上传token |
| | | */ |
| | | public String uploadToken(String bucket, String key, long expires, StringMap policy, boolean strict) { |
| | | long deadline = System.currentTimeMillis() / 1000 + expires; |
| | | return uploadTokenWithDeadline(bucket, key, deadline, policy, strict); |
| | | } |
| | | |
| | | public String uploadTokenWithDeadline(String bucket, String key, long deadline, StringMap policy, boolean strict) { |
| | | // TODO UpHosts Global |
| | | String scope = bucket; |
| | | if (key != null) { |
| | | scope = bucket + ":" + key; |
| | | } |
| | | StringMap x = new StringMap(); |
| | | copyPolicy(x, policy, strict); |
| | | x.put("scope", scope); |
| | | x.put("deadline", deadline); |
| | | |
| | | String s = Json.encode(x); |
| | | return signWithData(StringUtils.utf8Bytes(s)); |
| | | } |
| | | |
| | | public String uploadTokenWithPolicy(Object obj) { |
| | | String s = Json.encode(obj); |
| | | return signWithData(StringUtils.utf8Bytes(s)); |
| | | } |
| | | |
| | | @Deprecated |
| | | public StringMap authorization(String url, byte[] body, String contentType) { |
| | | String authorization = "QBox " + signRequest(url, body, contentType); |
| | | return new StringMap().put("Authorization", authorization); |
| | | } |
| | | |
| | | @Deprecated |
| | | public StringMap authorization(String url) { |
| | | return authorization(url, null, null); |
| | | } |
| | | |
| | | /** |
| | | * 生成 HTTP 请求签名字符串 |
| | | * |
| | | * @param url 签名请求的 url |
| | | * @param method 签名请求的 method |
| | | * @param body 签名请求的 body |
| | | * @param contentType 签名请求的 contentType |
| | | * @return 签名 |
| | | */ |
| | | @Deprecated |
| | | public String signRequestV2(String url, String method, byte[] body, String contentType) { |
| | | return signQiniuAuthorization(url, method, body, contentType); |
| | | } |
| | | |
| | | public String signQiniuAuthorization(String url, String method, byte[] body, String contentType) { |
| | | Headers headers = null; |
| | | if (!StringUtils.isNullOrEmpty(contentType)) { |
| | | headers = new Headers.Builder().set(HTTP_HEADER_KEY_CONTENT_TYPE, contentType).build(); |
| | | } |
| | | return signQiniuAuthorization(url, method, body, headers); |
| | | } |
| | | |
| | | public String signQiniuAuthorization(String url, String method, byte[] body, Headers headers) { |
| | | URI uri = URI.create(url); |
| | | if (StringUtils.isNullOrEmpty(method)) { |
| | | method = "GET"; |
| | | } |
| | | |
| | | StringBuilder sb = new StringBuilder(); |
| | | sb.append(method).append(" ").append(uri.getPath()); |
| | | |
| | | if (uri.getQuery() != null) { |
| | | sb.append("?").append(uri.getRawQuery()); |
| | | } |
| | | |
| | | sb.append("\nHost: ").append(uri.getHost() != null ? uri.getHost() : ""); |
| | | |
| | | if (uri.getPort() > 0) { |
| | | sb.append(":").append(uri.getPort()); |
| | | } |
| | | |
| | | String contentType = null; |
| | | |
| | | if (null != headers) { |
| | | contentType = headers.get(HTTP_HEADER_KEY_CONTENT_TYPE); |
| | | if (contentType != null) { |
| | | sb.append("\n").append(HTTP_HEADER_KEY_CONTENT_TYPE).append(": ").append(contentType); |
| | | } |
| | | |
| | | List<Header> xQiniuheaders = genXQiniuSignHeader(headers); |
| | | java.util.Collections.sort(xQiniuheaders); |
| | | if (xQiniuheaders.size() > 0) { |
| | | for (Header h : xQiniuheaders) { |
| | | sb.append("\n").append(h.name).append(": ").append(h.value); |
| | | } |
| | | } |
| | | } |
| | | |
| | | sb.append("\n\n"); |
| | | |
| | | if (body != null && body.length > 0 && null != contentType && !"".equals(contentType) |
| | | && !"application/octet-stream".equals(contentType)) { |
| | | sb.append(new String(body, Constants.UTF_8)); |
| | | } |
| | | Mac mac = createMac(); |
| | | mac.update(StringUtils.utf8Bytes(sb.toString())); |
| | | |
| | | String digest = UrlSafeBase64.encodeToString(mac.doFinal()); |
| | | return this.accessKey + ":" + digest; |
| | | } |
| | | |
| | | private List<Header> genXQiniuSignHeader(Headers headers) { |
| | | |
| | | ArrayList<Header> hs = new ArrayList<Header>(); |
| | | for (String name : headers.names()) { |
| | | if (name.length() > "X-Qiniu-".length() && name.startsWith("X-Qiniu-")) { |
| | | String value = headers.get(name); |
| | | if (value != null) { |
| | | hs.add(new Header(canonicalMIMEHeaderKey(name), value)); |
| | | } |
| | | } |
| | | } |
| | | return hs; |
| | | } |
| | | |
| | | public Headers qiniuAuthorization(String url, String method, byte[] body, Headers headers) { |
| | | Headers.Builder builder = null; |
| | | if (headers == null) { |
| | | builder = new Headers.Builder(); |
| | | } else { |
| | | builder = headers.newBuilder(); |
| | | } |
| | | |
| | | setDefaultHeader(builder); |
| | | |
| | | String authorization = "Qiniu " + signQiniuAuthorization(url, method, body, builder.build()); |
| | | builder.set("Authorization", authorization).build(); |
| | | return builder.build(); |
| | | } |
| | | |
| | | @Deprecated |
| | | public StringMap authorizationV2(String url, String method, byte[] body, String contentType) { |
| | | Headers headers = null; |
| | | if (!StringUtils.isNullOrEmpty(contentType)) { |
| | | headers = new Headers.Builder().set(HTTP_HEADER_KEY_CONTENT_TYPE, contentType).build(); |
| | | } |
| | | |
| | | headers = qiniuAuthorization(url, method, body, headers); |
| | | if (headers == null) { |
| | | return null; |
| | | } |
| | | |
| | | Set<String> headerKeys = headers.names(); |
| | | StringMap headerMap = new StringMap(); |
| | | for (String key : headerKeys) { |
| | | String value = headers.get(key); |
| | | if (value != null) { |
| | | headerMap.put(key, value); |
| | | } |
| | | } |
| | | return headerMap; |
| | | } |
| | | |
| | | @Deprecated |
| | | public StringMap authorizationV2(String url) { |
| | | return authorizationV2(url, "GET", null, (String) null); |
| | | } |
| | | |
| | | //连麦 RoomToken |
| | | public String signRoomToken(String roomAccess) throws Exception { |
| | | String encodedRoomAcc = UrlSafeBase64.encodeToString(roomAccess); |
| | | byte[] sign = createMac().doFinal(encodedRoomAcc.getBytes()); |
| | | String encodedSign = UrlSafeBase64.encodeToString(sign); |
| | | return this.accessKey + ":" + encodedSign + ":" + encodedRoomAcc; |
| | | } |
| | | |
| | | public String generateLinkingDeviceToken(String appid, String deviceName, long deadline, String[] actions) { |
| | | LinkingDtokenStatement[] staments = new LinkingDtokenStatement[actions.length]; |
| | | |
| | | for (int i = 0; i < actions.length; ++i) { |
| | | staments[i] = new LinkingDtokenStatement(actions[i]); |
| | | } |
| | | |
| | | SecureRandom random = new SecureRandom(); |
| | | StringMap map = new StringMap(); |
| | | map.put("appid", appid).put("device", deviceName).put("deadline", deadline) |
| | | .put("random", random.nextInt()).put("statement", staments); |
| | | String s = Json.encode(map); |
| | | return signWithData(StringUtils.utf8Bytes(s)); |
| | | } |
| | | |
| | | public String generateLinkingDeviceTokenWithExpires(String appid, String deviceName, |
| | | long expires, String[] actions) { |
| | | long deadline = (System.currentTimeMillis() / 1000) + expires; |
| | | return generateLinkingDeviceToken(appid, deviceName, deadline, actions); |
| | | } |
| | | |
| | | public String generateLinkingDeviceVodTokenWithExpires(String appid, String deviceName, long expires) { |
| | | return generateLinkingDeviceTokenWithExpires(appid, deviceName, expires, new String[]{DTOKEN_ACTION_VOD}); |
| | | } |
| | | |
| | | public String generateLinkingDeviceStatusTokenWithExpires(String appid, String deviceName, long expires) { |
| | | return generateLinkingDeviceTokenWithExpires(appid, deviceName, expires, new String[]{DTOKEN_ACTION_STATUS}); |
| | | } |
| | | |
| | | |
| | | private static void setDefaultHeader(Headers.Builder builder) { |
| | | if (!isDisableQiniuTimestampSignature()) { |
| | | builder.set("X-Qiniu-Date", xQiniuDate()); |
| | | } |
| | | } |
| | | |
| | | private static boolean isDisableQiniuTimestampSignature() { |
| | | String value = System.getenv(DISABLE_QINIU_TIMESTAMP_SIGNATURE_ENV_KEY); |
| | | if (value == null) { |
| | | return false; |
| | | } |
| | | value = value.toLowerCase(); |
| | | return value.equals("true") || value.equals("yes") || value.equals("y") || value.equals("1"); |
| | | } |
| | | |
| | | private static String xQiniuDate() { |
| | | DateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'"); |
| | | format.setTimeZone(TimeZone.getTimeZone("UTC")); |
| | | return format.format(new Date()); |
| | | } |
| | | |
| | | class LinkingDtokenStatement { |
| | | @SerializedName("action") |
| | | private String action; |
| | | |
| | | LinkingDtokenStatement(String action) { |
| | | this.action = action; |
| | | } |
| | | |
| | | public String getAction() { |
| | | return action; |
| | | } |
| | | |
| | | public void setAction(String action) { |
| | | this.action = action; |
| | | } |
| | | } |
| | | |
| | | private class Header implements Comparable<Header> { |
| | | String name; |
| | | String value; |
| | | |
| | | Header(String name, String value) { |
| | | this.name = name; |
| | | this.value = value; |
| | | } |
| | | |
| | | @Override |
| | | public int compareTo(Header o) { |
| | | int c = this.name.compareTo(o.name); |
| | | if (c == 0) { |
| | | return this.value.compareTo(o.value); |
| | | } else { |
| | | return c; |
| | | } |
| | | } |
| | | } |
| | | |
| | | public static class Request { |
| | | private final String url; |
| | | private final String method; |
| | | private final Headers header; |
| | | private final byte[] body; |
| | | |
| | | /** |
| | | * @param url 回调地址 |
| | | * @param method 回调请求方式 |
| | | * @param header 回调头,注意 Content-Type Key 字段需为:{@link QNYAuth#HTTP_HEADER_KEY_CONTENT_TYPE},大小写敏感 |
| | | * @param body 回调请求体。原始请求体,不要解析后再封装成新的请求体--可能导致签名不一致。 |
| | | **/ |
| | | public Request(String url, String method, Headers header, byte[] body) { |
| | | this.url = url; |
| | | this.method = method; |
| | | this.header = header; |
| | | this.body = body; |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | register-with-eureka: true #在注册中心进行注册 |
| | | fetch-registry: true #从Eureka中获取注册信息。 |
| | | |
| | | --- |
| | | |
| | | #spring: |
| | | # profiles: local |
| | | # datasource: |
| | | # url: jdbc:mysql://Rm-wz9rpe0t74ys3b1h8go.mysql.rds.aliyuncs.com:3306/oktravel?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=Asia/Shanghai |
| | | # username: root |
| | | # password: Root2020! |
| | | # db-name: guns #用来搜集数据库的所有表 |
| | | # filters: wall,mergeStat |
| | | --- |
| | | |
| | | ################# 测试环境 ################### |
| | | spring: |
| | | profiles: local |
| | | datasource: |
| | | url: jdbc:mysql://localhost:3306/feima?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=Asia/Shanghai |
| | | url: jdbc:mysql://localhost:3306/zytravel?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=Asia/Shanghai |
| | | username: root |
| | | password: s).iOqINE7Gj |
| | | password: 0KiwEhl6EnIFWNqB7d1FJLWKy9urjvMS |
| | | # password: 123456 |
| | | db-name: guns #用来搜集数据库的所有表 |
| | | filters: wall,mergeStat |
| | | |
| | |
| | | |
| | | wx: |
| | | grantType: authorization_code #填authorization_code |
| | | appid: 1 #应用唯一标识,在微信开放平台提交应用审核通过后获得 |
| | | appSecret: 1 #应用密钥AppSecret,在微信开放平台提交应用审核通过后获得 |
| | | appid: wx6078319d54d38c66 #应用唯一标识,在微信开放平台提交应用审核通过后获得 |
| | | appSecret: c3ef243fae93fb0fd093d457ada38b4c #应用密钥AppSecret,在微信开放平台提交应用审核通过后获得 |
| | | appletsAppid: #小程序APPid |
| | | appletsAppSecret: # |
| | | mchId: 1602881362 #微信支付分配的商户号 |
| | | key: xMCkkqlmQO3VEHwV5BgTSfdMIGZewO5I #key为商户平台设置的密钥key: |
| | | mchId: 1487457552 #微信支付分配的商户号 |
| | | key: kkTSfqlmgwOQIGZOdMe3VEHxMCwV5B5I #key为商户平台设置的密钥key: |
| | | |
| | | --- |
| | | |
| | |
| | | --- |
| | | |
| | | #filePath: /usr/local/server/orderPostionFile/ #存储订单轨迹文件路径 |
| | | filePath: C:/orderPostionFile/ #存储订单轨迹文件路径 |
| | | filePath: D:/web/orderPostionFile/ #存储订单轨迹文件路径 |
| | | |
| | | |
| | | |
| | | #支付回调地址 |
| | | #正式环境 |
| | | #callbackPath: https://okyueche.com:443/driver |
| | | callbackPath: https://www.zycx.ztrbkj.com:443/driver |
| | | #正式测试环境 |
| | | callbackPath: http://39.108.37.243/driver |
| | | #callbackPath: http://39.108.37.243/driver |
| | | |
| | | --- |
| | | #交通部推送数据功能开关 |
| | |
| | | <modules> |
| | | <module>guns-admin</module> |
| | | <module>guns-core</module> |
| | | <module>guns-rest</module> |
| | | <module>guns-generator</module> |
| | | </modules> |
| | | |