From 6f71c6abb6da52fe5d91a6a47e6fbec1fc126fb4 Mon Sep 17 00:00:00 2001 From: haown <454902499@qq.com> Date: Thu, 24 Jul 2025 14:28:49 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E4=BB=98=E4=BB=A3=E7=A0=81=E6=9A=82?= =?UTF-8?q?=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + exam-admin/pom.xml | 15 ++ .../exam/config/WeChatPaymentUrlConfig.java | 62 +++++++ .../exam/config/XylWeChatPaymentConfig.java | 42 +++++ .../payment/XylWeChatPaymentUtilConfig.java | 109 +++++++++++++ .../payment/service/PaymentService.java | 6 + .../service/impl/PaymentServiceImpl.java | 152 ++++++++++++++++++ .../payment/vo/WeChatAppletSignVO.java | 46 ++++++ .../com/yf/exam/modules/utils/WeChatUtil.java | 34 ++++ exam-admin/src/main/resources/application.yml | 16 ++ .../main/resources/baixing_apiclient_key.pem | 28 ++++ 11 files changed, 511 insertions(+) create mode 100644 exam-admin/src/main/java/com/yf/exam/config/WeChatPaymentUrlConfig.java create mode 100644 exam-admin/src/main/java/com/yf/exam/config/XylWeChatPaymentConfig.java create mode 100644 exam-admin/src/main/java/com/yf/exam/config/payment/XylWeChatPaymentUtilConfig.java create mode 100644 exam-admin/src/main/java/com/yf/exam/modules/payment/service/PaymentService.java create mode 100644 exam-admin/src/main/java/com/yf/exam/modules/payment/service/impl/PaymentServiceImpl.java create mode 100644 exam-admin/src/main/java/com/yf/exam/modules/payment/vo/WeChatAppletSignVO.java create mode 100644 exam-admin/src/main/java/com/yf/exam/modules/utils/WeChatUtil.java create mode 100644 exam-admin/src/main/resources/baixing_apiclient_key.pem diff --git a/.gitignore b/.gitignore index 289259a..9ad120f 100644 --- a/.gitignore +++ b/.gitignore @@ -39,5 +39,6 @@ nbdist/ .nb-gradle/ target/ +logs/ !.mvn/wrapper/maven-wrapper.jar diff --git a/exam-admin/pom.xml b/exam-admin/pom.xml index f91a326..b27b644 100644 --- a/exam-admin/pom.xml +++ b/exam-admin/pom.xml @@ -27,6 +27,7 @@ 3.9 2.17.2 exam-admin + 0.4.4 @@ -170,6 +171,20 @@ commons-io 2.11.0 + + + + com.github.wechatpay-apiv3 + wechatpay-apache-httpclient + ${wechatpay-apiv3.version} + + + + + org.apache.httpcomponents + httpclient + 4.5.13 + diff --git a/exam-admin/src/main/java/com/yf/exam/config/WeChatPaymentUrlConfig.java b/exam-admin/src/main/java/com/yf/exam/config/WeChatPaymentUrlConfig.java new file mode 100644 index 0000000..42bde2e --- /dev/null +++ b/exam-admin/src/main/java/com/yf/exam/config/WeChatPaymentUrlConfig.java @@ -0,0 +1,62 @@ +package com.yf.exam.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * @Description 微信支付接口地址 + * @Author 纪寒 + * @Date 2022-10-17 17:56:25 + * @Version 1.0 + */ +@Component +@Data +@ConfigurationProperties(prefix = "we-chat-payment-url-config") +public class WeChatPaymentUrlConfig { + + /** + * 小程序JSAPI下单接口地址 + */ + private String jsapiPalceOrderUrl; + + /** + * 微信支付订单号查询接口地址 + */ + private String queryOrderNoUrl; + + /** + * 商户订单号接口查询 + */ + private String queryMchIdUrl; + + /** + * 关闭订单接口地址 + */ + private String closeOrderUrl; + + /** + * 申请退款接口地址 + */ + private String refundApplyUrl; + + /** + * 查询单笔退款接口地址 + */ + private String refundQueryOrderUrl; + + /** + * 申请交易账单接口地址 + */ + private String tradeApplyBillUrl; + + /** + * 申请资金账单接口地址 + */ + private String capitalApplyBillUrl; + + /** + * App下单接口地址 + */ + private String appPlaceOrderUrl; +} diff --git a/exam-admin/src/main/java/com/yf/exam/config/XylWeChatPaymentConfig.java b/exam-admin/src/main/java/com/yf/exam/config/XylWeChatPaymentConfig.java new file mode 100644 index 0000000..60f69b0 --- /dev/null +++ b/exam-admin/src/main/java/com/yf/exam/config/XylWeChatPaymentConfig.java @@ -0,0 +1,42 @@ +package com.yf.exam.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * @Description 新医路商户号微信支付参数配置类 + * @Author 纪寒 + * @Date 2022-10-17 16:55:04 + * @Version 1.0 + */ +@Data +@Component +@ConfigurationProperties(prefix = "xyl-we-chat-config") +public class XylWeChatPaymentConfig { + + /** + * 新医路商户号 + */ + private String xylMchId; + + /** + * 新医路API证书序号getXylVerifier + */ + private String xylMchSerialNo; + + /** + * 新医路私钥文件 + */ + private String xylPrivateKeyPath; + + /** + * 新医路API V3版本密钥 + */ + private String xylPaymentKey; + + /** + * 新医路支付回调地址 + */ + private String xylWeChatNotifyUrl; +} diff --git a/exam-admin/src/main/java/com/yf/exam/config/payment/XylWeChatPaymentUtilConfig.java b/exam-admin/src/main/java/com/yf/exam/config/payment/XylWeChatPaymentUtilConfig.java new file mode 100644 index 0000000..06a5f0f --- /dev/null +++ b/exam-admin/src/main/java/com/yf/exam/config/payment/XylWeChatPaymentUtilConfig.java @@ -0,0 +1,109 @@ +package com.yf.exam.config.payment; + +import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder; +import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner; +import com.wechat.pay.contrib.apache.httpclient.auth.Verifier; +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.cert.CertificatesManager; +import com.wechat.pay.contrib.apache.httpclient.util.PemUtil; +import com.yf.exam.config.XylWeChatPaymentConfig; +import com.yf.exam.core.exception.ServiceException; +import java.nio.charset.StandardCharsets; +import java.security.PrivateKey; +import javax.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.impl.client.CloseableHttpClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; + +/** + * @Description 新医路商户号微信支付核心配置类 + * @Author 纪寒 + * @Date 2022-10-17 18:56:22 + * @Version 1.0 + */ +@Configuration +@Slf4j +public class XylWeChatPaymentUtilConfig { + + @Resource + private XylWeChatPaymentConfig xylWeChatPaymentConfig; + + /** + * 获取新医路签名信息 + * + * @return 签名信息 + * @throws Exception 异常信息 + */ + @Bean(name = "xylVerifier") + public Verifier getXylVerifier() throws Exception { + //获取商户私钥 + PrivateKey privateKey = getPrivateKey(xylWeChatPaymentConfig.getXylPrivateKeyPath()); + //私钥签名对象 + PrivateKeySigner privateKeySigner = new PrivateKeySigner(xylWeChatPaymentConfig.getXylMchSerialNo(), privateKey); + //身份认证对象 + WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(xylWeChatPaymentConfig.getXylMchId(), privateKeySigner); + // 获取证书管理器实例 + CertificatesManager certificatesManager = CertificatesManager.getInstance(); + // 向证书管理器增加需要自动更新平台证书的商户信息 + certificatesManager.putMerchant(xylWeChatPaymentConfig.getXylMchId(), wechatPay2Credentials, xylWeChatPaymentConfig.getXylPaymentKey().getBytes(StandardCharsets.UTF_8)); + // 从证书管理器中获取verifier + return certificatesManager.getVerifier(xylWeChatPaymentConfig.getXylMchId()); + } + + /** + * 获取新医路商户号带有签名的http请求对象 + * + * @return CloseableHttpClient对象 + */ + @Bean(name = "xinYiLuWeChatPayClient") + public CloseableHttpClient getXinYiLuWeChatPayClient(Verifier xylVerifier) { + log.info("开始获取新医路商户带有签名信息的http请求对象........"); + //获取商户私钥 + PrivateKey privateKey = getPrivateKey(xylWeChatPaymentConfig.getXylPrivateKeyPath()); + CloseableHttpClient closeableHttpClient = null; + try { + log.info("新医路签名验证证书,xinYiLuCertificatesVerifier:{}", xylVerifier); + //通过WeChatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新 + closeableHttpClient = WechatPayHttpClientBuilder.create() + .withMerchant(xylWeChatPaymentConfig.getXylMchId(), xylWeChatPaymentConfig.getXylMchSerialNo(), privateKey) + .withValidator(new WechatPay2Validator(xylVerifier)).build(); + } catch (Exception e) { + log.error("新医路验证签名信息失败,失败信息:{}", e.getMessage()); + } + return closeableHttpClient; + } + + /** + * 获取新医路商户号无签名的http请求对象 + * + * @return CloseableHttpClient对象 + */ + @Bean(name = "xinYiLuWeChatPayNoSignClient") + public CloseableHttpClient getXinYiLuWeChatPayNoSignClient() { + log.info("获取新医路商户的无签名信息的http请求对象........."); + //获取商户私钥 + PrivateKey privateKey = getPrivateKey(xylWeChatPaymentConfig.getXylPrivateKeyPath()); + //通过WeChatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新 + return WechatPayHttpClientBuilder.create() + .withMerchant(xylWeChatPaymentConfig.getXylMchId(), xylWeChatPaymentConfig.getXylMchSerialNo(), privateKey) + .withValidator((response) -> true).build(); + } + + /** + * 获取商户的私钥文件 + * + * @param filename 获取商户的私钥文件 + * @return 商户私钥 + */ + private PrivateKey getPrivateKey(String filename) { + try { + return PemUtil.loadPrivateKey(new ClassPathResource(filename).getInputStream()); + } catch (Exception e) { + log.error("新医路商户私钥文件不存在,错误原因:{}", e.getMessage()); + throw new ServiceException("新医路商户私钥文件不存在,请联系管理员!"); + } + } +} diff --git a/exam-admin/src/main/java/com/yf/exam/modules/payment/service/PaymentService.java b/exam-admin/src/main/java/com/yf/exam/modules/payment/service/PaymentService.java new file mode 100644 index 0000000..6c89e93 --- /dev/null +++ b/exam-admin/src/main/java/com/yf/exam/modules/payment/service/PaymentService.java @@ -0,0 +1,6 @@ +package com.yf.exam.modules.payment.service; + +public interface PaymentService { + + +} diff --git a/exam-admin/src/main/java/com/yf/exam/modules/payment/service/impl/PaymentServiceImpl.java b/exam-admin/src/main/java/com/yf/exam/modules/payment/service/impl/PaymentServiceImpl.java new file mode 100644 index 0000000..73dc443 --- /dev/null +++ b/exam-admin/src/main/java/com/yf/exam/modules/payment/service/impl/PaymentServiceImpl.java @@ -0,0 +1,152 @@ +package com.yf.exam.modules.payment.service.impl; + +import com.alibaba.fastjson2.JSONObject; +import com.yf.exam.config.WeChatPaymentUrlConfig; +import com.yf.exam.config.XylWeChatPaymentConfig; +import com.yf.exam.core.exception.ServiceException; +import com.yf.exam.modules.payment.service.PaymentService; +import com.yf.exam.modules.payment.vo.WeChatAppletSignVO; +import com.yf.exam.modules.utils.WeChatUtil; +import java.nio.charset.StandardCharsets; +import java.security.PrivateKey; +import java.security.Signature; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.annotation.Resource; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.util.EntityUtils; +import org.springframework.util.Base64Utils; + +/** + * @description: + * @author: haown + * @create: 2025-07-23 09:44 + **/ +public class PaymentServiceImpl implements PaymentService { + + @Resource(name = "xinYiLuWeChatPayClient") + private CloseableHttpClient xinYiLuWeChatPayClient; + @Resource + private WeChatPaymentUrlConfig weChatPaymentUrlConfig; + @Resource + private WeChatUtil weChatUtil; + @Resource + private XylWeChatPaymentConfig xylWeChatPaymentConfig; + + + /** + * H5下单成功状态码 + */ + private static final int HAVE_BODY_SUCCESS_CODE = 200; + + /** + * H5下单成功状态码 + */ + private static final int NO_HAVE_BODY_SUCCESS_CODE = 204; + + /** + * 签名算法 + */ + private static final String SIGNATURE_ALGORITHM = "SHA256withRSA"; + + /** + * 签名方式 + */ + private static final String SIGN_TYPE = "RSA"; + + /** + * 请求h5下单接口方法 + * + * @param jsApiParams 下单参数 + * @param paymentDTO 输入参数 + * @param prepayId JsAp下单接口返回值 + * @return 结果 + * @throws Exception 异常信息 + */ + private String requestH5Interface(String jsApiParams, PaymentDTO paymentDTO, String prepayId) throws Exception { + //log.info("JsApi请求下单参数 ====> {}", jsApiParams); + StringEntity stringEntity = new StringEntity(jsApiParams, StandardCharsets.UTF_8); + stringEntity.setContentType("application/json"); + HttpPost httpPost = new HttpPost(weChatPaymentUrlConfig.getJsapiPalceOrderUrl()); + httpPost.setEntity(stringEntity); + httpPost.setHeader("Accept", "application/json"); + CloseableHttpResponse response = null; + String payAccount = ""; + try { + response = xinYiLuWeChatPayClient.execute(httpPost); + payAccount = "山东柏杏新医健康服务有限公司"; + //处理响应结果 + if (Objects.isNull(response)) { + //log.error("JsApi下单接口执行错误, 执行账户为 ====> {}", payAccount); + throw new ServiceException("JsApi下单接口执行异常,请联系管理员!"); + } + //响应状态码 + int statusCode = response.getStatusLine().getStatusCode(); + //响应体 + String result = EntityUtils.toString(response.getEntity()); + if (statusCode == HAVE_BODY_SUCCESS_CODE) { + //请求成功,取出prepay_id的值并放入Redis缓存中,prepay_id的有效期为两小时,此处缓存一个半小时 + Map resultMap = JSONObject.parseObject(result); + prepayId = resultMap.getOrDefault("prepay_id", "").toString(); + redisTemplate.opsForValue().set(Constants.PREPAY_ID_KEY + paymentDTO.getOrderNo(), prepayId, 5400, TimeUnit.SECONDS); + } else if (statusCode == NO_HAVE_BODY_SUCCESS_CODE) { + //请求成功,无返回体 + log.info("JsApi下单成功,无返回值信息!"); + } else { + //请求失败 + log.error("JsApi下单失败,失败原因为 ====> {}", result); + throw new ServiceException("JsApi下单失败,失败原因为:" + result); + } + } catch (Exception e) { + log.error("JsApi下单失败,失败原因 =====> {}", e.getMessage()); + throw new ServiceException("JsApi下单失败,请联系管理员!"); + } finally { + if (response != null) { + response.close(); + } + } + return prepayId; + } + + /** + * 构建微信小程序调起支付参数设置 + * + * @param prepayId jsapi下单返回参数信息 + * @param buySource 购买来源 + * @return 参数信息 + * @throws Exception 异常信息 + */ + private WeChatAppletSignVO getSignInfo(String prepayId, String buySource) throws Exception { + //根据购买来源判断使用泉医到家小程序id还是泉医助手小程序id + String appId = BuySourceEnum.TRAINING.getInfo().equals(buySource) ? nurseAppletChatConfig.getAppletId() : appletChatConfig.getAppletId(); + //随机字符串 + String nonceStr = UUID.randomUUID().toString().replace("-", ""); + //时间戳 + String timestamp = String.valueOf(System.currentTimeMillis() / 1000); + //获取商户私钥 + PrivateKey privateKey = null; + privateKey = weChatUtil.getPrivateKey(xylWeChatPaymentConfig.getXylPrivateKeyPath()); + if (privateKey == null) { + throw new ServiceException("获取商户私钥失败,请联系管理员!"); + } + //计算签名信息 + prepayId = "prepay_id=" + prepayId; + String signatureStr = Stream.of(appId, timestamp, nonceStr, prepayId) + .collect(Collectors.joining("\n", "", "\n")); + log.info("计算签名认证信息 =====> {}", signatureStr); + Signature sign = Signature.getInstance(SIGNATURE_ALGORITHM); + sign.initSign(privateKey); + sign.update(signatureStr.getBytes(StandardCharsets.UTF_8)); + String paySign = Base64Utils.encodeToString(sign.sign()); + return WeChatAppletSignVO.builder().appId(appId).timeStamp(timestamp).nonceStr(nonceStr).prepayId(prepayId) + .signType(SIGN_TYPE).paySign(paySign).build(); + } + +} diff --git a/exam-admin/src/main/java/com/yf/exam/modules/payment/vo/WeChatAppletSignVO.java b/exam-admin/src/main/java/com/yf/exam/modules/payment/vo/WeChatAppletSignVO.java new file mode 100644 index 0000000..d0338ca --- /dev/null +++ b/exam-admin/src/main/java/com/yf/exam/modules/payment/vo/WeChatAppletSignVO.java @@ -0,0 +1,46 @@ +package com.yf.exam.modules.payment.vo; + +import java.io.Serializable; +import lombok.Builder; +import lombok.Data; + +/** + * @Description 微信小程序调起支付参数信息 + * @Author 纪寒 + * @Date 2022-10-20 09:59:19 + * @Version 1.0 + */ +@Builder +@Data +public class WeChatAppletSignVO implements Serializable { + private static final long serialVersionUID = -2527792374746553807L; + /** + * 小程序id + */ + private String appId; + + /** + * 时间戳 + */ + private String timeStamp; + + /** + * 随机字符串 + */ + private String nonceStr; + + /** + * 订单详情扩展字符串,小程序为prepay_id的值 + */ + private String prepayId; + + /** + * 签名方式 + */ + private String signType; + + /** + * 签名 + */ + private String paySign; +} diff --git a/exam-admin/src/main/java/com/yf/exam/modules/utils/WeChatUtil.java b/exam-admin/src/main/java/com/yf/exam/modules/utils/WeChatUtil.java new file mode 100644 index 0000000..8347971 --- /dev/null +++ b/exam-admin/src/main/java/com/yf/exam/modules/utils/WeChatUtil.java @@ -0,0 +1,34 @@ +package com.yf.exam.modules.utils; + +import com.wechat.pay.contrib.apache.httpclient.util.PemUtil; +import com.yf.exam.core.exception.ServiceException; +import java.security.PrivateKey; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Component; + +/** + * @Description 微信工具类 + * @Author 纪寒 + * @Date 2022-10-20 10:11:38 + * @Version 1.0 + */ +@Component +@Slf4j +public class WeChatUtil { + + /** + * 获取商户的私钥文件 + * + * @param filename 获取商户的私钥文件 + * @return 商户私钥 + */ + public PrivateKey getPrivateKey(String filename) { + try { + return PemUtil.loadPrivateKey(new ClassPathResource(filename).getInputStream()); + } catch (Exception e) { + log.error("商户私钥文件不存在,错误原因:{}", e.getMessage()); + throw new ServiceException("商户私钥文件不存在,请联系管理员!"); + } + } +} diff --git a/exam-admin/src/main/resources/application.yml b/exam-admin/src/main/resources/application.yml index 739a661..99b08ac 100644 --- a/exam-admin/src/main/resources/application.yml +++ b/exam-admin/src/main/resources/application.yml @@ -29,3 +29,19 @@ server: min-response-size: 10 mime-types: application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css +# 新医路微信商户号配置参数 +xyl-we-chat-config: + # 新医路商户号 1633348407 山东新医路信息科技有限公司 山东柏杏新医健康服务有限公司 + xyl-mch-id: 1690248007 + # 新医路商户号API证书序号 7C6A18FC8E1F0445901B1BE1C4DD1ACE284C3D79 + xyl-mch-serial-no: 760D3316C2F3DF8D1DB05B56A37BFCD3C34EEDA8 + # 新医路商户私钥文件 + xyl-private-key-path: baixing_apiclient_key.pem + # 新医路API V3版本密钥 Xyl699003981qazVFR4xsw23edcASDFG + xyl-payment-key: baixingXINYIHULIZHAN202400000000 + # 新医路微信支付回调地址 https://quanyidaojia.xinelu.cn + xyl-wechat-notify-url: http://8.131.93.145:54097 +# h5支付接口地址 +we-chat-payment-url-config: + # h5下单接口地址 + h5-palce-order-url: https://api.mch.weixin.qq.com/v3/pay/transactions/h5 diff --git a/exam-admin/src/main/resources/baixing_apiclient_key.pem b/exam-admin/src/main/resources/baixing_apiclient_key.pem new file mode 100644 index 0000000..6fc8e63 --- /dev/null +++ b/exam-admin/src/main/resources/baixing_apiclient_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDUI5gWlq+q0K1k ++NZZe2qJhUH1qce00Dc6j7Rc6Ubnb7u7/UEqJMc/N2m/oIBdb5Lmb3OJZDhV8kHE +S1/U9aM/UZEW2fJWkcHxCyIreVJvETSCdFtgvk/lzwkkLZZiA8Hb0Irq4nJB+QFl +K4o7LLDMYhTI14WeH46jgOTdk5e1jKl2F9ShAt9TX3ZHVgnY4wp+iG3xAZytjyLJ +szbPLVrYAt3JTfzstsdfIIafKssBFExglzjnCeS6DCBDZkr9vEqG921nAKVVlC6j +CPDtxITddF25+uI7c0CAozCA0TAoXL7tyzgfnzfy3KkLz3wmMyb5IN/6vDg4A559 +wNNmE1jdAgMBAAECggEAKKs6OPpiawjedQEPdtAmOH8HiiUmWA+ixuNN3JIMOco9 +32hJ2d57JC9nYolOkpsVOoAbUjeYZUGwQgWBNb5xsW3dttfJkbcXyzIrNtJnb0uJ +GYldC0rw3km2ouzqa5f0zkNInocTCHrIPbD/KyECM+yJt4c54nqCSe4n8iKdbvxS +vNKcpQatfs2Egm1PcHsZ00bNSWlii/cz30CVUGCPYx0TZ0WhcjI5nFHINpRIM9rJ +A0K2R0rqE6/9MXNAJe4+h2TRvmWghBhx+QHCQRnc5ExIGoVsSiGvQkkMQmW8wmmw +SMxjAWjWNphFh4a+6Zv3UAfRyIjaS40RYyN7y3MeAQKBgQD+kjDOlNrsGoP35dbo +NuZieFWqm1gowA2cRwoAJ/qImllU7TTgVAyrMo9vu36ABw+rhDW6rSFB9r7hGGXj +NS5RfiezazwGj7ymQj3WtUoJlCmCuOGVIxCbQPUgSRc7+VBdvNf+6oUhIua7ncEG +WNAmcbU0gdAjG5S7j/LzOoStoQKBgQDVVG4gDeGktG+EQAsdcItm78Wzb+7P/5Bc +uyISCfENqbmzzfogRHqZEN5C+ZZP3S/On6q7jpDUWFP+WBBED6hezESo4kVA7Zh9 +LsGU58nTGijxMoo05eUaXmZzvmjgNmpMHOMCKBCPnGZ67DeRwB/oFAfKwx4RRa++ +VHrYnLSJvQKBgQCnjJRvAu3rw6/j8vQ1Nhz/5m+LsF6fw3exyde9LpLoYZ42FUFd +/DOyYb6iLWce4IbhvkyWpuhiwAH1qNc2aYQowr1ii0ugje3+B08oB33JPCjuDrz6 +KW/+nww2yaRvJrJMX8RR1Qz2OEBgb33hrYaiJui6vE2/LaIAqMegan10wQKBgCVU +XODnDPERUeJGgqtoIjylAGdh0tw60Dwp0tBtRO0rIf/Ar2AuG3Xlab82hYL8JX12 +mx2u2NEPk8MSDeabBs9v1yPmVFAEQ4bEQ8OWu85g6YErYtvWzrxKgIsIarmxS/B9 +rYuXDy7SI2ynISI0CGFIAAUPF5fWJeacSdLVuRHRAoGBAO2cBz0bZJdKhoR+NMqN +CHpiTY+72hLhy4LB0XV7KsEumI0KI2i5EA4/cD+VCb+Qe6Hagoy78W/0s5MwBWzk +OwJ5JxBPZZROGwegxfb1P3NC1wazprKVTYbIUSomFbON4qQDjou13Y7gFeWsv2gE +Xq/BCiAbrbmltVKdxdqtRaQP +-----END PRIVATE KEY-----