当前位置: 首页 > news >正文

深圳企业画册印刷湖南专业seo公司

深圳企业画册印刷,湖南专业seo公司,前端开发培训多少钱,wordpress mingle一、需要准备的资料 1.小程序AppID 如:wx2e56f5****** 2.商户号 如:1641****** 3.商户API私钥路径:什么是商户API证书?如何获取商户API证书? 获取文件如下图: 如: 本地路径:E:\Env\e…

一、需要准备的资料

        1.小程序AppID

                如:wx2e56f5******

        2.商户号

                如:1641******

        3.商户API私钥路径:什么是商户API证书?如何获取商户API证书? 获取文件如下图:

                如:

                本地路径:E:\Env\eladmin\cert\c2\apiclient_key.pem(本地部署写入绝对路径)

                服务器路径:/data/cert/eladmin/c2/apiclient_key.pem(服务器写入相对路径)

        4.商户证书序列号:登录商户平台【API安全】->【API证书】->【查看证书】,可查看商户API证书序列号。

                如:4F24D009CDBC89A**********************

        5.商户APIV3密钥:API v3密钥 - 通用规则 | 微信支付商户文档中心

                如:tYsmXJrIr*****************

                【商户平台】->【账户中心】->【API安全】的页面设置该密钥,请求才能通过微信支付的签名校验。密钥的长度为32个字节。

        6.商户平台证书路径

                如:

                本地路径:E:\Env\eladmin\cert\c2\apiclient_cert.pem(本地部署写入绝对路径)

                服务器路径:/data/cert/eladmin/c2/apiclient_cert.pem(服务器写入相对路径)

        7.商户平台证书路径p12

                如:

                本地路径:E:\Env\eladmin\cert\c2\apiclient_cert.p12(本地部署写入绝对路径)

                服务器路径:/data/cert/eladmin/c2/apiclient_cert.p12(服务器写入相对路径)

二、代码部分

1.pom.xml内加入微信支付扩展
<!--     微信支付   --><dependency><groupId>com.github.wechatpay-apiv3</groupId><artifactId>wechatpay-java</artifactId><version>0.2.7</version></dependency>
2.在resources的dev和prod内加入微信支付必填字段#微信支付字段
wx:merchantId: 164*******privateKeyPath: E:\Env\eladmin\cert\c2\apiclient_key.pemcertPath: E:\Env\eladmin\cert\c2\apiclient_cert.pemcertP12Path: E:\Env\eladmin\cert\c2\apiclient_cert.p12merchantSerialNumber: 4F24D009CDBC**********************apiV3key: tYsmXJr******************appId: wx2e56f5******
3.微信支付测试接口3-1:测试下单接口/api/weChatPay/ceshiJSAPI3-2:测试微信支付结果回调地址,当微信支付后,微信方返回支付信息,在回调接口内触发业务逻辑注:测试回调接口必须为线上接口,线下无法实现可先在线上将微信返回数据打印到txt文件内,然后在本地测试回调接口,触发业务逻辑/api/weChatPay/ceshiPayNotify(放入线上的测试回调接口)/api/weChatPay/payNotify(本地测试回调接口)--可在postman内测试测试时,在Headers内Wechatpay-Serial、Wechatpay-Nonce、Wechatpay-Timestamp、Wechatpay-Signature必填上微信返回的json,直接放入raw-json内进行测试4.退款测试接口/api/weChatPay/ceshiRefund(回调接口不是必填项,可用可不用)
WeChatPayService.java:可放在Service内
----------------------------------------------------package me.zhengjie.modules.api.service;import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.Random;@Service
@RequiredArgsConstructor
public class WeChatPayService {/** 商户API私钥路径 */@Value("${wx.privateKeyPath}") //可自己写死路径public  String privateKeyPath;//=============生成签名=====开始===================================================/*** 作用:使用字段appId、timeStamp、nonceStr、package计算得出的签名值* 场景:根据微信统一下单接口返回的 prepay_id 生成调启支付所需的签名值* @param appId* @param timestamp* @param nonceStr* @param pack package* @return* @throws Exception*/public String getSign(String appId, long timestamp, String nonceStr, String pack) throws Exception{String message = buildMessage(appId, timestamp, nonceStr, pack);String paySign= sign(message.getBytes("utf-8"));return paySign;}private String buildMessage(String appId, long timestamp, String nonceStr, String pack) {return appId + "\n"+ timestamp + "\n"+ nonceStr + "\n"+ pack + "\n";}private String sign(byte[] message) throws Exception{Signature sign = Signature.getInstance("SHA256withRSA");//这里需要一个PrivateKey类型的参数,就是商户的私钥。sign.initSign(getPrivateKey(privateKeyPath));sign.update(message);return Base64.getEncoder().encodeToString(sign.sign());}/*** 获取私钥。** @param filename 私钥文件路径  (required)* @return 私钥对象*/public static PrivateKey getPrivateKey(String filename) throws IOException {String content = new String(Files.readAllBytes(Paths.get(filename)), "utf-8");try {String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "").replaceAll("\\s+", "");KeyFactory kf = KeyFactory.getInstance("RSA");return kf.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey)));} catch (NoSuchAlgorithmException e) {throw new RuntimeException("当前Java环境不支持RSA", e);} catch (InvalidKeySpecException e) {throw new RuntimeException("无效的密钥格式");}}/*** 获取随机位数的字符串* @param length* @return*/public static String getRandomString(int length) {String base = "abcdefghijklmnopqrstuvwxyz0123456789";Random random = new Random();StringBuffer sb = new StringBuffer();for (int i = 0; i < length; i++) {int number = random.nextInt(base.length());sb.append(base.charAt(number));}return sb.toString();}//=============生成签名=====结束===================================================/*** 获取请求文体* @param request* @return* @throws IOException*/public static String getRequestBody(HttpServletRequest request) throws IOException {ServletInputStream stream = null;BufferedReader reader = null;StringBuffer sb = new StringBuffer();try {stream = request.getInputStream();// 获取响应reader = new BufferedReader(new InputStreamReader(stream));String line;while ((line = reader.readLine()) != null) {sb.append(line);}} catch (IOException e) {throw new IOException("读取返回支付接口数据流出现异常!");} finally {reader.close();}return sb.toString();}
}
Controller代码如下:package me.zhengjie.modules.api.rest;import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSONObject;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.payments.jsapi.JsapiService;
import com.wechat.pay.java.service.payments.jsapi.model.Amount;
import com.wechat.pay.java.service.payments.jsapi.model.Payer;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.refund.RefundService;
import com.wechat.pay.java.service.refund.model.AmountReq;
import com.wechat.pay.java.service.refund.model.CreateRequest;
import com.wechat.pay.java.service.refund.model.Refund;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.annotation.AnonymousAccess;
import me.zhengjie.annotation.Log;
import me.zhengjie.config.FileProperties;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.api.service.WeChatPayService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;@Slf4j
@RestController
@RequiredArgsConstructor
@Api(tags = "1.微信小程序")
@RequestMapping("/api/weChatPay")
public class WeChatPayContoller {private final WeChatPayService weChatPayService;private final FileProperties fileProperties;/*** appID*/@Value("${wx.appId}") // 可自己写死--我引用的是自己写的配置内(写死的方式如:appId=wx12345678910)public String appId;/*** 商户号*/@Value("${wx.merchantId}") // 可自己写死public String merchantId;/*** 商户API私钥路径*/@Value("${wx.privateKeyPath}") //可自己写死public String privateKeyPath;/*** 商户证书序列号*/@Value("${wx.merchantSerialNumber}") // 可自己写死public String merchantSerialNumber;/*** 商户APIV3密钥*/@Value("${wx.apiV3key}") //可自己写死public String apiV3key;/*** 商户平台证书路径*/@Value("${wx.certPath}") // 可自己写死public String certPath;/*** 商户平台证书路径p12*/@Value("${wx.certP12Path}") //可自己写死public String certP12Path;private static Map<String, Config> configMap = new HashMap<>();private static Config config = null;private static JsapiService service = null;private static RefundService refundService = null;/*** JSAPI 测试下单接口*/@PostMapping(value = "/ceshiJSAPI")@Log("JSAPI 测试下单接口")@ApiOperation("JSAPI 测试下单接口")@AnonymousAccess@Transactional(rollbackFor = Exception.class)public JSONObject ceshiJSAPI() throws Exception {if (config == null) {config =new RSAAutoCertificateConfig.Builder().merchantId(merchantId).privateKeyFromPath(privateKeyPath).merchantSerialNumber(merchantSerialNumber).apiV3Key(apiV3key).build();}if (service == null) {service = new JsapiService.Builder().config(config).build();}// request.setXxx(val)设置所需参数,具体参数可见Request定义PrepayRequest request = new PrepayRequest();Amount amount = new Amount();amount.setTotal(1);//金额,1为0.01元request.setAmount(amount);request.setAppid(appId);request.setMchid(merchantId);request.setDescription("测试商品标题");//下单标题request.setNotifyUrl("https://www.ceshi123.com/api/weChatPay/ceshiPayNotify");//要求必须为线上接口String ddh = weChatPayService.getRandomString(20);request.setOutTradeNo(ddh);//订单号Payer payer = new Payer();payer.setOpenid("oMr**********");//openidrequest.setPayer(payer);PrepayResponse response = service.prepay(request);JSONObject result = new JSONObject();Long date = new Date().getTime();//获取当前时间戳String nonceStr = weChatPayService.getRandomString(28);//随机字符串,长度为32个字符以下result.put("timeStamp", date.toString());//时间戳result.put("nonceStr", nonceStr);//随机字符串,长度为32个字符以下result.put("package", "prepay_id=" + response.getPrepayId());//PrepayIdresult.put("signType", "RSA");//签名类型result.put("paySign", weChatPayService.getSign(appId, date, nonceStr, "prepay_id=" + response.getPrepayId()));//签名return result;}/*** 测试微信支付结果回调地址(放入线上测试)** @param*/@PostMapping(value = "/ceshiPayNotify")@Log("ceshiPayNotify方法")@ApiOperation("ceshiPayNotify方法")@AnonymousAccesspublic void ceshi_payNotify(HttpServletRequest request) throws IOException {//微信返回的证书序列号String serialNo = request.getHeader("Wechatpay-Serial");//微信返回的随机字符串String nonceStr = request.getHeader("Wechatpay-Nonce");//微信返回的时间戳String timestamp = request.getHeader("Wechatpay-Timestamp");//微信返回的签名String wechatSign = request.getHeader("Wechatpay-Signature");String singType = request.getHeader("Wechatpay-Signature-Type");String collect = request.getReader().lines().collect(Collectors.joining());try {FileUtil.writeUtf8String(collect, fileProperties.getPath().getPath() + "/huidiao-collect.txt");//打印看效果FileUtil.writeUtf8String(serialNo, fileProperties.getPath().getPath() + "/huidiao-serialNo.txt");//打印看效果FileUtil.writeUtf8String(singType, fileProperties.getPath().getPath() + "/huidiao-Signature-Type.txt");//打印看效果FileUtil.writeUtf8String(nonceStr, fileProperties.getPath().getPath() + "/huidiao-nonceStr.txt");//打印看效果FileUtil.writeUtf8String(timestamp, fileProperties.getPath().getPath() + "/huidiao-timestamp.txt");//打印看效果FileUtil.writeUtf8String(wechatSign, fileProperties.getPath().getPath() + "/huidiao-wechatSign.txt");//打印看效果//TODO 业务校验---可以写入自己的业务逻辑} catch (Exception e) {System.out.println("e = " + e);FileUtil.writeUtf8String("22222222222222222222", fileProperties.getPath().getPath() + "/huidiao22.txt");//打印看效果}}/*** 微信支付结果回调地址(本地)** @param request* @return*/@PostMapping(value = "/payNotify")@AnonymousAccess@Transactional(rollbackFor = Exception.class)public ResponseEntity<Object> wxCallback(HttpServletRequest request) throws Exception {//获取报文String body = weChatPayService.getRequestBody(request);//随机串String nonce = request.getHeader("Wechatpay-Nonce");//微信传递过来的签名String signature = request.getHeader("Wechatpay-Signature");//证书序列号(微信平台)String wechatPaySerial = request.getHeader("Wechatpay-Serial");String singType = request.getHeader("Wechatpay-Signature-Type");//时间戳String timestamp = request.getHeader("Wechatpay-Timestamp");if (configMap.get("config") == null) {config = new RSAAutoCertificateConfig.Builder().merchantId(merchantId).privateKeyFromPath(privateKeyPath).merchantSerialNumber(merchantSerialNumber).apiV3Key(apiV3key).build();configMap.put("config", config);}else {config = configMap.get("config");}NotificationParser parser = new NotificationParser((NotificationConfig) config);RequestParam.Builder builder = new RequestParam.Builder();builder.body(body);builder.signature(signature);builder.nonce(nonce);builder.timestamp(timestamp);builder.serialNumber(wechatPaySerial);builder.signType(singType);RequestParam requestParam = builder.build();Transaction parse = parser.parse(requestParam, Transaction.class);if ("SUCCESS".equals(parse.getTradeState().toString())) {//支付成功,你的业务逻辑return new ResponseEntity<>(HttpStatus.OK);} else {throw new BadRequestException( "支付失败");}}/** 测试退款申请* @return*/@PostMapping(value = "/ceshiRefund")@Log("JSAPI 测试退款接口")@ApiOperation("JSAPI 测试退款接口")@AnonymousAccess@Transactional(rollbackFor = Exception.class)public JSONObject ceshiRefund(String No) throws Exception {if (config == null) {config = new RSAAutoCertificateConfig.Builder().merchantId(merchantId).privateKeyFromPath(privateKeyPath).merchantSerialNumber(merchantSerialNumber).apiV3Key(apiV3key).build();}if (refundService == null) {// 初始化服务refundService = new RefundService.Builder().config(config).build();}CreateRequest request = new CreateRequest();request.setOutTradeNo(No);//商户订单号request.setOutRefundNo(weChatPayService.getRandomString(16));//商户退款单号,随机生成request.setReason("取消订单的退款");//退款原因AmountReq amount = new AmountReq();//金额信息amount.setRefund(Long.parseLong("1"));//退款金额(0.01元)amount.setTotal(Long.parseLong("1"));//原订单退款金额(0.01元)amount.setCurrency("CNY");//人民币request.setAmount(amount);//        request.setNotifyUrl("https://https://www.ceshi123.com/api/weChatPay/ceshiRefundNotify");//回调接口,退款时非必填--这里我就没写接口JSONObject result = new JSONObject();try {Refund response = refundService.create(request);result.put("code", "SUCCESS");result.put("message", "退款成功");return result;} catch (ServiceException e) { // 服务返回状态小于200或大于等于300,例如500// 调用e.getResponseBody()获取返回体打印日志或上报监控,更多方法见ServiceException定义return JSONObject.parseObject(e.getResponseBody());}}}
http://www.khdw.cn/news/10068.html

相关文章:

  • dede后台网站主页广告推广平台网站
  • 海口网站建设推广发软文的平台
  • 旅游网站建设规划方案站长友情链接平台
  • 绍兴做网站选哪家官方百度
  • 购物网站功能长沙关键词自然排名
  • 烟台商城网站制作搜索引擎优化规则
  • 定兴做网站的外贸谷歌seo
  • 三线城市做网站需求长春做网站公司长春seo公司
  • 企业网站建设费用记入网站建设山东聚搜网络
  • 百度搜索自己的网站自己怎么建网站
  • 网站快照不更新了网址链接
  • 电脑上自己做科目一的网站公司企业网站建设
  • 做网站的天空网全免费建立自己的网站
  • 南宁定制网站建设最新的军事新闻
  • 网架加工厂有招工的吗哈尔滨seo优化
  • 在百度上做网站有用吗郴州seo网络优化
  • wordpress修改首页文章样式安卓优化神器
  • 和顺网站建设友情链接是什么
  • 网络营销推广的步骤安徽网站关键字优化
  • 北京通州做网站推广技巧
  • 网站的建设方面网络推广的调整和优化
  • wordpress 如何修改关于我们沈阳网站推广优化
  • 哈尔滨手机网站制作网站建设的一般步骤
  • 国内人做韩国网站一般都卖什么手续淘宝seo搜索引擎原理
  • 网站托管公司站长之家ping
  • 论坛网站文本抓取怎么做网页搜索快捷键是什么
  • 忘记网站后台地址百度收录快的发帖平台
  • 海外网站营销今日预测足球比分预测
  • 长沙手机网站建设哪些内容成都网站建设方案外包
  • 小甲鱼网站开发广州关键词seo