微信支付小程序支付获取OpenID

在这里插入图片描述

在对接微信支付JSAPI支付的时候。怎么获取用户的OpenID,让我陷入了深深的绝望。特此整理一下流程和方法。
在接入微信支付前必须要做的一些步骤:
https://pay.weixin.qq.com/docs/merchant/products/jsapi-payment/preparation.html
1、选择接入模式:普通商户或普通服务商
2、申请参数:AppID、商户号
3、配置应用
上面这些可以自行参考官方文档做配置或者也可以留言讨论。

注意1:

在这里插入图片描述

看一下我的服务器上的位置。这个是前端小程序的打包文件的存放地址。
在这里插入图片描述

如果这个txt放置的位置对。配置这个网页授权域名的时候就会无法保存。
在这里插入图片描述

注意2

OpenID: OpenID是微信用户在AppID下的唯一用户标识(AppID不同,则获取到的OpenID就不同),可用于永久标记一个用户。OpenID获取方式请参考以下文档小程序获取OpenID (opens new window)、公众号获取OpenID (opens new window)、App获取OpenID (opens new window)。
OpenID获取方式:
前端部分:
在这里插入图片描述

微信登录方法:

wxLogin() {
	window.location.href =
		`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${APP_ID}&redirect_uri=${encodeURIComponent(REDIRECT)}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`;
},

https://ww.xxx.com/h5/index.html的页面中调用授权获取的code,拿到这个code,然后才能获取用户的OpenId。此方法需要注意两个APP_ID和REDIRECT,一个为微信应用ID(微信公众号ID、小程序ID)。
另一个就是授权成功后需要展示的页面。我这个地方放的是首页。注意。本地域名貌似不行。
https://ww.xxx.com/h5/index.html,
我们看看index页面中的写法:

getCode() {
	if (window.location.search.includes('code=')) {
		let url_params = Object.fromEntries(window.location.search.slice(1).split('&').map(v => v.split('=')))
		return url_params.code
	}else{
		this.$api.msg("获取Code失败")
		return null
	}
},

// 然后我在index页面中写了一个created,调用了一下后端获取用户OpenId的接口

created() {
	console.log("code====", this.getCode())
	let code = this.getCode()
	// 调用后端的接口获取openId,和用户的基本信息
	getUserInfo(code).then(res => {
		console.log('-getUserInfo获取OpenID-------', res)
	})
},

这个地方就是从window.location中获取code,拿到code 之后我们就可以调用后端的接口来获取用户的OpenID。

Java代码

<!-- 需要引入这个微信公众号仓库地址-->
<dependency>
	<groupId>com.github.binarywang</groupId>
	<artifactId>weixin-java-mp</artifactId>
	<version>4.4.0</version>
</dependency>

配置微信公众号好服务

/**
 * 配置微信WxMpService
 */
@Configuration
@RequiredArgsConstructor
public class WxMpServiceConfig {
    @Autowired
    private WechatProperties properties;
 
    @Bean
    public WxMpService wxMpService() {
        WxMpService wxMpService = new WxMpServiceImpl();
        wxMpService.setWxMpConfigStorage(wxMpConfigStorage());
        return wxMpService;
    }

    @Bean
    public WxMpConfigStorage wxMpConfigStorage() {
        WxMpDefaultConfigImpl wxMpDefaultConfig = new WxMpDefaultConfigImpl();
        wxMpDefaultConfig.setAppId(properties.getAppId());
        wxMpDefaultConfig.setSecret(properties.getAppSecret());
        return wxMpDefaultConfig;
    }

}

获取用户OpenId和基本信息接口

@GetMapping("/getUserInfo")
@ApiOperation("获取微信用户基本信息")
public WxOAuth2UserInfo getUserInfo(@RequestParam("code") String code) throws WxErrorException {
    WxOAuth2Service oAuth2Service = this.wxMpService.switchoverTo(properties.getAppId()).getOAuth2Service();
    WxOAuth2AccessToken wxOAuth2AccessToken = oAuth2Service.getAccessToken(code);
    String accessToken = wxOAuth2AccessToken.getAccessToken();
    String openId = wxOAuth2AccessToken.getOpenId();
    log.info("[微信公众号] 授权回调 accessToken:[{}]", accessToken);
    log.info("[微信公众号] 授权回调 openId:[{}]", openId);
    WxOAuth2UserInfo userInfo = oAuth2Service.getUserInfo(wxOAuth2AccessToken, "zh_CN");
    log.info("[微信公众号] 授权回调 用户信息:[{}]", JSONUtil.toJsonStr(userInfo));
    return userInfo;
}

注意3

然后如果你直接Hbuilder运行到浏览器的方法微信登录的话。就会给你提示:
在这里插入图片描述

这个地方可以添加自定义的设备型号来不让这个提示。但是我这个好像没有用。
在这里插入图片描述

在用户代理字符串中输入下面的字符:

Mozilla/5.0 (Linux; Android 5.0; SM-N9100 Build/LRX21V) > AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 > Chrome/37.0.0.0 Mobile Safari/537.36 > MicroMessenger/6.0.2.56_r958800.520 NetType/WIFI

这个时候就可以使用微信开发者工具中的:公众号网页项目
在这里插入图片描述
在这里插入图片描述

来做测试了。然后回车就可以了。
在这里插入图片描述

同意。就可以了。
在这里插入图片描述

由于我写了好几种获取Open的方法。而我们前面获取到的Code只能使用一次。所以后面的都会提示:错误代码:40163, 错误信息:oauth_code已使用,微信原始报文:

{"errcode":40163,"errmsg":"code been used, rid: 659f8fe0-3b83730b-10fb9122"}

同时大家也注意一下。如果微信开发者工具-公众号网页中没有拿到OpenId,建议大家看看服务器上的Jar的日志中是否打印了OpenId。我的就是在日志中获取到的

WechatpayController: [微信公众号] 授权回调 openId:[o7lso1XXXXXXX-XXXXXXXm4]

注意3

先看一下微信支付官方的文档,

/**
     * 微信 JSAPI 支付
     *
     * @param total       金额,单位分
     * @param description 订单说明
     * @param outTradeNo  订单
     * @return
     * @throws IOException
     */
    public Map<String, Object> jsapiPay(Integer total, String description, String outTradeNo) throws IOException {
        CloseableHttpResponse response = null;
        Map<String, Object> result = new HashMap<>();
        try {
            HttpPost httpPost = new HttpPost(PayConstants.PAY_URL_JSAPI);
            // 请求body参数
            Amount amount = new Amount();
            amount.setCurrency(PayConstants.CURRENCY);
            amount.setTotal(total);

            // 【支付者】 支付者信息。
            Payer payer=new Payer();
            // 这个是我获取到的自己的OpenId,做微信支付测试使用。
            payer.setOpenid("o7lso1XXXXXXX-XXXXXXXm4");

            // 支付参数必填参数
            PayParam nativePayParams = PayParam.builder().applicationId(properties.getApplicationId())
                    .description(description)
                    .merchantId(properties.getMerchantId())
                    .notifyUrl(properties.getNotifyUrl())
                    .outTradeNo(outTradeNo)
                    .amount(amount)
                    .payer(payer)
                    .build();

            String reqdata = JSON.toJSONString(nativePayParams);
            StringEntity entity = new StringEntity(reqdata, "utf-8");
            entity.setContentType("application/json");
            httpPost.setEntity(entity);
            httpPost.setHeader("Accept", "application/json");
            //完成签名并执行请求
            response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == 200) { //处理成功
                logger.info("success,return body {}", EntityUtils.toString(response.getEntity()));
                result = JSON.parseObject(EntityUtils.toString(response.getEntity()), Map.class);
            } else if (statusCode == 204) { //处理成功,无返回Body
                logger.info("success");
            } else {
                logger.error("请求失败,响应结果Code {},返回结果Body {}", statusCode, EntityUtils.toString(response.getEntity()));
                throw new IOException("支付失败!");
            }


        } catch (IOException e) {
            logger.error("微信H5支付失败:{}", e.getMessage(), e);
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return result;
    }

测试一下

@SpringBootTest
public class MallPortalApplicationTests {

    @Autowired
    private PayTemplate payTemplate;
   
    @Test
    public void contextLoadsJsapi() throws Exception {
        Map<String, Object> result = payTemplate.jsapiPay(1, "智慧商城静宁苹果1箱", IdUtil.nanoId());
        System.out.println(result);
    }

}

测试结果:

success,return body {"prepay_id":"wx11145921849880c1256a35dcff784a0000"}
{prepay_id=wx11145921849880c1256a35dcff784a0000}

下面这个是我的个人公共号 只会写Bug的程序猿,大家可以关注一下,一键三连。相互交流学习。

在这里插入图片描述

  • 19
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拈㕦一笑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值