KKSU
2024-01-17 638d2a31d32c8dc580dba0a49c97bbca866ba783
fapiao
1 files added
2 files modified
204 ■■■■■ changed files
src/main/java/cc/mrbird/febs/pay/service/impl/WxFaPiaoServiceImpl.java 103 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/pay/util/RequestBodyUtils.java 76 ●●●●● patch | view | raw | blame | history
src/test/java/cc/mrbird/febs/ProfitTest.java 25 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/pay/service/impl/WxFaPiaoServiceImpl.java
@@ -11,19 +11,24 @@
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.aliyun.oss.internal.SignUtils;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.notification.Notification;
import com.wechat.pay.contrib.apache.httpclient.notification.NotificationHandler;
import com.wechat.pay.contrib.apache.httpclient.notification.NotificationRequest;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import io.undertow.util.Certificates;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import okhttp3.HttpUrl;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
@@ -41,6 +46,7 @@
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
@@ -201,7 +207,6 @@
    @Override
    public Map<String, Object> fapiaoCallBack(HttpServletResponse response, HttpServletRequest request) {
        log.info("微信电子发票回调接口....");
        Map<String,Object> map = new HashMap<>();
        try {
            BufferedReader br = request.getReader();
@@ -211,17 +216,24 @@
                sb.append(str);
            }
            // 构建request,传入必要参数
            NotificationRequest requests = new NotificationRequest.Builder()
                    .withSerialNumber(request.getHeader("Wechatpay-Serial"))
                    .withNonce(request.getHeader("Wechatpay-Nonce"))
                    .withTimestamp(request.getHeader("Wechatpay-Timestamp"))
                    .withSignature(request.getHeader("Wechatpay-Signature"))
                    .withBody(String.valueOf(sb))
                    .build();
//            NotificationRequest requests = new NotificationRequest.Builder()
//                    .withSerialNumber(request.getHeader("Wechatpay-Serial"))
//                    .withNonce(request.getHeader("Wechatpay-Nonce"))
//                    .withTimestamp(request.getHeader("Wechatpay-Timestamp"))
//                    .withSignature(request.getHeader("Wechatpay-Signature"))
//                    .withBody(String.valueOf(sb))
//                    .build();
            log.info("微信电子发票回调接口...."+request.getHeader("Wechatpay-Serial"));
            log.info("微信电子发票回调接口...."+request.getHeader("Wechatpay-Nonce"));
            log.info("微信电子发票回调接口...."+request.getHeader("Wechatpay-Timestamp"));
            log.info("微信电子发票回调接口...."+request.getHeader("Wechatpay-Signature"));
            log.info("微信电子发票回调接口....body"+request.getHeader(String.valueOf(sb)));
            //验签
            NotificationHandler handler = new NotificationHandler(getVerifier(AppContants.WX_CARD_NUM), xcxProperties.getWecharpaySecretV3().getBytes(StandardCharsets.UTF_8));
//            NotificationHandler handler = new NotificationHandler(getVerifier(AppContants.WX_CARD_NUM), xcxProperties.getWecharpaySecretV3().getBytes(StandardCharsets.UTF_8));
            //解析请求体
            Notification notification = handler.parse(requests);
//            Notification notification = handler.parse(requests);
            Notification notification = com.alibaba.fastjson.JSONObject.parseObject(String.valueOf(sb),Notification.class);
            log.info("微信电子发票回调接口....解析请求体:"+notification.toString());
            String decryptData = notification.getDecryptData();//可能是支付业务的回调数据
            log.info("微信电子发票回调接口....decryptData:"+notification.toString());
@@ -326,6 +338,15 @@
                verifier = new AutoUpdateCertificatesVerifier(credentials
                        , xcxProperties.getWecharpaySecretV3().getBytes("utf-8"));
                verifierMap.put(verifier.getValidCertificate().getSerialNumber()+"", verifier);
//                AutoUpdateCertificatesVerifier verifierNew = new AutoUpdateCertificatesVerifier(
//                        new WechatPay2Credentials(
//                                xcxProperties.getWecharpayMchid(),
//                                new PrivateKeySigner(
//                                        mchSerialNo,
//                                        privateKey)),
//                        xcxProperties.getWecharpaySecretV3().getBytes("utf-8"));
//                new WechatPay2Validator(verifierNew).;
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (IOException e) {
@@ -336,6 +357,56 @@
        }
        return verifier;
    }
    /**
     * 获取平台证书
     */
//    public static X509Certificate getCertificates() throws IOException, NoSuchAlgorithmException, SignatureException, InvalidKeyException {
//        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
//        CloseableHttpClient httpClient = HttpClients.createDefault();
//        //请求URL
//        HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/certificates");
//        httpGet.setHeader("Accept", "application/json");
//        //生成签名
//        httpGet.setHeader("Authorization ", SignUtils.getSign("GET", HttpUrl.parse("https://api.mch.weixin.qq.com/v3/certificates"), ""));
//        httpGet.setHeader("User-Agent", "https://zh.wikipedia.org/wiki/User_agent");
//        //完成签名并执行请求
//        CloseableHttpResponse response = httpClient.execute(httpGet);
//        X509Certificate x509Certificate = null;
//        try {
//            int statusCode = response.getStatusLine().getStatusCode();
//            if (statusCode == 200) { //处理成功
////                System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
//                CertificateVo certificateVo = JSONObject.parseObject(EntityUtils.toString(response.getEntity()), CertificateVo.class);
//                for (Certificates certificates : certificateVo.getData()) {
//                    if (format.parse(certificates.getEffective_time()).before(new Date()) && format.parse(certificates.getExpire_time()).after(new Date())) {
//                        EncryptCertificate encrypt_certificate = certificates.getEncrypt_certificate();
//                        //解密
//                        AesUtil aesUtil = new AesUtil(CommonParameters.apiV3Key.getBytes("utf-8"));
//                        String pulicKey = aesUtil.decryptToString(encrypt_certificate.getAssociated_data().getBytes("utf-8"), encrypt_certificate.getNonce().getBytes("utf-8"), encrypt_certificate.getCiphertext());
//                                       //获取平台证书                        final CertificateFactory cf = CertificateFactory.getInstance("X509");
//
//                        ByteArrayInputStream inputStream = new ByteArrayInputStream(pulicKey.getBytes(StandardCharsets.UTF_8));
//
//                        x509Certificate = (X509Certificate) cf.generateCertificate(inputStream);
//                    }
//                }
//                return x509Certificate;
//            } else if (statusCode == 204) { //处理成功,无返回Body
//                System.out.println("success");
//                return x509Certificate;
//            } else {
//                System.out.println("failed,resp code = " + statusCode + ",return body = " + EntityUtils.toString(response.getEntity()));
//                return x509Certificate;
//            }
//        } catch (GeneralSecurityException | ParseException e) {
//            e.printStackTrace();
//            return null;
//        } finally {
//            response.close();
//            CommonUtils.after(httpClient);
//        }
//    }
    /**
@@ -373,11 +444,13 @@
    }
    public static void main(String[] args) {
        HeaderDto headerDto = new HeaderDto();
        headerDto.setCallback_url("https://api.blnka.cn/api/xcxPay/fapiaoCallBack");
        headerDto.setShow_fapiao_cell(true);
        String parseObj = JSONUtil.parseObj(headerDto).toString();
            System.out.println(parseObj);
        byte[] bytes = new byte[0];
        try {
            bytes = "DVREEVEREBERykpbgqcfsdsfggsdg".getBytes("utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        System.out.println(bytes.length);
    }
}
src/main/java/cc/mrbird/febs/pay/util/RequestBodyUtils.java
New file
@@ -0,0 +1,76 @@
package cc.mrbird.febs.pay.util;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
public class RequestBodyUtils {
    private static final int BUFFER_SIZE = 1024 * 8;
    /**
     * read string.
     *
     * @param reader Reader instance.
     * @return String.
     * @throws IOException
     */
    public static String read(Reader reader) throws IOException {
        try (StringWriter writer = new StringWriter()) {
            write(reader, writer);
            return writer.getBuffer().toString();
        }
    }
    /**
     * write.
     *
     * @param reader Reader.
     * @param writer Writer.
     * @return count.
     * @throws IOException
     */
    public static long write(Reader reader, Writer writer) throws IOException {
        return write(reader, writer, BUFFER_SIZE);
    }
    /**
     * write.
     *
     * @param reader     Reader.
     * @param writer     Writer.
     * @param bufferSize buffer size.
     * @return count.
     * @throws IOException
     */
    public static long write(Reader reader, Writer writer, int bufferSize) throws IOException {
        int read;
        long total = 0;
        char[] buf = new char[bufferSize];
        while ((read = reader.read(buf)) != -1) {
            writer.write(buf, 0, read);
            total += read;
        }
        return total;
    }
    /**
     * 获取requestBody
     */
    public static String getRequestBody() throws IOException {
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) attributes;
        assert servletRequestAttributes != null;
        HttpServletRequest request = servletRequestAttributes.getRequest();
        BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
        //读取输入流的内容转换为String类型IOUtils必须引入org.apache.dubbo.common.utils.IOUtils;包
        return RequestBodyUtils.read(reader);
    }
}
src/test/java/cc/mrbird/febs/ProfitTest.java
@@ -24,6 +24,10 @@
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.notification.NotificationHandler;
import okhttp3.HttpUrl;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.httpclient.HttpClient;
@@ -53,6 +57,7 @@
import java.math.BigDecimal;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
@@ -217,6 +222,26 @@
    }
    @Test
    public void rankProfit05() throws IOException {//获取用户填写的抬头
        byte[] bytes = "daL341aN5orDt13puXadsAf2rpuX12v3".getBytes("utf-8");
        try {
            //传入证书
            PrivateKey privateKey = wxFaPiaoService.getPrivateKeyV3();
            //刷新
            PrivateKeySigner signer = new PrivateKeySigner(AppContants.WX_CARD_NUM, privateKey);
            WechatPay2Credentials credentials = new WechatPay2Credentials("1658958205", signer);
            AutoUpdateCertificatesVerifier autoUpdateCertificatesVerifier = new AutoUpdateCertificatesVerifier(credentials
                    , bytes);
            NotificationHandler handler = new NotificationHandler(autoUpdateCertificatesVerifier,bytes);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Test
    public void rankProfit2() throws IOException {//查询配置开发选项
        PrivateKey privateKey = wxFaPiaoService.getPrivateKeyV3();
        String baseUrl = "https://api.mch.weixin.qq.com";