1. 程式人生 > >支付寶面對面支付(境內)

支付寶面對面支付(境內)

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&

key=value&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