這個支付的流程是前端H5(APP等)需要支付時調用后台的接口拿到我們加密的簽名去調起支付寶的支付界面(支付寶APP)進行支付操作,並且前端在支付成功后,支付寶后台會回調一個我們在簽名時寫入的一個接口地址進行支付結果的異步通知。
前置准備
- 1、在整個編寫過程中使用到的變量主要有私鑰、公鑰以及你的APPID(H5支付不需要),這些都是你在螞蟻金服注冊之后拿到的。
2、使用到的jar包:
- alipay-sdk-java*.jar—————————支付寶SDK編譯文件jar
- alipay-sdk-java*-source.jar——————支付寶SDK源碼文件jar
- commons-logging-1.1.1.jar——————SDK依賴的日志jar
commons-logging-1.1.1-sources.jar———SDK依賴的日志源碼jar
支付寶的SDK的jar包沒有在maven repository里注冊,因此要自己去官網上下載生成jar包並打進maven倉庫里,懶得寫的同學可以點擊這里直接下載。
代碼
獲取簽名的接口
@ResponseBody
@RequestMapping(value="/alipaySign",method=RequestMethod.POST)
public JSONObject signprams(Double totalAmount,String userId,String out_trade_no){
String subject = "Your Subject"; //主題
String body = "Your Body"; //主題內容
String CHARSET = "utf-8";
/**
* 實例化客戶端
*/
AlipayClient alipayClient = new DefaultAlipayClient
(PayConstants.Ali_Open_Api_Domain,PayConstants.Ali_AppId,
PayConstants.ALI_PRIVATE_KEY,"json",CHARSET,PayConstants.ALI_PUBLIC_KEY,"RSA2");
//實例化具體API對應的request類,類名稱和接口名稱對應
AlipayTradeAppPayRequest alirequest = new AlipayTradeAppPayRequest();
//sdk中的model入參
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setPassbackParams(body); //描述信息,添加附加數據
model.setSubject(subject); //商品標題
model.setOutTradeNo(out_trade_no); //訂單號
model.setTimeoutExpress("30m"); //超時關閉該訂單時間
model.setTotalAmount(Double.toString(totalAmount)); //將double數值轉換成String類
model.setProductCode(PayConstants.Ali_ProductCode);
alirequest.setBizModel(model);
alirequest.setNotifyUrl(PayConstants.Ali_Notify_Url); //回調地址
String orderStr = "";
try {
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(alirequest);
orderStr = response.getBody();
} catch (AlipayApiException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String sign = DigestUtils.md5Hex(out_trade_no).toUpperCase();
/////////////////處理你自己的邏輯/////////////////////////
JSONObject resObj = new JSONObject();
resObj.put("code", "SUCCESS");
resObj.put("out_trade_no", out_trade_no);
resObj.put("sign", sign);
resObj.put("orderStr",orderStr);
System.out.println(resObj.toJSONString());
System.out.println(resObj.toString());
return resObj;
}
回調的接口
回調的地址一定要保證是外網的地址,內網開發地址因為防火牆的限制不一定能訪問到。
@ResponseBody
@RequestMapping(value="/alipayNotify",method=RequestMethod.POST)
public String getNotify(HttpServletRequest request){
Map requestParams = request.getParameterMap();
logger.info("支付寶支付結果通知:"+requestParams.toString());
//獲取支付寶POST過來反饋信息
Map<String,String> params = new HashMap<String,String>();
for(Iterator iter=requestParams.keySet().iterator();iter.hasNext();){
String name = (String)iter.next();
String[] values = (String[]) requestParams.get(name);
String valueStr= "";
for(int i=0;i < values.length;i++){
valueStr = (i == values.length - 1) ? valueStr + values[i]
: valueStr + values[i] + ",";
logger.info(valueStr);
//亂碼解決,這段代碼在出現亂碼時使用。
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
}
}
///////////////////處理自己的邏輯//////////////////////
try {
boolean flag = AlipaySignature.rsaCheckV1
(params, PayConstants.ALI_PUBLIC_KEY, "UTF-8", "RSA2");
if(flag){
if("TRADE_SUCCESS".equals(params.get("trade_status")))
}
} catch (AlipayApiException e) {
e.printStackTrace();
}
return "SUCCESS";
}