官方文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

微信PC二维码支付方式参考:https://www.cnblogs.com/pxblog/p/10542917.html

沙箱环境调试:https://www.cnblogs.com/pxblog/p/13844925.html

本地开发环境支付回调调试方法可以参考:https://www.cnblogs.com/pxblog/p/11623053.html

引入jdom-1.1.3.jar包

HttpClientUtil.java

package weixinpay;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils; import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate; public class HttpClientUtil { private static class SingletonHolder{
private final static HttpClientUtil INSTANCE=new HttpClientUtil();
} private HttpClientUtil(){} public static HttpClientUtil getInstance(){
return SingletonHolder.INSTANCE;
} public String get(String url){
CharsetHandler handler = new CharsetHandler("UTF-8");
CloseableHttpClient client = null;
try {
HttpGet httpget = new HttpGet(new URI(url));
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
client= httpClientBuilder.build();
client = (CloseableHttpClient) wrapClient(client);
return client.execute(httpget, handler);
} catch (Exception e) {
//e.printStackTrace();
return "";
}finally {
try {
if(client!=null){
client.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
} public static String post(String url, String params,String contentType)
{ //创建HttpClientBuilder
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
//HttpClient
CloseableHttpClient client = httpClientBuilder.build();
client = (CloseableHttpClient) wrapClient(client); HttpPost post = new HttpPost(url);
CloseableHttpResponse res = null;
try
{
StringEntity s = new StringEntity(params,"UTF-8");
if(StringUtils.isBlank(contentType)){
s.setContentType("application/json");
}
s.setContentType(contentType);
s.setContentEncoding("utf-8");
post.setEntity(s);
res = client.execute(post);
HttpEntity entity = res.getEntity();
return EntityUtils.toString(entity, "utf-8");
}
catch (Exception e)
{
e.printStackTrace();
} finally {
try {
res.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return "";
} public static String post(String urlStr,String xmlInfo) {
String line1 = "";
try {
URL url = new URL(urlStr);
URLConnection con = url.openConnection();
con.setDoOutput(true);
//con.setRequestProperty("Pragma:", "no-cache");
con.setRequestProperty("Cache-Control", "no-cache");
con.setRequestProperty("Content-Type", "text/xml"); OutputStreamWriter out = new OutputStreamWriter(con
.getOutputStream());
out.write(new String(xmlInfo.getBytes("utf-8")));
out.flush();
out.close();
BufferedReader br = new BufferedReader(new InputStreamReader(con
.getInputStream()));
String line = "";
for (line = br.readLine(); line != null; line = br.readLine()) {
line1+=line;
}
return new String(line1.getBytes(),"utf-8");
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
} private class CharsetHandler implements ResponseHandler<String> {
private String charset; public CharsetHandler(String charset) {
this.charset = charset;
} public String handleResponse(HttpResponse response)
throws ClientProtocolException, IOException {
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() >= 300) {
throw new HttpResponseException(statusLine.getStatusCode(),
statusLine.getReasonPhrase());
}
HttpEntity entity = response.getEntity();
if (entity != null) {
if (!StringUtils.isBlank(charset)) {
return EntityUtils.toString(entity, charset);
} else {
return EntityUtils.toString(entity);
}
} else {
return null;
}
}
} private static HttpClient wrapClient(HttpClient base) {
try {
SSLContext ctx = SSLContext.getInstance("TLSv1");
X509TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] xcs,
String string) throws CertificateException {
} public void checkServerTrusted(X509Certificate[] xcs,
String string) throws CertificateException {
} public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
ctx.init(null, new TrustManager[] { tm }, null);
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(ctx, new String[] { "TLSv1" }, null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
return httpclient; } catch (Exception ex) {
return null;
}
} }

Num62.java

package weixinpay;

/**
* 62进制数字
*/
public class Num62 {
/**
* 62个字母和数字,含大小写
*/
public static final char[] N62_CHARS = { '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z' };
/**
* 36个小写字母和数字
*/
public static final char[] N36_CHARS = { '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z' }; /**
* 10 个数字
*/
public static final char[] N10_CHARS = { '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9' };
/**
* 长整型用N36表示的最大长度
*/
public static final int LONG_N36_LEN = 13;
/**
* 长整型用N62表示的最大长度
*/
public static final int LONG_N62_LEN = 11; /**
* 长整型转换成字符串
*
* @param l
* @param chars
* @return
*/
private static StringBuilder longToNBuf(long l, char[] chars) {
int upgrade = chars.length;
StringBuilder result = new StringBuilder();
int last;
while (l > 0) {
last = (int) (l % upgrade);
result.append(chars[last]);
l /= upgrade;
}
return result;
} /**
* 长整数转换成N62
*
* @param l
* @return
*/
public static String longToN62(long l) {
return longToNBuf(l, N62_CHARS).reverse().toString();
} /**
* 长整型转换成N36
*
* @param l
* @return
*/
public static String longToN36(long l) {
return longToNBuf(l, N36_CHARS).reverse().toString();
} /**
* 长整数转换成N62
*
* @param l
* @param length
* 如不足length长度,则补足0。
* @return
*/
public static String longToN62(long l, int length) {
StringBuilder sb = longToNBuf(l, N62_CHARS);
for (int i = sb.length(); i < length; i++) {
sb.append('0');
}
return sb.reverse().toString();
} /**
* 长整型转换成N36
*
* @param l
* @param length
* 如不足length长度,则补足0。
* @return
*/
public static String longToN36(long l, int length) {
StringBuilder sb = longToNBuf(l, N36_CHARS);
for (int i = sb.length(); i < length; i++) {
sb.append('0');
}
return sb.reverse().toString();
} /**
* N62转换成整数
*
* @param n62
* @return
*/
public static long n62ToLong(String n62) {
return nToLong(n62, N62_CHARS);
} /**
* N36转换成整数
*
* @param n36
* @return
*/
public static long n36ToLong(String n36) {
return nToLong(n36, N36_CHARS);
} private static long nToLong(String s, char[] chars) {
char[] nc = s.toCharArray();
long result = 0;
long pow = 1;
for (int i = nc.length - 1; i >= 0; i--, pow *= chars.length) {
int n = findNIndex(nc[i], chars);
result += n * pow;
}
return result;
} private static int findNIndex(char c, char[] chars) {
for (int i = 0; i < chars.length; i++) {
if (c == chars[i]) {
return i;
}
}
throw new RuntimeException("N62(N36)非法字符:" + c);
} public static void main(String[] args) {
System.out.println(longToN62(Long.MAX_VALUE));
}
}

微信支付支付参数配置类

PaymentConfig.java

package weixinpay;

public class PaymentConfig {
/*******微信支付参数*********/
//公众账号ID
public static final String appid="wxd";
//密钥
public static final String appKey="h";
//商户号
public static final String mch_id="1584";
//接口地址
public static final String pay_url="https://api2.mch.weixin.qq.com/pay/unifiedorder"; //交易场景信息
public static final String scene_info = "{\"store_info\" : {\"id\": \"zxbm\",\"name\": \"支付\",\"area_code\": \"430000\",\"address\": \"中国\" }}"; }

PayUtil.java

package weixinpay;

import org.apache.commons.lang.StringUtils;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder; import java.io.*;
import java.security.MessageDigest;
import java.util.*; public class PayUtil { /**
* 将需要传递给微信的参数转成xml格式
* @param parameters
* @return
*/
public static String assembParamToXml(Map<String,String> parameters){
StringBuffer sb = new StringBuffer();
sb.append("<xml>");
Set<String> es = parameters.keySet();
List<Object> list=new ArrayList<Object>(es);
Object[] ary =list.toArray();
Arrays.sort(ary);
list=Arrays.asList(ary);
Iterator<Object> it = list.iterator();
while(it.hasNext()) {
String key = (String) it.next();
String val=(String) parameters.get(key);
if ("attach".equalsIgnoreCase(key)||"body".equalsIgnoreCase(key)||"sign".equalsIgnoreCase(key)) {
sb.append("<"+key+">"+"<![CDATA["+val+"]]></"+key+">");
}else {
sb.append("<"+key+">"+val+"</"+key+">");
}
}
sb.append("</xml>");
return sb.toString();
} /**
* 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
* @param strxml
* @return
* @throws JDOMException
* @throws IOException
*/
public static Map parseXMLToMap(String strxml) throws JDOMException, IOException {
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 =PayUtil.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(getChildrenText(list));
}
sb.append(value);
sb.append("</" + name + ">");
}
}
return sb.toString();
} /**
* 微信支付签名sign
* @param param
* @param key
* @return
*/
@SuppressWarnings("unchecked")
public static String createSign(Map<String, String> param,String key){
//签名步骤一:按字典排序参数
List list=new ArrayList(param.keySet());
Object[] ary =list.toArray();
Arrays.sort(ary);
list=Arrays.asList(ary);
String str="";
for(int i=0;i<list.size();i++){
str+=list.get(i)+"="+param.get(list.get(i)+"")+"&";
}
//签名步骤二:加上key
str+="key="+key;
//步骤三:加密并大写
str=PayUtil.MD5Encode(str,"utf-8").toUpperCase();
return str;
} public static String MD5Encode(String origin,String charsetName){
String resultString=null;
try{
resultString=new String(origin);
MessageDigest md=MessageDigest.getInstance("MD5");
if(StringUtils.isBlank(charsetName)){
resultString=byteArrayToHexString(md.digest(resultString.getBytes()));
}else{
resultString=byteArrayToHexString(md.digest(resultString.getBytes(charsetName)));
}
}catch(Exception e){ }
return resultString;
} public static String byteArrayToHexString(byte b[]){
StringBuffer resultSb=new StringBuffer();
for(int i=0;i<b.length;i++){
resultSb.append(PayUtil.byteToHexString(b[i]));
}
return resultSb.toString();
} public static String byteToHexString(byte b){
int n=b;
if(n<0){
n+=256;
}
int d1=n/16;
int d2=n%16;
return PayUtil.hexDigits[d1]+PayUtil.hexDigits[d2];
} public static final String hexDigits[]={ "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" }; /**
* 元转换为分
* @param amount
*/
public static String changeY2F(Double amount){
String currency = amount.toString();
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();
} }

WeixinPay.java

package weixinpay;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.ui.ModelMap; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map; public class WeixinPay { /**
* 微信统一下单
*
* @param trade_type 交易类型
* @param openId 用户的openId
* @param request
* @param wxReturn 微信支付异步回调地址
* @param orderNo 订单号
* @param price 订单金额
* @return
*/
public static Map<String, String> weixinUniformOrder(String openId,
HttpServletRequest request, String wxReturn, String orderNo, Double price) {
Map<String, String> paramMap = new HashMap<String, String>();
// 微信分配的公众账号ID(企业号corpid即为此appId)[必填]
paramMap.put("appid", PaymentConfig.appid);
// 微信支付分配的商户号 [必填]
paramMap.put("mch_id", PaymentConfig.mch_id);
// 终端设备号(门店号或收银设备ID),注意:PC网页或公众号内支付请传"WEB" [非必填]
paramMap.put("device_info", "WEB");
// 随机字符串,不长于32位。 [必填]
paramMap.put("nonce_str", RandomStringUtils.random(10, Num62.N62_CHARS));
// 商品或支付单简要描述 [必填]
paramMap.put("body", PaymentConfig.mch_id);
// 商户系统内部的订单号,32个字符内、可包含字母, [必填]
paramMap.put("out_trade_no", orderNo);
// 符合ISO 4217标准的三位字母代码,默认人民币:CNY. [非必填]
paramMap.put("fee_type", "CNY"); // 金额必须为整数 单位为分 [必填]
paramMap.put("total_fee", PayUtil.changeY2F(price));
// APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP [必填]
paramMap.put("spbill_create_ip", request.getRemoteAddr());
// 接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。 [必填]
paramMap.put("notify_url", wxReturn);
// 交易类型{取值如下:JSAPI,NATIVE,APP,(JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付)}
// [必填]
paramMap.put("trade_type", "JSAPI");
//openid trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识
paramMap.put("openid", openId);
// 商品ID{trade_type=NATIVE,此参数必传。此id为二维码中包含的商品ID,商户自行定义。}
paramMap.put("product_id", "商品ID");
// 根据微信签名规则,生成签名
paramMap.put("sign", PayUtil.createSign(paramMap, PaymentConfig.appKey));
// 把参数转换成XML数据格式
String xmlWeChat = PayUtil.assembParamToXml(paramMap);
String resXml = HttpClientUtil.post(PaymentConfig.pay_url, xmlWeChat);
Map<String, String> map = new HashMap<String, String>();
try {
if (StringUtils.isNotBlank(resXml)) {
map = PayUtil.parseXMLToMap(resXml);
}
} catch (Exception e) {
e.printStackTrace();
}
return map;
} /**
* 微信公众号支付(手机端)
*
* @param wxReturn 微信支付异步回调地址
* @param openId 用户的openid
* @param orderNo 订单号
* @param price 订单金额
* @param request
* @param response
* @param model
* @return
*/
public static String weixinPayByMobile(String wxReturn, String openId, String orderNo, Double price,
HttpServletRequest request, HttpServletResponse response,
ModelMap model) {
Map<String, String> map = weixinUniformOrder(openId,
request, wxReturn, orderNo, price);
String returnCode = map.get("return_code");
if (returnCode.equalsIgnoreCase("FAIL")) { //调用失败操作
//当return_code为FAIL时返回信息为错误原因 ,例如 签名失败、参数格式校验错误
map.get("return_msg"); } else if (returnCode.equalsIgnoreCase("SUCCESS")) {
if (map.get("err_code") != null) { //支付失败操作
//错误代码描述
map.get("err_code_des"); } else if (map.get("result_code").equalsIgnoreCase(
"SUCCESS")) {
String prepay_id = map.get("prepay_id");
Long time = System.currentTimeMillis() / 1000;
String nonceStr = RandomStringUtils.random(16, Num62.N10_CHARS);
//公众号appid
model.addAttribute("appId", PaymentConfig.appid);
//时间戳 当前的时间 需要转换成秒
model.addAttribute("timeStamp", time);
//随机字符串 不长于32位
model.addAttribute("nonceStr", nonceStr);
//订单详情扩展字符串 统一下单接口返回的prepay_id参数值,提交格式如:prepay_id=***
model.addAttribute("package", "prepay_id=" + prepay_id);
//签名方式 签名算法,暂支持MD5
model.addAttribute("signType", "MD5");
Map<String, String> paramMap = new HashMap<String, String>();
paramMap.put("appId", PaymentConfig.appid);
paramMap.put("timeStamp", time.toString());
paramMap.put("nonceStr", nonceStr);
paramMap.put("package", "prepay_id=" + prepay_id);
paramMap.put("signType", "MD5");
//签名
model.addAttribute("paySign", PayUtil.createSign(paramMap, PaymentConfig.appKey)); //跳转到 weixin_prepay.html
return "weixin_prepay.html";
}
}
// 失败提示跳转页面,自己设计
return "error.html";
} //通知微信正确接收
public static String getSuccessXml() {
String xml = "<xml>" +
"<return_code><![CDATA[SUCCESS]]></return_code>" +
"<return_msg><![CDATA[OK]]></return_msg>" +
"</xml>";
return xml;
} }

微信公众号支付跳转页面主要逻辑代码

weixin_prepay.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>微信支付</title>
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js" type="text/javascript"></script>
<script type="text/javascript">
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '${appId!}', // 必填,公众号的唯一标识
timestamp: "${timeStamp!}", // 必填,生成签名的时间戳
nonceStr: '${nonceStr!}', // 必填,生成签名的随机串
signature: "${paySign!}", // 必填,签名,见附录1
jsApiList: ['chooseWXPay'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
wx.ready(function () {
wx.chooseWXPay({
appId: "${appId!}",
timestamp: "${timeStamp!}",
nonceStr: "${nonceStr!}",
package: "${package!}",
signType: "MD5",
paySign: "${paySign!}",
success: function (res) {
alert("成功");
window.location.href = "成功之后跳转地址";
},
cancel: function () {
alert("用户已取消");
},
error: function (e) {
alert("失败");
}
});
});
</script>
</head>
<body>
<div class="w1187b">
<div class="w1173">
</div>
</div>
</body>
</html>

后台控制器调用类

WeixinPayAct.java

package weixinpay;

import org.apache.commons.lang.StringUtils;
import org.jdom.JDOMException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import weixin.XMLUtil; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*; @Controller
public class WeixinPayAct { /**
* 微信支付
*
* @param request
* @param response
* @param model
* @return
*/
@RequestMapping(value = "weixin_Pay")
public String selectPay(HttpServletRequest request,
HttpServletResponse response, ModelMap model) { String wxReturn = "微信支付异步回调地址";
String orderNo = "订单号";
String openId = "用户的openId";
//支付金额
Double price = 0.01; return WeixinPay.weixinPayByMobile(wxReturn, openId, orderNo, price,
request, response, model); } /**
* 微信支付通知
*
* @return
*/
@ResponseBody
@RequestMapping(value = "/wechart_notice")
public String wechartNotice(HttpServletRequest request, HttpServletResponse response, ModelMap model) {
String result = "";
try {
InputStream inStream = request.getInputStream();
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outSteam.write(buffer, 0, len);
}
outSteam.close();
inStream.close();
result = new String(outSteam.toByteArray(), "utf-8");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//判断返回报文是否为空
if (StringUtils.isNotBlank(result)) {
try {
Map<String, String> map = XMLUtil.doXMLParse(result);
//获取商家订单编号 对应orderID
String orderNo = map.get("out_trade_no");
//String orderNo = RequestUtils.getQueryParam(request,"orderNo");
//获取微信支付订单号
String transaction_id = map.get("transaction_id"); Order order = orderMng.findByOrderNo(orderNo);
//判断支付是否成功
if ("SUCCESS".equals(map.get("result_code"))) {
//支付成功,这里之所以加了一个判断,是因为这个回调可能会有多次,所以我们只有当订单状态时未支付的情况下,才执行下面操作
if (!Constants.ORDER_SUCCESS.equals(order.getStatus())) {
//当微信支付成功后,把订单支付状态改为已支付
order.setStatus(Constants.ORDER_SUCCESS);
}
//处理业务逻辑
} else {
//支付失败
order.setStatus(Constants.ORDER_FAIL);
}
orderMng.update(order);
} catch (JDOMException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return WeixinPay.getSuccessXml();
} }

如果浏览器请求返回:errMsg: "chooseWXPay:fail, the permission value is offline verifying"

这个错误是由于我们用的开发工具开发,只要在手机上打开就可以了

JAVA微信支付——微信公众号内支付 代码的更多相关文章

  1. 【微信支付】公众号 JSAPI支付 HTML5(使用MUI前端框架)+WebApi 实现流程

    必要参数:      1) AppID,AppSecret : 在微信公众号后台管理—>(菜单栏)开发 —> 基本设置     2)商户号 :在微信公众号后台管理—>(菜单栏)微信支 ...

  2. 微信公众号H5支付遇到的那些坑

    简史 官方文档说的很清楚,商户已有H5商城网站,用户通过消息或扫描二维码在微信内打开网页时,可以调用微信支付完成下单购买的流程. 当然,最近微信支付平台也加入了纯H5支付,也就是说用户可以在微信以外的 ...

  3. 微信公众号内H5调用微信支付国内服务商模式

    最近在折微信公众号内H5用JSAPI调用微信支付,境内服务商版支付,微信支付给出的官方文档以及SDK不够详细,导至我们走了一些弯路,把他分享出来,我这边主要是用PHP开发,所以未加说的话示例都是PHP ...

  4. 微信支付之扫码支付、公众号支付、H5支付、小程序支付相关业务流程分析总结

    前言 很久以来,一直想写一篇微信支付有关的总结文档:一方面是总结自己的一些心得,另一方面也可以帮助别人,但是因种种原因未能完全理解透彻微信支付的几大支付方式,今天有幸做一些总结上的文章,也趁此机会,将 ...

  5. .NET Core之微信支付之公众号、H5支付篇

    前言 本篇主要记录微信支付中公众号及H5支付全过程. 准备篇 公众号或者服务号(并开通微信支付功能).商户平台中开通JSAPI支付.H5支付. 配置篇 公众号或者服务号中 -------开发----- ...

  6. .net 微信支付(公众号支付)遇到的问题

    啥也不说了搬砖的都知道老板说是什么就是什么 最近我老板让饿哦做一个微信支付的功能  还带微信上面京东众筹活动的那种,我买东西别人出钱的那种 然后用微信支付 我是新手之前也没有做过这个 所以估计着过程中 ...

  7. 【微信支付】公众号、商户基础配置和流程(包括设置支付授权目录、测试支付目录和白名单、JS接口安全域名、授权回调域名等)

    一.使用场景以及说明 使用场景:商户已有H5商城网站,用户通过消息或扫描二维码在微信内打开网页时,可以调用微信支付完成下单购买的流程. 说明:1.用户打开图文消息或者扫描二维码,在微信内置浏览器打开网 ...

  8. 微信公众号JSAPI支付

    微信公众号JSAPI支付 一:配置参数 申请成功后,获取接口文件, 将所有文件放入项目根目录weixin下,在WxPay.ub.config.php中填入配置账户信息; 二:设置授权 开发者中心-&g ...

  9. asp.net core 微信扫码支付(扫码支付,H5支付,公众号支付,app支付)之1

    2018-08-13更新生成二维码的方法 在做微信支付前,首先要了解你需要什么方式的微信支付,目前本人做过的支付包含扫码支付.H5支付.公众号支付.App支付等,本人使用的是asp.net mvc c ...

随机推荐

  1. 洛谷 P5853 - [USACO19DEC]Tree Depth P(生成函数+背包)

    洛谷题面传送门 神仙题. 首先考虑一个点的深度是什么,注意到对于笛卡尔树而言直接从序列的角度计算一个点的深度是不容易的,因为这样会牵扯到序列中多个元素,需要 fixed 的东西太多,计算起来太复杂了. ...

  2. Codeforces 536D - Tavas in Kansas(dp)

    Codeforces 题目传送门 & 洛谷题目传送门 其实这题本该 2019 年 12 月就 AC 的(详情请见 ycx 发此题题解的时间),然鹅鸽到了现在-- 首先以 \(s,t\) 分别为 ...

  3. 关于 n 个 [0,1] 的随机变量第 k 小的期望值

    今天做到一道题,感觉里面一个结论有点意思,就到网上扒了篇证明(bushi)下来了. 知乎回答习惯,先抛结论,再给证明(大雾 结论:对于 \(n\) 个取值范围为 \([0,1]\) 的随机变量 \(x ...

  4. TP、PHP同域不同子级域名共享Session、单点登录

    TP.PHP同域不同子级域名共享Session.单点登录 目的: 为了部署同个域名下不同子级域名共享会话,从而实现单点登录的问题,一处登录,同域处处子系统即可以实现自动登录. PHP支持通过设置coo ...

  5. windows下typora图片自动上传到图床(附带腾讯云教程)

    目录 1. 背景 2. 在Typora中使用 3. 安装 3.1 安装教程环境说明 3.2 安装步骤 3.3 配置图床 3.3.1 插件配置 3.3.2 腾讯云参数获取 3.3.2.1 新建子用户,获 ...

  6. Windows系统安装MySQL详细教程和安装过程中问题汇总(命令安装),更新时间2021-12-8

    安装包下载 下载地址:https://dev.mysql.com/downloads/mysql/ 点击下载之后,可以选择注册Oracle账号,也可以跳过直接下载. 下载完成后,选择一个磁盘内放置并解 ...

  7. accomplish, accord

    accomplish =achieve; accomplishment=achievement. accomplished: well educated/trained, skilled. skill ...

  8. 输入URL展示过程

    一. 输入URL,回车 敲击某个键时,键盘内的处理器会先对键矩阵进行分析,然后将数据发送到计算机 计算机接收到来自键盘的信号,由键盘控制器(一种集成电路)进行处理,发送给操作系统 操作系统会分析,这些 ...

  9. 创建Oracle数据库实例

    创建Oracle数据库实例 转自oracle数据库创建实例 数据库已经安装完成,可以正常登陆查看用户等操作. system用户只能用normal身份登陆em.除非你对它授予了sysdba的系统权限或者 ...

  10. 【Linux】【Basis】块存储,文件存储,对象存储

    1. 块存储: 定义:这种接口通常以QEMU Driver或者Kernel Module的方式存在,这种接口需要实现Linux的Block Device的接口或者QEMU提供的Block Driver ...