喜欢的朋友可以关注下,粉丝也缺。
相信很多的码友在项目中都需要接入微信支付,虽说微信支付已成为一个普遍的现象,但是接入的过程中难免会遇到各种各样的坑,这一点支付宝的SDK就做的很好,已经完成的都知道了。
下面就开始我们的代码之旅,这里我将给大家提供两种支付一个是微信公众号支付,一个是APP微信支付。
一 微信公众号支付
流程:
1.获取用户openid
2.获取token,注意获取的token是有时效的而且接口是有获取上线,具体看微信API文档
3.拿商品信息(金额,名字等)去请求统一下单接口
4.统一下单接口获取预支付ID,后进行二次签名把参数返回给前端
5.前端JS中接收到参数调起支付
6.支付成功页面跳转以及回调处理
下面我们就来具体说说功能
GetOpenId:获取用户openid
public class GetOpenid extends HttpServlet {
private static final Logger logger = Logger.getLogger(GetOpenid.class);
@SuppressWarnings("unused")
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
HttpSession session = request.getSession();
PreparedStatement pst=null;
String username="";
//获取code
String appid=WeiXinUitls.appid;
String code = request.getParameter("code");
String rturl = request.getParameter("rturl");
String appsecret = WeiXinUitls.appsecret;
String grant_type = "authorization_code";
String returnJSON = HttpTool.getToken(appid, appsecret, grant_type,code);
JSONObject obj = JSONObject.fromObject(returnJSON);
if(!(obj==null)){
String openid = obj.get("openid").toString();
String token = obj.get("access_token").toString();
String retoken = obj.get("refresh_token").toString();
//获取微信用户
String getuserinfo = HttpTool.getuserinfo(token, openid);
JSONObject fromObject = JSONObject.fromObject(getuserinfo);
String stropenid = fromObject.get("openid").toString();
session.setAttribute("openid", stropenid);
String strnickname = fromObject.get("nickname").toString();
String strcity = fromObject.get("city").toString();
String strcountry = fromObject.get("country").toString();
String strprovince = fromObject.get("province").toString();
String strsex = fromObject.get("sex").toString();
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
public static String RmFilter(String message){
if ((message == null) || (message.equals(""))) {
message = "";
}
message = message.replace("<","");
message = message.replace(">","");
message = message.replace("'","");
message = message.replace("\"","");
//message = message.replace("/","/");
message = message.replace("%","");
message = message.replace(";","");
message = message.replace("(","");
message = message.replace(")","");
message = message.replace("&","");
message = message.replace("+","_");
return message;
}
}
RefTicket:获取ticket
public class RefTicket extends TimerTask{
private static ServletContext application = null;
public RefTicket(ServletContext application){
this.application = application;
}
public void run() {
String jsapi_ticket = getTicket();
if(!"".equalsIgnoreCase(jsapi_ticket)){
this.application.setAttribute("jsapi_ticket", jsapi_ticket);
System.out.println("jsapi_ticket:"+jsapi_ticket);
System.out.println("jsapi_ticket--application:"+this.application.getAttribute("jsapi_ticket"));
}
}
private static DefaultHttpClient httpclient;
static {
httpclient = new DefaultHttpClient();
httpclient = (DefaultHttpClient) HttpClientConnectionManager
.getSSLInstance(httpclient);
}
private String getTicket(){
String token = (String) this.application.getAttribute("token");
if("".equalsIgnoreCase(token) || null == token ){
return "";
}
HttpGet get = HttpClientConnectionManager
.getGetMethod("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+token+"&type=jsapi");
HttpResponse response;
try {
response = httpclient.execute(get);
String jsonStr = EntityUtils
.toString(response.getEntity(), "utf-8");
JSONObject demoJson = JSONObject.fromObject(jsonStr);
return demoJson.getString("ticket");
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return "";
}
}
RefToken:获取token
public class RefToken extends TimerTask{
private final static String appId = "wx842b838875cd9bd3";
private final static String appSecret = "ce7948b66d04b5ae714c9d0e4bc6eba9";
private static ServletContext application = null;
public RefToken(ServletContext application){
this.application = application;
}
public void run() {
String token = getAccessToken(appId,appSecret);
if(!"".equalsIgnoreCase(token)){
this.application.setAttribute("token", token);
System.out.println("token---init:"+token);
String ticket = getTicket();
this.application.setAttribute("jsapi_ticket", ticket);
System.out.println("ticket--init:"+ticket);
}
}
private static DefaultHttpClient httpclient;
static {
httpclient = new DefaultHttpClient();
httpclient = (DefaultHttpClient) HttpClientConnectionManager
.getSSLInstance(httpclient);
}
private static String getAccessToken(String appid, String secret) {
HttpGet get = HttpClientConnectionManager
.getGetMethod("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
+ appid + "&secret=" + secret);
HttpResponse response;
try {
response = httpclient.execute(get);
String jsonStr = EntityUtils
.toString(response.getEntity(), "utf-8");
JSONObject demoJson = JSONObject.fromObject(jsonStr);
return demoJson.getString("access_token");
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return "";
}
private String getTicket(){
String token = (String) this.application.getAttribute("token");
if("".equalsIgnoreCase(token) || null == token ){
return "";
}
HttpGet get = HttpClientConnectionManager
.getGetMethod("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+token+"&type=jsapi");
HttpResponse response;
try {
response = httpclient.execute(get);
String jsonStr = EntityUtils
.toString(response.getEntity(), "utf-8");
JSONObject demoJson = JSONObject.fromObject(jsonStr);
return demoJson.getString("ticket");
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return "";
}
}
GetSignature :
public class GetSignature extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger(GetSignature.class);
public GetSignature() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try{
response.setCharacterEncoding("UTF-8");
request.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
//你的支付目录的Url,不需要转义,不包含#及其后面部分
String url = request.getParameter("url");
ServletContext application = this.getServletContext();
String jsapi_ticket=String.valueOf(application.getAttribute("jsapi_ticket"));
JSONObject obj = WeixinPay.getSignature(url, jsapi_ticket);
// Map<String, String> sign = Sign.sign(jsapi_ticket,url);
out.print(obj.toString());
out.flush();
out.close();
}catch (Exception e) {
logger.error(e.getMessage(), e);
e.printStackTrace();
}
}
}
JS中初始化:
//支付初始化
function initPay(openId){
//获取当前页面URL
var geturl=window.location.href.split('#')[0];
var getencodeurl=encodeURIComponent(geturl);
$.ajax({
type : 'POST',
url : "/GetSignature?url="+getencodeurl,
contentType:"application/x-www-form-urlencoded",
success : function(response) {
var params = eval("(" + response + ")");
wx.config({
debug: false,
appId : params.appid, // 必填,公众号的唯一标识
timestamp : params.timestamp, // 必填,生成签名的时间戳
nonceStr : params.nonceStr, // 必填,生成签名的随机串
signature : params.signature,// 必填,签名,见附录1
jsApiList : [ 'chooseWXPay']
});
wx.ready(function() {
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
$("#weixinpay").on('click', function(t) {
// var c_sname =getQueryString("c_sname");
var paymoney=document.getElementById("money").value;//实际付款
var phone=document.getElementById("phone").value;//手机号
if(phone==null||phone==""){
Dialog.alert("请填写手机号码!");
}else{
$("#weixinpay").unbind('click');
$("#mcover").css("display","block");
// alert($("#payment").serialize());
$.ajax({
type : 'POST',
// url:"/topayServlet",
url : "/topayServlet?openId="+openId+"&money="+paymoney+"&phone="+phone,
// data:$("#payment").serialize(),// 提交formid
// async: false,
success : function(response) {
var params = eval("(" + response + ")");
$("#mcover").css("display","none");
wx.chooseWXPay({
appId : params.appId,
timestamp :params.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
nonceStr : params.nonceStr, // 支付签名随机串,不长于 32 位
package : params.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
signType :params.signType,
paySign : params.paySign,
success : function(res) {
if(res.errMsg == "chooseWXPay:ok" ) {
window.location.href="/3g/shareBusiness.jsp?sid="+sp+"&c_sname="+skf+"&phone="+phone;
//支付成功
$("#weixinpay").bind('click');
}
},
cancel: function (res) {
window.location.href="/3g/shop_list.jsp";
$("#weixinpay").bind('click');
},
fail:function(res){
window.location.href="/3g/shop_list.jsp";
$("#weixinpay").bind('click');
}
});
},
error : function() {
// window.location.reload();
// alert("服务器异常,统一下单接口出错!");
}
})
}
});
});
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
// wx.error(function(res){
// alert('wx.error: '+JSON.stringify(res));
// });
},
error : function() {
// window.location.reload();
// Dialog.alert("服务器异常,支付初始化失败!");
}
})
}
TopayServlet:统一下单接口
/**
* 支付请求处理
* @author dsn
*
*/
public class TopayServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1359159929707330023L;
private static final Logger logger = Logger.getLogger(TopayServlet.class);
private String finalmoney=null;
private String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
//商户相关资料
private String appid = WeiXinUitls.appid;
private String appsecret = WeiXinUitls.appsecret;
private String partner = WeiXinUitls.partner;
private String partnerkey = WeiXinUitls.partnerkey;
@SuppressWarnings("static-access")
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
request.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
//网页授权后获取传递的参数
String openId = request.getParameter("openId");
String sid = request.getParameter("sssp"); //商户ID
String money = request.getParameter("money");//实际付款
String phone = request.getParameter("phone");//手机号
String c_sname = new String(skf.getBytes("ISO-8859-1"), "utf-8");
//拼接字符串
String zong=sid+"*"+money+"*"+phone+"*"+jfdy;
//金额转化为分为单位
String money2 = TenpayUtil.getMoney(money);
//获取openId后调用统一支付接口https://api.mch.weixin.qq.com/pay/unifiedorder
String currTime = TenpayUtil.getCurrTime();
//8位日期
String strTime = currTime.substring(8, currTime.length());
//四位随机数
String strRandom = TenpayUtil.buildRandom(4) + "";
//10位序列号,可以自行调整。
String strReq = strTime + strRandom;
//商户号
String mch_id = partner;
//子商户号 非必输
//String sub_mch_id="";
//设备号 非必输
String device_info="WEB";
//随机数
String nonce_str = strReq;
//商品描述
//String body = describe;
//商品描述根据情况修改
String body = c_sname;
//附加数据
String attach = zong;
//商户订单号
String out_trade_no = NonceString.generate();
//int intMoney = Integer.parseInt(finalmoney);
//总金额以分为单位,不带小数点
//int total_fee = intMoney;
//订单生成的机器 IP
String spbill_create_ip = request.getRemoteAddr();
//订 单 生 成 时 间 非必输
String time_start =TenpayUtil.getStartTime();
//订单失效时间 非必输
String time_expire =TenpayUtil.getEndTime();;
//商品标记 非必输
String goods_tag = "WXG";
//这里notify_url是 支付完成后微信发给该链接信息,可以判断会员是否支付成功,改变订单状态等。
String notify_url ="http://www.yiquanmian.com/notifyServlet";
String trade_type = "JSAPI";
String openid = openId;
//非必输
// String product_id = "";
SortedMap<String, String> packageParams = new TreeMap<String, String>();
packageParams.put("appid", appid);
packageParams.put("mch_id", mch_id);
packageParams.put("nonce_str", nonce_str);
packageParams.put("body", body);
packageParams.put("attach", attach);
packageParams.put("out_trade_no", out_trade_no);
packageParams.put("total_fee", money2);
packageParams.put("spbill_create_ip", spbill_create_ip);
packageParams.put("time_start", time_start);
packageParams.put("time_expire", time_expire);
packageParams.put("notify_url", notify_url);
packageParams.put("trade_type", trade_type);
packageParams.put("openid", openid);
RequestHandler reqHandler = new RequestHandler(request, response);
reqHandler.init(appid, appsecret, partnerkey);
String sign = reqHandler.createSign(packageParams);
String xml="<xml>"+
"<appid>"+appid+"</appid>"+
"<mch_id>"+mch_id+"</mch_id>"+
"<nonce_str>"+nonce_str+"</nonce_str>"+
"<sign>"+sign+"</sign>"+
"<body><![CDATA["+body+"]]></body>"+
"<attach>"+attach+"</attach>"+
"<out_trade_no>"+out_trade_no+"</out_trade_no>"+
"<total_fee>"+money2+"</total_fee>"+
"<spbill_create_ip>"+spbill_create_ip+"</spbill_create_ip>"+
"<time_start>"+time_start+"</time_start>"+
"<time_expire>"+time_expire+"</time_expire>"+
"<notify_url>"+notify_url+"</notify_url>"+
"<trade_type>"+trade_type+"</trade_type>"+
"<openid>"+openid+"</openid>"+
"</xml>";
String allParameters = "";
try {
allParameters = reqHandler.genPackage(packageParams);
} catch (Exception e) {
logger.error(e.getMessage(), e);
e.printStackTrace();
}
String prepay_id="";
try {
prepay_id= new GetWxOrderno().getPayNo(createOrderURL, xml);
// JSONObject xmls = p.getJSONObject("xml");
if(prepay_id.equals("")){
request.setAttribute("ErrorMsg", "统一支付接口获取预支付订单出错");
response.sendRedirect("error.jsp");
}
} catch (Exception e1) {
logger.error(e1.getMessage(), e1);
e1.printStackTrace();
}
SortedMap<String, String> finalpackage = new TreeMap<String, String>();
String appid2 = appid;
String timestamp = Sha1Util.getTimeStamp();
String nonceStr2 = nonce_str;
String prepay_id2 = "prepay_id="+prepay_id;
String packages = prepay_id2;
finalpackage.put("appId", appid2);
finalpackage.put("timeStamp", timestamp);
finalpackage.put("nonceStr", nonceStr2);
finalpackage.put("package", packages);
finalpackage.put("signType", "MD5");
String finalsign = reqHandler.createSign(finalpackage);
finalpackage.put("paySign",finalsign);
JSONObject jsonObject1 = JSONObject.fromObject(finalpackage);
out.print(jsonObject1);
out.flush();
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
NotifyServlet:回调处理类
public class NotifyServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 6743167121907086323L;
private static final Logger logger = Logger.getLogger(NotifyServlet.class);
private String resultXML;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// response.setContentType("text/html;charset=utf-8");
HttpSession session = request.getSession();
int i = 0;
//
String inputLine;
String notityXml = "";
String resXml = "";
try {
while ((inputLine = request.getReader().readLine()) != null) {
notityXml += inputLine;
}
request.getReader().close();
} catch (Exception e) {
e.printStackTrace();
}
try {
Map m = GetWxOrderno.parseXmlToList2(notityXml);
WxPayResult wpr = new WxPayResult();
String appid = m.get("appid").toString();
String bank_type = m.get("bank_type").toString();
String attach = m.get("attach").toString();
String cash_fee = m.get("cash_fee").toString();
String fee_type = m.get("fee_type").toString();
String is_subscribe = m.get("is_subscribe").toString();
String mch_id = m.get("mch_id").toString();
String nonce_str = m.get("nonce_str").toString();
String openid = m.get("openid").toString();
String out_trade_no = m.get("out_trade_no").toString();
String result_code = m.get("result_code").toString();
String return_code = m.get("return_code").toString();
String sign = m.get("sign").toString();
String time_end = m.get("time_end").toString();
String times = time_end.substring(0, 4) + "-"
+ time_end.substring(4, 6) + "-" + time_end.substring(6, 8)
+ " " + time_end.substring(8, 10) + ":"
+ time_end.substring(10, 12) + ":"
+ time_end.substring(12, 14);
Timestamp tstamp = Timestamp.valueOf(times);
String total_fee = m.get("total_fee").toString();
int totalint = Integer.parseInt(total_fee);
double pasint = totalint * 0.01;
String trade_type = m.get("trade_type").toString();
String transaction_id = m.get("transaction_id").toString();
if ("SUCCESS".equals(result_code)) {
// 支付成功
// 处理附加数据
// 判断订单是否已经存在
if (rs.next()) {
if(transaction_id.equals(rs.getString("ddh"))){
System.out.println("订单已经存在");
}
} else {
// ----------------------------------------------------发送短信-------------------------------------------
// 给用户发短信
// 给商家发短信
}
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[false]]></return_msg>"
+ "</xml> ";
}
BufferedOutputStream out = new BufferedOutputStream(
response.getOutputStream());
out.write(resXml.getBytes());
out.flush();
out.close();
} catch (Exception e) {
logger.error(e.getMessage(), e);
e.printStackTrace();
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
上面就是微信公众号的核心代码,需要源码的可以去我的地址下
https://download.csdn.net/download/dsn727455218/9325425
重点提示一下一定要在js的页面中引入微信的js文件不然会调不起支付的
<script type="text/javascript" charset="UTF-8"
src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
二 APP支付
流程:
1.Android引入微信支付的SDK
2.拿商品信息请求统一下单接口
3.统一下单接口获取预支付ID,后进行二次签名把参数返回给前端
4.前端JS中接收到参数调起支付
5.支付成功页面跳转以及回调处理
具体骚操作:
首先在Constants.java中设置相关参数,具体请查看该文件注释,同时根据注释修改androidmanifest.xml文件
要保证: 包名和开放平台一致,签名和开放平台一致,并且再公众平台做设置,详情请阅读: http://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=8_5,注意:此条仅仅适用于android,ios不受签名文件限制
要保证回调类WXPayEntryActivity.java文件必须位于包名的wxapi目录下,否则会导致无法回调的情况,注意:此条仅仅适用于android,ios有固定格式,请参考ios demo
上面是Android的注意事项
androidmanifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="你的项目包名"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="4" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".PayActivity"
android:label="@string/app_name"
android:exported="true"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="你的开发者ID"/>
</intent-filter>
</activity>
<activity
android:name=".wxapi.WXPayEntryActivity"
android:exported="true"
android:launchMode="singleTop"/>
<receiver
android:name="net.sourceforge.simcpux.AppRegister">
<intent-filter>
<action android:name="com.tencent.mm.plugin.openapi.Intent.ACTION_REFRESH_WXAPP" />
</intent-filter>
</receiver>
</application>
</manifest>
PayActivity:调起支付类
public class PayActivity extends Activity {
private static final String TAG = "MicroMsg.SDKSample.PayActivity";
PayReq req;
final IWXAPI msgApi = WXAPIFactory.createWXAPI(this, null);
TextView show;
Map<String,String> resultunifiedorder;
StringBuffer sb;
private IWXAPI api; // IWXAPI 是第三方app和微信通信的openapi接口
private Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pay);
//微信appId
api = WXAPIFactory.createWXAPI( this, Constants.APP_ID);
api.registerApp(Constants.APP_ID);
final Button appayBtn = (Button) findViewById(R.id.appay_btn);
appayBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String url = "http://192.168.0.104:8080/wx_pay/servlet/TopayServlet";
Toast.makeText(PayActivity.this, "获取订单中...", Toast.LENGTH_SHORT).show();
try{
byte[] buf = Util.httpGet(url);
if (buf != null && buf.length > 0) {
String content = new String(buf);
Log.e("get server pay params:",content);
JSONObject json = new JSONObject(content);
if(null != json && json.getString("returnstatus").equals("success") ){
String retmsg = json.getString("retmsg");
JSONObject json2 = new JSONObject(retmsg);
PayReq req = new PayReq();
//req.appId = "wxf8b4f85f3a794e77"; // 测试用appId
Log.e("get appid :",json2.getString("appid"));
Log.e("get partnerid :",json2.getString("partnerid"));
Log.e("get prepayid :",json2.getString("prepayid"));
Log.e("get noncestr :",json2.getString("noncestr"));
Log.e("get timestamp :",json2.getString("timestamp"));
Log.e("get package :",json2.getString("package"));
Log.e("get sign :",json2.getString("sign"));
//从服务器获取
req.appId = json2.getString("appid");
req.partnerId = json2.getString("partnerid");
req.prepayId = json2.getString("prepayid");
req.nonceStr = json2.getString("noncestr");
req.timeStamp = json2.getString("timestamp");
req.packageValue = json2.getString("package");
req.sign = json2.getString("sign");
req.extData = "app data"; // optional
Toast.makeText(PayActivity.this, "正常调起支付", Toast.LENGTH_SHORT).show();
// 在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信
api.sendReq(req);
Log.e("get api.sendReq(req) :",api.sendReq(req)+"");
}else{
Log.d("PAY_GET", "返回错误"+json.getString("retmsg"));
Toast.makeText(PayActivity.this, "返回错误"+json.getString("retmsg"), Toast.LENGTH_SHORT).show();
}
}else{
Log.d("PAY_GET", "服务器请求错误");
Toast.makeText(PayActivity.this, "服务器请求错误", Toast.LENGTH_SHORT).show();
}
}catch(Exception e){
Log.e("PAY_GET", "异常:"+e.getMessage());
Toast.makeText(PayActivity.this, "异常:"+e.getMessage(), Toast.LENGTH_SHORT).show();
}
// appayBtn.setEnabled(true);
}
});
}
WXPayEntryActivity:支付成功页面跳转类
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler{
private static final String TAG = "MicroMsg.SDKSample.WXPayEntryActivity";
private IWXAPI api;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pay_result);
//微信APP_ID
api = WXAPIFactory.createWXAPI(this, Constants.APP_ID);
api.handleIntent(getIntent(), this);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
api.handleIntent(intent, this);
}
@Override
public void onReq(BaseReq req) {
}
@Override
public void onResp(BaseResp resp) {
Log.d(TAG, "onPayFinish, errCode = " + resp.errCode);
String msg = "";
if (resp.errCode == 0) {
msg = "支付成功";
} else if (resp.errCode == -1) {
msg = "已取消支付";
} else if (resp.errCode == -2) {
msg = "支付失败";
}
Toast.makeText(WXPayEntryActivity.this, resp.errCode+"------"+msg, Toast.LENGTH_SHORT).show();
finish();
}
}
PrepayId:统一下单接口
/**
* Servlet implementation class prepayid
*/
public class PrepayId extends HttpServlet {
private static final long serialVersionUID = 1L;
// key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置
//TODO
private static String KEY = "你的商户平台key";
/**
* Default constructor.
*/
public PrepayId() {}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
@SuppressWarnings("rawtypes")
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
SortedMap<String, String> map = new TreeMap<String, String>();
//TODO 你的appid
map.put("appid", "");
//TODO 你的商户id
map.put("mch_id", "");
map.put("nonce_str", String.valueOf(System.currentTimeMillis()));
map.put("body", "lidongliang");
map.put("out_trade_no", String.valueOf(System.currentTimeMillis()));
map.put("total_fee", "1");
map.put("spbill_create_ip", "192.168.0.105");
map.put("notify_url", "你的回调地址");
map.put("trade_type", "APP");
String sign = createSign(map);
map.put("sign", sign);
// 生成XMl
Set set = map.entrySet();
Iterator it = set.iterator();
StringBuffer sb = new StringBuffer();
sb.append("<xml>");
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
sb.append("<" + key + "><![CDATA[");
sb.append(value);
sb.append("]]></" + key + ">");
}
sb.append("</xml>");
try {
System.out.println("111111111" + sb.toString());
String postData = NetUtil.doPost(url, sb.toString());
System.out.println("222222222" + postData.toString());
SortedMap<String, String> test = new TreeMap<String, String>();
JSONObject json = XML.toJSONObject(postData).getJSONObject("xml");
test.put("appid", json.getString("appid"));
test.put("partnerid", json.getString("mch_id"));
test.put("prepayid", json.getString("prepay_id"));
test.put("package", "Sign=WXPay");
test.put("noncestr", String.valueOf(System.currentTimeMillis()));
test.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
test.put("sign", createSign(test));
response.getWriter().append(new JSONObject(test).toString());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {}
/**
* 微信支付签名算法sign
*
* @param characterEncoding
* @param parameters
* @return
*/
@SuppressWarnings("rawtypes")
public static String createSign(SortedMap<String, String> parameters) {
StringBuffer sb = new StringBuffer();
// 所有参与传参的参数按照accsii排序(升序)
Set es = parameters.entrySet();
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 + "&");
}
}
sb.append("key=" + KEY);
System.out.println("字符串拼接后是:" + sb.toString());
String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
System.out.println("sign:" + sign);
return sign;
}
}
NotifyHandle:支付回调类
@Controller
@RequestMapping("notifyhandle")
public class NotifyHandle extends BaseAction{
@Resource
private ServiceSinggleService ssService;
@Resource
private ElutionRecordService edService;
@Resource
private AppUserService appuserService;
@Resource
private MsgJpushService mjService;
private static final Logger logger = Logger.getLogger(NotifyHandle.class);
@ResponseBody
@RequestMapping(value="/notify")
public String notify(ServiceSinggle ssinggle,ElutionRecord record,MsgJpush msgjpush,AppUser appuser,HttpServletRequest request,HttpSession session,HttpServletResponse response){
String inputLine;
String notityXml = "";
String resXml = "";
try {
while ((inputLine = request.getReader().readLine()) != null) {
notityXml += inputLine;
}
request.getReader().close();
Map m = GetWxOrderno.parseXmlToList2(notityXml);
String result_code = m.get("result_code").toString();
if("SUCCESS".equals(result_code)){
//查询是否存在订单
String attach = m.get("attach").toString();
String out_trade_no = m.get("out_trade_no").toString();
String time_end = m.get("time_end").toString();
String total_fee = m.get("total_fee").toString();
int totalint = Integer.parseInt(total_fee);
//订单更新 继续你的逻辑操作
} else {
resXml = "<xml>"
+ "<return_code><![CDATA[FAIL]]></return_code>"
+ "<return_msg><![CDATA[false]]></return_msg>"
+ "</xml> ";
}
BufferedOutputStream out = new BufferedOutputStream(
response.getOutputStream());
out.write(resXml.getBytes());
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
}
APP的微信支付就是这么的简单:上面我贴的核心代码,一些工具类没有贴出来需要demo可以去下面地址下载
https://download.csdn.net/download/dsn727455218/10304062
如果遇到签名错误,缺少参数,返回-1,等错误请参考我的另一篇文章:微信支付遇到的几个问题
https://blog.csdn.net/dsn727455218/article/details/70139320
看着是不是很简单,完美的解决。
到这里已经完成了微信支付功能,如有需要可以加我Q群【308742428】大家一起讨论技术。
后面会不定时为大家更新文章,敬请期待。