1.收货地址

2.微信支付
master
litao 2 years ago
parent db4982112b
commit ccf71b60a7
  1. 21
      pom.xml
  2. 18
      src/main/java/org/springblade/weixin/controller/AppEbLoginController.java
  3. 43
      src/main/java/org/springblade/weixin/controller/WeChatAddressController.java
  4. 3
      src/main/java/org/springblade/weixin/controller/WeChatUserController.java
  5. 42
      src/main/java/org/springblade/weixin/entity/WeChatAddress.java
  6. 10
      src/main/java/org/springblade/weixin/entity/WeChatUser.java
  7. 33
      src/main/java/org/springblade/weixin/mapper/WeChatAddressMapper.java
  8. 23
      src/main/java/org/springblade/weixin/mapper/WeChatAddressMapper.xml
  9. 36
      src/main/java/org/springblade/weixin/service/IWeChatAddressService.java
  10. 71
      src/main/java/org/springblade/weixin/service/impl/WeChatAddressServiceImpl.java
  11. 10
      src/main/java/org/springblade/weixin/utils/WeChatUtil.java
  12. 329
      src/main/java/org/springblade/weixin/utils/WxPayUtils.java

@ -196,6 +196,27 @@
<artifactId>fastjson</artifactId> <artifactId>fastjson</artifactId>
<version>1.2.75</version> <version>1.2.75</version>
</dependency> </dependency>
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
<version>0.4.8</version>
</dependency>
<!-- HttpUrl要用-->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.3</version>
</dependency>
<!-- java基础类-->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

@ -8,16 +8,14 @@ import org.springblade.common.cache.DictCache;
import org.springblade.common.enums.DictEnum; import org.springblade.common.enums.DictEnum;
import org.springblade.core.log.exception.ServiceException; import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.tool.api.R; import org.springblade.core.tool.api.R;
import org.springblade.core.tool.support.Kv;
import org.springblade.core.tool.utils.SpringUtil; import org.springblade.core.tool.utils.SpringUtil;
import org.springblade.modules.auth.endpoint.BladeTokenEndPoint; import org.springblade.modules.auth.endpoint.BladeTokenEndPoint;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IUserService;
import org.springblade.weixin.entity.WeChatPhone; import org.springblade.weixin.entity.WeChatPhone;
import org.springblade.weixin.entity.WeChatPhoneInfo; import org.springblade.weixin.entity.WeChatPhoneInfo;
import org.springblade.weixin.entity.WeChatUser; import org.springblade.weixin.entity.WeChatUser;
import org.springblade.weixin.service.IWeChatUserService; import org.springblade.weixin.service.IWeChatUserService;
import org.springblade.weixin.utils.WeChatUtil; import org.springblade.weixin.utils.WeChatUtil;
import org.springblade.weixin.utils.WxPayUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.HashMap; import java.util.HashMap;
@ -33,15 +31,10 @@ public class AppEbLoginController {
/** /**
* 获取openid * 获取openid
*
* @param weChatPhone
* @return
*/ */
@PostMapping("/login") @PostMapping("/login")
public R<Map> login(@RequestBody WeChatPhone weChatPhone) { public R<Map> login(@RequestBody WeChatPhone weChatPhone) {
//小程序appId appSecret //小程序 appId = "wx432c2efe6df3b97a" appSecret = "859df8b167e74223e9237dee1b344524"
// String appId = "wx432c2efe6df3b97a";
// String appSecret = "859df8b167e74223e9237dee1b344524";
String appId = DictCache.getValue(DictEnum.WECHAT_APP, "appId"); String appId = DictCache.getValue(DictEnum.WECHAT_APP, "appId");
String appSecret = DictCache.getValue(DictEnum.WECHAT_APP, "appSecret"); String appSecret = DictCache.getValue(DictEnum.WECHAT_APP, "appSecret");
@ -57,7 +50,7 @@ public class AppEbLoginController {
WeChatUser user = weChatUserService.getOne(Wrappers.<WeChatUser>lambdaQuery().eq(WeChatUser::getOpenId, openid)); WeChatUser user = weChatUserService.getOne(Wrappers.<WeChatUser>lambdaQuery().eq(WeChatUser::getOpenId, openid));
if (user != null) { if (user != null) {
map.put("userInfo", user); map.put("userInfo", user);
// BladeTokenEndPoint point = SpringUtil.getBean(BladeTokenEndPoint.class); BladeTokenEndPoint point = SpringUtil.getBean(BladeTokenEndPoint.class);
// Kv admin = point.token("000000", "admin", "21232f297a57a5a743894a0e4a801fc3", "", ""); // Kv admin = point.token("000000", "admin", "21232f297a57a5a743894a0e4a801fc3", "", "");
} }
//获得响应的数据 //获得响应的数据
@ -109,4 +102,9 @@ public class AppEbLoginController {
return R.data(phoneInfo.getPurePhoneNumber()); return R.data(phoneInfo.getPurePhoneNumber());
} }
@PostMapping("/createOrder")
public R createOrder(String openId) {
return R.data(WxPayUtils.createOrderJSApiV3(openId));
}
} }

@ -0,0 +1,43 @@
package org.springblade.weixin.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.weixin.entity.WeChatAddress;
import org.springblade.weixin.entity.WeChatUser;
import org.springblade.weixin.service.IWeChatAddressService;
import org.springframework.web.bind.annotation.*;
@RestController
@AllArgsConstructor
@RequestMapping("/address")
public class WeChatAddressController {
private final IWeChatAddressService weChatAddressService;
@GetMapping("/list")
public R<IPage<WeChatAddress>> list(WeChatUser weChatUser, Query query) {
// return R.data(weChatAddressService.getPage(weChatUser, Condition.getPage(query)));
return R.data(weChatAddressService.page(Condition.getPage(query), Wrappers.<WeChatAddress>lambdaQuery().eq(weChatUser.getId() != null, WeChatAddress::getUserId, weChatUser.getId())));
}
@PostMapping("/save")
public R save(@RequestBody WeChatAddress weChatAddress) {
return R.status(weChatAddressService.add(weChatAddress));
}
@PostMapping("/update")
public R update(@RequestBody WeChatAddress weChatAddress) {
return R.status(weChatAddressService.edit(weChatAddress));
}
@PostMapping("/delete")
public R delete(@RequestParam String ids) {
return R.status(weChatAddressService.deleteLogic(Func.toLongList(ids)));
}
}

@ -24,7 +24,8 @@ public class WeChatUserController {
@PostMapping("/save") @PostMapping("/save")
public R save(@RequestBody WeChatUser weChatUser) { public R save(@RequestBody WeChatUser weChatUser) {
return R.status(weChatUserService.save(weChatUser)); weChatUserService.save(weChatUser);
return R.data(weChatUser);
} }
@PostMapping("/update") @PostMapping("/update")

@ -0,0 +1,42 @@
package org.springblade.weixin.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import org.springblade.core.mp.base.BaseEntity;
@Data
@TableName("eh_address")
public class WeChatAddress extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 用户id
*/
private Long userId;
/**
* 收货人
*/
private String consignee;
/**
* 手机号码
*/
private String phone;
/**
* 所在地区
*/
private String area;
/**
* 详细地址
*/
private String address;
/**
* 是否默认地址(0否 1是)
*/
private Integer isDefault;
}

@ -2,11 +2,11 @@ package org.springblade.weixin.entity;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
import org.springblade.core.tenant.mp.TenantEntity; import org.springblade.core.mp.base.BaseEntity;
@Data @Data
@TableName("eh_wx_user") @TableName("eh_wx_user")
public class WeChatUser extends TenantEntity { public class WeChatUser extends BaseEntity {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**
@ -15,17 +15,17 @@ public class WeChatUser extends TenantEntity {
private String openId; private String openId;
/** /**
* 微信用户唯一标识 * 昵称
*/ */
private String username; private String username;
/** /**
* 微信用户唯一标识 * 手机
*/ */
private String phone; private String phone;
/** /**
* 微信用户唯一标识 * 头像
*/ */
private String avatar; private String avatar;

@ -0,0 +1,33 @@
/*
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the dreamlu.net developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: Chill 庄骞 (smallchill@163.com)
*/
package org.springblade.weixin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.weixin.entity.WeChatAddress;
import org.springblade.weixin.entity.WeChatUser;
import java.util.List;
/**
* Mapper 接口
* @author BladeX
*/
public interface WeChatAddressMapper extends BaseMapper<WeChatAddress> {
List<WeChatAddress> getPage(IPage<WeChatAddress> page, WeChatUser weChatUser);
}

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.springblade.weixin.mapper.WeChatAddressMapper">
<select id="getPage" resultType="org.springblade.weixin.entity.WeChatAddress">
SELECT
ad.id,
ad.consignee,
ad.phone,
ad.area,
ad.address,
ad.is_default,
ad.status
FROM eh_wx_user AS us
LEFT JOIN eh_address AS ad ON us.id = ad.user_id
WHERE
us.is_deleted = 0 AND ad.is_deleted = 0
<if test="weChatUser.openId != null and weChatUser.openId != ''">
AND us.open_id = #{weChatUser.openId}
</if>
ORDER BY ad.create_time DESC
</select>
</mapper>

@ -0,0 +1,36 @@
/*
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the dreamlu.net developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: Chill 庄骞 (smallchill@163.com)
*/
package org.springblade.weixin.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.core.mp.base.BaseService;
import org.springblade.weixin.entity.WeChatAddress;
import org.springblade.weixin.entity.WeChatUser;
/**
* 服务类
*
* @author BladeX
*/
public interface IWeChatAddressService extends BaseService<WeChatAddress> {
IPage<WeChatAddress> getPage(WeChatUser weChatUser, IPage<WeChatAddress> page);
boolean add(WeChatAddress weChatAddress);
boolean edit(WeChatAddress weChatAddress);
}

@ -0,0 +1,71 @@
/*
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the dreamlu.net developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: Chill 庄骞 (smallchill@163.com)
*/
package org.springblade.weixin.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.weixin.entity.WeChatAddress;
import org.springblade.weixin.entity.WeChatUser;
import org.springblade.weixin.mapper.WeChatAddressMapper;
import org.springblade.weixin.service.IWeChatAddressService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* 服务实现类
*/
@Service
@AllArgsConstructor
public class WeChatAddressServiceImpl extends BaseServiceImpl<WeChatAddressMapper, WeChatAddress> implements IWeChatAddressService {
private final WeChatAddressMapper weChatAddressMapper;
@Override
public IPage<WeChatAddress> getPage(WeChatUser weChatUser, IPage<WeChatAddress> page) {
return page.setRecords(weChatAddressMapper.getPage(page, weChatUser));
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean add(WeChatAddress weChatAddress) {
weChatAddress.setIsDefault(0);
// if (weChatAddress.getIsDefault() == 1) {
// WeChatAddress address = this.getOne(Wrappers.<WeChatAddress>lambdaQuery().eq(WeChatAddress::getUserId, weChatAddress.getUserId()).eq(WeChatAddress::getIsDefault, 1));
// if (address != null) {
// address.setIsDefault(0);
// this.updateById(address);
// }
// }
return this.save(weChatAddress);
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean edit(WeChatAddress weChatAddress) {
if (weChatAddress.getIsDefault() == 1) {
WeChatAddress address = this.getOne(Wrappers.<WeChatAddress>lambdaQuery().eq(WeChatAddress::getUserId, weChatAddress.getUserId()).eq(WeChatAddress::getIsDefault, 1));
if (address != null && !address.getId().equals(weChatAddress.getId())) {
address.setIsDefault(0);
this.updateById(address);
}
}
return this.updateById(weChatAddress);
}
}

@ -5,10 +5,12 @@ import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springblade.core.http.util.HttpUtil; import org.springblade.core.http.util.HttpUtil;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
@ -21,6 +23,8 @@ import java.util.Map;
public class WeChatUtil { public class WeChatUtil {
private static CloseableHttpClient httpClient;
/** /**
* 请求微信接口服务获取小程序全局唯一后台接口调用凭据access_token * 请求微信接口服务获取小程序全局唯一后台接口调用凭据access_token
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/access-token/auth.getAccessToken.html * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/access-token/auth.getAccessToken.html

@ -0,0 +1,329 @@
package org.springblade.weixin.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.*;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.*;
public class WxPayUtils {
private static Logger logger = LoggerFactory.getLogger(WxPayUtils.class);
//appId 微信公众号里创建的AppId,这里的公众号需要关联到微信支付上,
// 微信公众平台-基本配置-开发者ID(AppID),这个绑定到微信支付-产品中心-AppID账号管理-关联AppID.这里关联公众号的AppId
public static String appId = "wx432c2efe6df3b97a";
//微信支付商户号 微信支付-账户中心-商户信息-微信支付商户号.查看
public static String mchId = "1650865884";
// 微信下单回调地址,支付成功后会回调这个地址。
//对应文档 https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_1_5.shtml
public static String callbackUri = "http://www.baidu.com";
//APIv3密钥 在微信支付商户平台-账户中心-API安全里设置,如果设置了不知道,就只有修改
public static String apiV3Key = "2q5w8e3a6s9d1eeeeee8p5M6N9a09";
// 第三方用户唯一凭证密钥,即appsecret 微信公众平台-基本配置-开发者密码(AppSecret) 公众号基本配置里查询
public static String appSecret = "859df8b167e74223e9237dee1b344524";
// JSApi下单url地址
public static String JSApiPayUrl = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
// 商户私钥 获取对应的签名需要 在微信支付商户平台-账户中心-API安全里设置 养宠物那边复制的
// 对应文档 https://pay.weixin.qq.com/wiki/doc/apiv3_partner/open/pay/chapter2_1.shtml
private static String privateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC3qbz0hDWoilpKR6vYnyi4q+CCjmQUjZVIO9R9QE3OfU4qVIaUYavTL/QReO9QfMZcU3LN8JrfKBRedleBfObXXVTP9e1FZh078LEYOiI9Kdzipf3NvSzjaJqkweMe7gOaGWj60zUBQyIVN9+kQVIcqA/2oNgq3Pz88fRFaOgV91okPTj4yfE5mVZujsuHN1ov1Bbky+cbd77SIA5Vl0dXDVUB+A7ZSpc3GXeXPxbEUvHeeeeeeebOpZzcVYsnR82BfTyKmfKIhvHhQjJpHVwmjw/USxxyblLh7Nc1td7pjoommr9yvBn/knq52mPolurmUTHloOCUyxLFDfUeeeepF9iogaSswxGw6B2qK+Jd1ZOoUHnHS2XrazMwKnG1RuvZ9S6On2/lJBXxjWOcvAeKm0c/Nza3lGxcNFwD6CjiXwo+2cq82L9Y3aBiSJRQKb1";
//商户证书序列号
// 对应文档 https://pay.weixin.qq.com/wiki/doc/apiv3_partner/open/pay/chapter2_1.shtml
private static String mchSerialNo = "23BC1D2F580D5eeeeeeF63D95837CC5";
private static CloseableHttpClient httpClient;
/**
* 第一步获取code
* 获取用户openID第一步获取下一个接口的code参数
* 访问这个url后页面将跳转至 redirect_uri/?code=CODE&state=STATE
* 跳转的url携带code参数
* 官方文档路径
* https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
*
* @return url
*/
public static String getCodeUrl(String reUrl) {
String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
url = url.replace("APPID", appId).replace("REDIRECT_URI", URLEncoder.encode(reUrl));
return url;
}
/**
*第二部获取AccessToken里面包含openId
* 根据微信公众号的信息获取微信的accessToken
* {"access_token":"61_SiCTd--EFgkIpWZ4MrciAKJN0N_Dv-qdZLnJyh-","expires_in":7870,"refresh_token":"-kpaMn5czZelR87thefNLEC2WK_-","openid":"5vrCjeeMz36PQkCK57bo","scope":"snsapi_base"}
* 官方文档路径
* https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
*/
// public static String getAccessToken(String code) {
// String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
// url = url.replace("APPID", appId).replace("SECRET", appSecret).replace("CODE",code);
// System.out.println(url);
// String res = HttpRequestsUtils.sendGet(url, "");
// System.out.println(res);
// return res;
// }
/**
* 第三步JSAPI下单
* 使用官方开发库请求下单
*
* @param openId openId
* @return {"prepay_id": "wx2611215250487459928b000"}
* 官方文档路径
* https://pay.weixin.qq.com/wiki/doc/apiv3_partner/open/pay/chapter2_1.shtml
*/
public static String createOrderJSApiV3(String openId) {
payLoading();
//请求URL
HttpPost httpPost = new HttpPost(JSApiPayUrl);
// 请求body参数
StringEntity entity = new StringEntity(JSONObject.toJSONString(buildWxJsApiV3PayJson(openId, 0)), "utf-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
httpPost.setHeader("Accept", "application/json");
//完成签名并执行请求
CloseableHttpResponse response = null;
try {
response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
return EntityUtils.toString(response.getEntity());
} else if (statusCode == 204) {
return "";
} else {
System.out.println("failed,resp code = " + statusCode + ",return body = " + EntityUtils.toString(response.getEntity()));
throw new IOException("request failed");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
assert response != null;
response.close();
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return "";
}
/**
* 第四步生成支付参数
* 生成支付所需的参数
*
* @param prepay_id 下单接口返回的参数 预支付交易会话标识
* @return JSONObject
* @throws Exception e
*/
public static JSONObject getTokenWeiXin(String prepay_id) {
// 获取随机字符串
String nonceStr = getNonceStr();
// 获取微信小程序支付package
String packagestr = "prepay_id=" + prepay_id;
long timestamp = System.currentTimeMillis() / 1000;
//签名,使用字段appId、timeStamp、nonceStr、package计算得出的签名值
String message = buildMessageTwo(appId, timestamp, nonceStr, packagestr);
//获取对应的签名
String signature = sign(message.getBytes(StandardCharsets.UTF_8));
// 组装返回
JSONObject json = new JSONObject(new JSONObject());
json.put("appId", appId);
json.put("timeStamp", String.valueOf(timestamp));
json.put("nonceStr", nonceStr);
json.put("package", packagestr);
json.put("signType", "RSA");
json.put("paySign", signature);
return json;
}
/**
* 先调用下单然后调用生成支付参数
*
* @param openId openId
* @return 支付参数
*/
public static Object getPayParam(String openId) {
JSONObject jsonObject = JSON.parseObject(createOrderJSApiV3(openId));
return getTokenWeiXin(jsonObject.getString("prepay_id"));
}
/**
* 构造下单的json(第三步需要)
*
* @param description 商品描述
* @param amount 订单金额
* @param openId 用户ID onAky51Fojn3NoLrnKwcY
* @return JSONObject
*/
public static JSONObject buildWxJsApiV3PayJson(String description, String amount, String openId) {
//订单金额json
JSONObject amountJson = new JSONObject();
amountJson.put("total", Integer.valueOf(amount));
amountJson.put("currency", "CNY");
//支付者json
JSONObject payerJson = new JSONObject();
payerJson.put("openid", openId);
//基础信息json
JSONObject json = new JSONObject();
// 微信公众号里创建的APPID
json.put("appid", appId);
// 直连商户号 微信支付-账户中心-商户信息查看
json.put("mchid", mchId);
json.put("description", description);
// 商户订单号 自己生成
json.put("out_trade_no", generateNonceStr());
json.put("notify_url", callbackUri);
json.put("amount", amountJson);
json.put("payer", payerJson);
return json;
}
/**
* 根据商品goodsId构造下单的json (第三步需要)
*
* @return JSONObject
*/
public static JSONObject buildWxJsApiV3PayJson(String openId, Integer goodsId) {
return buildWxJsApiV3PayJson("测试商品", "1", openId);
}
/**
* 构造下单的json 无参数
*
* @return JSONObject
*/
public static JSONObject buildWxJsApiV3PayJson() {
return buildWxJsApiV3PayJson("测试商品", "1", "123123123124");
}
/**
* 初始化httpClient的通用方法第三步JSAPI下单
* 微信支付官方开发库
* 创建加载商户私钥加载平台证书
*/
public static void payLoading() {
logger.info("----------初始化httpClient-----------");
// 加载商户私钥(privateKey:私钥字符串)
PrivateKey merchantPrivateKey = PemUtil
.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes(StandardCharsets.UTF_8)));
// 加载平台证书(mchId:商户号,mchSerialNo:商户证书序列号,apiV3Key:V3密钥)
AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)), apiV3Key.getBytes(StandardCharsets.UTF_8));
// 初始化httpClient
httpClient = WechatPayHttpClientBuilder.create()
.withMerchant(mchId, mchSerialNo, merchantPrivateKey)
.withValidator(new WechatPay2Validator(verifier)).build();
}
/**
* 看情况调用 关闭httpClient客户端
*
* @throws IOException e
*/
public void after() throws IOException {
httpClient.close();
logger.info("----------关闭httpClient-----------");
}
/**
* 根据微信公众号的信息获取微信的Token(没有使用)
* 官方文档https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html
*/
// public static String getToken() {
// String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
// url = url.replace("APPID", appId).replace("APPSECRET", appSecret);
//
// String result = HttpRequestsUtils.sendGet(url,"");
// System.out.println(result);
// JSONObject jsonObject = JSON.parseObject(result);
// return jsonObject.getString("access_token");
// }
public static void main(String[] args) {
System.out.println(WxPayUtils.getCodeUrl(""));
// String str = WxPayUtils.getAccessToken();
// System.out.println(str);
}
// 获取随机字符串
public static String getNonceStr() {
return UUID.randomUUID().toString()
.replaceAll("-", "")
.substring(0, 32);
}
// 签名连接成一串
private static String buildMessageTwo(String appId, long timestamp, String nonceStr, String packag) {
return appId + "\n"
+ timestamp + "\n"
+ nonceStr + "\n"
+ packag + "\n";
}
/**
* 生成签名
* 官方文档https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_0.shtml
*
* @param message message
* @return String
*/
private static String sign(byte[] message) {
Signature sign = null;
try {
sign = Signature.getInstance("SHA256withRSA");
sign.initSign(PemUtil.loadPrivateKey(privateKey));
sign.update(message);
return Base64.getEncoder().encodeToString(sign.sign());
} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
e.printStackTrace();
}
return null;
}
/**
* 随机字符串 订单号
*
* @return
*/
public static String generateNonceStr() {
return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
}
}
Loading…
Cancel
Save