转载
到微信支付官方文档下载SDK
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- import org.springframework.beans.BeanUtils; -->
<!-- <dependency>-->
<!-- <groupId>org.springframework</groupId>-->
<!-- <artifactId>spring-beans</artifactId>-->
<!-- <version>5.3.6</version>-->
<!-- </dependency>-->
<!---->
<!--hutool具包-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.55</version>
<scope>compile</scope>
</dependency>
<!-- 模板引擎 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.5.6</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
</dependency>
<!---->
<dependency>
<groupId>top.jfunc.json</groupId>
<artifactId>Json-Gson</artifactId>
<version>1.0</version>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<!-- druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.17</version>
</dependency>
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
<!-- common-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
<!-- 阿里云oss依赖 -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.1.0</version>
</dependency>
<!-- 文件上传 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!--excel导入导出-->
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-web</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.jodconverter</groupId>
<artifactId>jodconverter-core</artifactId>
<version>4.2.2</version>
</dependency>
<dependency>
<groupId>org.jodconverter</groupId>
<artifactId>jodconverter-local</artifactId>
<version>4.2.2</version>
</dependency>
<!--jodconverter 核心包 -->
<dependency>
<groupId>org.jodconverter</groupId>
<artifactId>jodconverter-core</artifactId>
<version>4.2.2</version>
</dependency>
<!--jodconverter 本地支持包 -->
<dependency>
<groupId>org.jodconverter</groupId>
<artifactId>jodconverter-local</artifactId>
<version>4.2.2</version>
</dependency>
<!-- 代码生成器 依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
<!-- swagger2 -->
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>
<version>3.3.0</version>
</dependency>
<!-- jackson-->
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-collections/commons-collections -->
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-lang/commons-lang -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sf.ezmorph/ezmorph -->
<dependency>
<groupId>net.sf.ezmorph</groupId>
<artifactId>ezmorph</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.21</version>
</dependency>
<!--base64加密解密-->
<!--shiro依赖和缓存-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sf.json-lib/json-lib -->
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<!--解码-->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.57</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.57</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier><!-- 指定jdk版本 -->
</dependency>
<!-- JSON -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160810</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
<!-- httpGet -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<!-- httpGet -->
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-miniapp</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<!-- 增加微信sdk -->
<!-- <dependency>-->
<!-- <groupId>com.github.wxpay</groupId>-->
<!-- <artifactId>wxpay-sdk</artifactId>-->
<!-- <version>0.0.3</version>-->
<!-- </dependency>-->
<dependency>
<groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId>
<version>0.0.3</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
微信支付帮助类
package com.peng.logistics.wxzf;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
public class HttpUtil {
//private static final Log logger = Logs.get();
private final static int CONNECT_TIMEOUT = 5000; // in milliseconds
private final static String DEFAULT_ENCODING = "UTF-8";
public static String postData(String urlStr, String data){
return postData(urlStr, data, null);
}
public static String postData(String urlStr, String data, String contentType){
BufferedReader reader = null;
try {
URL url = new URL(urlStr);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
conn.setConnectTimeout(CONNECT_TIMEOUT);
conn.setReadTimeout(CONNECT_TIMEOUT);
if(contentType != null)
conn.setRequestProperty("content-type", contentType);
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), DEFAULT_ENCODING);
if(data == null)
data = "";
writer.write(data);
writer.flush();
writer.close();
reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), DEFAULT_ENCODING));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append("\r\n");
}
return sb.toString();
} catch (IOException e) {
//logger.error("Error connecting to " + urlStr + ": " + e.getMessage());
} finally {
try {
if (reader != null)
reader.close();
} catch (IOException e) {
}
}
return null;
}
}
package com.peng.logistics.wxzf;
import java.security.MessageDigest;
public class MD5 {
private static String byteArrayToHexString(byte b[]) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++)
resultSb.append(byteToHexString(b[i]));
return resultSb.toString();
}
private static String byteToHexString(byte b) {
int n = b;
if (n < 0)
n += 256;
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
public static String MD5Encode(String origin, String charsetname) {
String resultString = null;
try {
resultString = new String(origin);
MessageDigest md = MessageDigest.getInstance("MD5");
if (charsetname == null || "".equals(charsetname))
resultString = byteArrayToHexString(md.digest(resultString
.getBytes()));
else
resultString = byteArrayToHexString(md.digest(resultString
.getBytes(charsetname)));
} catch (Exception exception) {
}
return resultString;
}
private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
}
package com.peng.logistics.wxzf;
import java.util.Date;
public class MyExceptionOutLog {
public static String outLog(Exception e) {
String error = "";
StackTraceElement[] st = e.getStackTrace();
for (StackTraceElement stackTraceElement : st) {
String exclass = stackTraceElement.getClassName();
String method = stackTraceElement.getMethodName();
/*new Date() + ":" + */
error += "\t[类:" + exclass + "]调用"
+ method + "时在第" + stackTraceElement.getLineNumber()
+ "行代码处发生异常!\n\t\t\t异常类型:" + e.getClass().getName()
+ "\n\t\t异常信息为:"+ e.toString()+"\n";
}
return error;
}
}
package com.peng.logistics.wxzf;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
public class PayCommonUtil {
/**
* 是否签名正确,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
* @return boolean
*/
public static boolean isTenpaySign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {
StringBuffer sb = new StringBuffer();
Set es = packageParams.entrySet();
Iterator it = es.iterator();
while(it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
String k = (String)entry.getKey();
String v = (String)entry.getValue();
if(!"sign".equals(k) && null != v && !"".equals(v)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + API_KEY);
//算出摘要
String mysign = MD5.MD5Encode(sb.toString(), characterEncoding).toLowerCase();
String tenpaySign = ((String)packageParams.get("sign")).toLowerCase();
//System.out.println(tenpaySign + " " + mysign);
return tenpaySign.equals(mysign);
}
/**
* @author
* @Description:sign签名
* @param characterEncoding
* 编码格式
* @param packageParams
* 请求参数
* @return
*/
public static String createSign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {
StringBuffer sb = new StringBuffer();
Set es = packageParams.entrySet();
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = entry.getKey().toString();
String v = entry.getValue().toString();
if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + API_KEY);
String sign = MD5.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
return sign;
}
public static String createLinkString(Map<String, String> params) {
List<String> keys = new ArrayList<String>(params.keySet());
Collections.sort(keys);
String prestr = "";
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
String value = params.get(key);
if (i == keys.size() - 1) {// 拼接时,不包括最后一个&字符
prestr = prestr + key + "=" + value;
} else {
prestr = prestr + key + "=" + value + "&";
}
}
return prestr;
}
/**
* @author
* @Description:将请求参数转换为xml格式的string
* @param parameters
* 请求参数
* @return
*/
public static String getRequestXml(SortedMap<Object, Object> parameters) {
StringBuffer sb = new StringBuffer();
sb.append("<xml>");
Set es = parameters.entrySet();
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = entry.getKey().toString();
String v = entry.getValue().toString();
if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {
sb.append("<" + k + ">" + v + "</" + k + ">");
} else {
sb.append("<" + k + ">" + v + "</" + k + ">");
}
}
sb.append("</xml>");
return sb.toString();
}
/**
* 取出一个指定长度大小的随机正整数.
*
* @param length
* int 设定所取出随机数的长度。length小于11
* @return int 返回生成的随机数。
*/
public static int buildRandom(int length) {
int num = 1;
double random = Math.random();
if (random < 0.1) {
random = random + 0.1;
}
for (int i = 0; i < length; i++) {
num = num * 10;
}
return (int) ((random * num));
}
/**
* 获取当前时间 yyyyMMddHHmmss
*
* @return String
*/
public static String getCurrTime() {
Date now = new Date();
SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");
String s = outFormat.format(now);
return s;
}
public static boolean verify(String text, String sign, String key, String input_charset) {
text = text + key;
String mysign =MD5.MD5Encode(text, input_charset).toUpperCase();
System.out.println(mysign); System.out.println(mysign); System.out.println(mysign); System.out.println(mysign);
if (mysign.equals(sign)) {
return true;
} else {
return false;
}
}
}
package com.peng.logistics.wxzf;
import java.beans.Transient;
import java.util.HashMap;
import java.util.Map;
public class TransfersDto
{
// 与商户号关联应用(如微信公众号/小程序)的APPID
private String mch_appid;
// 微信支付分配的商户号
private String mchid;
// 商户名称, 如'XXX服务号'
private String mch_name;
// 商户订单号,需保持唯一性(只能是字母或者数字,不能包含有其他字符)
private String partner_trade_no;
// 商户appid下,某用户的openid
private String openid;
// NO_CHECK:不校验真实姓名 FORCE_CHECK:强校验真实姓名
private String check_name = "NO_CHECK";
// 企业付款金额,单位为元
private int amount;
// 随机字符串,不长于32位
private String nonce_str;
// 企业付款备注
private String desc;
private String appkey;
// 发起者IP地址+该IP可传用户端或者服务端的IP。
private String spbill_create_ip = "127.0.0.1";
public String getMch_appid()
{
return mch_appid;
}
public void setMch_appid(String mch_appid)
{
this.mch_appid = mch_appid;
}
public String getMchid()
{
return mchid;
}
/**
* 与商户号关联应用(如微信公众号/小程序)的APPID
*/
public void setMchid(String mchid)
{
this.mchid = mchid;
}
public String getPartner_trade_no()
{
return partner_trade_no;
}
public void setPartner_trade_no(String partner_trade_no)
{
this.partner_trade_no = partner_trade_no;
}
public String getOpenid()
{
return openid;
}
public void setOpenid(String openid)
{
this.openid = openid;
}
public String getCheck_name()
{
return check_name;
}
public int getAmount()
{
return amount;
}
/**
* 为了方便理解+这里接收的单位是元+会自动转换为分传给微信支付后台
*/
public void setAmount(double amount)
{
this.amount = (int)(amount * 100);
}
public String getNonce_str()
{
return nonce_str;
}
public void setNonce_str(String nonce_str)
{
this.nonce_str = nonce_str;
}
public String getDesc()
{
return desc;
}
public void setDesc(String desc)
{
this.desc = desc;
}
public String getAppkey()
{
return appkey;
}
public void setAppkey(String appkey)
{
this.appkey = appkey;
}
public String getSpbill_create_ip()
{
return spbill_create_ip;
}
public void setSpbill_create_ip(String spbill_create_ip)
{
this.spbill_create_ip = spbill_create_ip;
}
public String getMch_name()
{
return mch_name;
}
public void setMch_name(String mch_name)
{
this.mch_name = mch_name;
}
@Transient
public Map<String, String> map()
{
Map<String, String> map = new HashMap<String, String>();
map.put("mch_appid", this.mch_appid);
map.put("mchid", this.mchid);
map.put("mch_name", this.mch_name);
map.put("openid", this.openid);
map.put("amount", String.valueOf(this.amount));
map.put("desc", this.desc);
map.put("appkey", this.appkey);
map.put("nonce_str", this.nonce_str);
map.put("partner_trade_no", this.partner_trade_no);
map.put("spbill_create_ip", this.spbill_create_ip);
return map;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("[mch_appid]" + this.mch_appid);
sb.append(",[mchid]" + this.mchid);
sb.append(",[openid]" + this.openid);
sb.append(",[amount]" + this.amount);
sb.append(",[desc]" + this.desc);
sb.append(",[partner_trade_no]" + this.partner_trade_no);
sb.append(",[nonce_str]" + this.nonce_str);
sb.append(",[spbill_create_ip]" + this.spbill_create_ip);
sb.append(",[check_name]" + this.check_name);
return sb.toString();
}
}
package com.peng.logistics.wxzf;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
public class XMLUtil {
public static Map doXMLParse(String strxml) throws Exception {
strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");
if (null == strxml || "".equals(strxml)) {
return null;
}
Map m = new HashMap();
InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(in);
Element root = doc.getRootElement();
List list = root.getChildren();
Iterator it = list.iterator();
while (it.hasNext()) {
Element e = (Element) it.next();
String k = e.getName();
String v = "";
List children = e.getChildren();
if (children.isEmpty()) {
v = e.getTextNormalize();
} else {
v = XMLUtil.getChildrenText(children);
}
m.put(k, v);
}
//关闭流
in.close();
return m;
}
/**
* 获取子结点的xml
*
* @param children
* @return String
*/
public static String getChildrenText(List children) {
StringBuffer sb = new StringBuffer();
if (!children.isEmpty()) {
Iterator it = children.iterator();
while (it.hasNext()) {
Element e = (Element) it.next();
String name = e.getName();
String value = e.getTextNormalize();
List list = e.getChildren();
sb.append("<" + name + ">");
if (!list.isEmpty()) {
sb.append(XMLUtil.getChildrenText(list));
}
sb.append(value);
sb.append("</" + name + ">");
}
}
return sb.toString();
}
}
调用
小程序端
pay: function (e) {
//获取金额
//获取微信id
var openid = wx.getStorageSync("open_id");
//下订单并唤起微信支付
var that = this ;
let data ={
openid:openid,
price:0.1*10,
title:'订单名称',
goodsid:100
}
let data2 = JSON.stringify(data)
wx.request({
url:'https://letengh5.com:7000/order/returnparam',
data: {
'openid':openid,
'price':0.1*10,//付款金额
'title':'订单名称',
'goodsid':100,
'orderFormId':10622,//订单编号
'userId':10014,//用户ID
'accountPayable':100,//没有用优惠劵
'discountCouponId':0
},
method: "POST",
// headers: {
// 'Content-Type': 'multipart/form-data'
// },
header: { 'content-type': 'application/x-www-form-urlencoded' },
success: function (res) {
console.log(res)
//客户单发起微信请求
wx.requestPayment(
{
'appId': res.data.appid,
'timeStamp': res.data.timeStamp,
'nonceStr': res.data.nonceStr,
'package': res.data.package,
'signType': 'MD5',
'paySign': res.data.paySign,
'success': function (res) {
// errMsg: "requestPayment:ok"
wx.showToast({
title: '支付成功',
duration: 1200
})
console.log('支付成功',res);
//这里完成跳转
},
'fail': function (res) {
if(res.errMsg=="requestPayment:fail cancel"){
wx.showToast({
title: '支付取消',
duration: 1200
})
}else{
wx.showToast({
title: '支付失败',
// image: '../../images/error.png',
duration: 1200
})
}
//支付失败
console.log(res);
},
'complete': function (res) { }
})
}
})
}
Java后端
package com.peng.logistics.controller;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSON;
import com.peng.logistics.mapper.*;
import com.peng.logistics.ov.resp.PayResp;
import com.peng.logistics.wxzf.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.google.gson.Gson;
@Controller
@RequestMapping("order")
public class OrderController {
@Autowired
private OrderFormMapper orderFormMapper;
@Autowired
private ReceiptMapper receiptMapper;
@Autowired
private UserMapper userMapper;
@Autowired
private IncomeMapper incomeMapper;
@Autowired
private DiscountCouponMapper discountCouponMapper;
/*
* 购买 支付
* @param request
* @param response
* @return
* */
@ResponseBody
@RequestMapping("/returnparam")
public void doOrder(HttpServletRequest request, HttpServletResponse response) throws Exception {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
//得到openid(微信用户唯一的openid)
String openid = request.getParameter("openid");
//得到价钱(自定义)
int fee = 0;
if (null != request.getParameter("price")) {
fee = Integer.parseInt(request.getParameter("price").toString());
}
//得到商品的ID(自定义)
String goodsid = request.getParameter("goodsid");
//订单标题(自定义)
String title = request.getParameter("title");
//时间戳
String times = System.currentTimeMillis() + "";
//应收款
String accountPayable = request.getParameter("accountPayable");
//优惠劵ID
String discountCouponId = request.getParameter("discountCouponId");
//用户ID
String userId = request.getParameter("userId");
//订单ID
String orderFormId = request.getParameter("orderFormId");
//订单编号(自定义 这里以时间戳+随机数)
Random random = new Random();
String did = times + random.nextInt(1000);
//
// Map attach = new HashMap();
// attach.put("orderFormId", orderFormId);//订单号
// attach.put("userId", userId);//用户ID
// attach.put("accountPayable", accountPayable);//应收款
// attach.put("discountCouponId", discountCouponId);//优惠劵ID
PayResp payResp = new PayResp();
payResp.setOrderFormId(Integer.valueOf(orderFormId));
payResp.setUserId(Integer.valueOf(userId));
payResp.setAccountPayable(Integer.valueOf(accountPayable));
payResp.setDiscountCouponId(Integer.valueOf(discountCouponId));
String attach = JSON.toJSONString(payResp);
//支付成功后调用的参数
SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
packageParams.put("appid", "");//微信小程序ID
packageParams.put("mch_id", "");//商户ID
packageParams.put("nonce_str", times);//随机字符串(32位以内) 这里使用时间戳
packageParams.put("body", title);//支付主体名称 自定义
packageParams.put("out_trade_no", did + goodsid);//编号 自定义以时间戳+随机数+商品ID
packageParams.put("attach", attach);//追加数据(支付成功会把该数据追加到支付成功返回的数据)
packageParams.put("total_fee", fee);//价格 自定义
// packageParams.put("spbill_create_ip", remoteAddr);
packageParams.put("notify_url", "");//支付返回地址要外网访问的到, localhost不行,调用下面buy方法。(订单存入数据库)
packageParams.put("trade_type", "JSAPI");//这个api有,固定的
packageParams.put("openid", openid);//用户的openid 可以要 可以不要
//获取sign
String sign = PayCommonUtil.createSign("UTF-8", packageParams, "");//最后这个是自己在微信商户设置的32位密钥
packageParams.put("sign", sign);
//转成XML
String requestXML = PayCommonUtil.getRequestXml(packageParams);
//得到含有prepay_id的XML
String resXml = HttpUtil.postData("https://api.mch.weixin.qq.com/pay/unifiedorder", requestXML);
//解析XML存入Map
Map map = XMLUtil.doXMLParse(resXml);
// String return_code = (String) map.get("return_code");
//得到prepay_id
String prepay_id = (String) map.get("prepay_id");
SortedMap<Object, Object> packageP = new TreeMap<Object, Object>();
packageP.put("appId", "");//!!!注意,这里是appId,上面是appid
packageP.put("nonceStr", times);//时间戳
packageP.put("package", "prepay_id=" + prepay_id);//必须把package写成 "prepay_id="+prepay_id这种形式
packageP.put("signType", "MD5");//paySign加密
packageP.put("timeStamp", (System.currentTimeMillis() / 1000) + "");
//得到paySign
String paySign = PayCommonUtil.createSign("UTF-8", packageP, "leteng1302sudaweixizhifu20220207");//微信支付AIP的KEY
packageP.put("paySign", paySign);
//将packageP数据返回给小程序
Gson gson = new Gson();
String json = gson.toJson(packageP);
PrintWriter pw = response.getWriter();
pw.write(json);
pw.close();
}
//订单存入数据库 上面参数 packageParams.put("notify_url", "http://你的IP地址/order/buy.action");回调的就是这个方法
@RequestMapping(value = "/buy")
@ResponseBody
public void Buy(HttpServletRequest request, HttpServletResponse response) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream()));
String line = null;
StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null) {
sb.append(line);
}
br.close();
//sb为微信返回的xml
String notityXml = sb.toString();
String resXml = "";
Map map = XMLUtil.doXMLParse(notityXml);
String returnCode = (String) map.get("return_code");
System.err.println("------------" + map);
/*
*/
if ("SUCCESS".equals(returnCode)) {
PayResp payResp = JSONObject.parseObject(map.get("attach").toString(), PayResp.class);
// MySql 操作数据库
resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
} else {
resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
+ "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
}
BufferedOutputStream out = new BufferedOutputStream(
response.getOutputStream());
out.write(resXml.getBytes());
out.flush();
out.close();
}
}