最近公司开发一个一码多付的功能,就是一张二维码能够实现多种支付工具的支付,大致思想可以参照支付宝的这边文档点击打开链接。吐槽下支付宝的开发文档写的真的比微信的好。
具体就是由app产生二维码,链接指向后台处理,链接可以带个订单号等与你业务有关的参数。然后判断扫码客户端来返回各自的支付链接。
String out_trade_no=req.getParameter("out_trade_no");
String user_agent=req.getHeader("user-agent");
if(user_agent.indexOf("MicroMessenger")!=-1){ //微信
return "redirect:weixin://wxpay/s/An4baqw";
}else if (user_agent.indexOf("AlipayClient")!=-1) { //支付宝
return "redirect:https://qr.alipay.com/bavh4wjlxf12tper3a";
}
return "redirect:可以返回到你写的一个页面或者你公司的官网";//即非支付app扫码时
真的比较详细,按照他的步骤一部一部来就行了,这里就不讲申请和配置了,主要就是需要配一个密钥,他都有很详细的说明,说下代码部分。
首先你需要下载这个sdk引入你的项目。
然后你可以看这个文档。点击打开链接,这个文档详细的介绍了各个传参的意思,以及返回值,以下是生产二维码支付链接的代码实现:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time_expire= sdf.format(System.currentTimeMillis()+24*60*60*1000);
StringBuilder sb = new StringBuilder();
sb.append("{\"out_trade_no\":\"" + out_trade_no + "\","); //订单编号
sb.append("\"total_amount\":\""+total_amount+"\","); //订单价格
sb.append("\"subject\":\""+subject+"\",\"body\":\"订单扫码支付\",");
sb.append("\"store_id\":\""+store_id+"\",");
sb.append("\"time_expire\":\""+time_expire+"\"}");
AlipayClient alipayClient =new DefaultAlipayClient(AlipayConfig.ALIPAY_GATEWAY, AlipayConfig.APP_ID,
AlipayConfig.private_key, "json","utf-8",AlipayConfig.ali_public_key,AlipayConfig.sign_type);
// 使用SDK,构建群发请求模型
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
request.setBizContent(sb.toString());
request.setNotifyUrl("你的回调连接");
AlipayTradePrecreateResponse response = null;
// 使用SDK,调用交易下单接口
response = alipayClient
.execute(request);
log.info(response.getMsg());
// 这里只是简单的打印,请开发者根据实际情况自行进行处理
if (null != response && response.isSuccess()) {
if (response.getCode().equals("10000")) {
log.info("二维码值:"+response.getQrCode());
//商户将此二维码值生成二维码,然后展示给用户,用户用支付宝手机钱包扫码完成支付
} else {
//打印错误码
log.info("错误码:"+response.getSubCode());
log.info("错误描述:"+response.getSubMsg());
}
}
return response.getQrCode(); //这个就是支付宝的支付链接
好了你有了这个支付链接直接重定向过去就好了,然后重点讲下回调,回调的地址是上面设置好的。这里代码删除了部分,可能粘贴过去会跑不通,自行调整。参考这篇文档点击打开链接
log.info("============支付宝支付通知notifyAlipay===============");
try {
Map params = new HashMap();
Map requestParams = request.getParameterMap();
Iterator iter = requestParams.keySet().iterator();
while (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);
}
if (AlipayNotify.verify(params)) //需要链接到支付宝做一次验证
{
if (!trade_status.equals("WAIT_BUYER_PAY"))
{
if (trade_status.equals("TRADE_SUCCESS"))
{
//这里就表示支付成功执行自己的逻辑代码,记得这里需要返回success
result = "SUCCESS";
}
else if (trade_status.equals("TRADE_FINISHED"))
{
log.info("============TRADE_FINISHED===============");
}
}
PrintWriter out = response.getWriter();
out.println(result);
out.flush();
out.close();
}
else
{
log.info("============支付宝通知fail===============");
PrintWriter out = response.getWriter();
out.println("fail");
out.flush();
out.close();
}
} catch (Exception e) {
log.info("============支付宝通知fail===============");
e.printStackTrace();
}
public class AlipayNotify {
/**
* 支付宝消息验证地址
*/
private static final String HTTPS_VERIFY_URL = "https://mapi.alipay.com/gateway.do?service=notify_verify&";
/**
* 验证消息是否是支付宝发出的合法消息
* @param params 通知返回来的参数数组
* @return 验证结果
*/
public static boolean verify(Map params) {
//判断responsetTxt是否为true,isSign是否为true
//responsetTxt的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关
//isSign不是true,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关
String responseTxt = "true";
if(params.get("notify_id") != null) {
String notify_id = params.get("notify_id");
responseTxt = verifyResponse(notify_id);
}
String sign = "";
if(params.get("sign") != null) {sign = params.get("sign");}
boolean isSign = getSignVeryfy(params, sign);
if (isSign && responseTxt.equals("true")) {
return true;
} else {
return false;
}
}
/**
* 根据反馈回来的信息,生成签名结果
* @param Params 通知返回来的参数数组
* @param sign 比对的签名结果
* @return 生成的签名结果
*/
private static boolean getSignVeryfy(Map Params, String sign) {
//过滤空值、sign与sign_type参数
Map sParaNew = AlipayCore.paraFilter(Params);
//获取待签名字符串
String preSignStr = AlipayCore.createLinkString(sParaNew);
//获得签名验证结果
boolean isSign = false;
if(AlipayConfig.sign_type.equals("RSA")){
isSign = RSA.verify(preSignStr, sign, AlipayConfig.ali_public_key, AlipayConfig.input_charset);
}else if(AlipayConfig.sign_type.equals("RSA2")){
isSign = RSA.verify(preSignStr, sign, AlipayConfig.ali_public_key, AlipayConfig.input_charset,"SHA256WithRSA" );
}
return isSign;
}
/**
* 获取远程服务器ATN结果,验证返回URL
* @param notify_id 通知校验ID
* @return 服务器ATN结果
* 验证结果集:
* invalid命令参数不对 出现这个错误,请检测返回处理中partner和key是否为空
* true 返回正确信息
* false 请检查防火墙或者是服务器阻止端口问题以及验证时间是否超过一分钟
*/
private static String verifyResponse(String notify_id) {
//获取远程服务器ATN结果,验证是否是支付宝服务器发来的请求
String partner = AlipayConfig.partner;
String veryfy_url = HTTPS_VERIFY_URL + "partner=" + partner + "¬ify_id=" + notify_id;
return checkUrl(veryfy_url);
}
/**
* 获取远程服务器ATN结果
* @param urlvalue 指定URL路径地址
* @return 服务器ATN结果
* 验证结果集:
* invalid命令参数不对 出现这个错误,请检测返回处理中partner和key是否为空
* true 返回正确信息
* false 请检查防火墙或者是服务器阻止端口问题以及验证时间是否超过一分钟
*/
private static String checkUrl(String urlvalue) {
String inputLine = "";
try {
URL url = new URL(urlvalue);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection
.getInputStream()));
inputLine = in.readLine().toString();
} catch (Exception e) {
e.printStackTrace();
inputLine = "";
}
return inputLine;
}
}
验签代码
public static boolean verify(String preSignStr, String sign, String aliPublicKey, String inputCharset,
String string) {
try
{
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] encodedKey = Base64.decode(aliPublicKey);
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
java.security.Signature signature = java.security.Signature
.getInstance(string);
signature.initVerify(pubKey);
signature.update( preSignStr.getBytes(inputCharset) );
boolean bverify = signature.verify( Base64.decode(sign) );
return bverify;
}
catch (Exception e)
{
e.printStackTrace();
}
return false;
}
支付宝差不多就这样了,基本就能完成了,后面再说微信。