這次給的任務是看一下支付寶的app支付這塊。於是通過網上進行查找相關的資料,進行相關的開發,並記錄下來。
通過支付寶的官網進行查看:https://docs.open.alipay.com/54/106370/
1.引入支付寶的SDK的依賴;
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.7.89.ALL</version>
</dependency>
2.支付寶的參數(appid和祕鑰之類),具體每個數據怎麼來,可以單獨查詢。可以參考這個:https://blog.csdn.net/qq_35529931/article/details/104444967
並在工具類中實例化客戶端
//支付寶移動端appid
public static final String ALIPAY_APP_APPID = "2016101700707603";
//支付寶商戶私鑰
public static final String ALIPAY_PRIVATE_KEY =
"MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCMPgVZxah9Xtgdv/jFsaJVFyyvThBy" +
"/Zw7mDfoYETefYt1amcKHITQ9mOBrHZNsA3jsMBo9fXH14w/+3VxV/wgczbiCVyXgGXSCwcATt" +
"/PhQq8CT4CHAYNhhfysgbEWCsf+piAFfYMRwNus/xFb+N2wt1PRhAvRCSqvgFPoJmgR5Iyn1sYnWNj8F0+90mlv4E" +
"+DslF104+0ysfjOzy2r0uhKsLxXpr2EZt5H2xH7rfMvgO0EjFulvlwi6BAcc7uJGLeNeA17QYkx6tDqrtZ2oqw0v6UTulDlnFRUS6eQd2rKYQtT/ThL7BoYmCmS1YMuQ7Qwy7JQNXi5+7CSO4mj9DAgMBAAECggEAKbGWraXR/dPgtJeKQlwZQurs4gF3anhzplQO6wsT7oGsoG/NynfIFMfrtXWshlQ9DOBTk+Dr/Unb7Hm55MSftJYMTw8xc+k8XEHjBvhsGaoYEuc8hCwIsKSZIhJDaMQ9rfg2tn3Q9L14C8V+zrYBDiHI4fSWgzbjH8/1W9MHWVr7V84SXLyzeGi3JLYlHRKpewANUm4wicK4CYTVg/qxFP/WWrURCQnMAO/HU026QPOF9mbN9zrk2sKHG6MDHoNtpTmDbWzz9jWua3iCeuW/yj/lBjx42/EVu3W0C5XBFr6+arUbWvr5WZm7Ck+qJ9+tLbpp1k8hnWSo/C+6w4C8wQKBgQDjQuA6s83rJ5iNDdNzfxvokJYYTe+n9mPq79jAEhNAu7nx/WtZ6UVyWbOwFqVyMvW2bLOr8UbdFGIvVh0hTRSgEWGqlUK1dUSz3ru1mYSTVrCoLDkW81P/BEn7Lkszoy1DjGxB19gtsMc/oMNk7FxoGq0l0gSnDGTHeav9wkXl6wKBgQCd+hTejo1aAF/OwRLjuHwX5Mrv5dUBd9mMO06mYG9V+0SA5JPjrNgH6mlZkmw7IXfe2vebwIVqdP1gk+y0oLgR8qo36xqgT52cWd/IWPsjI8BzsDkOJG6Zcie0HTWztTpCLP73XCLdod3anuVVVG0mIJdGL2GH6HlucvefvpL+CQKBgGFxFzuURMKDI8G3H+bxpUG+XNzm7c8SshzV4hXYqjCjTUMY6aKPhptVItppm16vwvMJALDEryGzz7WEMtFIf4NycHH3tbagJWkKI2nl/RY/oVc6PvA8PNOnPyFX5B6r5IiF+RTyO1q75XK+t4jaX3Szm3IP7rbBdaSh4sDXP6kpAoGAEZs1iDhK+KTiCKDsAgUlj2QoWeQ7gRZiYIablV9aCTMfx12yPcWdrgQqCZmQBmcMfQHaZrlmJR80vfa+gsMGwLlSzziclxFId4xsrF9+XcQ2Rq51LWZSDTfzxNccjRK9k3KAWAEkwZ6woxTiakgmggFP2rqdHBCEuBKIFn2e1EECgYAyyMF3G7zZCGXuY0u90csefCkA4unUYbya+ncKNg0x03EYK3chI+5JlvwLnMTi39YRbS99UL+pKqphlILBnczYxaLczb7Lr45vdCN1YwPTH+/t7bDfWblRER+DDp78wIWFf+/OGuB4MOjBhbM/0m91ZpriR+wZHWIP/BoXwq5Mrw==";
//支付寶公鑰
public static final String ALIPAY_PUBLIC_KEY =
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjD4FWcWofV7YHb" +
"/4xbGiVRcsr04Qcv2cO5g36GBE3n2LdWpnChyE0PZjgax2TbAN47DAaPX1x9eMP" +
"/t1cVf8IHM24glcl4Bl0gsHAE7fz4UKvAk+AhwGDYYX8rIGxFgrH/qYgBX2DEcDbrP8RW" +
"/jdsLdT0YQL0Qkqr4BT6CZoEeSMp9bGJ1jY/BdPvdJpb+BPg7JRddOPtMrH4zs8tq9LoSrC8V6a9hGbeR9sR" +
"+63zL4DtBIxbpb5cIugQHHO7iRi3jXgNe0GJMerQ6q7WdqKsNL+lE7pQ5ZxUVEunkHdqymELU/04S" +
"+waGJgpktWDLkO0MMuyUDV4ufuwkjuJo/QwIDAQAB";
//支付寶網關
public static final String ALIPAY_GATEWAY_URL = "https://openapi.alipaydev.com/gateway.do";
// 驗證方式
public static final String SIGN_TYPE = "RSA2";
// 返回路徑
public static final String ALIPAY_NOTIFYURL = "https://www.alipy.com";
// 傳輸方式
public static final String FORMAT = "json";
// 字符串格式
public static final String CHARSET = "UTF-8";
private static AlipayClient alipayClient = null;
public static AlipayClient getAlipayClient() throws AlipayApiException {
//實例化客戶端
if (alipayClient == null) {
synchronized (AlipayUtil.class) {
if (null == alipayClient) {
alipayClient = new DefaultAlipayClient(ALIPAY_GATEWAY_URL, ALIPAY_APP_APPID, ALIPAY_PRIVATE_KEY,
FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);
}
}
}
return alipayClient;
}
3.接下來就是下單接口,需要的參數如下:
@NotNull(message = "缺少請求參數")
private String subject;
@NotNull(message = "缺少請求參數")
private String outTradeNo;
@NotNull(message = "缺少請求參數")
private String totalAmount;
private String body;
4.下單接口:
@RequestMapping(value = "/aliPay", method = RequestMethod.POST)
public Map<String, Object> aliPayOrder(@RequestBody AlipayDTO alipayDTO) {
Map map = Maps.newHashMap();
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
//(否)對一筆交易的具體描述信息。如果是多種商品,請將商品描述字符串累加傳給body。
model.setBody(alipayDTO.getBody());
//(是)商品的標題/交易標題/訂單標題/訂單關鍵字等
model.setSubject(alipayDTO.getSubject());
//(是)商戶網站唯一訂單號
model.setOutTradeNo(alipayDTO.getOutTradeNo());
//(是)訂單總金額,單位爲元,精確到小數點後兩位
model.setTotalAmount(alipayDTO.getTotalAmount());
//(否)設置未付款支付寶交易的超時時間,一旦超時,該筆交易就會自動被關閉。
model.setTimeoutExpress("30m");
//(是)銷售產品碼,商家和支付寶簽約的產品碼,爲固定值QUICK_MSECURITY_PAY
model.setProductCode("QUICK_MSECURITY_PAY");
request.setBizModel(model);
request.setNotifyUrl(AlipayUtil.ALIPAY_NOTIFYURL);
try {
//這裏和普通的接口調用不同,使用的是sdkExecute
AlipayTradeAppPayResponse responseStr = AlipayUtil.getAlipayClient().sdkExecute(request);
//可以直接給客戶端請求,無需再做處理。
map.put("msg", responseStr.getBody());
} catch (AlipayApiException e) {
log.info("AliPayOrder exception={}", e);
}
return map;
}
5.支付回調
@RequestMapping(value = "/aliPayNotify", method = RequestMethod.POST)
public String aliPayNotify(HttpServletRequest request) {
Map<String, String> params = Maps.newHashMap();
try {
//獲取支付寶POST過來反饋信息
Map requestParams = request.getParameterMap();
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] + ",";
}
//亂碼解決,這段代碼在出現亂碼時使用。
valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
}
//調用SDK驗證簽名
boolean flag = AlipaySignature.rsaCheckV1(params, AlipayUtil.ALIPAY_PUBLIC_KEY, AlipayUtil.CHARSET,
AlipayUtil.SIGN_TYPE);
if (flag) { // 驗證成功
return "success";
}
} catch (Exception e) {
log.info("aliPayNotify exception={}", e);
return "fail";
}
return "fail";
}
6.退款需要的參數類:
@NotNull(message = "缺少請求參數")
public BigDecimal refundAmount;
@NotNull(message = "缺少請求參數")
public String outTrandeNo;
@NotNull(message = "缺少請求參數")
public String tradeNo;
private String refundReason;
7.退款接口
/**
* 功能描述 退款申請
*
* @param reFundDTO
* @return Map<String,Object>
*/
@RequestMapping(value = "/aliPayRefund", method = RequestMethod.POST)
public Map<String, Object> aliPayRefund(@Valid @RequestBody ReFundDTO reFundDTO) {
Map map = Maps.newHashMap();
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
AlipayTradeRefundModel model = new AlipayTradeRefundModel();
// 退款金額
model.setRefundAmount(String.valueOf(reFundDTO.getRefundAmount()));
// 支付寶交易號
model.setTradeNo(reFundDTO.getTradeNo());
// 訂單支付時傳入的商戶訂單號
model.setOutTradeNo(reFundDTO.getOutTrandeNo());
if (StringUtils.isNotBlank(reFundDTO.getRefundReason())) {
// 退款原因
model.setRefundReason(reFundDTO.getRefundReason());
}
request.setBizModel(model);
try {
AlipayTradeRefundResponse response = AlipayUtil.getAlipayClient().execute(request);
map.put("response", URLDecoder.decode(response.getBody()));
return map;
} catch (AlipayApiException e) {
log.info("aliPayRefund exception={}", e);
e.printStackTrace();
}
return map;
}
8.開發環境僅僅可以測試一下下單接口,如下圖。
代碼的地址如下:
https://github.com/virtuousOne/pay