支付寶面對面支付(境內)
1、面對面支付分為掃碼支付PreCreatePay(使用者掃商家生成的二維碼)和條碼支付BarCodePay(商家掃使用者二維碼)
2、檔名:AlipayNotify.jsp(資訊回撥接收頁面)、BarCodePay.html/jsp(條碼支付)、PreCreatePay.html/jsp(掃碼支付)、Query.html/jsp(查詢交易資訊)、Refund.html/jsp(交易退款)、Cancel.java(撤銷交易)、CheckQuery.java(ajax 查詢交易)、Method.java(生成請求資料,生成請求連線、請求支付寶伺服器、查詢邏輯、撤銷邏輯)、web.xml(配置ajax 關聯到CheckQuery.java)
3、資料簽名方法最終會直接呼叫alipay-sdk-java20161213173952.jar,這個jar裡面有支付寶封裝好的簽名方法
4、境內支付寶使用的是RSA2金鑰,可自行根據支付寶整合的官網指引獲取
5、閘道器地址:測試環境為:https://openapi.alipaydev.com/gateway.do
正式環境為:https://openapi.alipay.com/gateway.do
(具體以官網整合文件為準)
拼接、傳送請求主要呼叫程式碼如下:
SimpleDateFormat date_out_trade_no = new SimpleDateFormat("yyyyMMddHHmmss"); String out_trade_no = date_out_trade_no.format(new Date()); String total_amount = request.getParameter("total_amount"); String discountable_amount = request.getParameter("discountable_amount"); String subject = request.getParameter("subject"); String body = out_trade_no; String operatorId = request.getParameter("operatorId"); String providerId = properties.pid; String extend_params = "{" + "\"sys_service_provider_id\":\"" + providerId + "\"" + "}"; String timeout_express = request.getParameter("timeout_express"); String scene = "bar_code"; String auth_code = request.getParameter("auth_code"); String method = "alipay.trade.pay"; String method2 = method.replace(".", "_"); String biz_content = ""; biz_content += "{" + "\"out_trade_no\":\"" + out_trade_no + "\"," + "\"scene\":\"" + scene + "\"," + "\"auth_code\":\"" + auth_code + "\"," + "\"total_amount\":\"" + total_amount + "\"," + "\"discountable_amount\":\"" + discountable_amount + "\"," + "\"subject\":\"" + subject + "\"," + "\"body\":\"" + body + "\"," + "\"operator_id\":\"" + operatorId + "\"," + "\"extend_params\":" + extend_params + "," + "\"timeout_express\":\"" + timeout_express + "\"}"; String url = ""; url = Method.GenerateURL_for_F2FPay(method,biz_content); System.out.println(url); String result = Method.requestAlipay(url,method2); System.out.println(result); String code = ""; String msg = ""; //fail response String sub_code = ""; String sub_msg = ""; //success response String trade_no = ""; String outtradeno = ""; String buyer_logon_id = ""; String totalamount = ""; String buyer_pay_amount = ""; String point_amount = ""; String invoice_amount = ""; String gmt_payment = ""; String fund_bill_list = ""; String buyer_user_id = ""; String trade_status = ""; try { JSONObject jsonObject2 = new JSONObject(result); code = jsonObject2.optString("code"); msg = jsonObject2.optString("msg"); if("10000".equals(code)){ trade_no = jsonObject2.optString("trade_no"); outtradeno = jsonObject2.optString("out_trade_no"); buyer_logon_id = jsonObject2.optString("buyer_logon_id"); totalamount = jsonObject2.optString("total_amount"); buyer_pay_amount = jsonObject2.optString("buyer_pay_amount"); point_amount = jsonObject2.optString("point_amount"); invoice_amount = jsonObject2.optString("invoice_amount"); gmt_payment = jsonObject2.optString("gmt_payment"); fund_bill_list = jsonObject2.optString("fund_bill_list"); buyer_user_id = jsonObject2.optString("buyer_user_id"); trade_status = jsonObject2.optString("trade_status"); System.out.println("code:"+code+"\n" +"msg:"+msg+"\n" +"trade_status:"+trade_status+"\n" +"trade_no:"+trade_no+"\n" +"outtradeno:"+outtradeno+"\n" +"buyer_logon_id:"+buyer_logon_id+"\n" +"total_amount:"+totalamount+"\n" +"buyer_pay_amount:"+buyer_pay_amount+"\n" +"point_amount:"+point_amount+"\n" +"invoice_amount:"+invoice_amount+"\n" +"gmt_payment:"+gmt_payment+"\n" +"fund_bill_list:"+fund_bill_list+"\n" +"buyer_user_id:"+buyer_user_id+"\n"); }else if("20000".equals(code)){ //未知異常 sub_code = jsonObject2.optString("sub_code");; sub_msg = jsonObject2.optString("sub_msg");; System.out.println("code:"+code+"\n"+"msg:"+msg+"\n"+"sub_code:"+sub_code+"\n"+"sub_msg:"+sub_msg); }else if("10003".equals(code)){ //等待付款 trade_no = jsonObject2.optString("trade_no"); outtradeno = jsonObject2.optString("out_trade_no"); buyer_logon_id = jsonObject2.optString("buyer_logon_id"); totalamount = jsonObject2.optString("total_amount"); buyer_pay_amount = jsonObject2.optString("buyer_pay_amount"); point_amount = jsonObject2.optString("point_amount"); invoice_amount = jsonObject2.optString("invoice_amount"); gmt_payment = jsonObject2.optString("gmt_payment"); fund_bill_list = jsonObject2.optString("fund_bill_list"); buyer_user_id = jsonObject2.optString("buyer_user_id"); trade_status = jsonObject2.optString("trade_status"); System.out.println("code:"+code+"\n" +"msg:"+msg+"\n" +"trade_status:"+trade_status+"\n" +"trade_no:"+trade_no+"\n" +"outtradeno:"+outtradeno+"\n" +"buyer_logon_id:"+buyer_logon_id+"\n" +"total_amount:"+totalamount+"\n" +"buyer_pay_amount:"+buyer_pay_amount+"\n" +"point_amount:"+point_amount+"\n" +"invoice_amount:"+invoice_amount+"\n" +"gmt_payment:"+gmt_payment+"\n" +"fund_bill_list:"+fund_bill_list+"\n" +"buyer_user_id:"+buyer_user_id+"\n"); }else{ //支付失敗 sub_code = jsonObject2.optString("sub_code");; sub_msg = jsonObject2.optString("sub_msg");; System.out.println("code:"+code+"\n"+"msg:"+msg+"\n"+"sub_code:"+sub_code+"\n"+"sub_msg:"+sub_msg); } } catch (JSONException e) { e.printStackTrace(); }
由上面程式碼可以看出,支付寶支付的請求資料出錯機會較大的是biz_content的值,其中注意格式為 {"key":value,"key2":value2} 的形式就好了,該有的都放到biz_content裡面,不該有的不放進去就好了
然後就是看生成完整請求資料的函式,參照Method類裡面的GenerateURL_for_F2FPay方法,把支付寶要求的資料放到Map裡面,把資料放到Map裡面之後,就能呼叫alipay提供的jar裡面的簽名方法,獲取sign值,最後連上sign值以前放到一個新的map裡面等待進一步生成最終的請求字串(記得放新Map的時候要對value值進行URLEncoder操作),呼叫Method類的createLinkString方法,生成最終的請求引數字串(其實就是把Map裡面的引數按照key=value&
具體程式碼如下:
public static String GenerateURL_for_F2FPay(String method,String biz_content){
System.out.println("");
System.out.println("-------------------------------------");
SimpleDateFormat date_timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String url = "";
String gateway = properties.open_api_domain+"?";
String app_id = properties.appid;
String format = "JSON";
String charset = "utf-8";
String sign_type = "RSA2";
String sign = "";
String timestamp = date_timestamp.format(new Date());
String version = "1.0";
Map<String, String> map1 = new TreeMap<String, String>();
map1.put("app_id", app_id);
map1.put("method", method);
map1.put("format", format);
map1.put("charset", charset);
map1.put("sign_type", sign_type);
map1.put("version", version);
map1.put("biz_content", biz_content);
map1.put("timestamp", timestamp);
String content = createLinkString(map1);
try {
sign = AlipaySignature.rsaSign(content, properties.private_key, charset,sign_type);
} catch (AlipayApiException e) {
e.printStackTrace();
}
Map<String, String> map = new TreeMap<String, String>();
map.put("app_id", URLEncoder.encode(app_id));
map.put("method", URLEncoder.encode(method));
map.put("format", URLEncoder.encode(format));
map.put("charset", URLEncoder.encode(charset));
map.put("sign", URLEncoder.encode(sign));
map.put("sign_type", URLEncoder.encode(sign_type));
map.put("version", URLEncoder.encode(version));
map.put("biz_content", URLEncoder.encode(biz_content));
map.put("timestamp", URLEncoder.encode(timestamp));
String mapString = createLinkString(map);
url = gateway+mapString;
System.out.println("url:"+url);
System.out.println("-------------------------------------");
System.out.println("");
return url;
}
public static String createLinkString(Map<String, String> params) {
List<String> keys = new ArrayList<String>(params.keySet());
Collections.sort(keys);
String prestr = "";
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
String value = params.get(key);
if (i == keys.size() - 1) {//拼接時,不包括最後一個&字元
prestr = prestr + key + "=" + value;
} else {
prestr = prestr + key + "=" + value + "&";
}
}
return prestr;
}
基本上就這樣了,其他查詢、撤銷訂單等操作的邏輯一模一樣,就是換了些引數或引數值而已
支付寶demo連結:http://download.csdn.net/download/qq_22778717/10231371