贴一下支付核心代码,以供后续参考:
业务层
import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; import com.alipay.api.DefaultAlipayClient; import com.alipay.api.domain.AlipayTradeAppPayModel; import com.alipay.api.internal.util.AlipaySignature; import com.alipay.api.request.AlipayTradeAppPayRequest; import com.alipay.api.request.AlipayTradeQueryRequest; import com.alipay.api.response.AlipayTradeAppPayResponse; import com.alipay.api.response.AlipayTradeQueryResponse; import com.aone.app.common.ali.pay.AlipayConfig; import com.aone.app.service.AliAppPayService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import java.util.HashMap; import java.util.Map; @Service public class AliAppAppPayServiceImpl implements AliAppPayService { private static final Logger logger = LoggerFactory.getLogger("AliAppAppPayServiceImpl"); /** * 预下单 * @param type * @param out_trade_no * @param money * @return */ public Map<String, String> aliPay(String type,String out_trade_no,String money){ Map map=new HashMap(); map.put("code", "201"); map.put("msg", "解析失败"); map.put("orderString", ""); //实例化客户端 AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL,AlipayConfig.APPID, AlipayConfig.PRIVATE_KEY,AlipayConfig.FORMAT,AlipayConfig.CHARSET,AlipayConfig.PUBLIC_KEY,AlipayConfig.SIGNTYPE); //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest(); //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。 AlipayTradeAppPayModel model = new AlipayTradeAppPayModel(); model.setBody("支付");//对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body。 model.setSubject("App支付宝支付");//商品的标题/交易标题/订单标题/订单关键字等 model.setOutTradeNo(out_trade_no);//商户网站唯一订单号 model.setTimeoutExpress("30m");//该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。 该参数数值不接受小数点, 如 1.5h,可转换为 90m。 //注:若为空,则默认为15d。 model.setTotalAmount("0.01");//订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000] model.setProductCode("QUICK_MSECURITY_PAY");//销售产品码,商家和支付宝签约的产品码,为固定值 QUICK_MSECURITY_PAY model.setPassbackParams(type); //公用参数(附加数据) request.setBizModel(model); request.setNotifyUrl(AlipayConfig.notify_url); try { //这里和普通的接口调用不同,使用的是sdkExecute AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request); //System.out.println(response.getBody());//就是orderString 可以直接给客户端请求,无需再做处理。 //@TODO 返回支付所需参数 map.put("code", "200"); map.put("msg", "ok"); map.put("orderString", response.getBody()); return map; } catch (AlipayApiException e) { e.printStackTrace(); } return map; } /** * 回调 * @param params */ public void notify(Map<String,String> params){ try { //调用SDK验证签名 boolean flag= AlipaySignature.rsaCheckV1(params, AlipayConfig.PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE); logger.info("验签结果:{}", flag); if(flag){ logger.info("支付状态为:{}", params.get("trade_status")); //签名通过 if("TRADE_SUCCESS".equals(params.get("trade_status"))){//支付成功 //付款金额 String amount = params.get("buyer_pay_amount"); //商户订单号 String out_trade_no = params.get("out_trade_no"); //支付宝交易号 String trade_no = params.get("trade_no"); //公用参数(附加数据) String passback_params = params.get("passback_params"); //@TODO 数据库操作 推送操作 if(StringUtils.isEmpty(passback_params)){ logger.info("附加数据类型为:{}", passback_params); }else{ //@TODO 预支付下单后回调的逻辑 } } } } catch (AlipayApiException e) { logger.info("==================验签失败 !"); e.printStackTrace(); } } }
控制层回调接口
/** * 支付宝支付异步结果通知 * @param request * @param response */ @RequestMapping(value = "aliPayNotify", method = {RequestMethod.GET, RequestMethod.POST}) public void aliPayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception{ System.out.print("支付宝回调开始"+" "); //获取支付宝POST过来反馈信息 Map<String,String> params = new HashMap<String,String>(); 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); } //@TODO 业务(调用业务层的回调,那里面处理业务逻辑) aliAppPayService.notify(params); System.out.print("支付宝回调结束"+" "); }
官方开发文档参考:https://docs.open.alipay.com/54/106370,如果代码有问题,参考官方文档。缺少其它东西参考支付宝手机网站支付。
开发过程中可能会出现:系统繁忙,请稍后再试。(ALIN10146),如果是这种错误的话,大概率配置的应用私钥和配置到蚂蚁金服上的应用公钥不匹配造成的,用RSA签名验签工具重新生成密钥后,使用工具上面的密钥匹配,成功后,再将应用公钥配置到平台上,重新拿新的支付宝公钥。