阿里支付筆記-移動應用和網頁支付Java後端實現

支付寶申請創建應用,獲取APPID、應用公鑰、應用私鑰、支付寶公鑰、商戶ID等。

具體可以參考官方文檔資料:https://opendocs.alipay.com/open

支付參數配置

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;

@Configuration
public class AlipayConfiguration {
	
	@Value("${alipay.gateway_url}")
    private String gatewayUrl = null;
	
    @Value("${alipay.app_id}")
    private String appId = null;
    
    @Value("${alipay.app_private_key}")
    private String appPrivateKey = null;
    
    @Value("${alipay.alipay_public_key}")
    private String alipayPublicKey = null;
    
    @Value("${alipay.method}")
    private String method = null;
    
    @Value("${alipay.version}")
    private String version = null;
    
    @Value("${alipay.format}")
    private String format = null;
    
    @Value("${alipay.charset}")
    private String charset = null;
    
    @Value("${alipay.sign_type}")
    private String signType = null;
    
    @Value("${alipay.timeout}")
    private String timeout = null;
    
    @Value("${alipay.product_code}")
    private String productCode = null;
    
    @Value("${alipay.seller_id}")
    private String sellerId = null;
    
    @Value("${alipay.seller_email}")
    private String sellerEmail = null;
    
    @Value("${alipay.return_url}")
    private String returnUrl = null;
    
    @Value("${alipay.notify_url}")
    private String notifyUrl = null;
    
    @Bean
    public AlipayClient alipayClient() {
        return new DefaultAlipayClient(gatewayUrl, appId, appPrivateKey, format, charset, alipayPublicKey, signType);
    }

	public String getGatewayUrl() {
		return gatewayUrl;
	}

	public String getAppId() {
		return appId;
	}

	public String getAppPrivateKey() {
		return appPrivateKey;
	}

	public String getAlipayPublicKey() {
		return alipayPublicKey;
	}

	public String getMethod() {
		return method;
	}

	public String getVersion() {
		return version;
	}

	public String getFormat() {
		return format;
	}

	public String getCharset() {
		return charset;
	}

	public String getSignType() {
		return signType;
	}

	public String getTimeout() {
		return timeout;
	}

	public String getProductCode() {
		return productCode;
	}

	public String getSellerId() {
		return sellerId;
	}

	public String getSellerEmail() {
		return sellerEmail;
	}

	public void setSellerEmail(String sellerEmail) {
		this.sellerEmail = sellerEmail;
	}

	public String getReturnUrl() {
		return returnUrl;
	}

	public String getNotifyUrl() {
		return notifyUrl;
	}

}

移動應用支付

接入流程可以參考官方文檔:https://opendocs.alipay.com/open/204/105297

@ApiV1RestController
public class AlipayController {
	
	private Logger LOG = LoggerFactory.getLogger(AlipayController.class);
	
	@Resource(name = "alipayTerminalService")
	private IAlipayService alipayTerminalService = null;
	
	@RequestMapping(value = "/recharge/alipay/terminal", method = RequestMethod.POST)
	public WebResult rechargeAlipayTerminal(Long rechargeItemId) {
		WebResult webResult = new WebResult();
		try {
			webResult.setCode(ResultCode.SUCCESS.getCode());
			webResult.setData(alipayTerminalService.mreadPaymentRequest(rechargeItemId));
		} catch (BusinessException be) {
			webResult.setCode(ResultCode.FAILURE.getCode());
			webResult.setFailure(be.getDefaultMessage());
		} catch (Exception e) {
			webResult.setCode(ResultCode.SYSTEM_IS_BUSY.getCode());
			webResult.setFailure(ResultCode.SYSTEM_IS_BUSY.getDesc());
		}
		return webResult;
	}
	
	@RequestMapping(value = "/recharge/alipay/terminal/notify", method = RequestMethod.POST)
	public void verifyAlipayTerminalNotify(HttpServletRequest request, HttpServletResponse response) {
		try {
			response.getWriter().write(alipayTerminalService.verifyPaymentNotifyCallback(request.getParameterMap()));
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
		}
	}

}
@Service("alipayTerminalService")
public class AlipayTerminalServiceImpl implements IAlipayService {

	private Logger LOG = LoggerFactory.getLogger(AlipayTerminalServiceImpl.class);
	
	@Autowired
	private AlipayConfiguration alipayConfiguration = null;
	
	@Resource(name = "rechargeItemService")
	private IRechargeItemService rechargeItemService = null;

	@Resource(name = "rechargeRecordService")
	private IRechargeRecordService rechargeRecordService = null;

	@Override
	public String mreadPaymentRequest(Long rechargeItemId) throws BusinessException {
		if (null == rechargeItemId) throw new BusinessException(ResultCode.PARAM_NULL);
		RechargeItem rechargeItem = rechargeItemService.readRechargeItemById(rechargeItemId);
		Map<String, String> params = new HashMap<String, String>();
		params.put("app_id", alipayConfiguration.getAppId());
		String outTradeNo = AlipayUtils.genOutTradeNo();
		params.put("biz_content", genBizContent(rechargeItem.getPresentPrice(), 
			rechargeItem.getName(), rechargeItem.getDesc(), outTradeNo));
		params.put("method", alipayConfiguration.getMethod());
		params.put("charset", alipayConfiguration.getCharset());
		params.put("version", alipayConfiguration.getVersion());
		params.put("sign_type", alipayConfiguration.getSignType());
		params.put("notify_url", alipayConfiguration.getNotifyUrl());
		params.put("timestamp", DateFormatter.TIME.get().format(new Date()));
		try {
			String sign = AlipaySignature.rsa256Sign(AlipaySignature.getSignContent(params),
				alipayConfiguration.getAppPrivateKey(), alipayConfiguration.getCharset());
			params.put("sign", sign);
		} catch (AlipayApiException e) {
			throw new BusinessException(ResultCode.ALIPAY_SIGN_EXCEPTION);
		} 
		
		insertRechargeRecord(rechargeItem, outTradeNo, params);
		
		List<Map.Entry<String, String>> rparams = new ArrayList<Map.Entry<String, String>>(params.entrySet());
		Collections.sort(rparams, new Comparator<Map.Entry<String, String>>() {
			@Override
			public int compare(Entry<String, String> o1, Entry<String, String> o2) {
				return o1.getKey().compareTo(o2.getKey());
			}
		});
		StringBuilder sb = new StringBuilder();
		try {
			for (Map.Entry<String, String> entry : rparams) {
				sb.append(entry.getKey() + "=" + URLEncoder.encode(entry.getValue(), alipayConfiguration.getCharset()) + "&");
			}
		} catch (UnsupportedEncodingException e) {
			LOG.error(e.getMessage(), e);
		}
		String result = sb.length() > 0 ? sb.deleteCharAt(sb.length() - 1).toString() : "";
		LOG.info("ali payment request params: {}", result);
		return result;
	}

	@Override
	public String verifyPaymentReturnCallback(Object callbackParams) throws BusinessException {
		return null;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public String verifyPaymentNotifyCallback(Object callbackParams) throws BusinessException {
		Map<String, String[]> requestParams = (Map<String, String[]>) callbackParams;
		Map<String, String> notifyParams = new HashMap<String, String>();
		try {
			for (Map.Entry<String, String[]> entry : requestParams.entrySet()) {
				String paramKey = entry.getKey();
				notifyParams.put(paramKey, "sign".equals(paramKey) ? entry.getValue()[0] : 
					URLDecoder.decode(entry.getValue()[0], alipayConfiguration.getCharset()));
			}
		} catch (UnsupportedEncodingException e) {
			LOG.error(e.getMessage(), e);
		}
		try {
			if (!AlipaySignature.rsaCheckV1(notifyParams, alipayConfiguration.getAlipayPublicKey(), 
					alipayConfiguration.getCharset(), notifyParams.get("sign_type"))) {
				LOG.error("Alipay Signature Failure!");
				return "FALSE";
			}
		} catch (AlipayApiException e) {
			LOG.error(e.getMessage(), e);
			return "FALSE";
		}
		if (!judgeParam(notifyParams, "seller_id", alipayConfiguration.getSellerId()) ||
				!judgeParam(notifyParams, "seller_email", alipayConfiguration.getSellerEmail()) ||
					!judgeParam(notifyParams, "app_id", alipayConfiguration.getAppId())) {
			LOG.error("notify verify seller_id {} or seller_email {} or app_id {} error",
				notifyParams.get("seller_id"), notifyParams.get("seller_email"), notifyParams.get("app_id"));
			return "FALSE";
		}
		String totalAmountTxt = notifyParams.get("total_amount");
		if (null == totalAmountTxt || "".equals(totalAmountTxt)) return "FALSE";
		String outTradeNo = notifyParams.get("out_trade_no");
		RechargeRecord rechargeRecord = rechargeRecordService.readRechargeRecordByOutTradeNo(outTradeNo);
		if (null == rechargeRecord || !rechargeRecord.getTotalMoney().equals(
				Double.parseDouble(totalAmountTxt))) {
			LOG.error("charging record: {}", rechargeRecord);
			LOG.error("{} , {}", rechargeRecord.getTotalMoney(), totalAmountTxt);
			return "FALSE";
		}
		updateRechargeRecord(rechargeRecord, notifyParams);
		return "SUCCESS";
	}
	
	/** 阿里APP支付字符串組合 */
	private String genBizContent(Double totalMoney, String subject, String body, 
			String outTradeNo) throws BusinessException {
		String bizContent = "" + "{\"timeout_express\":\"" + alipayConfiguration.getTimeout() + "\"," 
			+ "\"seller_id\":\"\"," + "\"product_code\":\"" + alipayConfiguration.getProductCode() + "\"," 
				+ "\"total_amount\":\"" + totalMoney + "\"," + "\"subject\":\"" + subject + "\"," + "\"body\":\"" 
					+ body + "\"," + "\"out_trade_no\":\"" + outTradeNo + "\"}";
		return bizContent;
	}
	
	/** 新增充值記錄 */
	private void insertRechargeRecord(RechargeItem rechargeItem, String outTradeNo, Map<String, String> params) {
		RechargeRecord rechargeRecord = new RechargeRecord();
		rechargeRecord.setUserId(WebUtils.getCurrentUserId());
		rechargeRecord.setTotalMoney(rechargeItem.getPresentPrice());
		rechargeRecord.setRechargeItem(GsonUtils.builder().toJson(rechargeItem));
		rechargeRecord.setChannel("alipay");
		rechargeRecord.setOutTradeNo(outTradeNo);
		rechargeRecord.setSign(params.get("sign"));
		rechargeRecord.setRechargeNote(GsonUtils.fromMapExtToJson(params));
		rechargeRecord.setTradeStatus(TradeStatus.INITIAL.value());
		rechargeRecord.setInsertTime(new Date());
		rechargeRecordService.insert(rechargeRecord);
	}
	
	private boolean judgeParam(Map<String, String> params, String paramKey, String targetValue) {
		String paramValue = params.get(paramKey);
		return (null != paramValue && !"".equals(paramValue) && paramValue.equals(targetValue)) ? true : false;
	}
	
	/** 更新充值記錄 */
	private void updateRechargeRecord(RechargeRecord rechargeRecord, Map<String, String> notifyParams) {
		String dbTradeStatus = rechargeRecord.getTradeStatus();
		if (TradeStatus.judgeIn(dbTradeStatus, TradeStatus.SUCCESS, TradeStatus.FINISHED)) return;
		RechargeRecord updateRechargeRecord = new RechargeRecord();
		updateRechargeRecord.setUserId(rechargeRecord.getUserId());
		updateRechargeRecord.setOutTradeNo(rechargeRecord.getOutTradeNo());
		updateRechargeRecord.setTradeNo(notifyParams.get("trade_no"));
		updateRechargeRecord.setResultNote(GsonUtils.fromMapExtToJson(notifyParams));
		updateRechargeRecord.setTradeStatus(TradeStatus.convert(notifyParams.get("trade_status")));
		rechargeRecordService.update(updateRechargeRecord); 
	}
	
}

網頁支付

接入流程可以參考官方文檔:https://opendocs.alipay.com/open/270/105899

@ApiV1RestController
public class AlipayController {
	
	private Logger LOG = LoggerFactory.getLogger(AlipayController.class);
	
	@Resource(name = "alipayWebPageService")
	private IAlipayService alipayWebPageService = null;
	
	@RequestMapping(value = "/recharge/alipay/webpage", method = RequestMethod.POST)
	public void rechargeAlipayWebPage(Long rechargeItemId, HttpServletResponse response) {
		try {
			response.setContentType("text/html;charset=utf-8");
			response.getWriter().write(alipayWebPageService.mreadPaymentRequest(rechargeItemId));
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
		}
	}
	
	@RequestMapping(value = "/recharge/alipay/webpage/return", method = RequestMethod.POST)
	public void verifyAlipayWebPageReturn(HttpServletRequest request, HttpServletResponse response) {
		try {
			LOG.info("payment return invoked!");
			alipayWebPageService.verifyPaymentNotifyCallback(request.getParameterMap());
			response.getWriter().write("SUCCESS");
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
		}
	}

	@RequestMapping(value = "/recharge/alipay/webpage/notify", method = RequestMethod.POST)
	public void verifyAlipayWebPageNotify(HttpServletRequest request, HttpServletResponse response) {
		try {
			LOG.info("payment notify invoked!");
			alipayWebPageService.verifyPaymentNotifyCallback(request.getParameterMap());
			response.getWriter().write("SUCCESS");
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
		}
	}
	
}
@Service("alipayWebPageService")
public class AlipayWebPageServiceImpl implements IAlipayService {

	private Logger LOG = LoggerFactory.getLogger(AlipayWebPageServiceImpl.class);
	
	@Autowired
	private AlipayClient alipayClient = null;

	@Autowired
	private AlipayConfiguration alipayConfiguration = null;
	
	@Resource(name = "rechargeItemService")
	private IRechargeItemService rechargeItemService = null;
	
	@Resource(name = "rechargeRecordService")
	private IRechargeRecordService rechargeRecordService = null;
	
	@Override
	public String mreadPaymentRequest(Long rechargeItemId) throws BusinessException {
		if (null == rechargeItemId) throw new BusinessException(ResultCode.PARAM_NULL);
		
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setApiVersion(alipayConfiguration.getVersion());
        // 同步通知路徑
        alipayRequest.setReturnUrl(alipayConfiguration.getReturnUrl());
        // 異步通知路徑
        alipayRequest.setNotifyUrl(alipayConfiguration.getNotifyUrl());

        RechargeItem rechargeItem = rechargeItemService.readRechargeItemById(rechargeItemId);
        String outTradeNo = AlipayUtils.genOutTradeNo();
        // 業務參數
        Map<String, String> params = new HashMap<String, String>(16);
        params.put("out_trade_no", outTradeNo);
        params.put("total_amount", String.format("%.2f", rechargeItem.getPresentPrice()));
        params.put("subject", rechargeItem.getName());
        params.put("body", rechargeItem.getDesc());
        params.put("product_code", "FAST_INSTANT_TRADE_PAY");
        params.put("passback_params", "");
        alipayRequest.setBizContent(GsonUtils.fromMapExtToJson(params));
        
        String result = "";
        try{
            AlipayTradePagePayResponse alipayResponse = alipayClient.pageExecute(alipayRequest);
            if(alipayResponse.isSuccess()) {
            	result = alipayResponse.getBody();
            	insertRechargeRecord(rechargeItem, outTradeNo, params);
            } else {
                LOG.error("payment form error : {}", alipayResponse.getSubMsg());
                result = "ERROR";
            }
        } catch (Exception e) {
            LOG.error(" payment error : {}", e.getMessage());
            e.printStackTrace();
        }
		return result;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public String verifyPaymentReturnCallback(Object callbackParams) throws BusinessException {
		Map<String, String[]> requestParams = (Map<String, String[]>) callbackParams;
		Map<String, String> notifyParams = new HashMap<String, String>();
		try {
			for (Map.Entry<String, String[]> entry : requestParams.entrySet()) {
				String paramKey = entry.getKey();
				notifyParams.put(paramKey, "sign".equals(paramKey) ? entry.getValue()[0] : 
					URLDecoder.decode(entry.getValue()[0], "UTF-8"));
			}
		} catch (UnsupportedEncodingException e) {
			LOG.error(e.getMessage(), e);
		}
		LOG.info("notifyParams {}", GsonUtils.builder().toJson(notifyParams));
		return "SUCCESS";
	}

	@SuppressWarnings("unchecked")
	@Override
	public String verifyPaymentNotifyCallback(Object callbackParams) throws BusinessException {
		Map<String, String[]> requestParams = (Map<String, String[]>) callbackParams;
		Map<String, String> notifyParams = new HashMap<String, String>();
		try {
			for (Map.Entry<String, String[]> entry : requestParams.entrySet()) {
				String paramKey = entry.getKey();
				String[] values = entry.getValue();
			    String valueStr = "";
			    for (int i = 0; i < values.length; i++) {
			        valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			    }
				notifyParams.put(paramKey, "sign".equals(paramKey) ? valueStr : URLDecoder.decode(valueStr, "UTF-8"));
			}
		} catch (UnsupportedEncodingException e) {
			LOG.error(e.getMessage(), e);
		}
		LOG.info("notifyParams {}", GsonUtils.builder().toJson(notifyParams));
		try {
			if (!AlipaySignature.rsaCheckV1(notifyParams, alipayConfiguration.getAlipayPublicKey(), 
					alipayConfiguration.getCharset(), notifyParams.get("sign_type"))) {
				LOG.error("Alipay Signature Failure!");
				return "FALSE";
			}
		} catch (AlipayApiException e) {
			LOG.error(e.getMessage(), e);
			return "FALSE";
		}
		if (!judgeParam(notifyParams, "seller_id", alipayConfiguration.getSellerId()) ||
				!judgeParam(notifyParams, "app_id", alipayConfiguration.getAppId())) {
			LOG.error("notify verify seller_id {} or auth_app_id {} error",
				notifyParams.get("seller_id"), notifyParams.get("auth_app_id"));
			return "FALSE";
		}
		String buyerPayAmountTxt = notifyParams.get("buyer_pay_amount");
		if (null == buyerPayAmountTxt || "".equals(buyerPayAmountTxt)) return "FALSE";
		String outTradeNo = notifyParams.get("out_trade_no");
		RechargeRecord rechargeRecord = rechargeRecordService.readRechargeRecordByOutTradeNo(outTradeNo);
		if (null == rechargeRecord || !rechargeRecord.getTotalMoney().equals(
				Double.parseDouble(buyerPayAmountTxt))) {
			LOG.error("charging record: {}", rechargeRecord);
			LOG.error("{} , {}", rechargeRecord.getTotalMoney(), buyerPayAmountTxt);
			return "FALSE";
		}
		updateRechargeRecord(rechargeRecord, notifyParams);
		return "SUCCESS";
	}
	
	/** 新增充值記錄 */
	private void insertRechargeRecord(RechargeItem rechargeItem, String outTradeNo, Map<String, String> params) {
		RechargeRecord rechargeRecord = new RechargeRecord();
		rechargeRecord.setUserId(WebUtils.getCurrentUserId());
		rechargeRecord.setTotalMoney(rechargeItem.getPresentPrice());
		rechargeRecord.setRechargeItem(GsonUtils.builder().toJson(rechargeItem));
		rechargeRecord.setChannel("alipay");
		rechargeRecord.setOutTradeNo(outTradeNo);
		rechargeRecord.setSign(params.get("sign"));
		rechargeRecord.setRechargeNote(GsonUtils.fromMapExtToJson(params));
		rechargeRecord.setTradeStatus(TradeStatus.INITIAL.value());
		rechargeRecord.setInsertTime(new Date());
		rechargeRecordService.insert(rechargeRecord);
	}
	
	private boolean judgeParam(Map<String, String> params, String paramKey, String targetValue) {
		String paramValue = params.get(paramKey);
		return (null != paramValue && !"".equals(paramValue) && paramValue.equals(targetValue)) ? true : false;
	}
	
	/** 更新充值記錄 */
	private void updateRechargeRecord(RechargeRecord rechargeRecord, Map<String, String> notifyParams) {
		String dbTradeStatus = rechargeRecord.getTradeStatus();
		if (TradeStatus.judgeIn(dbTradeStatus, TradeStatus.SUCCESS, TradeStatus.FINISHED)) return;
		RechargeRecord updateRechargeRecord = new RechargeRecord();
		updateRechargeRecord.setUserId(rechargeRecord.getUserId());
		updateRechargeRecord.setOutTradeNo(rechargeRecord.getOutTradeNo());
		updateRechargeRecord.setTradeNo(notifyParams.get("trade_no"));
		updateRechargeRecord.setResultNote(GsonUtils.fromMapExtToJson(notifyParams));
		updateRechargeRecord.setTradeStatus(TradeStatus.convert(notifyParams.get("trade_status")));
		rechargeRecordService.update(updateRechargeRecord); 
	}
	
}

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章