支付宝
一、支付宝支持支付方式
即时到账:买家选择手机扫一扫二维码付款或 买家选择在电脑端登录账户付款
手机网站支付:先唤醒 "支付宝" 客户端,安装支付宝,直接跳转支付宝支付,未安装支付宝,跳转网页支付宝支付
APP支付:先唤醒 "支付宝" 客户端,安装支付宝,直接跳转支付宝支付,未安装支付宝,跳转网页支付宝支付
当面付:1、条码支付:用户打开支付宝钱包,点击“付款”--》选择“付款码”,并提供给收银员用扫描设备扫描--》红外扫码枪,用于扫描用户手机支付宝客户端的“付款码”;
2、扫码支付:用户打开支付宝钱包,点击“付款”--》选择“扫码付”,付款确认--》显示二维码的收银终端:在商户收银终端,通常采用双屏显示器给用户显示二维码,或将打印出的二维码信息直接张贴出来供用户扫描;
3、声波支付:用户打开支付宝钱包,点击“付款”--》选择“声波付”,用户将手机靠近声波接收端--》声波接收终端:线下商户的声波接收终端主要是:置于收银台的麦克风或内置声波支付功能的其他终端设备(如:自助售货机),商户可通过该设备接收用户手 机支付宝的声波讯息进而完成支付。
二、APP支付
a、基于Android的Util的签名
1、按照支付宝申请条件,注册支付宝账户、添加开发者;
2、创建APP,获取APPID
3、根据APP提供的工具“.exe”,生成私钥,百度云地址:http://pan.baidu.com/s/1gfiaDkJ ;
4、AlipayConfig.class
package com.guduo.common.alipay.config; import com.guduo.common.config.ServiceConfig; /* * *类名:AlipayConfig *功能:基础配置类 *详细:设置帐户有关信息及返回路径 *版本:3.3 *日期:2012-08-10 *说明: *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。 *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。 *提示:如何获取安全校验码和合作身份者ID *1.用您的签约支付宝账号登录支付宝网站(www.alipay.com) *2.点击“商家服务”(https://b.alipay.com/order/myOrder.htm) *3.点击“查询合作者身份(PID)”、“查询安全校验码(Key)” *安全校验码查看时,输入支付密码后,页面呈灰色的现象,怎么办? *解决方法: *1、检查浏览器配置,不让浏览器做弹框屏蔽设置 *2、更换浏览器或电脑,重新登录查询。 */ public class AlipayConfig { //↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ // 合作身份者ID,以2088开头由16位纯数字组成的字符串 public static String partner = "2088421517609120"; // 商户的私钥,通过支付宝提供的EXE程序生成 public static String private_key = "********"; // 支付宝的公钥,无需修改该值 public static String alipay_public_key = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDI6d306Q8fIfCOaTXyiUeJHkrIvYISRcc73s3vF1ZT7XN8RNPwJxo8pWaJMmvyTn9N4HQ632qJBVHf8sxHi/fEsraprwCtzvzQETrNRwVxLO5jVmRGi60j8Ue1efIlzPXV9je9mkjzOmdssymZkh2QhUrCmZYI/FCEa3/cNMW0QIDAQAB"; // 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 public static String notify_url = ServiceConfig.ServiceLocal+"guduo-mobile/mobile/order/alipayNotify"; //↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ // 调试用,创建TXT日志文件夹路径 public static String log_path = "D:\\"; // 字符编码格式 目前支持 gbk 或 utf-8 public static String input_charset = "utf-8"; // 签名方式 不需修改 public static String sign_type = "RSA"; // 调用的接口名,无需修改 public static String service = "mobile.securitypay.pay"; // 支付宝分配给开发者的应用ID public static String app_id = "********"; // 接口名称,固定值 public static String method = "alipay.trade.app.pay"; // 调用的接口版本,固定为:1.0 public static String version = "1.0"; // 销售产品码,商家和支付宝签约的产品码,为固定值QUICK_MSECURITY_PAY public static String product_code = "QUICK_MSECURITY_PAY"; }
5、在百度云--http://pan.baidu.com/s/1gfiaDkJ 中复制文件夹"androidAlipayUtil"中的方法
6、生成签名
/** * <h1>支付宝签名</h1> * @param order * @author Lee */ @Override public Map<String, String> alipaySign(TransactionOrder order) { Map<String, String> sParaTemp = new HashMap<String, String>(); //------------不可空-------------- sParaTemp.put("app_id", AlipayConfig.app_id); //appId sParaTemp.put("method", AlipayConfig.method); // sParaTemp.put("charset", AlipayConfig.input_charset); sParaTemp.put("sign_type", AlipayConfig.sign_type); sParaTemp.put("timestamp", UtilDate.getDateFormatter()); //new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") sParaTemp.put("version", AlipayConfig.version); sParaTemp.put("notify_url", AlipayConfig.notify_url); //biz_content Map<String, String> biz_content = new HashMap<String, String>(); biz_content.put("subject", OrderEnum.parse(order.getType()));//订单类型 biz_content.put("out_trade_no", order.getOrderNo()); //订单号 biz_content.put("total_amount", order.getAmount()+""); //交易金额 biz_content.put("product_code", AlipayConfig.product_code); sParaTemp.put("biz_content", JSONObject.fromObject(biz_content).toString()); //签名后的字符串 Map<String, String> signMap = new HashMap<String, String>(); try { //签名 String orderParam = OrderInfoUtil2_0.buildOrderParam(sParaTemp); String signFromApp = OrderInfoUtil2_0.getSign(sParaTemp, AlipayConfig.private_key); String orderInfo = orderParam + "&" + signFromApp; signMap.put("orderInfo", orderInfo); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return signMap; }
7、支付回调:地址在AlipayConfig 中配置
/** * 支付宝回调 * @param request * @param response * @return */ @SuppressWarnings("rawtypes") @ResponseBody @RequestMapping(value = "/alipayNotify", method = RequestMethod.POST) public void alipayNotify(HttpServletRequest request, HttpServletResponse response) { ResponseData data = new ResponseData(); String orderNo = ""; String trade_status = ""; try { 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"), "gbk"); params.put(name, valueStr); } trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8"); orderNo = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8"); //签名 // if(AlipayNotify.verify(params)){//验证成功 if(AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.input_charset)){//验证成功 if(trade_status.equals("TRADE_SUCCESS")){ //验证成功后执行的业务
} else if (trade_status.equals("TRADE_CLOSED")) { data.setCode(CodeEnum.ZFB_CALLBACK_NOPAY.code); } else { data.setCode(CodeEnum.ZFB_CALLBACK_FALSE.code); } } else { data.setCode(CodeEnum.ZFB_NOTIFY_FALSE.code); } } catch (Exception e) { data.setCode(CodeEnum.EXCEPTION.code); e.printStackTrace(); } //调用日志写库操作 if (data.getCode().equals(CodeEnum.SUCCESS.code)) { MDCUtil.financeMdc(data, OrderEnum.ORDER_RECHARGE.id); log.info("支付宝支付成功,订单号:"+orderNo+",返回码:"+trade_status); } else { MDCUtil.financeMdc(data, OrderEnum.ORDER_RECHARGE.id); log.info(data.getDesc() + ",支付宝支付失败,订单号:"+orderNo+",返回码:"+trade_status); } }