一、工具准备
微信支付官网
官网:https://pay.weixin.qq.com 注册商家地址:https://pay.weixin.qq.com/index.php/apply/applyment_home/guide_normal 微信小程序支付:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_2.shtml
uniapp官网
https://uniapp.dcloud.io/
小程序官网
https://mp.weixin.qq.com/
工具下载
hbuilderx
https://www.dcloud.io/hbuilderx.html
微信小程序开发工具:
https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html
vscode工具:
https://code.visualstudio.com/
Linux客户端工具FinalShell下载
http://www.hostbuf.com/t/988.html
二、微信支付-申请流程和步骤
01、微信支付图解
02、申请注册流程和文档
官方网址:https://pay.weixin.qq.com/index.php 官方文档:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pages/index.shtml PC端微信小程序Navtive文档:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_7_0.shtml 微信小程序支付对接文档:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_1.shtml
三、微信支付-注册商家及获取商家mchid
目标
1、注册商家号 2、获取商家号mcid
01、注册成为商家
注册商家地址:https://pay.weixin.qq.com/index.php/apply/applyment_home/guide_normal
以上安装步骤填写即可。
02、进入微信支付后台获取商家号mchid
四、微信支付-商家-配置商家证书及获取API私钥
目标
1:获取API私钥
https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_1.shtml
01、配置商家证书及获取API私钥
02、生成私钥的代码
import java.util.Random;
public class RandomStringGenerator {
public static String getRandomStringByLength(int length) {
String base = "abcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < length; i++) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}
}
五、微信支付-商家-签约产品
目标
1:签约微信小程序支付产品 2:签约Native支付产品
01、产品类型表
文档:https://pay.weixin.qq.com/wiki/doc/apiv3/index.shtml
02、签约产品
六、微信支付-配置回调地址
目标
配偶在支付回调地址
配置如下
七、微信支付-微信小程序注册获取APPID
目标
1、注册微信小程序 2、微信支付绑定微信小程序
01、注册微信小程序
申请官网:https://mp.weixin.qq.com/ 注册地址:https://mp.weixin.qq.com/cgi-bin/registermidpage?action=index&lang=zh_CN&token=
01-1、申请注册
01-2、获取APPID
02、微信小程序配置及认证
八、微信支付-小程序和微信支付绑定关系
目标
完成小程序和微信支付的绑定关系
01、小程序与微笑支付绑定
九、实战部分
9.1 导入weixinpay工具包
工具包: https://download.csdn.net/download/qq_41096598/43396028
9.2 引入依赖
<dependency>
<groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId>
<version>0.0.3</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.13</version>
</dependency>
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.10</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.6</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
9.3 编写wx.properties
weixin.login.info.gateway=https://api.weixin.qq.com/sns/jscode2session
weixin.login.info.appid=
weixin.login.info.appsecret=
weixin.login.info.redirectUrl=
weixin.pay.info.gateway=https://api.mch.weixin.qq.com/pay/unifiedorder
weixin.pay.info.appsecret=
weixin.pay.info.mchid=
weixin.pay.info.type=JSAPI
weixin.pay.info.appid=
weixin.pay.info.notifyPath=
9.4 在springmvc.xml中配置
<context:property-placeholder location="classpath:wx.properties" file-encoding="UTF-8" ignore-unresolvable="true"/>
<context:component-scan base-package="com.dyt.config"/>
9.5 config配置
9.5.1 WeixinLoginProperties
package com.dyt.config;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@PropertySource("classpath:wx.properties")
public class WeixinLoginProperties implements InitializingBean {
@Value("${weixin.login.info.gateway}")
private String gateway;
@Value("${weixin.login.info.appid}")
private String appid;
@Value("${weixin.login.info.appsecret}")
private String appsecret;
@Value("${weixin.login.info.redirectUrl}")
private String redirectUrl;
public static String WX_OPEN_GATEWAY;
public static String WX_OPEN_APP_ID;
public static String WX_OPEN_APP_SECRET;
public static String WX_OPEN_REDIRECT_URL;
@Override
public void afterPropertiesSet() throws Exception {
WX_OPEN_GATEWAY = gateway;
WX_OPEN_APP_ID = appid;
WX_OPEN_APP_SECRET = appsecret;
WX_OPEN_REDIRECT_URL = redirectUrl;
}
}
9.5.2 WeixinPayProperties
package com.dyt.config;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@PropertySource(value = {"classpath:wx.properties"})
public class WeixinPayProperties implements InitializingBean {
@Value("${weixin.pay.info.gateway}")
private String gateway;
@Value("${weixin.pay.info.appid}")
private String appid;
@Value("${weixin.pay.info.type}")
private String type;
@Value("${weixin.pay.info.appsecret}")
private String appsecret;
@Value("${weixin.pay.info.mchid}")
private String mchid;
@Value("${weixin.pay.info.notifyPath}")
private String notifyPath;
public static String WX_GATEWAY;
public static String WX_APPID;
public static String WX_TYPE;
public static String WX_APPSECRET;
public static String WX_MCHID;
public static String WX_NOTIFYPATH;
@Override
public void afterPropertiesSet() throws Exception {
WX_GATEWAY = gateway;
WX_APPID = appid;
WX_TYPE = type;
WX_APPSECRET = appsecret;
WX_MCHID = mchid;
WX_NOTIFYPATH = notifyPath;
}
}
9.6 创建ApiPayController
package com.dyt.controller;
import com.alibaba.fastjson.JSONObject;
import com.dyt.common.pay.weixin.ReportReqData;
import com.dyt.common.pay.weixin.request.QrCodeRequest;
import com.dyt.common.pay.weixin.util.RandomStringGenerator;
import com.dyt.common.pay.weixin.util.SnowflakeIdWorker;
import com.dyt.config.WeixinPayProperties;
import com.dyt.vo.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
@Api(tags = "微信小程序支付")
@RestController
public class ApiPayController {
@PostMapping ("/weixinpay")
public R payFood(HttpServletRequest request, String money){
JSONObject json = new JSONObject();
String orderNo = new SnowflakeIdWorker(1, 2).nextId() + "";
String openid = request.getParameter("openid");
Integer userId = 1;
ReportReqData data = new ReportReqData();
data.setOpenid(openid);
data.setTrade_type(WeixinPayProperties.WX_TYPE);
data.setAppid(WeixinPayProperties.WX_APPID);
data.setMch_id(WeixinPayProperties.WX_MCHID);
data.setNotify_url(WeixinPayProperties.WX_NOTIFYPATH);
data.setBody("产品支付");
data.setOut_trade_no(orderNo);
data.setSpbill_create_ip(ip);
data.setTotal_fee(getMoney(money));
data.setNonce_str(RandomStringGenerator.getRandomStringByLength(32));
json.put("userId", userId);
json.put("type", "productpay");
String params = json.toString().replace("\"", "'");
data.setAttach(params);
Map<String, String> weixinMap = QrCodeRequest.submitWeixinMessage(data);
return R.ok().data("weixinMap",weixinMap).data("xxx","xxxx");
}
public static String getMoney(String amount) {
if (amount == null) {
return "";
}
String currency = amount.replaceAll("\\$|\\¥|\\,", "");
int index = currency.indexOf(".");
int length = currency.length();
Long amLong = 0L;
if (index == -1) {
amLong = Long.valueOf(currency + "00");
} else if (length - index >= 3) {
amLong = Long.valueOf((currency.substring(0, index + 3)).replace(".", ""));
} else if (length - index == 2) {
amLong = Long.valueOf((currency.substring(0, index + 2)).replace(".", "") + 0);
} else {
amLong = Long.valueOf((currency.substring(0, index + 1)).replace(".", "") + "00");
}
return amLong.toString();
}
}
9.7 创建ApiLoginController
package com.dyt.controller;
import com.dyt.common.HttpClientUtils;
import com.dyt.common.exception.DYTException;
import com.dyt.config.WeixinLoginProperties;
import com.dyt.vo.R;
import com.google.gson.Gson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@Api(tags = "微信小程序登录")
@RestController
public class ApiLoginController{
@PostMapping("/wxlogin")
public R callback(String code){
if(StringUtils.isEmpty(code)){
throw new DYTException(22008,"登录失败,尝试刷新重新登录!");
}
String baseAccessTokenUrl = WeixinLoginProperties.WX_OPEN_GATEWAY +
"?appid=%s" +
"&secret=%s" +
"&code=%s" +
"&grant_type=authorization_code";
String accessTokenUrl = String.format(baseAccessTokenUrl, WeixinLoginProperties.WX_OPEN_APP_ID, WeixinLoginProperties.WX_OPEN_APP_SECRET, code);
String result = null;
try {
result = new HttpClientUtils().get(accessTokenUrl);
Gson gson = new Gson();
Map<String, Object> resultMap = gson.fromJson(result, HashMap.class);
if (resultMap.get("errcode") != null) {
throw new DYTException(22006,"微信登录出错!");
}
String openid = (String) resultMap.get("openid");
if (StringUtils.isEmpty(openid)) {
throw new DYTException(22009,"登录失败,尝试刷新重新登录!");
}
return R.ok().data("openid", openid).data("token",token).data("resultMap",resultMap);
}catch (Exception e){
return R.error().code(601).message("微信解析失败");
}
}
}
9.8 注意事项
|