1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Java实现微信支付(微信公众号JSAPI支付)

Java实现微信支付(微信公众号JSAPI支付)

时间:2021-04-03 19:29:21

相关推荐

Java实现微信支付(微信公众号JSAPI支付)

Java实现微信支付(微信公众号JSAPI支付)

第一步 开发环境准备

在接入微信支付之前,需要现在微信支付商户平台入驻,成为商家,才能继续后续的开发。

微信支付商户平台网址:https://pay.

不过,个人用户是无法成为商家的,只有以下几种用户类型才可以成为商家。

成为商家之后,需要完成证书申请、秘钥配置、产品申请等操作,具体如下。

1.1 申请证书与秘钥的配置

进入微信支付商户平台,在账号中心→API安全页面,完成API证书的申请,和API秘钥的配置,如下图所示。

API证书申请的过程稍微复杂,但是官方有详细的申请教程,点击右侧的查看指引按钮,根据教程一步一步来操作即可。

两种API秘钥则是自定义的32个字符的字符串,任意填写并记住即可。

1.2 申请产品

进入微信支付商户平台,在产品中→我的产品页面,可以查看当前商户已开通未开通的产品,根据项目需求,字形申请开通即可。

1.3 开发配置信息填写

进入微信支付商户平台,在产品中心→开发配置页面,记下本商户的商户号,并填写已申请支付产品的各项授权目录回调链接等信息。

1.4 APPID账号管理

进入微信支付商户平台,在产品中心→APPID账号管理页面,关联诸如服务号、订阅号、小程序、企业微信、移动应用、网站应用等的APPID,如下图所示。

至此,微信支付商户的基本信息配置完毕,总结下来,以下五项信息时必须的:

商户号AppIDAPI证书(3个文件)APIv2秘钥APIv3秘钥回调链接

第二步 项目创建与依赖导入

2.1 创建SpringBoot项目

创建SpringBoot项目的教程太多太多了…比如:https://cxhit./article/details/113782979,所以这里不再赘述。

项目结构如下图所示。

2.2 导入依赖

在pom.xml文件中,导入微信支付的第三方SDK依赖:

<!-- 微信支付的核心依赖 --><!-- /artifact/com.github.binarywang/weixin-java-pay --><!-- /Wechat-Group/WxJava --><dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-pay</artifactId><version>4.3.0</version></dependency>

其中最新版本可前往Maven官方仓库查看。

代码部分

1、 获取openid

第一步:用户同意授权,获取code

前台请求自己写的接口,然后在后台此接口中调用微信授权接口,调用此接口需要有三个注意的地方

1. APPID:公众号的appid

2. REDIRECT_URI:这个地址是调用微信授权后的回调接口,在回调接口中我们可以拿到用户的信息,特别注意:redirect_uri地址需要使用 urlEncode 对链接进行处理

3. SCOPE:此处填snsapi_userinfo,需要用户点授权

/*** 微信授权接口* @param response* @throws IOException*/@RequestMapping("wxLogin")public void wxLogin(HttpServletResponse response) throws IOException {//域名String sym = "";//这里是回调的urlString redirectUri = URLEncoder.encode(sym+"/weChat/callBack","UTF-8");String url = "https://open./connect/oauth2/authorize?" +"appid=wx63d9c9b609ed6579" +"&redirect_uri=" + redirectUri +"&response_type=code" +"&scope=snsapi_userinfo" +"&state=STATE#wechat_redirect";response.sendRedirect(url.replace("APPID","wx63d9c9b609ed6579").replace("REDIRECT_URI",redirectUri).replace("SCOPE","snsapi_base"));}

接下来就是微信授权的回调接口

1、获取code

2、根据code获取openid

/*** 微信授权回调接口* @param request* @return*/@RequestMapping("callBack")public String callBack(HttpServletRequest request){//获取回调地址中的codeString code = request.getParameter("code");String appId = "xxxxxxxxxxx";String secret = "xxxxxxxxxxxxxxxxxxxxxxxx";String url = "https://api./sns/oauth2/access_token?" +"appid=" + appId +"&secret=" + secret +"&code=" + code +"&grant_type=authorization_code";//获取openIdString data = HttpUtil.doGet(url);AccessToken accessToken = JSONObject.parseObject(data, AccessToken.class);return accessToken.getOpenid();}

补上刚刚用的实体类AccessToken

@Datapublic class AccessToken {private String accessToken;private String expiresIn;private String refreshToken;private String openid;private String scope;}

2、创建配置实体类

import lombok.Data;import java.io.Serializable;/*** 微信支付配置信息* @author Administrator*/@Datapublic class WeChatPayEntity implements Serializable {private static final long serialVersionUID = 1L;/*** 必填:微信支付商户号*/private String mchId;/*** 必填:商户绑定的微信公众号、小程序、开放平台等的appid*/private String appId;/*** 必填:APIv2密钥(调用v2版本的API时,需用APIv2密钥生成签名)*/private String mchKey;/*** 必填:APIv3密钥(调用APIv3的下载平台证书接口、处理回调通知中报文时,要通过该密钥来解密信息)*/private String apiV3Key;/*** 必填:apiclient_cert.p12证书文件的绝对路径,或者以classpath:开头的类路径。*/private String keyPath;/*** 必填:apiclient_key.pem证书文件的绝对路径,或者以classpath:开头的类路径。*/private String privateKeyPath;/*** 必填:apiclient_cert.pem证书文件的绝对路径,或者以classpath:开头的类路径。*/private String privateCertPath;/*** 必填:微信支付异步回调通知地址。通知url必须以https开头(SSL协议),外网可访问,不能携带参数。*/private String notifyUrl;}

注意:为了减少代码篇幅,此代码引入了lombok。如果没有使用lombok,请自行生成Get和Set方法。

3、实现支付服务类

以下代码实现了基本的配置和支付、退款。查询功能,有详细的注解。

另外注意:以下代码中使用了Hutool组件的Id生成工具(用于生成订单号),请在pom文件中自行添加hutool的依赖

import com.cxhit.pay.wechat.entity.WeChatPayEntity;import com.github.binarywang.wxpay.bean.request.WxPayRefundV3Request;import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryV3Result;import com.github.binarywang.wxpay.bean.result.WxPayRefundV3Result;import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;import com.github.binarywang.wxpay.config.WxPayConfig;import com.github.binarywang.wxpay.exception.WxPayException;import com.github.binarywang.wxpay.service.WxPayService;import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;import mons.lang3.StringUtils;import org.springframework.stereotype.Service;/*** 微信支付服务类(只实现V3接口)** @author* @since*/@Servicepublic class WeChatPayService {// 是否启用沙箱环境。微信支付的沙箱环境贼垃圾...好多年不维护...千万不要用。。。private static final Boolean SAND_BOX_ENV = false;// 支付结果回调地址private static final String NOTIFY_URL = "/api/wx/pay/notify";/*** 获取微信支付相关接口服务(后续的几个服务方法,实现了基本的实例)* (此接口也可以直接在controller中使用)** @return 微信支付服务接口*/public WxPayService getWxPayService() {// TODO 此处可以从数据库读取微信支付的相关秘钥、证书等配置信息。但我们这里就直接写入静态数据进行演示WeChatPayEntity weChatPayEntity = new WeChatPayEntity();// 1. 填充基本信息(商户号与APPID)weChatPayEntity.setMchId("15333333333");weChatPayEntity.setAppId("wx123456789101112");// 2. 填充秘钥信息weChatPayEntity.setMchKey("abcdefghabcdefghabcdefghabcdefgh");weChatPayEntity.setApiV3Key("abcdefghabcdefghabcdefghabcdefgh");// 3. 填充证书路径信息weChatPayEntity.setKeyPath("E:\\微信支付\\Cert\\apiclient_cert.p12");weChatPayEntity.setPrivateKeyPath("E:\\微信支付\\Cert\\apiclient_key.pem");weChatPayEntity.setPrivateCertPath("E:\\微信支付\\Cert\\apiclient_cert.pem");// 4. 填充回调URLweChatPayEntity.setNotifyUrl(NOTIFY_URL);// 以下代码无需修改// 生成配置WxPayConfig payConfig = new WxPayConfig();// 填充基本配置信息payConfig.setAppId(StringUtils.trimToNull(weChatPayEntity.getAppId()));payConfig.setMchId(StringUtils.trimToNull(weChatPayEntity.getMchId()));payConfig.setMchKey(StringUtils.trimToNull(weChatPayEntity.getMchKey()));payConfig.setApiV3Key(StringUtils.trimToNull(weChatPayEntity.getApiV3Key()));payConfig.setKeyPath(StringUtils.trimToNull(weChatPayEntity.getKeyPath()));payConfig.setPrivateCertPath(StringUtils.trimToNull(weChatPayEntity.getPrivateCertPath()));payConfig.setPrivateKeyPath(StringUtils.trimToNull(weChatPayEntity.getPrivateKeyPath()));payConfig.setNotifyUrl(StringUtils.trimToNull(weChatPayEntity.getNotifyUrl()));// 创建配置服务WxPayService wxPayService = new WxPayServiceImpl();wxPayService.setConfig(payConfig);// 可以指定是否使用沙箱环境payConfig.setUseSandboxEnv(SAND_BOX_ENV);if (SAND_BOX_ENV) {try {payConfig.setMchKey(wxPayService.getSandboxSignKey());wxPayService.setConfig(payConfig);} catch (WxPayException e) {throw new RuntimeException(e.getMessage());}}// 返回结果return wxPayService;}/*** 下单接口(只设置了必填信息)(V3版本)** @param tradeType 必填:交易类型:jsapi(含小程序)、app、h5、native* @param description 必填:商品描述(商品标题)* @param outTradeNo 必填:商家订单号* @param total 必填:商品金额(单位:分)* @param openId特殊必填:支付用户的OpenId,JSAPI支付时必填。* @return 支付返回结果:{0:Y|N,1:支付结果} <br>* 关于支付结果: <br>* APP支付、JSAPI支付为[预支付交易会话标识] <br>* Native支付为[二维码链接] <br>* H5支付为[支付跳转链接]*/public String[] pay(String tradeType, String description, String outTradeNo, Integer total, String openId) {// 构建统一下单请求参数对象WxPayUnifiedOrderV3Request wxPayUnifiedOrderV3Request = new WxPayUnifiedOrderV3Request();// 对象中写入数据wxPayUnifiedOrderV3Request// 【1】必填信息// 商品描述:必填.setDescription(description)// 商户订单号:必填,同一个商户号下唯一.setOutTradeNo(outTradeNo)// 通知地址:必填,公网域名必须为https,外网可访问。可不填,通过配置信息读取(但这个组件没写...).setNotifyUrl(NOTIFY_URL)// 订单金额:单位(分).setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(total))// 【2】选填信息// 附加信息.setAttach("附加信息")// 订单优惠标记// ....setGoodsTag("ABCD");try {// 根据请求类型,返回指定类型,其中包含:【3】条件必填信息switch (tradeType.toLowerCase()) {// Native支付case "native":return new String[]{"Y", this.getWxPayService().unifiedOrderV3(TradeTypeEnum.NATIVE, wxPayUnifiedOrderV3Request).getCodeUrl()};// JSAPI支付case "jsapi":// 用户在直连商户appid下的唯一标识。 下单前需获取到用户的OpenidwxPayUnifiedOrderV3Request.setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid(openId));return new String[]{"Y", this.getWxPayService().unifiedOrderV3(TradeTypeEnum.JSAPI, wxPayUnifiedOrderV3Request).getPrepayId()};// H5支付case "h5":wxPayUnifiedOrderV3Request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo()// 用户终端IP.setPayerClientIp("12.34.56.78").setH5Info(new WxPayUnifiedOrderV3Request.H5Info()// 场景类型.setType("wechat")));return new String[]{"Y", this.getWxPayService().unifiedOrderV3(TradeTypeEnum.H5, wxPayUnifiedOrderV3Request).getH5Url()};// APP支付case "app":return new String[]{"Y", this.getWxPayService().unifiedOrderV3(TradeTypeEnum.APP, wxPayUnifiedOrderV3Request).getPrepayId()};default:// throw new RuntimeException("输入的[" + tradeType + "]不合法,只能为native、jsapi、h5、app其一,请核实!");return new String[]{"N", "输入的[" + tradeType + "]不合法,只能为native、jsapi、h5、app其一,请核实!"};}} catch (WxPayException e) {// throw new RuntimeException(e.getMessage());return new String[]{"N", e.getMessage()};}}/*** 订单查询接口(新版V3)** @param transactionId 微信订单号* @param outTradeNo 商户系统内部的订单号,当没提供微信订单号(transactionId)时需要传* @return 订单成功(SUCCESS):{0:Y,1:商户单号,2:微信单号,3:订单金额(分),4:交易时间,5:交易状态,6:交易描述}* 订单异常:{0:N,1:订单状态,2:订单描述}* 查询错误:{0:E,1:错误代码,2:错误描述}*/public String[] query(String transactionId, String outTradeNo) {// 商家单号和微信单号不能同时为空if (null == transactionId && null == outTradeNo) {return new String[]{"E","ERROR","微信单号和商户单号不能同时为空,请检查!"};}try {// 执行查询并返回查询结果WxPayOrderQueryV3Result wxPayOrderQueryV3Result = this.getWxPayService().queryOrderV3(transactionId, outTradeNo);// 如果交易成功,或者在退款中if ("SUCCESS".equals(wxPayOrderQueryV3Result.getTradeState()) || "REFUND".equals(wxPayOrderQueryV3Result.getTradeState())) {return new String[]{"Y",wxPayOrderQueryV3Result.getOutTradeNo(),wxPayOrderQueryV3Result.getTransactionId(),String.valueOf(wxPayOrderQueryV3Result.getAmount().getTotal()),wxPayOrderQueryV3Result.getSuccessTime(),wxPayOrderQueryV3Result.getTradeState(),wxPayOrderQueryV3Result.getTradeStateDesc()};} else {return new String[]{"N",wxPayOrderQueryV3Result.getTradeState(),wxPayOrderQueryV3Result.getTradeStateDesc()};}} catch (WxPayException e) {// throw new RuntimeException(e.getMessage());return new String[]{"E",e.getErrCode(),e.getErrCodeDes()};}}/*** 退款接口(新版V3)** @param outTradeNo 商户订单号* @param outRefundNo 商户退款单号* @param total 订单总金额(单位:分)* @param refund退款金额(单位:分)* @return 退款成功或退款处理中:{0:Y,1:商户单号,2:微信单号,3:退款单号,4:订单金额(分),5:退款金额(分),6:退款时间}<br>* 订单异常:{0:N,1:订单状态,2:订单描述}* 退款错误:{0:E,1:错误代码,2:错误描述}*/public String[] refund(String outTradeNo, String outRefundNo, Integer total, Integer refund) {// 几个参数不能为空if (null == outTradeNo || null == outRefundNo || null == total || null == refund) {return new String[]{"E","ERROR","商户单号、退款单号、订单金额、退款金额均不能为空,请检查!"};}// 构造请求参数WxPayRefundV3Request wxPayRefundV3Request = new WxPayRefundV3Request();wxPayRefundV3Request.setOutTradeNo(outTradeNo).setOutRefundNo(outRefundNo).setAmount(new WxPayRefundV3Request.Amount().setTotal(total).setRefund(refund).setCurrency("CNY"));try {// 执行请求并返回信息WxPayRefundV3Result wxPayRefundV3Result = this.getWxPayService().refundV3(wxPayRefundV3Request);// 退款处理中 || 退款成功if ("PROCESSING".equals(wxPayRefundV3Result.getStatus()) || "SUCCESS".equals(wxPayRefundV3Result.getStatus())) {return new String[]{"Y",wxPayRefundV3Result.getOutTradeNo(),wxPayRefundV3Result.getTransactionId(),wxPayRefundV3Result.getOutRefundNo(),String.valueOf(wxPayRefundV3Result.getAmount().getTotal()),String.valueOf(wxPayRefundV3Result.getAmount().getRefund()),wxPayRefundV3Result.getCreateTime()};} else {return new String[]{"N",wxPayRefundV3Result.getStatus(),"退款失败"};}} catch (WxPayException e) {// throw new RuntimeException(e.getMessage());return new String[]{"E",e.getErrCode(),e.getErrCodeDes()};}}}

3.1 服务类的补充说明

一般来说,我们将配置信息放在yaml文件中。这种操作是没有问题的。

但本文中的支付服务类的实现方案,可以实现将微信支付的配置信息,经过加密后,存储在数据库中。

当需要发起支付的时候,从数据库中读取信息后,经过解密,再写入到微信的支付配置类中。

对于本演示项目,其配置信息就直接写在代码里了,如下图所示。

4、实现控制类

代码中有详细注释,不过多解释

import cn.hutool.core.lang.Dict;import cn.hutool.core.util.IdUtil;import com.cxhit.pay.wechat.service.WeChatPayService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;/*** 微信支付控制类** @author* @since*/@RestController@RequestMapping("weChat")public class WeChatPayController {@Autowiredprivate WeChatPayService weChatPayService;/*** 微信支付接口** @param title 商品名称* @param price 商品价格* @return 返回结果*/@PostMapping(value = "/pay")@ResponseBodypublic Dict pay(String title, String price,String openId) {// 生成商家单号String outTradeNo = IdUtil.simpleUUID();// 支付宝价格转换成浮点数后,乘100,再取整,得以分为单位的价格Integer total = (int) (Float.parseFloat(price) * 100);// 发起支付请求String[] result = weChatPayService.pay("jsapi", title, outTradeNo, total, openId);// 返回结果:下单成功if ("Y".equals(result[0])) {return Dict.create().set("code", 200).set("qrcode", result[1]).set("outTradeNo", outTradeNo);}// 下单失败else {return Dict.create().set("code", 500).set("msg", result[1]);}}/*** 退款接口** @param outTradeNo 商家单号* @param amount退款金额(不能大于总金额)* @return 退款结果*/@PostMapping(value = "/refund")@ResponseBodypublic Dict refund(String outTradeNo, String amount) {// 生成商家退款单号String outRefundNo = IdUtil.simpleUUID();// 查询订单金额String[] query = weChatPayService.query(null, outTradeNo);// 查询成功if (query[0].equals("Y")) {int total = Integer.parseInt(query[3]);// 支付宝价格转换成浮点数后,乘100,再取整,得以分为单位的价格int refund = (int) (Float.parseFloat(amount) * 100);if (refund > total) {return Dict.create().set("code", 500).set("msg", "退款错误:退款金额不能大于支付金额!");}// 发起退款String[] result = weChatPayService.refund(outTradeNo, outRefundNo, total, refund);// 退款成功if (result[0].equals("Y")) {return Dict.create().set("code", 200).set("msg", "退款进行中,稍后到账!" +" <br>商户单号:" + result[1] +" <br>退款单号:" + result[3] +" <br>订单金额:" + result[4] + "分" +" <br>退款金额:" + result[5] + "分" +" <br>退款时间:" + result[6]);}// 退款失败else if (result[0].equals("N")) {return Dict.create().set("code", 500).set("msg", "退款失败:" + result[1] + result[2]);}// 退款发生错误else {return Dict.create().set("code", 500).set("msg", "退款错误:" + result[1] + result[2]);}}// 查询失败else {return Dict.create().set("code", 500).set("msg", "退款错误:" + query[1] + query[2]);}}/*** 查询接口** @param outTradeNo 商家订单号* @return 结果*/@PostMapping(value = "/query")@ResponseBodypublic Dict query(String outTradeNo) {// 查询订单String[] query = weChatPayService.query(null, outTradeNo);// 查询成功if (query[0].equals("Y")) {return Dict.create().set("code", 200).set("msg", "查询成功!" +" <br>商户单号:" + query[1] +" <br>微信单号:" + query[2] +" <br>订单金额:" + query[3] + "分" +" <br>交易时间:" + query[4] +" <br>交易状态:" + query[5] +" <br>交易描述:" + query[6]);}// 查询失败else if (query[0].equals("N")) {return Dict.create().set("code", 500).set("msg", "查询结果:" + query[1] + query[2]);}// 查询发送异常else {return Dict.create().set("code", 500).set("msg", "查询失败:" + query[1] + query[2]);}}}

到此为止,我们千辛万苦费劲拿到的范围值,仅仅是为了一个prepay_id,这个prepay_id是在微信支付接口返回的qrcode就是prepay_id

5、调起支付

看看前台都需接收哪些值吧

https://pay./wiki/doc/apiv3/apis/chapter3_1_4.shtml

Java代码展示:

import cn.hutool.core.io.file.FileReader;import com.alibaba.fastjson.JSONObject;import mons.lang.RandomStringUtils;import org.apache.poi.util.IOUtils;import org.junit.Test;import org.springframework.stereotype.Repository;import org.springframework.util.ResourceUtils;import java.io.IOException;import java.io.InputStream;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.security.Signature;import java.security.SignatureException;import java.util.Base64;@Repositorypublic class CreateSign {public String getToken(String appid,String prepay_id) throws IOException, SignatureException, NoSuchAlgorithmException, InvalidKeyException {String randomOnce = RandomStringUtils.randomAlphanumeric(32);//随机字符串String nonceStr = randomOnce;//真!随机字符串//时间戳long timestamp = System.currentTimeMillis() / 1000;//从下往上依次生成String message = buildMessage(appid, timestamp, nonceStr, prepay_id);//签名String signature = sign(message.getBytes("utf-8"));JSONObject param = new JSONObject();param.put("appId",appid);param.put("timeStamp",timestamp);param.put("nonceStr",randomOnce);param.put("package",prepay_id);param.put("signType","RSA");param.put("paySign",signature);return param.toString() ;}public String sign(byte[] message) throws NoSuchAlgorithmException, SignatureException, IOException, InvalidKeyException {//签名方式Signature sign = Signature.getInstance("SHA256withRSA");//在本地环境运行使用 私钥,通过MyPrivateKey来获取,这是个静态类可以接调用方法 ,需要的是_key.pem文件的绝对路径配上文件名sign.initSign(MyPrivatekey.getPrivateKey("E:\\微信支付\\Cert\\apiclient_key.pem"));//在服务器中使用这种方式//FileReader fileReader = new FileReader("\\usr\\local\\WXCertUtil\\cert\\1621641850_0614_cert\\apiclient_key.pem");sign.initSign(MyPrivatekey.getPrivateKey(fileReader.readString()));sign.update(message);return Base64.getEncoder().encodeToString(sign.sign());}/*** 按照前端签名文档规范进行排序,\n是换行* @param appid* @param timestamp* @param nonceStr* @param prepay_id* @return*/public String buildMessage(String appid, long timestamp,String nonceStr,String prepay_id) {return appid + "\n"+ timestamp + "\n"+ nonceStr + "\n"+ "prepay_id="+prepay_id + "\n";}}

补充上面代码用到的MyPrivateKey工具类

import org.springframework.stereotype.Repository;import java.io.IOException;import java.security.KeyFactory;import java.security.NoSuchAlgorithmException;import java.security.PrivateKey;import java.security.spec.InvalidKeySpecException;import java.security.spec.PKCS8EncodedKeySpec;import java.util.Base64;@Repositorypublic class MyPrivatekey {/*** 获取私钥。** @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 = filename.replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "").replaceAll("\\s+", "");KeyFactory kf = KeyFactory.getInstance("RSA");return kf.generatePrivate(new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(privateKey)));} catch (NoSuchAlgorithmException e) {throw new RuntimeException("当前Java环境不支持RSA", e);} catch (InvalidKeySpecException e) {throw new RuntimeException("无效的密钥格式");}}}

Service层代码:

@Overridepublic String rsaPaySign(String prepayId) {String appId = "XXXXXXX";try {String getToken = createSign.getToken(appId, prepayId);return getToken;} catch (IOException e) {e.printStackTrace();} catch (SignatureException e) {e.printStackTrace();} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();}return "签名错误";}

前端控制器Controller层代码:

/*** 调起支付对sign加密* @param prepayId* @return*/@GetMapping("rsaPaySign")public String rsaPaySign(@RequestParam("prepayId")String prepayId){System.out.println("prepayId:"+prepayId);String rsaPaySign = weChatPayService.rsaPaySign(prepayId);return rsaPaySign;}

6、前端调起支付部分代码(Vue)

function onBridgeReady() {WeixinJSBridge.invoke('getBrandWCPayRequest', {"appId":value.appId,//公众号ID,由商户传入"timeStamp": value.timeStamp+"",//时间戳,自1970年以来的秒数"nonceStr": value.nonceStr,//随机串"package": "prepay_id="+value.package,"signType": value.signType,//微信签名方式:"paySign": value.paySign},function(res) {if (res.err_msg == "get_brand_wcpay_request:ok") {//支付成功} else if (res.err_msg == "get_brand_wcpay_request:cancel") {} else if (res.err_msg == "get_brand_wcpay_request:fail") {} // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。});}if (typeof WeixinJSBridge == "undefined") {if (document.addEventListener) {document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);} else if (document.attachEvent) {document.attachEvent('WeixinJSBridgeReady', onBridgeReady);document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);}} else {onBridgeReady();}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。