1.前言
最近有在弄支付寶和微信的支付,現在我們來弄下支付寶的支付
首先註冊螞蟻金服開放平臺賬號這個就不多說了(個人用的是支付寶賬號)
配置好沙箱環境(一般來說沙箱環境跑通,到時候換上線上應用的配置就可以了)
詳細過程:https://openclub.alipay.com/read.php?tid=1513&fid=28
2.準備
下載相關的jar(sdk)
https://alipay.open.taobao.com/doc2/detail?treeId=54&articleId=103419&docType=1
maven導包
<dependency>
<groupId>com.alipay</groupId>
<artifactId>sdk-java</artifactId>
<version>20180309170622</version>
</dependency>
3.配置類
public class AlipayConfig {
//網關地址
//public static final String URL = "https://openapi.alipay.com/gateway.do"; //(正式環境)
public static final String URL = "https://openapi.alipaydev.com/gateway.do"; //沙箱(測試環境)
//APPID
public static final String ALIPAY_APPID = "";
//私鑰
public static String APP_PRIVATE_KEY = "";
//支付寶公鑰
public static String ALIPAY_PUBLIC_KEY = "";
//簽名算法類型(根據生成私鑰的算法,RSA2或RSA)
public static final String SIGNTYPE = "RSA2";
public static final String FORMAT = "json";//請求數據格式
public static final String CHARSET = "utf-8";//編碼集
// 服務器異步通知頁面路徑 需http://或者https://格式的完整路徑,不能加?id=123這類自定義參數,必須外網可以正常訪問
public static final String OWnotify_url = "";//網站掃碼
// 頁面跳轉同步通知頁面路徑 需http://或者https://格式的完整路徑,不能加?id=123這類自定義參數,必須外網可以正常訪問 商戶可以自定義同步跳轉地址
public static final String OWreturn_url = "";//網站掃碼
// 統一收單交易創建接口
private static AlipayClient alipayClient = null;
/**獲得初始化的AlipayClient
* @return 支付寶客戶端
*/
public static AlipayClient getAlipayClient() {
if (alipayClient == null) {
synchronized (AlipayConfig.class) {
if (null == alipayClient) {
alipayClient = new DefaultAlipayClient(URL, ALIPAY_APPID, APP_PRIVATE_KEY, FORMAT, CHARSET,ALIPAY_PUBLIC_KEY,SIGNTYPE);
}
}
}
return alipayClient;
}
}
4.支付寶電腦網站支付
4.1方法一:(返回的是from表單)
// 掃碼支付
@ResponseBody
@RequestMapping(value = "/pagePay")
public static String pagePay() {
int money = 100 ;//充值金額
//邏輯
long timeStart = Calendar.getInstance().getTimeInMillis();
String out_trade_no = timeStart+"";// 訂單號
// 獲得初始化的AlipayClient
AlipayClient alipayClient = AlipayConfig.getAlipayClient();
// 創建API對應的request
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
alipayRequest.setReturnUrl(AlipayConfig.OWreturn_url);// 回跳地址
alipayRequest.setNotifyUrl(AlipayConfig.OWnotify_url);// 通知地址
Map<String, Object> map = new HashMap<String, Object>();
map.put("out_trade_no", out_trade_no );// 訂單號
map.put("product_code", "FAST_INSTANT_TRADE_PAY");// 銷售產品碼
map.put("total_amount", money);// 交易金額,單位:元
map.put("subject", "電子門票");// 訂單標題
alipayRequest.setBizContent(JSON.toJSONString(map));
try {
// 調用SDK生成表單
String form = alipayClient.pageExecute(alipayRequest).getBody();
// 就是orderString可以直接給客戶端請求,無需再做處理。
System.out.println("---------支付寶掃碼---------> " + form);
return form;
} catch (AlipayApiException e) {
e.printStackTrace();
}
}
4.2 方法二: 返回的二維碼地址
可以前端生成二維碼也可後端生成二維碼傳輸前端,這裏我就只生成二維碼地址.
public static String alipay() throws AlipayApiException{
AlipayClient alipayClient = AlipayConfig.getAlipayClient();
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();//創建API對應的request類
Map<String,Object> map=new HashMap<String,Object>();
//設置回調地址
request.setReturnUrl(AlipayConfig.OWreturn_url);// 回跳地址
request.setNotifyUrl(AlipayConfig.OWnotify_url);// 通知地址
//根據訂單號查詢訂單信息
Map<String,Object> maps=new HashMap<String,Object>();
long timeStart = Calendar.getInstance().getTimeInMillis();
String out_trade_no = timeStart ;
maps.put("out_trade_no",out_trade_no);
maps.put("total_amount","0.01");
maps.put("subject",tpWxPay.getBody());
maps.put("timeout_express","5m");
//把訂單信息轉換爲json對象的字符串
String postdata = JSONObject.fromObject(maps).toString();
request.setBizContent(postdata);
AlipayTradePrecreateResponse response = alipayClient.execute(request);
String body = response.getBody();
JSONObject jsonObject = JSONObject.fromObject(body);
String qr_code = jsonObject.getJSONObject("alipay_trade_precreate_response").getString("qr_code");
map.put("qr_code", qr_code);
return qr_code;
}
5. 手機網站支付
返回一樣的是from表單,這樣前端直接掉起支付寶
/**
* 封裝好參數,前臺通過form表單來調起支付寶
* @throws AlipayApiException
* @throws IOException
*/
@RequestMapping("/getContext1")
public String alipayPayChongRequest(WxPayDto tpWxPay) throws AlipayApiException{
AlipayClient alipayClient = AlipayConfig.getAlipayClient();
//創建API對應的request類(主要是這裏變化了)
AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
request.setReturnUrl(AlipayConfig.OWreturn_url);// 回跳地址
request.setNotifyUrl(AlipayConfig.OWnotify_url);// 通知地址
AlipayTradeWapPayModel model=new AlipayTradeWapPayModel();
long timeStart = Calendar.getInstance().getTimeInMillis();
model.setOutTradeNo(timeStart +"");
model.setSubject("測試商品");
model.setTotalAmount("0.01");
model.setBody("測試商品");
model.setTimeoutExpress("30m");
model.setProductCode("QUICK_WAP_PAY");
request.setBizModel(model);
String form = alipayClient.pageExecute(request).getBody(); //調用SDK生成表單
System.out.println(form);
return form;
}
6. 回調
支付異步回調(支付成功後,支付寶會調用這個接口)
@RequestMapping(value = "/OWnotify", method = RequestMethod.POST)
public void OWnotify(HttpServletRequest request, HttpServletResponse httpResponse) {
// 獲取支付寶POST過來反饋信息
Map<String, String> params = new HashMap<String, String>();
Map<String, String[]> requestParams = request.getParameterMap();
Set<String> keySet = requestParams.keySet();
String out_trade_no = "";
String trade_status = "";
String total_amount = "";
for (String key : keySet) {
StringBuffer buffer = new StringBuffer();
for (String string : requestParams.get(key)) {
buffer.append(string);
}
params.put(key, buffer.toString());
if (key.equals("out_trade_no")) {
out_trade_no = buffer.toString();// 商戶訂單號
System.out.println(key + " : " + buffer.toString());
} else if (key.equals("trade_status")) {
trade_status = buffer.toString();// 交易狀態
System.out.println(key + " : " + buffer.toString());
} else if (key.equals("total_amount")) {
total_amount = buffer.toString().substring(0,buffer.toString().length()-3) + "";// 充值金額
System.out.println(key + " : " + total_amount);
}
}
System.out.println("支付異步回調");
try {
// 計算得出通知驗證結果
boolean verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY,
AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE);
if (verify_result) {// 驗證成功
if (trade_status.equals("TRADE_SUCCESS")) { // 交易支付成功
//邏輯
httpResponse.getWriter().println("success");
}
} else {// 驗證失敗
httpResponse.getWriter().println("fail");
}
} catch (Exception e) {
e.printStackTrace();
}
}
有異步當然就有同步啦(同步接口一般用於跳轉網頁,執行部分邏輯)
注意: 返回的是from表單的纔會主動調用(當然需要在配置類中配置啦)
使用request.getParameter能夠獲取到值或者用實體類
@RequestMapping("/OWreturn")
public ModelAndView OWreturn(HttpServletRequest request) {
ModelAndView mav = new ModelAndView();
System.out.println("支付同步回調");
mav.setViewName("");
return mav;
}
from表單發到前端,前端ajax請求成功後用$('#payFrom').html(from); 就會執行該from表單
好了!大概就是這樣吧!