支付宝wap支付过程中需要注意的坑

1,首先本人使用的是新版即时到帐的接口文档开发。本人没有使用支付宝的sdk包,所有代码都有自己参考Sdk包自己编写。并且wap手机支付异步通知和同步通知(新版称前台回调),都集成在之前开发的电脑扫码支付的同步和异步通知。

2,加密算法使用了RSA2,并使用RSA2进行签名和验证签名,本人使用自定义签名和自定义验签。

3,开发过程中要走了不少弯路,特把自己遇到的坑梳理一下,供自己以后复习和大家参考:

      (1)首先使用支付宝提供的生产公钥和私钥的工具,并商家用户创建应用,上传了应用公钥到支付宝,如下图所示:

   

这里注意的是:(1)选择RSA(SHA256)密钥。(2)这里有个概念没弄明白,应用公钥和支付宝公钥的区别,但是一定要明白签名我们带着自己的应用私钥去签名,当验证签名时,我们使用的是支付宝公钥而非应用公钥,我就在这里吃大亏了。

(2)在签名时参数问题

        查看文档,当时没明白,分为公共参数,业务参数之分,起初以为只传递业务参数即可,后来仔细看文档,公共参数也需要传递,并且要把业务参数封装到公共参数 biz_content字段中,并且要转成json字符串格式。


(3)还是签名时,我们要对传递的参数进行encode编码,哥们啊,看清楚啊,是值不是参数,都是血和泪啊大哭,之前就是把这个参数都进行了encode编码。验证签名时要对参数值进行decode解码,才能验证成功。对于sign签名要对参数名按照ASCII码排序,之后进行base64.encodeBase64加密和验证签名时Base64.decodeBase64,支付宝SDK的签名方法中已经做了处理,不做解释。这里只贴出了签名时对参数名排序和对参数值的encode加码和验证签名时对参数名排序和对参数值的decode解码代码。

/**
     * 
     * 对签名后的请求参数值
     * (1)对key排序
     * (2)对value进行encode编码
     * (3)验证签名时对value进行decode解码
     * @param params
     * @param charset
     * @return
     * @throws IOException
     */
    public static String buildQuery(Putter p, String charset) throws IOException {
    	Map params = p.getMap();
        if (params == null || params.isEmpty()) {
            return null;
        }
        StringBuilder query = new StringBuilder();
        List keys = new ArrayList(params.keySet());
        Collections.sort(keys);
        boolean hasParam = false;
        if(p.get("sign")!=null && !p.get("sign").equals("")){  //签名时使用
        	for (int i = 0; i < keys.size(); i++) {
        		String name = (String) keys.get(i);
        		String value = (String) params.get(name);
        		// 忽略参数名或参数值为空的参数
        		if (areNotEmpty(name, value)) {
        			if (hasParam) {
        				query.append("&");
        			} else {
        				hasParam = true;
        			}
        			
        			query.append(name).append("=").append(URLEncoder.encode(value, charset));
        		}
        	}
        	
        }else{  //验证签名时使用
        	for (int i = 0; i < keys.size(); i++) {
        		String name = (String) keys.get(i);
        		String value = (String) params.get(name);
        		// 忽略参数名或参数值为空的参数
        		if (areNotEmpty(name, value)) {
        			if (hasParam) {
        				query.append("&");
        			} else {
        				hasParam = true;
        			}
        			query.append(name).append("=").append(URLDecoder.decode(value, charset));
        		}
        	}
        	
        }

        return query.toString();
    }

(4)支付成功后,只要签名和验签没问题,没有什么好说的,可说的就是前台回调(即同步通知),之前总是不能跳转,看文档说是返回的json格式,说是和异步通知验签不同,其实是相同的,表面上的几点不同如下:

             (1) 参数名变更了,旧版的交易金额使用total_fee,新版现在使用total_amount

            (2)  名称改名,前台回调

            (3)  看文档返回的是json格式数据,但是在处理时,还是可以使用如下代码:

    
      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] + ",";
		}
		//乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
		valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
		params.put(name, valueStr);
	}
获取数据。然后做回调页面处理即可。
/** *SDK调用说明 */ public function index() { //调用测试 import('AlipaySDK.Alipay'); $pay = new \Alipay(); /** * $trade_type 交易类型 app wap web */ $data = $pay->alipay('215360251411626', '0.01', '测试', '测试', 'web', 'http://www.test.com/callback'); //wap 结果string(880) "https://openapi.alipay.com/gateway.do?alipay_sdk=alipay-sdk-php-20180705&app_id=2018072660781410&biz;_content={"body":"测试","subject":"测试","out_trade_no":"215360251411626","timeout_express":"90m","total_amount":"0.01","product_code":"QUICK_WAP_PAY"}&charset=UTF-8&format=json&method=alipay.trade.wap.pay&notify_url=http://www.test.com/callback&sign=RKPyAKAPv28GKfhWIdsCCOualcg2DMCbhpny6yw/tTvJ3Och+yIfS1au7zbGBnm5sFoX2enfgfZekTqBCyzK0/Irw01zDSAOJM4mPYxs96OUkOglWS5Zuq64JwQBAzesFvzKBGgsH2ecL8EUCclDbBIIrAT/DWr6KenyvQvXOxVQNwn540NoS754oBU0w9vLdrGj0Jljvn8D6cbDgnHiE8qLOgpaXv1ROLwtol0yj2H7cM/G7A9RM5Y8jV1aVNYWND8M4XAK5Wr8zwoa9RocbqDpYfw66NXSvrsuFpHf7MpWtSybH5TnxOP5kwzr7pJRDi0XRAyD9u1geei9thUsqA==&sign_type=RSA2&timestamp=2018-09-04+11:50:49&version=1.0" //app 结果直接返回客户端无需处理 alipay_sdk=alipay-sdk-php-20180705&app_id=2018072660781410&biz;_content={"body":"测试","subject":"测试","out_trade_no":"215360251411626","timeout_express":"90m","total_amount":"0.01","product_code":"QUICK_MSECURITY_PAY"}&charset=UTF-8&format=json&method=alipay.trade.app.pay¬ify_url=http://www.test.com/callback&sign_type=RSA2×tamp=2018-09-04+11:54:53&version=1.0&sign=Ab6a0lDxaNcWLL7XcETM85DbBrJI8Sj6czPGKBNK17MZ85FBeStKL+nA/Z4tMORC7H39ooVCDz9ILpbRUfU0eaE7Oe2MOz+Jsj7oUEqwvbvt7eebyPgy2PmPlfAwcZypKla0nUJwHOF5F0cL+mvMGk/K7f2PYMtWL/dIfPOQGC1hBoKFiS+ZF7jIJ98R0AaITAjvQ1drAmJqXpMzUCa1XsTCuQXMXYKu8DNGb/hooJu0xUH/qUU+4fKD0TmBYANQHIrKIBNFl6J2Gw504Mlcfh929ce+YdzF8DXQjacsBSp7f08UJ/FfRvhVXqAfX8lAFETGjc7FXGgU6simNgv1UQ== //web 结果 https://openapi.alipay.com/gateway.do?alipay_sdk=alipay-sdk-php-20180705&app_id=2018072660781410&biz;_content={"body":"测试","subject":"测试","out_trade_no":"215360251411626","timeout_express":"90m","total_amount":"0.01","product_code":"FAST_INSTANT_TRADE_PAY"}&charset=UTF-8&format=json&method=alipay.trade.page.pay¬ify_url=http://www.test.com/callback&sign=l9+A5ZByhwLjQwzRes9+ymKkFVu7uMND4j6cIWmXIXHjrBnGaHkcr+hVkwocaU3d/hB2hdPnxDruhyYFgchnsIA/XWumosG9uEnKyD/T52+VZ8FxLh5wpwH0ucvKzbMjgIWk9dPVjUAU5Zz7QjqKsJ+AsItFpttd0tEVZD4je2PFp5mizeCWT0id0H+y44IGexN705rNe6TGpfJDG0RSDsbD/ZoCzd8FRzC9cv5uwf00J1E9Yc0bUH/l37WFDBTv/LZnqdfeWpaiu8ro7CJ3R+z/xGQTHToo2zLtEc4Cwop096X8WqwSdGbyI9FCemcFzigRB+6yzD9nS4PsWEG3Ug==&sign_type=RSA2×tamp=2018-09-04+11:56:06&version=1.0 echo $data; exit; } /** * 回调地址 */ public function callback() { import('AlipaySDK.Alipay'); $pay = new \Alipay(); $data = $_POST; $verify_result = $pay->check($data); if ($verify_result) { // 验证成功 $out_trade_no = $data['out_trade_no']; // 支付宝交易号 $trade_no = $data['trade_no']; // 交易状态 $trade_status = $data['trade_status']; if ($trade_status == 'TRADE_FINISHED') { //成功之后的操作 } else if ($trade_status == 'TRADE_SUCCESS') { //成功之后的操作 } echo "success"; // 请不要修改或删除 } else { // 验证失败 echo "fail"; } } 声明:是文档根据Alipay文档二次整合,完全开源。如果觉得还可以请点击收藏
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值