首页 > 其他分享 >微信支付:wxpay.unifiedOrder(data)返回appid 与 openId 不配

微信支付:wxpay.unifiedOrder(data)返回appid 与 openId 不配

时间:2023-11-07 16:36:57浏览次数:25  
标签:wxpay openId 微信 param put import data public

原因:小程序和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,openId,微信,param,put,import,data,public
From: https://www.cnblogs.com/luolei0120/p/17815280.html

相关文章

  • 企业微信开启接收消息+验证URL有效性
    企业微信开启接收消息+验证URL有效性......
  • 如何快速导出、备份微信通讯录好友联系人微信号
    6-9如果因工作需要,你有多个微信,并且你的业务开发的客户都在这些微信里,将会面临一个问题,那就是备份问题,因为通过微信做业务,如果遇到微信不小心被封号,或者离职的交接等情况,客户联系方式的损失是影响比较大的。所以一定要及时对微信的通讯录备份下来,如果你的习惯比较好,会将客户的手机......
  • uniapp+微信小程序 激励广告
    防忘首先在onready里面准备好代码 包括广告准备就绪 准备出错,广告关闭data(){return{showAd:false,canShowAd:false,rewardedVideoAd:null,}},onReady()......
  • 电脑端如何打开两个微信?
    作为一个程序员还问这个问题?不觉得有点丢人么?哈哈,其实我刚开始也不会,这不弄好了之后,就赶紧来做个功课;只需三步,轻松解决:第一步,右击微信-属性,复制起始位置的文件路径 第二步:桌面新建一个文本文件,记事本打开,复制下面的代码并粘贴,记得修改文件路径(代码中红色的部分),保存。1......
  • 微信小程序云开发如何实现多条件多字段模糊查询
    之前的博文中,已经跟大家介绍过,微信小程序云开发如何实现单条件单字段的模糊查询,这个是很常见的业务需求。在一些更复杂的场景下,我们需要实现多条件多字段的模糊查询,比如同时兼容对商品名称、类别、产地等多条件的模糊查询。我们看一下云开发如何实现。什么是多条件模糊查询(与、或)公......
  • 微信小程序云开发如何优雅的实现模糊查询
    微信官方自从推出微信小程序云开发之后,让小程序开发的门槛再次降低,你可以不需要掌握任何后端的语言和数据库,有一些js的基本功,就可以完成一个完整带前后端交互功能的小程序项目。今天我们介绍一个日常开发中非常常见的需求,就是实现模糊查询,这个主要是后端做的,我们看看云开发如何实现......
  • 基于微信小程序的短文写作竞赛管理系统-计算机毕业设计源码+LW文档
    摘 要随着世界经济信息化、全球网络化的到来推动信息线上管理的飞速发展,为短文写作竞赛行业的改革起到关键作用。若想达到安全,快捷的目的,就需要拥有信息化的组织和管理模式,建立一套合理、畅通、高效的短文写作竞赛管理系统小程序。当前的短文写作竞赛管理存在工作效率低下,人员和......
  • 基于微信小程序的上门维修系统-计算机毕业设计源码+LW文档
    摘 要随着科学研究的不断深入,有关上门维修的各种信息量也在成倍增长。面对庞大的信息量,就需要有上门维修系统来提高管理工作的效率。通过这样的系统,我们可以做到信息的规范管理和快速查询,从而减少了管理方面的工作量。建立基于微信小程序的上门维修系统,进一步提高用户对上门维......
  • pc微信逆向之收取消息及撤回消息
    收取消息关键词及内存值分布原理猜测:根据MsgSvrID本地数据库查询,看有没有到库里,如果有,则记录:addListUniqBySvrIddicardmsgbecausesvridrepeat%d,否则开始正常进库,所以Hook的地方,就是根据这个关键词找到函数的头就可以1).关键词:addListUniqBySvrIddicardmsgbecausesvrid......
  • uniApp 仿微信下拉菜单
    uniApp仿微信下拉菜单手指长按事件longpress@longpress="longpress(index,$event)"下拉菜单 <!--长按的下拉菜单--> <viewclass="jh-w-200jh-h-60-minjh-dropDownMenujh-shadow-greyjh-bg-whitejh-solid" :id="'dropDownMenu&#......