一、引入maven
< dependency>
< groupId> com.github.binarywang</ groupId>
< artifactId> weixin-java-pay</ artifactId>
< version> 3.3.4.B</ version>
< exclusions>
< exclusion>
< artifactId> qrcode-utils</ artifactId>
< groupId> com.github.binarywang</ groupId>
</ exclusion>
</ exclusions>
</ dependency>
< dependency>
< groupId> org.jdom</ groupId>
< artifactId> jdom</ artifactId>
< version> 1.1</ version>
< scope> compile</ scope>
</ dependency>
二、调用
package com. dcqq. wechat ;
import com. dcqq. common. core. controller. BaseController ;
import com. dcqq. common. core. domain. R ;
import com. dcqq. common. core. domain. entity. SysUser ;
import com. dcqq. common. utils. ip. IpUtils ;
import com. dcqq. common. utils. wx. HttpUtil ;
import com. dcqq. common. utils. wx. PayCommonUtil ;
import com. dcqq. common. utils. wx. WxPayConfig ;
import com. dcqq. common. utils. wx. XMLUtil ;
import com. dcqq. system. domain. TShopOrder ;
import com. dcqq. system. domain. vo. PayVo ;
import com. dcqq. system. service. ISysUserService ;
import com. dcqq. system. service. ITShopOrderService ;
import com. github. binarywang. wxpay. bean. notify. WxPayNotifyResponse ;
import io. swagger. annotations. Api ;
import io. swagger. annotations. ApiOperation ;
import org. springframework. beans. factory. annotation. Autowired ;
import org. springframework. web. bind. annotation. * ;
import javax. servlet. ServletInputStream ;
import javax. servlet. http. HttpServletRequest ;
import javax. servlet. http. HttpServletResponse ;
import java. io. BufferedOutputStream ;
import java. io. BufferedReader ;
import java. io. DataInputStream ;
import java. io. InputStreamReader ;
import java. math. BigDecimal ;
import java. util. * ;
@RestController
@Api ( tags = "微信支付管理" )
@RequestMapping ( "/wechat/pay" )
public class ApiPayController extends BaseController {
@Autowired
private ITShopOrderService shopOrderService;
@Autowired
private ISysUserService userService;
@PostMapping ( "/tradeOrder" )
@ApiOperation ( "支付接口" )
public R tradeOrder ( @RequestBody PayVo payVo, HttpServletRequest request) {
TShopOrder order = shopOrderService. getByOrderNo ( payVo. getOrderNo ( ) ) ;
if ( payVo. getPayWay ( ) == 2 ) {
Map < String , Object > map = wxPay ( order, request) ;
return R . ok ( map) ;
}
return null ;
}
private Map < String , Object > wxPay ( TShopOrder order, HttpServletRequest request) {
SysUser user = userService. selectUserById ( order. getSysUserId ( ) ) ;
String openid= user. getOpenId ( ) ;
Integer total= order. getOrderPrice ( ) . multiply ( new BigDecimal ( "100" ) ) . intValue ( ) ;
try {
request. setCharacterEncoding ( "UTF-8" ) ;
String title = "小程序微信支付" ;
String times = System . currentTimeMillis ( ) + "" ;
SortedMap < String , Object > packageParams = new TreeMap < String , Object > ( ) ;
packageParams. put ( "appid" , WxPayConfig . appid) ;
packageParams. put ( "mch_id" , WxPayConfig . mch_id) ;
packageParams. put ( "nonce_str" , times) ;
packageParams. put ( "body" , title) ;
packageParams. put ( "out_trade_no" , order. getOrderNo ( ) ) ;
packageParams. put ( "total_fee" , total) ;
packageParams. put ( "attach" , "" ) ;
packageParams. put ( "spbill_create_ip" , IpUtils . getIpAddr ( request) ) ;
packageParams. put ( "notify_url" , WxPayConfig . notify_url) ;
packageParams. put ( "trade_type" , WxPayConfig . tradeType) ;
packageParams. put ( "openid" , openid) ;
String sign = PayCommonUtil . createSign ( "UTF-8" , packageParams, WxPayConfig . apiKey) ;
packageParams. put ( "sign" , sign) ;
String requestXML = PayCommonUtil . getRequestXml ( packageParams) ;
System . out. println ( requestXML) ;
String resXml = HttpUtil . postData ( WxPayConfig . pay_url, requestXML) ;
System . out. println ( resXml) ;
Map map = XMLUtil . doXMLParse ( resXml) ;
System . out. println ( map) ;
String prepay_id = ( String ) map. get ( "prepay_id" ) ;
SortedMap < String , Object > packageP = new TreeMap < String , Object > ( ) ;
packageP. put ( "appId" , WxPayConfig . appid) ;
packageP. put ( "nonceStr" , times) ;
packageP. put ( "package" , "prepay_id=" + prepay_id) ;
packageP. put ( "signType" , WxPayConfig . signType) ;
packageP. put ( "timeStamp" , ( System . currentTimeMillis ( ) / 1000 ) + "" ) ;
String paySign = PayCommonUtil . createSign ( "UTF-8" , packageP, WxPayConfig . apiKey) ;
packageP. put ( "paySign" , paySign) ;
return packageP;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
return null ;
}
@RequestMapping ( value= "/wxNotify" )
public String wxNotify ( HttpServletRequest request) {
String result = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>" ;
try {
DataInputStream in = new DataInputStream ( request. getInputStream ( ) ) ;
byte [ ] bytes = new byte [ request. getContentLength ( ) ] ;
in. readFully ( bytes) ;
in. close ( ) ;
String xml = new String ( bytes) ;
Map < String , String > map = XMLUtil . doXMLParse ( xml) ;
if ( map != null && ! map. isEmpty ( ) ) {
System . out. println ( map) ;
System . out. println ( map. get ( "attach" ) ) ;
if ( map. get ( "return_code" ) . equals ( "SUCCESS" ) ) {
String orderSn= map. get ( "out_trade_no" ) ;
shopOrderService. payCallback ( orderSn) ;
return WxPayNotifyResponse . success ( "处理成功!" ) ;
}
}
return result. replace ( "SUCCESS" , "FAIL" ) . replace ( "OK" , "返回数据错误" ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
return result. replace ( "SUCCESS" , "FAIL" ) . replace ( "OK" , "本地服务器内部错误" ) ;
}
}
}
三、引入工具类,在公共文件下创建wx文件夹,把下面的代码全部放里面
package com. dcqq. common. utils. wx ;
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 final static int CONNECT_TIMEOUT = 5000 ;
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) {
} finally {
try {
if ( reader != null )
reader. close ( ) ;
} catch ( IOException e) {
}
}
return null ;
}
}
package com. dcqq. common. utils. wx ;
import org. apache. commons. lang3. StringUtils ;
import javax. servlet. http. HttpServletRequest ;
public class IpUtils {
public static String getIpAddr ( HttpServletRequest request) {
String ip = request. getHeader ( "X-Forwarded-For" ) ;
if ( StringUtils . isNotEmpty ( ip) && ! "unKnown" . equalsIgnoreCase ( ip) ) {
int index = ip. indexOf ( "," ) ;
if ( index != - 1 ) {
return ip. substring ( 0 , index) ;
} else {
return ip;
}
}
ip = request. getHeader ( "X-Real-IP" ) ;
if ( StringUtils . isNotEmpty ( ip) && ! "unKnown" . equalsIgnoreCase ( ip) ) {
return ip;
}
return request. getRemoteAddr ( ) ;
}
}
package com. dcqq. common. utils. wx ;
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. dcqq. common. utils. wx ;
import java. text. SimpleDateFormat ;
import java. util. * ;
public class PayCommonUtil {
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 ( ) ;
return tenpaySign. equals ( mysign) ;
}
public static String createSign ( String characterEncoding, SortedMap < String , 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 ) ;
System . out. println ( sb. toString ( ) ) ;
String sign = MD5. MD5Encode ( sb. toString ( ) , characterEncoding) . toUpperCase ( ) ;
return sign;
}
public static String getRequestXml ( SortedMap < String , 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 + ">" + "<![CDATA[" + v + "]]></" + k + ">" ) ;
} else {
sb. append ( "<" + k + ">" + v + "</" + k + ">" ) ;
}
}
sb. append ( "</xml>" ) ;
return sb. toString ( ) ;
}
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) ) ;
}
public static String getCurrTime ( ) {
Date now = new Date ( ) ;
SimpleDateFormat outFormat = new SimpleDateFormat ( "yyyyMMddHHmmss" ) ;
String s = outFormat. format ( now) ;
return s;
}
}
package com. dcqq. common. utils. wx ;
public class WxPayConfig {
public static final String appid = "wxaf1111111111111111111" ;
public static final String mch_id = "55555555" ;
public static final String key = "A5223241994ASDr222222222" ;
public static final String notify_url = "http://com.ss/wechat/pay/wxNotify" ;
public static final String signType = "MD5" ;
public static final String tradeType = "JSAPI" ;
public static final String apiKey = "A5223241994ASDr222222222" ;
public static final String pay_url = "https://api.mch.weixin.qq.com/pay/unifiedorder" ;
}
package com. dcqq. common. utils. wx ;
import org. jdom. Document ;
import org. jdom. Element ;
import org. jdom. JDOMException ;
import org. jdom. input. SAXBuilder ;
import java. io. ByteArrayInputStream ;
import java. io. IOException ;
import java. io. InputStream ;
import java. util. HashMap ;
import java. util. Iterator ;
import java. util. List ;
import java. util. Map ;
public class XMLUtil {
public static Map doXMLParse ( 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 = XMLUtil . getChildrenText ( children) ;
}
m. put ( k, v) ;
}
in. close ( ) ;
return m;
}
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 ( ) ;
}
}