在具体的支付逻辑在onClick这个点击事件中,下面具体来看这个点击事件中所做的内容:
以上这些只需要注意下面这行代码:
MyWxPayUtils.Pay(UiUtils.getContext(), Params, Url_pay);
参数2: 下单需要提交的参数
(这个参数的内容参考 https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1)
参数3: 用户生成并返回”正确的预支付交易回话标识”的Servlet
/**
* 进行微信支付的工具类
*
* @author king
*
*/
public class MyWxPayUtils {
public static Context mContext = null;
public static WXPay wxPay = null;
// 调用该方法进行支付
public static void Pay(Context context, Map Params,
String URL) {
mContext = context;
String ip = getIpAddress(context); //获取本机的Ip地址
Params.put("ip", ip);
// 1.首先进行请求服务器,上传本次微信支付的订单详情,并获取预支付Id
HttpHelper httpHelper = new HttpHelper(context, URL, Params,
new Handler() {
@Override
public void handleMessage(Message msg) {
wxPay = new WXPay(); // 封装从服务器获取的用于支付的参数
String json_wx = (String) msg.obj;
try {
JSONObject jsonObject = new JSONObject(json_wx);
wxPay.setPrepay_id(jsonObject
.getString("prepay_id"));
wxPay.setSign(jsonObject.getString("sign"));
wxPay.setOut_trade_no(jsonObject
.getString("out_trade_no"));
} catch (JSONException e) {
Log.i("MyWxPayUtils", "json解析异常");
e.printStackTrace();
}
// 2.调用微信支付的逻辑
IWXAPI wxapi = WXAPIFactory.createWXAPI(mContext,
WxPay.appid);
wxapi.registerApp(WxPay.appid); //进行注册
PayReq payRequest = new PayReq();
payRequest.appId = WxPay.appid; // 应用id
payRequest.partnerId = WxPay.partnerid; // 商户id
payRequest.prepayId = wxPay.getPrepay_id();// 预支付订单ID
payRequest.packageValue = WxPay.packageValue;// 扩展字段
payRequest.nonceStr = WxPayUtils.genNonceStr(); // 随机字符串
payRequest.timeStamp = WxPayUtils.genTimeStamp(); // 时间戳
// 二次签名
List signParams = new LinkedList();
signParams.add(new BasicNameValuePair("appid",
payRequest.appId));
signParams.add(new BasicNameValuePair("noncestr",
payRequest.nonceStr));
signParams.add(new BasicNameValuePair("package",
payRequest.packageValue));
/** 注意二次签名这里不再是mch_id,变成了prepayid; */
signParams.add(new BasicNameValuePair("partnerid",
payRequest.partnerId));
signParams.add(new BasicNameValuePair("prepayid",
payRequest.prepayId));
signParams.add(new BasicNameValuePair("timestamp",
payRequest.timeStamp));
payRequest.sign = genAppSign(signParams); // 签名
wxapi.sendReq(payRequest); //开始调用微信支付
Log.i("Test", "Sign:\n" + payRequest.sign);
}
});
// 2.通过handler告知要进行调用微信支付了
}
private static String getIpAddress(Context context) {
// 获取wifi服务
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
// 判断wifi是否开启
if (!wifiManager.isWifiEnabled()) {
wifiManager.setWifiEnabled(true);
}
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
String intToIp = intToIp(ipAddress);
Log.i("Test", "本机IP:"+intToIp);
return intToIp;
}
/**
* 在app端生成签名
* @param params
* @return
*/
private static String genAppSign(List params) {
StringBuilder str = new StringBuilder();
for (int i = 0; i < params.size(); i++) {
str.append(params.get(i).getName());
str.append('=');
str.append(params.get(i).getValue());
str.append('&');
}
str.append("key=");
str.append(WxPay.API_KEY);
String appSign = MD5.getMessageDigest(str.toString().getBytes())
.toUpperCase();
Log.e("orion", appSign);
return appSign;
}
// 将获取到的ip转换成字符串
public static String intToIp(int i) {
return (i & 0xFF) + "." + ((i >> 8) & 0xFF) + "." + ((i >> 16) & 0xFF)
+ "." + (i >> 24 & 0xFF);
}
}
/**
* 返回给客户端预支付id
* @author 春水碧于天
*
*/
public class WxPayRetrunServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
String spbill_create_ip =request.getParameter("ip"); //获取终端的IP地址
System.out.println("终端ip:"+spbill_create_ip);
String encode = TenpayUtil.getCharacterEncoding(request, response);
System.out.println("编码:"+encode);
String body = request.getParameter("body"); //商品描述
String total_fee = request.getParameter("total_fee"); //消费的金额
//获取当前具体的日期
Calendar calendar=Calendar.getInstance();
int year=calendar.get(Calendar.YEAR);
int month=calendar.get(Calendar.MONTH)+1;
int day=calendar.get(Calendar.DAY_OF_MONTH);
int hour=calendar.get(Calendar.HOUR_OF_DAY);
int minute=calendar.get(Calendar.MINUTE);
int second=calendar.get(Calendar.SECOND);
String currentDateTime=year+"-"+month+"-"+day+" "+hour+":"+minute+":"+second;
//---------------生成订单号 开始------------------------
//当前时间 yyyyMMddHHmmss
String currTime = TenpayUtil.getCurrTime();
//8位日期
String strTime = currTime.substring(8, currTime.length());
//四位随机数
String strRandom = TenpayUtil.buildRandom(4) + "";
//10位序列号,可以自行调整。
String strReq = strTime + strRandom;
//订单号,此处用时间加随机数生成,商户根据自己情况调整,只要保持全局唯一就行
String out_trade_no = strReq;
//---------------生成订单号 结束------------------------
//
PrepayIdRequestHandler prepayReqHandler = new PrepayIdRequestHandler(request, response);//获取prepayid的请求类
ClientRequestHandler clientHandler = new ClientRequestHandler(request, response);//返回客户端支付参数的请求类
String noncestr = WXUtil.getNonceStr();
String timestamp = WXUtil.getTimeStamp();
////设置获取prepayid支付参数
prepayReqHandler.setParameter("appid", ConstantUtil.APP_ID); //应用id
prepayReqHandler.setParameter("mch_id", ConstantUtil.PARTNER); //商户号
prepayReqHandler.setParameter("nonce_str", noncestr);//随机字符串
prepayReqHandler.setParameter("body", body);//商品描述
prepayReqHandler.setParameter("out_trade_no", out_trade_no);//商户订单号
prepayReqHandler.setParameter("total_fee",total_fee);//总金额
prepayReqHandler.setParameter("spbill_create_ip", spbill_create_ip);//终端IP
prepayReqHandler.setParameter("notify_url", ConstantUtil.TOKENURL);//通知地址
prepayReqHandler.setParameter("trade_type", "APP");//指定支付方式
WXPay wxPay = new WXPay(); //用于封装传回客户端的调用微信支付所需的参数
wxPay.setOut_trade_no(out_trade_no); //订单号
//生成获取预支付签名
String sign = prepayReqHandler.createMD5Sign();
wxPay.setSign(sign);
System.out.println("签名:"+sign);
prepayReqHandler.setParameter("sign",sign);
String gateUrl = ConstantUtil.GATEURL ;
prepayReqHandler.setGateUrl(gateUrl);
String prepayid = null;
try{
//获取prepayId
prepayid = prepayReqHandler.sendPrepay();
wxPay.setPrepay_id(prepayid);
System.out.println("预支付签名:"+prepayid);
} catch (JSONException e) {
e.printStackTrace();
}
Gson gson = new Gson();
String json_wxpay = gson.toJson(wxPay);
response.getWriter().write(json_wxpay);
}
}
当调用MyWxPayUtils.pay()方法进行支付的时候,首先携带由调用者传递过来的Params(提交的参数参考 https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1,需要注意的是客户端仅需要提供body,detail,total_fell等不涉及用户安全的参数,一些涉及到安全的参数全部在服务端进行配置 )去请求WxPayRetrunServlet,用于获取Android客户端调用起微信支付所必须的prepayId。
注意红框中圈出来的部分,prepayId 这个就是前面请求WxPayRetrunServlet获取到的,也是是否能够调用起来微信支付的关键。
需要根据微信官方文档给出的签名算法,对字段名为appid,partnerid,prepayid,noncestr,timestamp,package进行二次签名得到sign这个参数。
下面关注WxPayRetrunServlet是如何获取prepayId的,看下面的图中的标记:
以上两个步骤完成后,下面关注Android客户端是如何调用起微信支付的。
先向微信注册APPId:
IWXAPI wxapi = WXAPIFactory.createWXAPI(mContext,WxPay.appid);
wxapi.registerApp(WxPay.appid); //进行注册
调起支付:
wxapi.sendReq(payRequest); //开始调用微信支付
payRequest为第一步中封装的那些调用微信支付的必要参数
api = WXAPIFactory.createWXAPI(this, WxPay.appid);
appidapi.handleIntent(getIntent(), this);
3.支付的结果会回调给onResp方法
“`
@Override
public void onResp(BaseResp resp){
}
“`
根据BaseResp对象中封装的code进行判断即可