AlipayConfig
package ******;
import java.io.FileWriter;
import java.io.IOException;
/**
* @author lcwen
* @version $Id: AlipayConfig.java 2020年3月11日 上午10:48:40 $
*/
public class AlipayConfig {
/**商户appid*/
public static String APPID = "";
/**商户私钥 pkcs8格式的*/
public static String RSA_PRIVATE_KEY = "";
/**支付宝公钥*/
public static String ALIPAY_PUBLIC_KEY = "";
/**服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问*/
public static String notify_url = "";
/**页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址*/
public static String return_url = "";
/**请求网关地址*/
public static String URL = "https://openapi.alipay.com/gateway.do";
/**编码*/
public static String CHARSET = "UTF-8";
/**返回格式*/
public static String FORMAT = "json";
/**日志记录目录*/
public static String log_path = "C:\\";
/**RSA2*/
public static String SIGNTYPE = "RSA2";
/** 销售产品码:QUICK_WAP_PAY */
public static String PRODUCT_CODE = "QUICK_WAP_PAY";
/**
* 写日志,方便测试(看网站需求,也可以改成把记录存入数据库)
* @param sWord 要写入日志里的文本内容
*/
public static void logResult(String sWord) {
FileWriter writer = null;
try {
writer = new FileWriter(log_path + "alipay_log_" + System.currentTimeMillis()+".txt");
writer.write(sWord);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
AlipayUtil
package ***.pay.alipay.util;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import ***.config.AlipayConfig;
/**
* @author lcwen
* @version $Id: AlipayUtil.java 2020年3月11日 下午3:05:38 $
*/
public class AlipayUtil {
/**
* 简要说明:获取支付宝支付参数 <br>
* @param out_trade_no 订单号
* @param subject 商品名称
* @param total_amount 金额
* @param description 商品介绍
* @param timeout_express 超时时间(可为null)
* @param passbackParams 附近参数
* @return
*/
public static String getPayParam(String out_trade_no ,
String subject ,
String total_amount ,
String description ,
String timeout_express,
String passbackParams ,
String firstUrl){
AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL,
AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY,
AlipayConfig.FORMAT, AlipayConfig.CHARSET,
AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);
AlipayTradeWapPayRequest request=new AlipayTradeWapPayRequest();
// 封装请求支付信息
AlipayTradeWapPayModel model=new AlipayTradeWapPayModel();
model.setOutTradeNo(out_trade_no);
model.setSubject(subject);
model.setTotalAmount(total_amount);
model.setBody(description);
model.setTimeoutExpress(timeout_express);
model.setProductCode(AlipayConfig.PRODUCT_CODE);
model.setPassbackParams(passbackParams);
request.setBizModel(model);
request.setNotifyUrl(firstUrl + AlipayConfig.notify_url);//异步地址
request.setReturnUrl(firstUrl + AlipayConfig.return_url);//同步地址
String form = ""; //form表单生产
try {
// 调用SDK生成表单
form = client.pageExecute(request).getBody();
} catch (AlipayApiException e) {
e.printStackTrace();
}
return form;
}
}
UrlConstants
package com.meal.pay.wxpay.config;
/**
* @author lcwen
* @version $Id: UrlConstants.java 2020年3月13日 上午10:36:31 $
*/
public interface UrlConstants {
/** 支付异步通知URL **/
String VIP_NOTIFY_URL = "";
}
WxpayConfig
package ***.pay.wxpay.config;
import java.io.InputStream;
import java.util.ResourceBundle;
import com.github.wxpay.sdk.WXPayConfig;
public class WxpayConfig implements WXPayConfig{
@Override
public String getAppID() {
return "";
}
public String getSecret(){
return "";
}
@Override
public String getMchID() {
return "";
}
@Override
public String getKey() {
return "";
}
@Override
public InputStream getCertStream() {
return null;
}
@Override
public int getHttpConnectTimeoutMs() {
return 0;
}
@Override
public int getHttpReadTimeoutMs() {
return 0;
}
}
WXPayConstants
package com.meal.pay.wxpay.config;
import org.apache.commons.httpclient.HttpClient;
/**
* 常量
*/
public class WXPayConstants {
public enum SignType {
MD5, HMACSHA256
}
public static final String DOMAIN_API = "api.mch.weixin.qq.com";
public static final String DOMAIN_API2 = "api2.mch.weixin.qq.com";
public static final String DOMAIN_APIHK = "apihk.mch.weixin.qq.com";
public static final String DOMAIN_APIUS = "apius.mch.weixin.qq.com";
public static final String FAIL = "FAIL";
public static final String SUCCESS = "SUCCESS";
public static final String HMACSHA256 = "HMAC-SHA256";
public static final String MD5 = "MD5";
public static final String FIELD_SIGN = "sign";
public static final String FIELD_SIGN_TYPE = "sign_type";
public static final String WXPAYSDK_VERSION = "WXPaySDK/3.0.9";
public static final String USER_AGENT = WXPAYSDK_VERSION +
" (" + System.getProperty("os.arch") + " " + System.getProperty("os.name") + " " + System.getProperty("os.version") +
") Java/" + System.getProperty("java.version") + " HttpClient/" + HttpClient.class.getPackage().getImplementationVersion();
public static final String ACCESS_TOKEN_SUFFIX = "https://api.weixin.qq.com/sns/oauth2/access_token";
public static final String MICROPAY_URL_SUFFIX = "/pay/micropay";
public static final String UNIFIEDORDER_URL_SUFFIX = "/pay/unifiedorder";
public static final String ORDERQUERY_URL_SUFFIX = "/pay/orderquery";
public static final String REVERSE_URL_SUFFIX = "/secapi/pay/reverse";
public static final String CLOSEORDER_URL_SUFFIX = "/pay/closeorder";
public static final String REFUND_URL_SUFFIX = "/secapi/pay/refund";
public static final String REFUNDQUERY_URL_SUFFIX = "/pay/refundquery";
public static final String DOWNLOADBILL_URL_SUFFIX = "/pay/downloadbill";
public static final String REPORT_URL_SUFFIX = "/payitil/report";
public static final String SHORTURL_URL_SUFFIX = "/tools/shorturl";
public static final String AUTHCODETOOPENID_URL_SUFFIX = "/tools/authcodetoopenid";
// sandbox
public static final String SANDBOX_MICROPAY_URL_SUFFIX = "/sandboxnew/pay/micropay";
public static final String SANDBOX_UNIFIEDORDER_URL_SUFFIX = "/sandboxnew/pay/unifiedorder";
public static final String SANDBOX_ORDERQUERY_URL_SUFFIX = "/sandboxnew/pay/orderquery";
public static final String SANDBOX_REVERSE_URL_SUFFIX = "/sandboxnew/secapi/pay/reverse";
public static final String SANDBOX_CLOSEORDER_URL_SUFFIX = "/sandboxnew/pay/closeorder";
public static final String SANDBOX_REFUND_URL_SUFFIX = "/sandboxnew/secapi/pay/refund";
public static final String SANDBOX_REFUNDQUERY_URL_SUFFIX = "/sandboxnew/pay/refundquery";
public static final String SANDBOX_DOWNLOADBILL_URL_SUFFIX = "/sandboxnew/pay/downloadbill";
public static final String SANDBOX_REPORT_URL_SUFFIX = "/sandboxnew/payitil/report";
public static final String SANDBOX_SHORTURL_URL_SUFFIX = "/sandboxnew/tools/shorturl";
public static final String SANDBOX_AUTHCODETOOPENID_URL_SUFFIX = "/sandboxnew/tools/authcodetoopenid";
}
NotifyInfo
package ***.pay.wxpay.pojo;
import java.io.Serializable;
/**
* @author lcwen
* @version $Id: NotifyInfo.java 2020年3月13日 上午10:43:16 $
*/
public class NotifyInfo implements Serializable {
private static final long serialVersionUID = 1L;
private java.lang.String return_code;
private java.lang.String return_msg;
private java.lang.String appid;
private java.lang.String mch_id;
private java.lang.String device_info;
private java.lang.String nonce_str;
private java.lang.String sign;
private java.lang.String sign_type;
private java.lang.String result_code;
private java.lang.String err_code;
private java.lang.String err_code_des;
private java.lang.String openid;
private java.lang.String is_subscribe;
private java.lang.String trade_type;
private java.lang.String bank_type;
private java.lang.Integer total_fee;
private java.lang.Integer settlement_total_fee;
private java.lang.String fee_type;
private java.lang.Integer cash_fee;
private java.lang.String cash_fee_type;
private java.lang.Integer coupon_fee;
private java.lang.Integer coupon_count;
private java.lang.String coupon_type_$n;
// CASH--充值代金券
// NO_CASH---非充值代金券
// 并且订单使用了免充值券后有返回(取值:CASH、NO_CASH)。$n为下标,从0开始编号,举例:coupon_type_0
// 代金券ID coupon_id_$n 否 String(20) 10000 代金券ID,$n为下标,从0开始编号
private java.lang.Integer coupon_fee_$n;
private java.lang.String transaction_id;
private java.lang.String out_trade_no;
private java.lang.String attach;
private java.lang.String time_end;
public java.lang.String getReturn_code() {
return return_code;
}
public void setReturn_code(java.lang.String return_code) {
this.return_code = return_code;
}
public java.lang.String getReturn_msg() {
return return_msg;
}
public void setReturn_msg(java.lang.String return_msg) {
this.return_msg = return_msg;
}
public java.lang.String getAppid() {
return appid;
}
public void setAppid(java.lang.String appid) {
this.appid = appid;
}
public java.lang.String getMch_id() {
return mch_id;
}
public void setMch_id(java.lang.String mch_id) {
this.mch_id = mch_id;
}
public java.lang.String getDevice_info() {
return device_info;
}
public void setDevice_info(java.lang.String device_info) {
this.device_info = device_info;
}
public java.lang.String getNonce_str() {
return nonce_str;
}
public void setNonce_str(java.lang.String nonce_str) {
this.nonce_str = nonce_str;
}
public java.lang.String getSign() {
return sign;
}
public void setSign(java.lang.String sign) {
this.sign = sign;
}
public java.lang.String getSign_type() {
return sign_type;
}
public void setSign_type(java.lang.String sign_type) {
this.sign_type = sign_type;
}
public java.lang.String getResult_code() {
return result_code;
}
public void setResult_code(java.lang.String result_code) {
this.result_code = result_code;
}
public java.lang.String getErr_code() {
return err_code;
}
public void setErr_code(java.lang.String err_code) {
this.err_code = err_code;
}
public java.lang.String getErr_code_des() {
return err_code_des;
}
public void setErr_code_des(java.lang.String err_code_des) {
this.err_code_des = err_code_des;
}
public java.lang.String getOpenid() {
return openid;
}
public void setOpenid(java.lang.String openid) {
this.openid = openid;
}
public java.lang.String getIs_subscribe() {
return is_subscribe;
}
public void setIs_subscribe(java.lang.String is_subscribe) {
this.is_subscribe = is_subscribe;
}
public java.lang.String getTrade_type() {
return trade_type;
}
public void setTrade_type(java.lang.String trade_type) {
this.trade_type = trade_type;
}
public java.lang.String getBank_type() {
return bank_type;
}
public void setBank_type(java.lang.String bank_type) {
this.bank_type = bank_type;
}
public java.lang.Integer getTotal_fee() {
return total_fee;
}
public void setTotal_fee(java.lang.Integer total_fee) {
this.total_fee = total_fee;
}
public java.lang.Integer getSettlement_total_fee() {
return settlement_total_fee;
}
public void setSettlement_total_fee(java.lang.Integer settlement_total_fee) {
this.settlement_total_fee = settlement_total_fee;
}
public java.lang.String getFee_type() {
return fee_type;
}
public void setFee_type(java.lang.String fee_type) {
this.fee_type = fee_type;
}
public java.lang.Integer getCash_fee() {
return cash_fee;
}
public void setCash_fee(java.lang.Integer cash_fee) {
this.cash_fee = cash_fee;
}
public java.lang.String getCash_fee_type() {
return cash_fee_type;
}
public void setCash_fee_type(java.lang.String cash_fee_type) {
this.cash_fee_type = cash_fee_type;
}
public java.lang.Integer getCoupon_fee() {
return coupon_fee;
}
public void setCoupon_fee(java.lang.Integer coupon_fee) {
this.coupon_fee = coupon_fee;
}
public java.lang.Integer getCoupon_count() {
return coupon_count;
}
public void setCoupon_count(java.lang.Integer coupon_count) {
this.coupon_count = coupon_count;
}
public java.lang.String getCoupon_type_$n() {
return coupon_type_$n;
}
public void setCoupon_type_$n(java.lang.String coupon_type_$n) {
this.coupon_type_$n = coupon_type_$n;
}
public java.lang.Integer getCoupon_fee_$n() {
return coupon_fee_$n;
}
public void setCoupon_fee_$n(java.lang.Integer coupon_fee_$n) {
this.coupon_fee_$n = coupon_fee_$n;
}
public java.lang.String getTransaction_id() {
return transaction_id;
}
public void setTransaction_id(java.lang.String transaction_id) {
this.transaction_id = transaction_id;
}
public java.lang.String getOut_trade_no() {
return out_trade_no;
}
public void setOut_trade_no(java.lang.String out_trade_no) {
this.out_trade_no = out_trade_no;
}
public java.lang.String getAttach() {
return attach;
}
public void setAttach(java.lang.String attach) {
this.attach = attach;
}
public java.lang.String getTime_end() {
return time_end;
}
public void setTime_end(java.lang.String time_end) {
this.time_end = time_end;
}
}
Unifiedorder
package ***.pay.wxpay.pojo;
import java.io.Serializable;
public class Unifiedorder implements Serializable {
private static final long serialVersionUID = 1L;
// 必填
private String appid;
private String mch_id;
private String nonce_str;
private String sign;
private String body;
private String out_trade_no;
private java.lang.Integer total_fee;
private String spbill_create_ip;
private String notify_url;
private String trade_type;
// 非必填
private String product_id;
private String openid;
private String limit_pay;
private String time_start;
private String time_expire;
private String goods_tag;
private String fee_type;
private String device_info;
private String sign_type;
private String detail;
private String attach;
public String getAppid() {
return appid;
}
public Unifiedorder setAppid(String appid) {
this.appid = appid;
return this;
}
public String getMch_id() {
return mch_id;
}
public Unifiedorder setMch_id(String mch_id) {
this.mch_id = mch_id;
return this;
}
public String getNonce_str() {
return nonce_str;
}
public Unifiedorder setNonce_str(String nonce_str) {
this.nonce_str = nonce_str;
return this;
}
public String getSign() {
return sign;
}
public Unifiedorder setSign(String sign) {
this.sign = sign;
return this;
}
public String getBody() {
return body;
}
public Unifiedorder setBody(String body) {
this.body = body;
return this;
}
public String getOut_trade_no() {
return out_trade_no;
}
public Unifiedorder setOut_trade_no(String out_trade_no) {
this.out_trade_no = out_trade_no;
return this;
}
public java.lang.Integer getTotal_fee() {
return total_fee;
}
public Unifiedorder setTotal_fee(java.lang.Integer total_fee) {
this.total_fee = total_fee;
return this;
}
public String getSpbill_create_ip() {
return spbill_create_ip;
}
public Unifiedorder setSpbill_create_ip(String spbill_create_ip) {
this.spbill_create_ip = spbill_create_ip;
return this;
}
public String getNotify_url() {
return notify_url;
}
public Unifiedorder setNotify_url(String notify_url) {
this.notify_url = notify_url;
return this;
}
public String getTrade_type() {
return trade_type;
}
public Unifiedorder setTrade_type(String trade_type) {
this.trade_type = trade_type;
return this;
}
public String getProduct_id() {
return product_id;
}
public Unifiedorder setProduct_id(String product_id) {
this.product_id = product_id;
return this;
}
public String getOpenid() {
return openid;
}
public Unifiedorder setOpenid(String openid) {
this.openid = openid;
return this;
}
public String getLimit_pay() {
return limit_pay;
}
public Unifiedorder setLimit_pay(String limit_pay) {
this.limit_pay = limit_pay;
return this;
}
public String getTime_start() {
return time_start;
}
public Unifiedorder setTime_start(String time_start) {
this.time_start = time_start;
return this;
}
public String getTime_expire() {
return time_expire;
}
public Unifiedorder setTime_expire(String time_expire) {
this.time_expire = time_expire;
return this;
}
public String getGoods_tag() {
return goods_tag;
}
public Unifiedorder setGoods_tag(String goods_tag) {
this.goods_tag = goods_tag;
return this;
}
public String getFee_type() {
return fee_type;
}
public Unifiedorder setFee_type(String fee_type) {
this.fee_type = fee_type;
return this;
}
public String getDevice_info() {
return device_info;
}
public Unifiedorder setDevice_info(String device_info) {
this.device_info = device_info;
return this;
}
public String getSign_type() {
return sign_type;
}
public Unifiedorder setSign_type(String sign_type) {
this.sign_type = sign_type;
return this;
}
public String getDetail() {
return detail;
}
public Unifiedorder setDetail(String detail) {
this.detail = detail;
return this;
}
public String getAttach() {
return attach;
}
public Unifiedorder setAttach(String attach) {
this.attach = attach;
return this;
}
}
UnifiedOrderResponse
package com.meal.pay.wxpay.pojo;
public class UnifiedOrderResponse{
private String return_code; //返回状态码
private String return_msg; //返回信息
private String appid; //公众账号ID
private String mch_id; //商户号
private String device_info; //设备号
private String nonce_str; //随机字符串
private String sign; //签名
private String result_code; //业务结果
private String err_code; //错误代码
private String err_code_des;
private String trade_type; // 交易类型
private String prepay_id; // 预支付交易会话标识
private String code_url;
public String getReturn_code() {
return return_code;
}
public void setReturn_code(String return_code) {
this.return_code = return_code;
}
public String getReturn_msg() {
return return_msg;
}
public void setReturn_msg(String return_msg) {
this.return_msg = return_msg;
}
public String getAppid() {
return appid;
}
public void setAppid(String appid) {
this.appid = appid;
}
public String getMch_id() {
return mch_id;
}
public void setMch_id(String mch_id) {
this.mch_id = mch_id;
}
public String getDevice_info() {
return device_info;
}
public void setDevice_info(String device_info) {
this.device_info = device_info;
}
public String getNonce_str() {
return nonce_str;
}
public void setNonce_str(String nonce_str) {
this.nonce_str = nonce_str;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getResult_code() {
return result_code;
}
public void setResult_code(String result_code) {
this.result_code = result_code;
}
public String getErr_code() {
return err_code;
}
public void setErr_code(String err_code) {
this.err_code = err_code;
}
public String getErr_code_des() {
return err_code_des;
}
public void setErr_code_des(String err_code_des) {
this.err_code_des = err_code_des;
}
public String getTrade_type() {
return trade_type;
}
public void setTrade_type(String trade_type) {
this.trade_type = trade_type;
}
public String getPrepay_id() {
return prepay_id;
}
public void setPrepay_id(String prepay_id) {
this.prepay_id = prepay_id;
}
public String getCode_url() {
return code_url;
}
public void setCode_url(String code_url) {
this.code_url = code_url;
}
}
MyX509TrustManager
package com.meal.pay.wxpay.util;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
public class MyX509TrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(
X509Certificate[] paramArrayOfX509Certificate, String paramString)
throws CertificateException {
}
@Override
public void checkServerTrusted(
X509Certificate[] paramArrayOfX509Certificate, String paramString)
throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
WxPayUtil
package com.meal.pay.wxpay.util;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.wxpay.sdk.WXPayConfig;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.google.common.collect.Maps;
import com.meal.pay.wxpay.config.WxpayConfig;
import com.meal.pay.wxpay.pojo.UnifiedOrderResponse;
import com.meal.pay.wxpay.pojo.Unifiedorder;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import com.thoughtworks.xstream.io.xml.XppDriver;
public class WxPayUtil {
private static final Logger logger = LoggerFactory
.getLogger(WxPayUtil.class);
private static final BigDecimal N100 = new BigDecimal("100");
private static final String SUCCESS = "SUCCESS";
/**
* 简要说明:获取H5支付参数 <br>
* 创建者:lcwen
* 创建时间:2020年3月13日 下午4:24:15
* @param out_trade_no
* @param body
* @param total_fee
* @param spbill_create_ip
* @param notify_url
* @param attach
* @return
* @throws Exception
*/
public static Map<String, Object> getH5PayParam(String out_trade_no,
String body,
BigDecimal total_fee,
String spbill_create_ip ,
String notify_url,
String attach ,
String openid) throws Exception{
String order = orderToXml(out_trade_no, body, total_fee, spbill_create_ip, notify_url, attach, openid);
UnifiedOrderResponse res = unifiedorder(order);
if (res == null) {
logger.error("调用微信统一下单接口失败,返回信息:NULL");
return null;
}
if (res.getReturn_code().equals(SUCCESS)) {
if (res.getResult_code().equals(SUCCESS)) {
return getSign2Param(res);
} else {
logger.error("调用微信统一下单接口失败,返回信息:errCode=[{}],errMsg=[{}]",
res.getErr_code(), res.getErr_code_des());
}
}else {
logger.error("调用微信统一下单接口失败,返回信息:returnCode=[{}],reurnMsg=[{}]",
res.getReturn_code(), res.getReturn_msg());
}
return null;
}
/**
* 二次签名并返回微信预支付订单参数
*/
private static Map<String, Object> getSign2Param(UnifiedOrderResponse res) throws Exception{
Map<String, Object> result = new HashMap<String, Object>();
SortedMap<String,String> signMap = Maps.newTreeMap();//自然升序map
String prepayId = "prepay_id="+res.getPrepay_id();
String timeStamp = getTimeStamp();
String nonceStr = WXPayUtil.generateNonceStr();
signMap.put("appId",res.getAppid());
signMap.put("package",prepayId);
signMap.put("timeStamp",timeStamp);
signMap.put("nonceStr",nonceStr);
signMap.put("signType","MD5");
result.put("appId",res.getAppid());
result.put("timeStamp",timeStamp);
result.put("nonceStr",nonceStr);
result.put("prepayId",prepayId);
result.put("paySign",createSign2(signMap));
return result;
}
/**
* 获取当前时间戳
* @return 当前时间戳字符串
*/
public static String getTimeStamp(){
return String.valueOf(System.currentTimeMillis()/1000);
}
/**
* 简要说明:生成签名订单xml <br>
* 创建者:lcwen
* 创建时间:2020年3月13日 上午10:18:58
* @param out_trade_no 订单号
* @param body 商品描述
* @param total_fee 金额
* @param spbill_create_ip 服务器终端IP地址
* @param notify_url 异步回调地址
* @param attach 附加参数
* @param scene H5支付必传
* @return
* @throws Exception
*/
private static String orderToXml(String out_trade_no,
String body,
BigDecimal total_fee,
String spbill_create_ip ,
String notify_url,
String attach ,
String openid) throws Exception {
Unifiedorder unifiedorder = new Unifiedorder();
WXPayConfig config = new WxpayConfig();
unifiedorder.setAppid(config.getAppID())
.setMch_id(config.getMchID())
.setNonce_str(WXPayUtil.generateNonceStr())
.setBody(body)
.setOut_trade_no(out_trade_no)
.setTotal_fee(total_fee.multiply(N100).intValue())//金额需要扩大100倍:1代表支付时是0.01
.setSpbill_create_ip(spbill_create_ip)
.setNotify_url(notify_url)
.setTrade_type("JSAPI")//MWEB-h5支付、 JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付
.setAttach(attach)
.setOpenid(openid)
.setSign(createSign(unifiedorder));// 签名
XStream xStream = new XStream(new XppDriver(new XmlFriendlyNameCoder(
"_-", "_")));
xStream.alias("xml", Unifiedorder.class);
return xStream.toXML(unifiedorder);
}
/**
* 简要说明:统一下单API <br>
* 创建者:lcwen
* 创建时间:2020年3月13日 上午9:21:19
* @param orderInfo
* @return
*/
private static UnifiedOrderResponse unifiedorder(String orderInfo) {
String url = WXPayConstants.UNIFIEDORDER_URL;
try {
HttpURLConnection conn = (HttpURLConnection) new URL(url)
.openConnection();
// 加入数据
conn.setRequestMethod("POST");
conn.setDoOutput(true);
BufferedOutputStream buffOutStr = new BufferedOutputStream(
conn.getOutputStream());
buffOutStr.write(orderInfo.getBytes("UTF-8"));
buffOutStr.flush();
buffOutStr.close();
// 获取输入流
BufferedReader reader = new BufferedReader(new InputStreamReader(
conn.getInputStream(), "UTF-8"));
String line = null;
StringBuffer sb = new StringBuffer();
while ((line = reader.readLine()) != null) {
sb.append(line);
}
XStream xStream = new XStream(new XppDriver(
new XmlFriendlyNameCoder("_-", "_")));// 说明3(见文末)
// 将请求返回的内容通过xStream转换为UnifiedOrderRespose对象
xStream.alias("xml", UnifiedOrderResponse.class);
logger.info("微信调用统一下单接口,返回数据:[{}]",sb.toString());
UnifiedOrderResponse uor = (UnifiedOrderResponse )xStream.fromXML(sb.toString());//若此处不可转化可用json方式去转化
// 根据微信文档return_code 和result_code都为SUCCESS的时候才会返回code_url
// <span style="color:#ff0000;"><strong>说明4(见文末)</strong></span>
if (null != uor && "SUCCESS".equals(uor.getReturn_code())
&& "SUCCESS".equals(uor.getResult_code())) {
return uor;
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 简要说明:创建签名 <br>
* 创建者:lcwen
* 创建时间:2020年3月13日 上午9:42:35
* @param unifiedOrder
* @return
* @throws Exception
*/
private static String createSign(Unifiedorder unifiedOrder)
throws Exception {
SortedMap<String, String> params = new TreeMap<String, String>();
params.put("appid", unifiedOrder.getAppid());
params.put("body", unifiedOrder.getBody());
params.put("mch_id", unifiedOrder.getMch_id());
params.put("nonce_str", unifiedOrder.getNonce_str());
params.put("notify_url", unifiedOrder.getNotify_url());
params.put("out_trade_no", unifiedOrder.getOut_trade_no());
params.put("spbill_create_ip", unifiedOrder.getSpbill_create_ip());
params.put("trade_type", unifiedOrder.getTrade_type());
params.put("total_fee", unifiedOrder.getTotal_fee() + "");
params.put("attach", unifiedOrder.getAttach());
params.put("openid", unifiedOrder.getOpenid());
String sign = createSign2(params);
return sign;
}
/**
* 简要说明:二次签名 <br>
* 创建者:lcwen
* 创建时间:2020年3月13日 上午9:39:44
* @param parameters
* @return
* @throws Exception
*/
@SuppressWarnings("rawtypes")
private static String createSign2(SortedMap<String, String> parameters) throws Exception {
StringBuffer sb = new StringBuffer();
Set es = parameters.entrySet();// 所有参与传参的参数按照accsii排序(升序)
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
Object v = entry.getValue();
if (null != v && !"".equals(v) && !"sign".equals(k)
&& !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
WXPayConfig config = new WxpayConfig();
sb.append("key=" + config.getKey()); // KEY是商户秘钥
String sign = WXPayUtil.MD5(sb.toString()).toUpperCase();// MD5加密
return sign;
}
}
WxSignUtil
package com.meal.pay.wxpay.util;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import com.github.wxpay.sdk.WXPayConfig;
import com.meal.pay.wxpay.config.WXPayConstants;
import com.meal.pay.wxpay.config.WxpayConfig;
import com.meal.util.JsonUtils;
/**
* ************ 微信授权
* 工程名:meal
* 包名:com.meal.pay.wxpay.util
* 文件名:WxSignUtil.java
* @author lcwen
* @version $Id: WxSignUtil.java 2020年3月16日 下午4:57:30 $
*/
public class WxSignUtil {
/**
* 简要说明:授权并获取openid <br>
* 详细说明:TODO
* 创建者:lcwen
* 创建时间:2020年3月16日 下午5:16:22
* 更新者:
* 更新时间:
* @param code
* @return
* @throws Exception
*/
@SuppressWarnings("rawtypes")
public static String accessWithOpenid(String code) throws Exception{
WxpayConfig config = new WxpayConfig();
String req_url = WXPayConstants.ACCESS_TOKEN_SUFFIX + "?appid="
+ config.getAppID() + "&secret=" + config.getSecret()
+ "&code=" + code + "&grant_type=authorization_code";
String res = httpsRequest(req_url, "GET", null);
if (res != null) {
Map map = JsonUtils.jsonToPojo(res, Map.class);
try {
return map.get("openid").toString();
} catch (Exception e) {
throw new Exception("授权获取openid出错:CODE:" + map.get("errcode")
+ ",ERRMSG:" + map.get("errmsg") + "");
}
}
throw new Exception("微信授权失败:" + res);
}
/**
* 简要说明:发起请求 <br>
* 详细说明:TODO
* 创建者:lcwen
* 创建时间:2020年3月16日 下午5:17:52
* 更新者:
* 更新时间:
* @param requestUrl
* @param requestMethod
* @param outputStr
* @return
*/
public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
StringBuffer buffer = null;
try {
// 创建SSLContext
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
TrustManager[] tm = { new MyX509TrustManager() };
// 初始化
sslContext.init(null, tm, new java.security.SecureRandom());
// 获取SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();
URL url = new URL(requestUrl);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setRequestMethod(requestMethod);
// 设置当前实例使用的SSLSocketFactory
conn.setSSLSocketFactory(ssf);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.connect();
// 往服务器端写内容
if (null != outputStr) {
OutputStream os = conn.getOutputStream();
os.write(outputStr.getBytes("utf-8"));
os.close();
}
// 读取服务器端返回的内容
InputStream is = conn.getInputStream();
InputStreamReader isr = new InputStreamReader(is, "utf-8");
BufferedReader br = new BufferedReader(isr);
buffer = new StringBuffer();
String line = null;
while ((line = br.readLine()) != null) {
buffer.append(line);
}
} catch (Exception e) {
e.printStackTrace();
}
return buffer.toString();
}
}