• H5调起支付宝支付


    1.H5调起支付宝支付,我这里是的方法是H5通过访问后端接口,由后台生成一个隐藏的form表单,将form表单作为一个字符串返回给H5,H5将form表单渲染到页面上,通过提交form表单调起支付宝支付。

    form表单大致是这样的,这里我从别处找到

    <form name="punchout_form" method="post" action="https://openapi.alipay.com/gateway.do?charset=UTF-8&method=alipay.trade.wap.pay&sign=DEpMkI**********************eWUs6EW3QKlt9OHYv%2FqkporO8Sr5%2Bay5VA9dpx3pAbIiPPajQ2gEcWHvz5bm*******kxH8ZvHUXahQL9S69p9wKNXpXOxYadlsxE8QKGUc4cO5rrgGq08%2BpiOq%2FOz4fLogEBWANXILUMWXNzJn8YryNifZ416Pd%2BxkKgXs%2Fo%2FQDcqEUg*********VXXPRq7IGRGQg%2FpZkOhxCH%2Fq%2B9hnWEncAfQLlAXfPqjdcQTNJ0TJdVr1X1ENOdAr5LQkydWw2EQ8g%3D%3D&return_url=+https%3A%2F%2**********&notify_url=+https%3A%2F%*********Fpub%2Fapi%2Fv1%2F********allback1&version=1.0&app_id=20********57&sign_type=R***&timestamp=2019-0******55&alipay_sdk=al*******.49.ALL&format=json">
    <input type="hidden" name="biz_content" value="{&quot;body&quot;:&quot;&quot;,&quot;enable_pay_channels&quot;:&quot;balance,moneyFund,bankPay,debitCardExpress,creditCardExpress,creditCard,pcredit,pcreditpayInstallment,coupon,point,voucher,mdiscount,honeyPay&quot;,&quot;out_trade_no&quot;:&quot;132ecf937ad84487aa6cbaeb2ec157fe&quot;,&quot;product_code&quot;:&quot;13&quot;,&quot;subject&quot;:&quot;SpringBoot 2.x微信支付在线教育网站项目实战&quot;,&quot;timeout_express&quot;:&quot;20m&quot;,&quot;total_amount&quot;:&quot;98&quot;}">
    <input type="submit" value="立即支付" style="display:none" >
    </form>
    <script>document.forms[0].submit();</script>
    2.如何生成form表单并返回给H5,这里只是使用了支付宝sdk里面的方法 生成form表单,不用请求支付宝后台,与微信统一下单接口有所区别。需要注意返回值类型Map<String,StringBuffer>,使用StringBuffer返回给H5可以正常收到,如果使用String类型,map被包装类包装后序列化到H5可能接收不到。

    /**
    * 支付宝下单参数 json.put("out_trade_no", ""); //商户订单号
    json.put("total_amount", "0.01"); //总金额,元为单位
    * @param map
    * @return
    * @throws Exception
    */
    public static Map<String,StringBuffer> aliPay(Map<String,String> map) throws Exception
    //这里采用RSA2 加密方式
    AlipayClient client = new DefaultAlipayClient(AliPayProperties.URL, aliPayProperties.getAppid(), Configs.getPrivateKey(), AliPayProperties.FORMAT, AliPayProperties.CHARSET, Configs.getAlipayPublicKey(),AliPayProperties.SIGNTYPE);
    AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();

    JSONObject json = new JSONObject();
    json.putAll(map); //包含商户订单号,金额
    json.put("product_code", "QUICK_WAP_WAY");
    json.put("subject", aliPayProperties.getSubject()); //商品的标题/交易标题/订单标题/订单关键字等。

    request.setBizContent(json.toString());
    request.setNotifyUrl(aliPayProperties.getNotifyUrl()); //设置回调地址
    request.setReturnUrl(aliPayProperties.getReturnUrl()); //设置返回地址
    Map<String,StringBuffer> resmap = null;
    AlipayTradeWapPayResponse response;
    try {
    response = client.pageExecute(request);
    StringBuffer sb = new StringBuffer();
    String data =response.getBody() ; //获取form表单字符串
    log.info("支付宝下单参数拼接:"+data);
    sb.append(data);
    resmap = new HashMap<String,StringBuffer>();
    resmap.put("from", sb);
    } catch (AlipayApiException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    return resmap;
    }

    2.支付宝回调方法,最主要两点,一个是如何接受参数,另一个是验签 ,这里需要将支付宝回调的参数转为map

    @RequestMapping(value = "/alyPayNotify")
    public String alyPayNotify(HttpServletRequest request, HttpServletResponse response) throws IOException, JDOMException {
    log.info("支付宝支付成功回调");
    //这里拿到支付宝通知数据
    Map<String, Object> params = convertRequestParamsToMap(request); // 将异步通知中收到的待验证所有参数都存放到map中
    String paramsJson = JSON.toJSONString(params);
    log.info("支付宝回调,{}"+ paramsJson);
    Map<String, String> map = JSON.parseObject(paramsJson, new TypeReference<Map<String, String>>(){});
    return aliPayService.aliPayNotify(map, response);

    }

    // 将request中的参数转换成Map
    private static Map<String, Object> convertRequestParamsToMap(HttpServletRequest request) {
    Map<String,Object> returnMap = new HashMap<String,Object>();
    Map<String,String[]> map = new HashMap<String,String[]>();
    map = request.getParameterMap();
    Iterator entries = map.entrySet().iterator();
    Map.Entry entry;
    String name ="";
    String value=null;
    while (entries.hasNext()){
    entry=(Map.Entry)entries.next();
    name = (String) entry.getKey();
    Object objvalue = entry.getValue();
    if(objvalue == null){
    value = null;
    }else if(objvalue instanceof String[]){
    /**条件如果成立,objvalue就是一个数组,需要将它转换成为字符串,并拼接上逗号,并吧末尾的逗号去掉*/
    String[] values = (String[]) objvalue;
    for(int i=0;i<values.length;i++){
    value = values[i]+",";//这里我拼接的是英文的逗号。
    }
    value = value.substring(0,value.length()-1);//截掉最后一个逗号。
    }else{
    value = objvalue.toString();
    }
    log.info("key:"+name);
    log.info("value:"+value);
    returnMap.put(name , value);
    }
    Iterator it = returnMap.keySet().iterator();
    while (it.hasNext()){
    Object key = it.next();
    if(returnMap.get(key) == null || "".equals (((String)returnMap.get(key)).trim())){
    returnMap.put((String) key, null);
    }
    }
    return returnMap;

    }
    3,支付宝回调验签,这里需要选择输出流的形式返回success ,return 方式支付宝好像不接受,不知道是不是因为版本原因,代码我就不一一修改了。这里签名验证方式与网上的有些方法也略有区别,参数不同。具体可参考我的另一篇支付宝博客

    地址:https://blog.csdn.net/qq_38669394/article/details/106336900

    @Override
    public String aliPayNotify(Map<String, String> map, HttpServletResponse response) {
    // 调用SDK验证签名
    try {
    String sign = (String) map.get("sign");
    String content = AlipaySignature.getSignCheckContentV1(map);
    boolean signVerified = AlipaySignature.rsaCheck(content, sign, Configs.getAlipayPublicKey(), AliPayProperties.CHARSET, AliPayProperties.SIGNTYPE);

    if (signVerified) {
    log.info("支付宝回调签名认证成功");
    // 按照支付结果异步通知中的描述,对支付结果中的业务内容进行1\2\3\4二次校验,校验成功后在response中返回success,校验失败返回failure
    //检查金额是否一致
    //this.check(params);
    // 支付宝建议 另起线程处理业务
    Executors.newFixedThreadPool(20).execute(new Runnable() {
    @Override
    public void run() {
    log.info("ZFB回调参数" + map);
    String trade_status = map.get("trade_status");
    log.info("trade_status:" + trade_status);
    // 支付成功
    if (trade_status.equals("TRADE_SUCCESS")) {
    // 处理支付成功逻辑
    try {
    // 处理业务逻辑。。。
    String out_trade_no = map.get("out_trade_no");
    String trade_no = map.get("trade_no");
    String total_amount = map.get("total_amount");

    } catch (Exception e) {
    log.error("支付宝回调业务处理报错,params:" + e);
    }
    } else {
    log.error("没有处理支付宝回调业务,支付宝交易状态:{},params:{}", trade_status);
    }
    }
    });
    BufferedOutputStream out = null;
    try {
    out = new BufferedOutputStream(response.getOutputStream());
    out.write("success".getBytes());
    out.flush();
    out.close();
    } catch (Exception e) {
    e.printStackTrace();
    }
    return "success";

    } else {
    log.info("支付宝回调签名认证失败,signVerified=false, paramsJson:{}");
    return "failure";
    }

    } catch (AlipayApiException e) {

    log.error("支付宝回调签名认证失败,paramsJson:{},errorMsg:{}", e.getMessage());
    return "failure";
    }
    }

  • 相关阅读:
    verilog parameter 位宽问题
    quartus prime 16.0 报警告 inferring latch
    Quartus prime16.0 组合逻辑always块中敏感向量表不全
    centos6.8下安装matlab2009(图片转帖)
    centos6.8下普通用户下quartus编程识别不到用户开发板
    centos6.8下安装破解quartus prime16.0以及modelsim ae安装
    PHP TP 生成二维码
    模态框MODAL的一些事件捕捉
    iOS微信第三方登录实现
    PHP ini 配置无效的坑给自己记录
  • 原文地址:https://www.cnblogs.com/zeenzhou/p/16173963.html
Copyright © 2020-2023  润新知