之前写过支付宝,微信app支付开发,现在将支付宝的退款,微信退款,支付宝提现功能贴出来。

微信提现功能之前看了官方文档。好像不太好实现,所以换了一个思路。商户转账到用户端,

但是企业对用户转账有限制,需要该商户入住超过90天,需要该商户连续一个月有正常收入才能开通该功能。

所以现在我每天给商户端转账1元。等开通后在贴出代码。

以下是支付宝退款,申请提现代码:

/**
     * 支付宝退款交易申请
     * @param req
     * @param res
     * @return
     */
    @OperLog(logDescription="支付宝退款交易申请")
    @RequestMapping(value="refundPay",method=RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> refundPay(HttpServletRequest req,
            HttpServletResponse res){
        res.setCharacterEncoding("UTF-8");
        
        String createNum = req.getParameter("complete_order_details_number");
        String refundAmount = req.getParameter("refundAmount");
        String refundReason = StringUtils.isNullString(req.getParameter("refundReason"))?"用户申请退款":req.getParameter("refundReason");
        
        CompleteOrderDetails completeOrderDetails = completeOrderDetailsService.selectCompleteOrderDetailsById(createNum);
        
        if(StringUtils.isObjectNull(completeOrderDetails))
            return JsonMethod.setJsonMethod(PathKeyEnum.ERROR.getKey(), "当前订单不存在", PathCommon.ERROR);
        
        String stagePrice = completeOrderDetails.getComplete_order_details_stage_price();
        
        if(StringUtils.isNullString(stagePrice) || StringUtils.isNullString(refundAmount))
            return JsonMethod.setJsonMethod(PathKeyEnum.ERROR.getKey(), "申请的退款金额不存在!", PathCommonEnum.ERROR.getValue());
        
        //如果左边比右边大,则退款金额失败
        if(CommonUtils.compareTo(Double.parseDouble(refundAmount), Double.parseDouble(stagePrice)) == 1)
            return JsonMethod.setJsonMethod(PathKeyEnum.ERROR.getKey(), "申请退款的金额超出付款过的金额!", PathCommonEnum.ERROR.getValue());
        //上面的判断方法用的工具类是自己写的。并非是阿里提供。
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", AlipayConfig.APP_ID, AlipayConfig.APP_PRIVATE_KEY, "json", AlipayConfig.input_charset, AlipayConfig.ALIPAY_PUBLIC_KEY, "RSA2");
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
        
        model.setOutTradeNo(createNum);//12345678900
        //model.setTradeNo("1234567890000");//支付宝交易号 和上面的2选1即可
        model.setRefundAmount(refundAmount);//需要退款的金额,该金额不能大于订单金额,单位为元,支持两位小数
        model.setRefundReason(refundReason);//退款的原因说明
        request.setBizModel(model);
        
        try {
            //这里和普通的接口调用不同,使用的是sdkExecute
            AlipayTradeRefundResponse response = alipayClient.execute(request);
            
            if(response.isSuccess()){

//同意申请退款
                refundService.updateSureRefund(completeOrderDetails.getComplete_order_only_md5());
                return JsonMethod.setJsonMethod(PathKeyEnum.SUCCESS.getKey(), PathKeyEnum.SUCCESS.getValue(), response.getBody());
            }
        } catch (Exception e) {
              LogComm.setLog(e.getMessage()+",退款抛出异常");
        }
        return JsonMethod.setJsonMethod(PathKeyEnum.ERROR.getKey(), PathKeyEnum.ERROR.getValue(), PathCommon.ERROR);
    }

/**
     * 支付宝申请提现 该提现功能是针对后台管理系统申请提现,然后支付宝商家端自动转账到该商家
     * @param session
     * @param req
     * @param res
     * @return
     */
    @OperLog(logDescription="支付宝申请提现")
    @RequestMapping(value="zhuanzhang",method={RequestMethod.POST,RequestMethod.GET})
    @ResponseBody
    public Map<String, Object> zhuanzhang(HttpSession session,HttpServletRequest req,
            HttpServletResponse res){
        res.setCharacterEncoding("UTF-8");
        
        String assembly_only_md5 = super.getMasterAssemblyMD5(session);
        if(StringUtils.isNullString(assembly_only_md5))
            return JsonMethod.setJsonMethod(PathKeyEnum.LOGINFAILURE.getKey(), PathKeyEnum.LOGINFAILURE.getValue(), PathCommonEnum.ERROR.getValue());
        
        AssemblyWallet assemblyWallet = assemblyWalletService.selectAssemblyWalletInfo(assembly_only_md5);
        
        if(StringUtils.isObjectNull(assemblyWallet))
            return JsonMethod.setJsonMethod(PathKeyEnum.ERROR.getKey(), PathKeyEnum.ERROR.getValue(), PathCommonEnum.ERROR.getValue());
        
        String curPrice = req.getParameter("curPrice");//转账的金额
        String realName = req.getParameter("realName");//可以自己填写真是姓名
        if(StringUtils.isNullString(curPrice) || 
                StringUtils.isNullString(realName))
            return JsonMethod.setJsonMethod(PathKeyEnum.PARAMERROR.getKey(), PathKeyEnum.PARAMERROR.getValue(), PathCommonEnum.ERROR.getValue());
        
        if(CommonUtils.compareTo(Double.parseDouble(curPrice), Double.parseDouble(assemblyWallet.getAssembly_price())) == 1)
            return JsonMethod.setJsonMethod(PathKeyEnum.ERROR.getKey(), "申请提现的错误,请重新申请提现!", PathCommonEnum.ERROR.getValue());
        
        if(CommonUtils.compareTo(Double.parseDouble(curPrice), Double.parseDouble("0.1")) == -1)
            return JsonMethod.setJsonMethod(PathKeyEnum.ERROR.getKey(), "提现金额不得小于0.1元!", PathCommonEnum.ERROR.getValue());
        
        if(CommonUtils.compareTo(Double.parseDouble(curPrice), Double.parseDouble("10000")) == 1)
            return JsonMethod.setJsonMethod(PathKeyEnum.ERROR.getKey(), "单笔提现不得超过10000元!", PathCommonEnum.ERROR.getValue());
        //转账到商家的支付宝。即:商户 > 个人支付宝 
        AlipayFundTransToaccountTransferModel model = new AlipayFundTransToaccountTransferModel();
        String curOrderNum = CommonUtils.createNum();
        model.setOutBizNo(curOrderNum);//生成新的订单编号
        model.setPayeeType("ALIPAY_LOGONID");
        //账号数据从数据库里获取
        model.setPayeeAccount(assemblyWallet.getAlipay_account());//转账接收的账户
        //最低0.1元
        model.setAmount(curPrice);//转账金额
        model.setPayerShowName("");//商户端的名称
        //接受方真是姓名
        model.setPayeeRealName(realName);
        
        try {
            return alipayZhuanZhang(model, assembly_only_md5, curPrice, curOrderNum);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            LogComm.setLog("整装公司后台提现抛出异常:" + e.getMessage());
        }
        return JsonMethod.setJsonMethod(PathKeyEnum.ERROR.getKey(), "提现失败,请稍后再试!", PathCommonEnum.ERROR.getValue());
    }

/**
     * 调用阿里转账api
     * @param model
     * @return
     */
    private Map<String, Object> alipayZhuanZhang(AlipayFundTransToaccountTransferModel model,
            String assembly_only_md5,String curPrice,String curOrderNum){
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", AlipayConfig.APP_ID, AlipayConfig.APP_PRIVATE_KEY, "json", AlipayConfig.input_charset, AlipayConfig.ALIPAY_PUBLIC_KEY, "RSA2");
        
        AlipayFundTransToaccountTransferRequest request = new AlipayFundTransToaccountTransferRequest();
        request.setBizModel(model);
        try {
            AlipayFundTransToaccountTransferResponse response = alipayClient.execute(request);
            String result = response.getBody();
            
            if (response.isSuccess()) {
                //修改商家支付宝余额
                assemblyWalletService.updateAssemblyWalletInfo(assembly_only_md5, curPrice);

//记录商家提现数据
                assemblyWalletOrderService.insertAssemblyWalletOrder(curOrderNum, curPrice, assembly_only_md5);
                return JsonMethod.setJsonMethod(PathKeyEnum.SUCCESS.getKey(), PathKeyEnum.SUCCESS.getValue(), PathCommonEnum.SUCCESS.getValue());
            }else{
                JSONObject jsonObject = JSONObject.parseObject(result);
                String out_biz_no = jsonObject.getJSONObject("alipay_fund_trans_toaccount_transfer_response").getString("out_biz_no");
                AlipayFundTransOrderQueryModel queryModel = new AlipayFundTransOrderQueryModel();
                queryModel.setOutBizNo(out_biz_no);
                AlipayFundTransOrderQueryRequest req = new AlipayFundTransOrderQueryRequest();
                req.setBizModel(model);
                AlipayFundTransOrderQueryResponse res = alipayClient.execute(req);
                
                if(res.isSuccess()){
                    //修改商家支付宝余额
                    assemblyWalletService.updateAssemblyWalletInfo(assembly_only_md5, curPrice);
                    assemblyWalletOrderService.insertAssemblyWalletOrder(curOrderNum, curPrice, assembly_only_md5);
                    return JsonMethod.setJsonMethod(PathKeyEnum.SUCCESS.getKey(), PathKeyEnum.SUCCESS.getValue(), PathCommonEnum.SUCCESS.getValue());
                }else{
                    return JsonMethod.setJsonMethod(PathKeyEnum.ERROR.getKey(), response.getSubMsg(), PathCommonEnum.ERROR.getValue());
                }
            }
        } catch (Exception e) {
            // TODO: handle exception
            LogComm.setLog("申请提现抛出异常:" + e.getMessage());
        }
        return JsonMethod.setJsonMethod(PathKeyEnum.ERROR.getKey(), PathKeyEnum.ERROR.getValue(), PathCommonEnum.ERROR.getValue());
    }

下面是微信退款,

/**
     * 微信退款交易申请
     * @param req
     * @param res
     * @return
     */
    @OperLog(logDescription="微信退款交易申请")
    @RequestMapping(value="refundPay",method=RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> refundPay(HttpServletRequest req,
            HttpServletResponse res){
        res.setCharacterEncoding("UTF-8");
        
        String createNum = req.getParameter("complete_order_details_number");
        String refundAmount = req.getParameter("refundAmount");
        
        CompleteOrderDetails completeOrderDetails = completeOrderDetailsService.selectCompleteOrderDetailsById(createNum);
        
        if(StringUtils.isObjectNull(completeOrderDetails))
            return JsonMethod.setJsonMethod(PathKeyEnum.ERROR.getKey(), "当前订单不存在", PathCommon.ERROR);
        
        String stagePrice = completeOrderDetails.getComplete_order_details_stage_price();
        
        if(StringUtils.isNullString(stagePrice) || StringUtils.isNullString(refundAmount))
            return JsonMethod.setJsonMethod(PathKeyEnum.ERROR.getKey(), "申请的退款金额不存在!", PathCommonEnum.ERROR.getValue());
        
        //如果左边比右边大,则退款金额失败
        if(CommonUtils.compareTo(Double.parseDouble(refundAmount), Double.parseDouble(stagePrice)) == 1)
            return JsonMethod.setJsonMethod(PathKeyEnum.ERROR.getKey(), "申请退款的金额超出付款过的金额!", PathCommonEnum.ERROR.getValue());
        
        try {
            WxPayUtilConfig config = new WxPayUtilConfig();
            
            WXPay wxPay = new WXPay(config);
            Map<String, String> param = new HashMap<String, String>();
            param.put("appid", config.getAppID());
            //内容描述可通过前端app传递过来.
            param.put("mch_id", config.getMchID());
            param.put("nonce_str", WXPayUtil.generateNonceStr());
            //param.put("notify_url", WXPayCommonPath.REFUND_NOTIFYURL);
            param.put("out_refund_no", createNum);
            param.put("out_trade_no", createNum);
            param.put("refund_fee",String.valueOf((int)CommonUtils.mul(Double.parseDouble(refundAmount), 100.00)));
            param.put("total_fee", String.valueOf((int)CommonUtils.mul(Double.parseDouble(completeOrderDetails.getComplete_order_details_stage_price()), 100.00)));//金额 以分为单位.我这边是测试数据.
            //param.put("transaction_id", "4200000284201901150238168840");
            String sign = WXPayUtil.generateSignature(param,WXPayCommonPath.API_KEY);
            param.put("sign", sign);
            //WXPayUtil.generateSignedXml(param, WXPayCommonPath.API_KEY);
            Map<String, String> returnMap = wxPay.refund(param);
            
            if("SUCCESS".equals(returnMap.get("return_code"))){
                refundService.updateSureRefund(completeOrderDetails.getComplete_order_only_md5());
                return JsonMethod.setJsonMethod(PathKeyEnum.SUCCESS.getKey(), "退款成功", PathCommonEnum.SUCCESS.getValue());
            }
        } catch (Exception e) {
            // TODO: handle exception
            LogComm.setLog("微信退款交易申请抛出异常:" + e.getMessage());
            return JsonMethod.setJsonMethod(PathKeyEnum.ERROR.getKey(), "退款失败,微信退款api抛出异常", PathCommonEnum.ERROR.getValue());
        }
        
        return JsonMethod.setJsonMethod(PathKeyEnum.ERROR.getKey(), PathKeyEnum.ERROR.getValue(), PathCommonEnum.ERROR.getValue());
    }

微信提现:官方文档看到了是红包形式的转账。限制5K,

然后我研究了商户对银行卡转账。等待开通功能。等好了之后在贴出来。

上面退款功能:

用户在app端发起退款申请,

后台针对该数据同意/拒绝退款,。同意就是上面的代码。

提现是商家后台输入金额,支付宝账号,等。然后确定,商户 > 商家(个人支付宝账号。)

以上功能是可以通过的。已上线。

2019/04/11:今天整个项目测试中,发现了一个支付宝退款bug,故现在写下来:

支付宝退款分两种,

1:部分退款

2:全额退款

部分退款:

model.setOutRequestNo("TK"+CommonUtils.createNum());//部分退款下,该字段需要传递

该值是属于自定义字段,如果是部分退款的话,则该值必须填写。可以进行判断,提现的金额是否小于付款的金额。

全额退款:

因为全额退款会触发通知,支付宝的回调通知会默认使用你支付时的回调链接。

所以要在回调的方法那做判断处理

String refund_fee = params.get("refund_fee");
String gmt_refund = params.get("gmt_refund");

以上2个字段只有退款时会存在,支付时 则该值为null

所以要做好判断。

if(StringUtils.isNullString(refund_fee) && StringUtils.isNullString(gmt_refund)){

//支付时回调,直接将之前写的代码放进去

}else if(!StringUtils.isNullString(refund_fee) && !StringUtils.isNullString(gmt_refund)){

//全额退款时回调,

return "success";

}else{

LogComm.setLog("未知的支付宝回调功能!");
            return "fail";

}

这样支付宝退款功能就ok了。至于微信,还没有去看, 是否跟支付宝一样,如果是的话,我估计微信有点坑。

以上功能是咨询了支付宝技术客服,然后自己写了。并且已测试通过。

支付宝退款,支付宝提现转账相关推荐

  1. java 支付宝退款、提现(单笔转账到支付宝账户接口)

    支付宝退款 import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; import com.alipa ...

  2. 支付宝支付-常用支付API详解(查询、退款、提现等)-转

    所有的接口支持沙盒环境的测试 1.前言 前面几篇文件详细介绍了 支付宝提现.扫码支付.条码支付.Wap支付.App支付 支付宝支付-提现到个人支付宝 支付宝支付-扫码支付 支付宝支付-刷卡支付(条码支 ...

  3. java 支付宝转账_Java 支付宝支付,退款,单笔转账到支付宝账户(支付宝订单退款)...

    上一篇写到支付宝的支付,这代码copy下来就能直接用了,   我写学习文档时会经常贴 官方参数文档的案例地址, 因为我觉得 请求参数,响应参数说明 官方文档整理的很好,毕竟官方不会误导大家. 我学一个 ...

  4. 支付宝支付-常用支付API详解(查询、退款、提现等)(转)

    所有的接口支持沙盒环境的测试 1.前言前面几篇文件详细介绍了 支付宝提现.扫码支付.条码支付.Wap支付.App支付支付宝支付-提现到个人支付宝支付宝支付-扫码支付支付宝支付-刷卡支付(条码支付)支付 ...

  5. 支付宝 单笔转账到支付宝账户接口 - 提现

    实现用户提现 资金自动到账 前期的支付宝配置 可以参考文章 支付宝配置 (新版) 当前开发环境: Windows phpstudy ThinkPHP5 支付宝接口新版 1.0 实现提现的步骤 1 开发 ...

  6. java 支付宝 退款_Java 支付宝支付,退款,单笔转账到支付宝账户(支付宝支付)

    最近一直在接触第三方,刚接入完支付宝的API做一下总结,个人能力薄弱有不对的地方望指教.  做的是一个小型电商项目,所以会接入第三方的支付和登入功能, 第一次接入第三方撸了很多官方文档. 然后创建应用 ...

  7. Java 支付宝支付,退款,单笔转账到支付宝账户(支付宝支付)

    最近一直在接触第三方,刚接入完支付宝的API做一下总结,个人能力薄弱有不对的地方望指教.  做的是一个小型电商项目,所以会接入第三方的支付和登入功能, 第一次接入第三方撸了很多官方文档. 进入主题, ...

  8. 明天支付宝就开始提现收费了!这几招可以让你受用

    成都亿合科技小编又要躁动了,10月12日,也就是明天开始,支付宝提现将正式收费啦!! 按照之前支付宝公布的规定,对个人用户超出免费额度的提现,支付宝将收取0.1%的服务费(与微信相同),个人用户每人累 ...

  9. 支付宝给个人账号转账付款

    一.说明 转账到支付宝账户是为了满足支付宝商户向其他支付宝账户进行单笔转账的需求,针对具备开发能力的商户,提供通过 API 接口完成单笔转账的功能.商家只需输入另一个正确的支付宝账号,即可将单笔资金从 ...

  10. 支付宝支付之“单笔转账到支付宝账户接口”的调用(生成签名、上传应用公钥、下载SDK、接口调用、报错自动排查、查看错误码)

    支付宝接口调用 "单笔转账到支付宝账户"的接口调用,一般涉及到下面几个知识点 1.生成签名 在使用支付宝接口的时候,需要使用支付宝的签名,这里需要使用支付宝的RSA生成工具. 关于 ...

最新文章

  1. Android中悬浮窗口的实现原理和示例代码
  2. concurrent (二)AQS
  3. java实现续打功能_浅谈报表工具的打印方案
  4. Elasticsearch 动态添加mapping
  5. 用Java编写模仿的太阳系(九星行旋转)--原创
  6. Docker搭建便捷的开发者环境
  7. mysqldump原理及实验
  8. linux添加硬盘不重启(vmware下或者虚拟机下面)
  9. CVPR 2020 oral:亮风台提出完全可训练的图匹配方法
  10. IP计算机取证,计算机取证1资料.doc
  11. 和平精英、宾果消消消等多款游戏APP存隐私不合规行为
  12. Altium Designer 在pcb下导入的原件引脚是绿的
  13. 关于瑞昱8763bfr的学习总结(1)
  14. 2021年9月25日PMI认证考点考场安排
  15. 用大数据文本挖掘来看“共享单车”的行业现状及走势
  16. [Poi 2012] bzoj2794 Cloakroom [dp]
  17. 客户端Connection reset by peer怎么办?——可能只是服务端挂了
  18. LR字符串截取lr_save_var
  19. Processing摸索前行(9)-音频可视化
  20. STM32F427利用FSMC接口访问FPGA的SRAM(3)—— STM32F427访问FPGA的SRAM

热门文章

  1. windows start 命令启动 GUI 程序
  2. 高三数学辅导:不等式、推理与证明
  3. 如何使用 ELEMENTOR
  4. c++while循环
  5. Windows11上找BitLocker密钥
  6. 第三方支付相关知识结构
  7. ansys 英文路径 安装失败
  8. 思科 Cisco DHCP中继配置
  9. html表格数据填充,bootstrap table.js动态填充单元格数据的多种方法
  10. 网站建设的一些基本教程操作