26、【支付模組開發】——支付寶回撥函式實現和查詢使用者訂單狀態介面編寫
阿新 • • 發佈:2018-11-01
####1、支付寶回撥函式實現
我們在除錯支付寶沙箱環境的時候,支護寶會有一個回撥函式,也就是在支付成功之後,可以呼叫我們支付之後需要執行的相關方法,從而達到資料庫的資料和我們的操作相統一。
首先我們先在本地將回調函式編寫好~
在OrderController
類中新建我們的支付寶回撥函式
*Controller
:
//支付寶回撥函式
@RequestMapping("alipay_callback.do")
@ResponseBody
public Object alipayCallback(HttpServletRequest request) {
Map< String, String> params= Maps.newHashMap();
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]+",";
}
params.put(name,valueStr);
}
logger.info("支付寶回撥, sign:{},trade_status:{},引數:{}",params.get("sign"),params.get( "trade_status"),params.toString());
//!!! 驗證回撥的正確性,是不是支付寶發了,而且還要避免重複通知
params.remove("sign_type");
try {
boolean alipayRSACheckedV2 = AlipaySignature.rsaCheckV2(params, Configs.getAlipayPublicKey(),"utf-8", Configs.getSignType());
if(!alipayRSACheckedV2){
return ServerResponse.createByErrorMessage("非法請求,驗證不通過");
}
} catch (AlipayApiException e) {
logger.info("支付寶回撥異常",e);
}
//TODO 驗證各種資料
ServerResponse serverResponse = iOrderService.aliCallback(params);
if(serverResponse.isSuccess()){
return Const.AlipayCallback.RESPONSE_SUCCESS;
}
return Const.AlipayCallback.RESPONSE_FAILED;
}
*Service
:
//支付寶的回撥通知介面
ServerResponse aliCallback(Map<String,String> params);
在Const
類中新增下面列舉函式:
public enum OrderStatusEnum{
CANCELED(0,"已取消"),
NO_PAY(10,"未支付"),
PAID(20,"已付款"),
SHIPPED(40,"已發貨"),
ORDER_SUCCESS(50,"訂單完成"),
OEDER_CLOSE(60,"訂單關閉");
OrderStatusEnum(int code,String value){
this.code=code;
this.value=value;
}
public enum PayPlatformEnum{
ALIPAY(1,"支付寶");
PayPlatformEnum(int code,String value){
this.code=code;
this.value=value;
}
private String value;
private int code;
public String getValue() {
return value;
}
public int getCode() {
return code;
}
}
*ServiceImpl
:
//支付寶的回撥通知介面
public ServerResponse aliCallback(Map<String,String> params){
// System.out.println("支付寶回撥");
//訂單號
Long orderNo = Long.parseLong(params.get("out_trade_no"));
//交易號
String tradeNo= params.get("trade_no");
//交易狀態
String tradeStatus = params.get("trade_status");
// System.out.println("tradeStatus:"+tradeStatus);
Order order = orderMapper.selectByOrderNo(orderNo);
if(order == null){
// System.out.println("order == null");
return ServerResponse.createByErrorMessage("非該商場的訂單,回撥忽略");
}
if(order.getStatus() >= Const.OrderStatusEnum.PAID.getCode()){
// System.out.println("支付寶重複呼叫");
return ServerResponse.createBySuccess("支付寶重複呼叫");
}
String su="TRADE_SUCCESS";
if(su.equals(tradeStatus)){
// System.out.println("開始更新為支付完成狀態");
order.setPaymentTime(DateTimeUtil.strToDate(params.get("gmt_payment")));
order.setStatus(Const.OrderStatusEnum.PAID.getCode());
orderMapper.updateByPrimaryKeySelective(order);
}
PayInfo payInfo =new PayInfo();
payInfo.setUserId(order.getUserId());
payInfo.setOrderNo(order.getOrderNo());
payInfo.setPayPlatform(Const.PayPlatformEnum.ALIPAY.getCode());
payInfo.setPlatformNumber(tradeNo);
payInfo.setPlatformStatus(tradeStatus);
payInfoMapper.insert(payInfo);
return ServerResponse.createBySuccess();
}
selectByOrderNo
這個方法需要我們自己編寫:
*Mapper
:
//根據訂單號來查詢訂單是否存在
Order selectByOrderNo(Long orderNo);
*Mappler.xml
:
<select id="selectByOrderNo" resultMap="BaseResultMap" parameterType="long" >
select
<include refid="Base_Column_List"/>
from mmall_order
where order_no=#{orderNo}
</select>
####2、查詢使用者訂單狀態介面
*Controller
:
//查詢使用者訂單狀態介面
@RequestMapping("query_order_pay_status.do")
@ResponseBody
public ServerResponse<Boolean> queryOrderPayStatus(HttpSession session,Long orderNo){
User user = (User) session.getAttribute(Const.CURRENT_USER);
if (user == null) {
return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(), ResponseCode.NEED_LOGIN.getDesc());
}
ServerResponse serverResponse = iOrderService.queryOrderPayStatus(user.getId(), orderNo);
if(serverResponse.isSuccess()){
return ServerResponse.createBySuccess(true);
}
return ServerResponse.createBySuccess(false);
}
*Service
:
//查詢訂單狀態的介面實現
ServerResponse queryOrderPayStatus(Integer userId,Long orderNo);
*ServiceImpl
:
//查詢訂單狀態的介面實現
public ServerResponse queryOrderPayStatus(Integer userId,Long orderNo){
Order order = orderMapper.selectByUserIdAndOrderNo(userId,orderNo);
if(order == null){
return ServerResponse.createByErrorMessage("使用者沒有該訂單");
}
if(order.getStatus()>=Const.OrderStatusEnum.PAID.getCode()){
return ServerResponse.createBySuccess();
}
return ServerResponse.createByError();
}
selectByUserIdAndOrderNo
是重用上面的方法,所以不再貼出來~
####3、介面測試
1、給沙箱環境配置我們的回撥地址:
開啟沙箱環境:https://openhome.alipay.com/platform/appDaily.htm
在圖上所示配置我們的回撥地址
由於我們是在本地開發,所以需要將本地IP對映到公網,
這個教程有講怎麼將本地IP對映到公網:https://blog.csdn.net/czjlghndcy/article/details/81130029
對映好公網IP之後,我們就將對應生成的共網IP以及定義的介面訪問地址貼上到沙箱環境中的回撥地址中即可~
測試介面:
支付一個未支付的:
對生成的二維碼進行支付
查詢訂單狀態:
顯示已支付,So,我們的回撥介面以及訂單狀態查詢介面測試成功啦