微信支付:wxpay.unifiedOrder(data)返回appid 与 openId 不配
原因:小程序和APP、公众号等支付方式夸端口调用支付,后台配置多个appId时
A程序中的openid 在B程序中支付。即使用A程序的openid和B程序的appIdy去调用wxpay.unifiedOrder(data)
把请求统一支付的参数输出:得到当前的appid,微信返回后看到另一个Appid,如果两个一致,则不会出现不匹配问题。不一致,就会报appid 与 openId 不配的错误。
解决方式:由于系统中的WeiXinConfigUtil文件实现了微信SDK的WXPayConfig,多个appid在上送请求支付时对获取APPid做了区分获取,但是没有重写getAppID()方法,导致默认使用appID作为属性的参数值是固定的,在SDK内部获取appid时,不是动态获取,而是配置好的固定值,所以重写getAppID()方法,通过tradeType来区分获取的是哪一个appid
package com.wlnl.lanaer.service.api.util; import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.github.wxpay.sdk.WXPayConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream; /**
* <p>
* 微信支付工具类
* </p>
*
* @author luolei
* @Version: V1.0
* @since 2019-06-04 21:02
*/
@Slf4j
public class WeiXinConfigUtil implements WXPayConfig { private byte[] certData;
/**
* 微信支付应用ID app_id
*/
public static final String APP_ID = "123456789";
/**
* 微信支付key
*/
public static final String KEY = "666666666666";
/**
* 微信支付商户号 mch_id
*/
public static final String MCH_ID = "8888888888"; public WeiXinConfigUtil() {
this.certData = getCertStream("apiclient_cert.p12");
} /**
* 读取resource目录的配置文件
*
* @param path : 文件名称
* @return 返回读取byte数组
*/
public byte[] getCertStream(String path) { try {
if (StrUtil.isEmpty(path)) {
throw new Exception("读取文件路径为空");
}
ClassPathResource classPathResource = new ClassPathResource(path);
//获取文件流
InputStream stream = classPathResource.getInputStream(); byte[] content = IoUtil.readBytes(stream);
stream.read(content);
stream.close();
return content;
} catch (IOException e) {
log.error("读取文件流异常: {}", e.getMessage());
e.printStackTrace(); } catch (Exception e) {
log.error("读取文件路径异常: {}", e.getMessage());
e.printStackTrace(); }
return null;
} @Override
public String getAppID() {
return APP_ID;
} //parnerid,商户号
@Override
public String getMchID() {
return MCH_ID;
} @Override
public String getKey() {
return KEY;
} @Override
public InputStream getCertStream() {
ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);
return certBis;
} @Override
public int getHttpConnectTimeoutMs() {
return 8000;
} @Override
public int getHttpReadTimeoutMs() {
return 10000;
} }
如果微信支付key和微信支付商户号 mch_id不需要修该时(即多个程序使用的微信支付key和微信支付商户号 mch_id都是同一个)
我们只需要修改微信程序的app_id,这是就可以再创建一个类WeiXinMiniProConfigUtil继承我们上面写的WeiXinConfigUti类,并且重写getAppID()方法,代码如下
package com.wlnl.lanaer.service.api.util;
/**
* @author luolei
* @version v1.0.1
* @since 2021/9/7
**/public class WeiXinMiniProConfigUtil extends WeiXinConfigUtil { /**
* 小程序appid
* 如果有多个appId的情况不能写死
*/
// public static final String WX_MINI_PRO_APP_ID = "123456789"; //老版小程序appId
public static String WX_MINI_PRO_APP_ID = "987654321"; /**
* 注意这里一定要重写getAppID()方法,返回我们指定的appId
* @return
*/
@Override
public String getAppID() {
return WX_MINI_PRO_APP_ID;
} public WeiXinMiniProConfigUtil(){} /**
* 使用可修改的appId,防止appId与openId不匹配的问题
* @param appId
*/
public WeiXinMiniProConfigUtil(String appId) {
WX_MINI_PRO_APP_ID = appId;
} }
下面就是测试微信支付是否能下单成功了,代码如下
package com.wlnl.lanaer.service.api.mq; import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayUtil;
import com.google.common.collect.Maps;
import com.wlnl.lanaer.service.api.KxkdApiServiceApplication;
import com.wlnl.lanaer.service.api.constant.enums.ResultEnum;
import com.wlnl.lanaer.service.api.exeception.LanaerException;
import com.wlnl.lanaer.service.api.exeception.OrderExistException;
import com.wlnl.lanaer.service.api.util.WeiXinMiniProConfigUtil;
import com.wlnl.lanaer.service.api.vendors.tencent.pay.WeiXinPayConstant;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.util.StringUtils; import java.util.Map; /**
* @Description TODO
* @Date 2023/04/08 15:27
* @Created by luolie
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = {KxkdApiServiceApplication.class})
@AutoConfigureMockMvc
@ExtendWith(SpringExtension.class)
@ActiveProfiles(profiles = "dev")
public class TestWxPush {
/**
* 微信下单测试
*/
@Test
public void doUnifiedOrderTest() {
Map map = doUnifiedOrder("5555555555", "111111111111111111");
} /**
* 小程序支付场景
*/
public Map doUnifiedOrder(String appId, String openId) {
try {
WeiXinMiniProConfigUtil config = new WeiXinMiniProConfigUtil(appId); //使用前端传过来的appId,防止appId与openId不匹配的问题
WXPay wxpay = new WXPay(config);
Map<String, String> data = Maps.newHashMap();
data.put("appid", config.getAppID());
data.put("mch_id", config.getMchID());
data.put("nonce_str", WXPayUtil.generateNonceStr());
data.put("body", "测试微信支付");
data.put("out_trade_no", "2021WERUN1647840687637");
data.put("total_fee", "1000"); // 支付金额
data.put("spbill_create_ip", "59.37.125.120"); //自己的服务器IP地址
data.put("notify_url", "支付成功后的回调url(外网可访问的https协议的url)"); // 异步通知地址(请注意必须是外网)
data.put("trade_type", "JSAPI");
data.put("openid", openId); // trade_type是JSAPI的时候,必须有openid
data.put("sign", WXPayUtil.generateSignature(data, config.getKey()));
//使用官方API请求预付订单
Map<String, String> response = wxpay.unifiedOrder(data);
//主要返回以下5个参数
if (WeiXinPayConstant.WEIXIN_PAY_RESULT_SUCCESS.equals(response.get(WeiXinPayConstant.WEIXIN_PARY_RETURN_CODE)) && WeiXinPayConstant.WEIXIN_PAY_RESULT_SUCCESS.equals(response.get(WeiXinPayConstant.WEIXIN_RESULT_CODE))) {
Map<String, String> param = Maps.newHashMap();
param.put("appId", config.getAppID());
param.put("timeStamp", System.currentTimeMillis() / 1000 + "");
param.put("nonceStr", WXPayUtil.generateNonceStr());
param.put("package", "prepay_id=" + response.get("prepay_id"));
param.put("signType", "MD5");
param.put("sign", WXPayUtil.generateSignature(param, config.getKey()));
// 以下是返回的
param.put("partnerid", response.get("mch_id"));
param.put("prepayid", response.get("prepay_id"));
param.put("body", "测试微信支付");
param.put("out_trade_no", "2021WERUN1647840687637");
param.put("total_fee", "1000");
return param;
} else {
String err_code = response.get("err_code");
// 商户订单号重复
if (!StringUtils.isEmpty(err_code) && "INVALID_REQUEST".equals(err_code)) {
throw new OrderExistException(response.get(WeiXinPayConstant.WEIXIN_ERR_CODE_DESG));
}
// 订单创建失败
if (WeiXinPayConstant.WEIXIN_PAY_RESULT_FALL.equals(response.get(WeiXinPayConstant.WEIXIN_PARY_RETURN_CODE))) {
throw new LanaerException(response.get(WeiXinPayConstant.WEIXIN_PARY_RETURN_MSG));
}
String err_code_des = response.get("err_code_des");
if (StringUtils.hasLength(err_code_des)) {
throw new LanaerException(err_code_des);
}
}
} catch (OrderExistException e) {
throw e;
} catch (Exception e) {
e.printStackTrace();
throw new LanaerException(ResultEnum.ERROR_CODE.getCode(), "下单失败");
}
throw new LanaerException(ResultEnum.ERROR_CODE.getCode(), "下单失败");
}
}
微信支付:wxpay.unifiedOrder(data)返回appid 与 openId 不配的更多相关文章
- ASP.NET WEB API微信支付通知接口,返回xml数据,微信服务器不识别问题
原文:ASP.NET WEB API微信支付通知接口,返回xml数据,微信服务器不识别问题 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/MrTra ...
- 微信支付中的jsapi返回提示信息
jsapi中跳转到微信支付中触发的方法是js中的getBrandWCPayRequest方法. 改方法中的返回结果msg提示信息如下: err_msg:get_brand_wcpay_request: ...
- iOS 微信支付点击左上角返回解决方案
在网了搜了一些解决方案,感觉并不是那么严谨,于是自己动手搞了一下,直接说思路 iOS调起第三方支付和安卓还不一样,安卓是把第三方的支付SDK直接镶嵌在自己的App中,而iOS由于沙盒机制,各个应用之间 ...
- 【原创分享·微信支付】 C# MVC 微信支付教程系列之扫码支付
微信支付教程系列之扫码支付 今天,我们来一起探讨一下这个微信扫码支付.何为扫码支付呢?这里面,扫的码就是二维码了,就是我们经常扫一扫的那种二维码图片,例如,我们自己添 ...
- iOS应用之微信支付集成-直接前端集成
所有信息的生成都在前端完成,包括对订单进行sign签名以及MD5签名加密(此方法相对来说有些复杂,没有官方给的方法简单).注:官方给的是v3&v4支付流程,签名和加密都是在服务器端进行,由于没 ...
- C# 微信支付教程系列之扫码支付
微信支付教程系列之扫码支付 今天,我们来一起探讨一下这个微信扫码支付.何为扫码支付呢?这里面,扫的码就是二维码了,就是我们经常扫一扫的那种二维码图片,例如,我们自己添加好友的时候 ...
- .Net 微信开发与微信支付
.NET https://github.com/JeffreySu/WeiXinMPSDK JAVA http://git.oschina.net/pyinjava/fastweixin ...
- 微信公众号支付|微信H5支付|微信扫码支付|小程序支付|APP微信支付解决方案总结
最近负责的一些项目开发,都用到了微信支付(微信公众号支付.微信H5支付.微信扫码支付.APP微信支付).在开发的过程中,在调试支付的过程中,或多或少都遇到了一些问题,今天总结下,分享,留存. 先说注意 ...
- Java 后端微信支付demo
Java 后端微信支付demo 一.导入微信SDK 二.在微信商户平台下载证书放在项目的resources目录下的cert文件夹下(cert文件夹需要自己建) 三.实现微信的WXPayConfig接口 ...
- 微信小程序中实现微信支付
最近在做微信小程序,今天刚好做到小程序里的微信支付这块,踩过不少坑,特此写个博客记录下,希望能帮到其它人吧. 我总结了一下,小程序中的微信支付和之前其它的公众号里的微信支付有两个区别,第一就是小程序必 ...
随机推荐
- KVM "shutting down, reason=crashed" 问题处理
打开debug日志抓取信息 2022-10-12 07:42:43.698+0000: 63115: debug : processMonitorEOFEvent:4814 : Monitor con ...
- 关于 ModelScope 的视频 “AI 换脸” 优化方案
前言 前面一文,初步完成了一下 "AI 换脸" 视频处理程序.完成了视频拆帧,拆帧图片人脸融合,已经音频提取和最后的人脸融合图片的整合(也就是将图片和音频组成视频).但是在人脸融合 ...
- 将Python打包成exe
使用以下命令首先安装包 pip install pyinstaller 参数以及用法 -F生成结果是一个exe文件,所有的第三方依赖.资源和代码均被打包进该exe内 -D生成结果是一个目录,各种第三方 ...
- Kioptrix: Level 1 (#1) 古老的Apache Samba VULN
0×01 Vulnhub靶机渗透总结之 Kioptrix: Level 1 (#1) 系列专栏:Vulnhub靶机渗透系列 欢迎大佬:点赞️收藏关注 首发时间: 2023年8月20日 如有错误 还望告 ...
- Web安全漏洞解决方案
1.已解密的登录请求 推理: AppScan 识别了不是通过 SSL 发送的登录请求. 测试请求和响应: 1.1.1 产生的原因 登录接口,前端传入的密码参数没有经过md5的加密就直接传给了后端 1. ...
- 这才叫 API 接口设计!
API 接口设计 Token 设计 Token 是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个 Token 便将此 Token 返回给客户端,以后客户端只需带上 ...
- 原来你是这样的JAVA[05]--String
1.从概念上讲,java字符串就是Unicode字符串. 2.字符串拼接 用指定分隔符拼接字符串数组时,使用StringJoiner或者String.join()更方便: 用StringJoiner拼 ...
- AutoEmbedding论文阅读笔记
问题背景 目前推荐系统中, 在特征维度上低频特征和高频特征的维度是通过遍历mask特征获得到的auc衰减衡量特征对模型的重要度来决定的. 如果想提升模型效果, 在field层面上需要减少进行基于经验的 ...
- Servlet 上
Servlet 1.什么是Servlet Servlet即Server Applet是运行在Web服务器端的小程序 2.创建Servlet的三种方式 注意:从Tomcat10.0以后,我们统一用 ja ...
- Spring Boot 中使用 Poi-tl 渲染数据并生成 Word 文档
本文 Demo 已收录到 demo-for-all-in-java 项目中,欢迎大家 star 支持!后续将持续更新! 前言 产品经理急冲冲地走了过来.「现在需要将按这些数据生成一个 Word 报告文 ...