1、概念
电脑网站支付,也称扫码支付,是专门针对PC端业务而开发的一种支付方式,既有支付宝提供在网页展示一个动态生成的支付二维码,用户通过手机支付宝扫码以后可实现支付功能的一种支付方式。
2、创建应用
登录支付宝开放平台(open.alipay.com),创建应用,应用审核通过会生成一个APPID。
3、签约电脑网站支付功能
在 能力列表 中点击 添加能力来添加电脑网站支付功能,并签约方可调用
4、配置应用公钥和应用私钥
参考文档,非常详细https://opendocs.alipay.com/open/270/105899
5、接入SDK
/**
* 电脑网站支付
* https://docs.open.alipay.com/270/105899/
* @paramhttpResponse
* @throws ServletException
* @throws IOException
*/
public static void pcWebPay(String amount,HttpServletResponse httpResponse) {
AlipayClient alipayClient = new DefaultAlipayClient(URL, APP_ID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE); //获得初始化的AlipayClient
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();//创建API对应的request
alipayRequest.setReturnUrl("https://www.baidu.com");
alipayRequest.setNotifyUrl("https://xxx.xxx.com/abc/alipay/pcWebPayCallBack");//在公共参数中设置回跳和通知地址
alipayRequest.setBizContent("{" +
" \"out_trade_no\":\""+System.currentTimeMillis()+"\"," +
" \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," +
" \"total_amount\":"+amount+"," +
" \"subject\":\"Iphone6 16G\"," +
" \"body\":\"Iphone6 16G\"," +
" \"passback_params\":\"123&456&789"," +
" \"extend_params\":{" +
" \"sys_service_provider_id\":\""+System.currentTimeMillis()+"\"" +
" }"+
" }");//填充业务参数
try {
String form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单
httpResponse.setContentType("text/html;charset=" + CHARSET);
httpResponse.getWriter().write(form);//直接将完整的表单html输出到页面
httpResponse.getWriter().flush();
httpResponse.getWriter().close();
} catch (AlipayApiException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 扫码支付回调 当收银台调用预下单请求API生成二维码展示给用户后,用户通过手机扫描二维码进行支付,支付宝会将该笔订单的变更信息,沿着商户调用预下单请求时所传入的通知地址主动推送给商户。
* 通知参数说明 https://docs.open.alipay.com/194/103296/
* 程序执行完后必须打印输出“success”(不包含引号)。如果商户反馈给支付宝的字符不是 success 这7个字符,支付宝服务器会不断重发通知,直到超过24小时22分钟。一般情况下,25小时以内完成8次通知(通知的间隔频率一般是:4m,10m,10m,1h,2h,6h,15h);
* 程序执行完成后,该页面不能执行页面跳转。如果执行页面跳转,支付宝会收不到 success 字符,会被支付宝服务器判定为该页面程序运行出现异常,而重发处理结果通知;
* @paramalipayPublicKey
* @paramrequest
* @return
*/
public static void qrcodePayCallBack(String alipayPublicKey, HttpServletRequest request, HttpServletResponse response) {
Map<String, String> result = 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");
result.put(name, valueStr);
}
//支付宝交易凭证号
String tradeNo = result.get("trade_no");
//原支付请求的商户订单号
String outTradeNo = result.get("out_trade_no");
String appId = result.get("app_id");
String sellerId = result.get("seller_id");
String totalAmount = result.get("total_amount");
String body = result.get("body");
logger.info("tradeNo=={},outTradeNo=={},appId=={},sellerId=={},totalAmount=={},body=={}",tradeNo,outTradeNo,appId,sellerId,totalAmount,body);
//切记alipaypublickey是支付宝的公钥,请去open.alipay.com对应应用下查看。
try {
boolean flag = AlipaySignature.rsaCheckV1(result, alipayPublicKey, CHARSET, SIGN_TYPE);
logger.info("支付宝回调结果===========" + flag);
if (flag) {
logger.info("支付宝回调success===========");
toAliPayResult = "success";
} else {
logger.info("支付宝回调failure===========");
toAliPayResult = "failure";
}
//用字节流形式打印success,解决支付宝重复回调
BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
out.write(toAliPayResult.getBytes());
out.flush();
out.close();
} catch (AlipayApiException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
6、测试