下面使用沙箱環境來測試
首先導入支付寶的依賴再開始工作:
<!-- 引入支付寶-->
<!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-easysdk -->
<!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java -->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.4.27.ALL</version>
</dependency>
1.填支付寶商戶配置,直接創建類來測,也可以獲取application配置,這里就用配置類讀取
下面的配置密鑰等經過處理,不能直接使用。
*/
public class AliPayConfig {
// 商戶APPID
public static String APPID="2021000118697085";//
// 應用私鑰pkcs8
public static String RSA_PRIVATE_KEY="MIIEvwIBADANBgkqtvyqkneOovUGnE0Q8KK5wwQQkw0zsjwvKn7MRbZJZmAUDavC6zEzHHyeJvuIkMtJIlE4eiwUAc2GT8/Kp/Fzs/CWWoWhecrdB2xDm/KsJFZ22cxpFvpeDKrAh+E2SAsqwEWXSSobTeyTUqpPFyiHQh5kw53is543nAWMQ6J02ls7RiHjn8uZkaPEodrzRSw4ScFe80kfktZ+77pqrTdJId2bvQ1gvF2AILBanBFB4RsVQxZ8SIvceaC6rvFolf6639cHWzMPZ43hqG63UwCcShTnWa7cdB2nQDWOHZW6lKDaQMk05AgMBAAECggEAW3p+yfYD0G9whDQddoizm+wOYG6iJirmggwIOz0Qwb6j0HxTzVzKsk58ZAOl0IluD51fttn2G7XtBI+TIoqYyXpRttx1J6k2Hj0HLpza7z1PAuqJ2PY4SYNE+QwCKfLZxNr7Vk9+hr+phzDwR803gh3sFwCvJfhR+jEtYu60KUfDxvUDdhqETwx16iZSaZA7FHpdiwoQtTNWSnontOJ7Vb0+9R+bsiDzVpINFUyp0aRffxqImjA6rtUE7qeGNlZMQw4OKF7qd3J4SKRgBgEt4UQW+LMupo9pPUulN7Xbd4RjUrerefywyVp2NTR67JP1eKMzOlN/sW/C66IWvmomwQKBgQDK8bopRwXD8h6pVa8hagcvOfZ0SNWo3gaHmXW7bHcK/x7QtVfN0A/NEFKT+VBOBKTJ1kpWJhZSHFCwLH6Qh5IJx/QPBbs0593wmV/kUE2XfQx4gfv09pviQd0HkPcXuUU01SAqfr/KAc0WZL8DIBVO67q7tGz6lp/2/a+YeY6KWwKBgQC1BsL6TwEbqAjH23HVgp6RMLoVXmTRDFN0PgVpx6QCAflQTSCGwQnbUGFEObcJCyLleWy1/v6wGgVYmcmlsF3aQhxyHCWpn/1kgkSoEjU8aiGfFYvZdsfu8CfI9TecNXQtUg3t0swWYQxdKERmKQ8dTkSqZbVttu1YgOh5anbS+wKBgQC8K5Hu//lqi66+V8JAey0aLuZDP91L7EGlrTaqh5GBUrfh0KMPJCHig4XtyjcZf9jDhLv8UOhVTgfKshbQL8PK6elznF7OWUdB9RQigArRsZLEkdFqetZi3arxfwp8pr5ylEJ05H0z8qOUZeluHmtjd9L2g/6gAtVjkCkmeV8fDQKBgQCqgJ7eodD6Wo9CpocWQbvWJp3uCIVOfJyR7OSuWBI6rd9D6hELuv/sqE2ks/OYuft5RZ/F31HFTgzhAaByxaXwL7qZI7e5h25j32qJHvUzXQcjzmh1P7Jac6oVVhm1sIcnNJTX/mapYWkCyS17R4rr4E8+ayOyHcx5Qpkz2rnmRwKBgQC3/0/yAJgUy8J7oe7PLNokAtIYH+2FzIML5aMF6azvjn/vyl/dkBfaMQ8bLzlwrLBV6SzO4ZtBtVoGI1iPZQfE7zs30i1Mk4A/wa5fEigQDnJPpvEvLQR5zc79mrXjUQ4hAU02yU5YKdm4VPvGWky5sLCzZO6o2xbq8AB8n9/w+A==";//真實
// 服務器異步通知頁面 http://或者https://完整路徑 必須外網可以訪問
public static String notify_url="http://127.0.0.1:9090/alipaynotify";
// 同步通知路徑,支付后頁面跳轉
public static String return_url="https://www.baidu.com";
// 請求網關地址
public static String server_URL="https://openapi.alipaydev.com/gateway.do";//
// 編碼
public static String CHARSET="UTF-8";
// 返回格式
public static String FORMAT="json";
// 支付寶公鑰
public static String ALIPAY_PUBLIC_KEY="MIIBIjANBg+ZYyU4gE0CByQFxVkHsXtA5xDSqVydqPER9f5Pz+fEnkqU48njGCQvSWxpOdDTArgq5ub9r+rIEYyzPedpcV3Y5yEY+8WKFr+HRdsax7LtuXOC7aws7mu6k4EfaqWs+zYKQJ8P/t+anPRF673o+MvWh/DK4L0vGM5BW7vY5FAf0NrGDMfbyDqh2Cp0HUXGImnuBp1+s3FpCb/1BHgTITHITwijKZZlWVUxTFenwcXGFC5aDA5ep0d9sR0Vif7Nn/JpjjCtda0CgmYBhqAHKLk9eH6hhIbQAowcMVDGNYFETVV20OxWwIDAQAB";//真實
// RSA2
public static String SIGNTYPE="RSA2";
}
2.接口接收參數
@Data
@AllArgsConstructor
@NoArgsConstructor
public class QrPayParam {
// @NotNull(message = "流水單號不能空")
// String out_trade_no;
@NotNull(message = "商品名稱不能空")
String subject;
@NotNull(message = "付款金額不能空")
String total_amount;
String body;
// @NotNull(message = "二維碼過期時間不能空")
// String timeout_express;
// @NotNull(message = "產品碼不能空")
// String product_code;
}
3.controller
下面是簡單的接口
@ResponseBody
@PostMapping("/pay")
public HashMap<String, Object> pay(@RequestBody QrPayParam param) throws AlipayApiException {
Integer uid = LocalUser.getUid();
AliPayConfig aliPayConfig = new AliPayConfig();
AlipayClient alipayClient = new DefaultAlipayClient(aliPayConfig.server_URL,
aliPayConfig.APPID,aliPayConfig.RSA_PRIVATE_KEY,aliPayConfig.FORMAT,aliPayConfig.CHARSET,
aliPayConfig.ALIPAY_PUBLIC_KEY,aliPayConfig.SIGNTYPE);
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
String idStr = IdUtil.getSnowflakeNextIdStr();//生成的流水號
model.setOutTradeNo(idStr);//設置商家這邊的流水單號 后台寫
model.setSubject(param.getSubject());//設置商品名稱
model.setTotalAmount(param.getTotal_amount());//設置付款金額
model.setBody(param.getBody());//設置商品描述
model.setTimeoutExpress("10m");//設置過期時間 格式:xxm 后台寫
// model.setProductCode(qrPayParam.getProduct_code());//設置產品碼 - 二維碼支付的話沒有該功能
request.setBizModel(model);//存入請求信息
request.setNotifyUrl(aliPayConfig.notify_url);//設置通知地址
request.setReturnUrl(aliPayConfig.return_url);//設置返回地址,二維碼支付此功能無效
// 生成表單,二維碼支付無表單
// String form = alipayClient.pageExecute(request).getBody();
// 封裝生成請求對象
AlipayTradePrecreateResponse response = alipayClient.execute(request);
// 發送請求,獲取返回信息
System.out.println(response.getBody());
HashMap<String, Object> map = new HashMap<>();
// 成功
if (response.isSuccess()){
System.out.println("調用成功");
JSONObject responJson = JSONUtil.parseObj(response.getBody());
JSONObject rsj = (JSONObject)responJson.get("alipay_trade_precreate_response");
String qr_code = (String) rsj.get("qr_code");//獲取二維碼地址
map.put("qrcode",qr_code);
map.put("out_trade_no",idStr);
return map;
}else {
JSONObject responJson = JSONUtil.parseObj(response.getBody());
JSONObject rsj = (JSONObject)responJson.get("alipay_trade_precreate_response");
String res = (String) rsj.get("sub_msg");//獲取返回錯誤的信息
map.put("sub_msg",res);
return map;
}
}
4.異步通知接口
用戶支付成功后(當面付只有成功支付后支付寶才向該地址發送通知,所以當有請求給這個地址,就表明有用戶掃碼支付了),支付寶會向該地址發送請求,下面只接收處理兩個參數,
還有更多的參數可以看:https://opendocs.alipay.com/open/194/103296
按照自己需求接收處理。下面的代碼只是簡單調用,沒有進行二次校驗密鑰,可能存在安全性問題,請查看支付寶的開發文檔接收參數驗證增加安全性。
// 接收異步消息並同步訂單狀態
@PostMapping("/alipaynotify")
public ApiRequest getnotify(String trade_no, String out_trade_no){
LambdaQueryWrapper<QrPay> wr = new LambdaQueryWrapper<QrPay>().eq(QrPay::getOutTradeNo, out_trade_no);
QrPay order = payService.getOne(wr);
System.out.println(order);
order.setState(1);
order.setPaytime(new DateTime().toString());
order.setTradeNo(trade_no);
System.out.println(order.getOutTradeNo());
boolean update = payService.update(order, wr);//提交修改訂單狀態
Integer uid = order.getUid();
LambdaQueryWrapper<User> userwr = new LambdaQueryWrapper<User>().eq(User::getId, uid);
User user = userService.getOne(userwr);
BigDecimal money = user.getMoney();//現在余額
System.out.println("現在余額:" +money);
System.out.println("開始加魚兒---"+ order.getTotalAmount().toString());
BigDecimal newmonry = new BigDecimal( money.add(order.getTotalAmount()).toString());//現在余額加上充值金額
System.out.println("新余額:"+newmonry);
user.setMoney(newmonry);
userService.update(user,userwr);
return ApiRequest.ok(update);
}
當發送請求成功后,支付寶會返回一個成功信息,里面含有當面付二維碼地址,需要獲取后返回給前端,前端頁面生成二維碼,用戶掃碼支付成功后,支付寶會異步回調你設置的接口地址。