app端微信支付(二) - 生成预付单

​前一篇文章的时序图中说了,app端调用微信支付必须先由后台调用微信后台生成预付单,再构建参数给手机端,而数据的构建要以xml形式,那么看看代码具体实现吧,代码已经精简过了,自己的业务已经除去,精简的代码附上注释是可以直接调用微信后台的

这个是微信所要接受的参数,咱们可以把它构建成一个entity

public class WXPrepay {
    private static String unifiedorder = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    private static String orderquery = "https://api.mch.weixin.qq.com/pay/orderquery";
    private String appid;                // 应用ID            微信开放平台审核通过的应用APPID
    private String mch_id;                // 商户号            微信支付分配的商户号
    private String nonce_str = OrderUtil.CreateNoncestr();        // 随机字符串        随机字符串,不长于32位
    private String sign;                // 签名
    private String body;                // 商品描述        商品描述交易字段格式根据不同的应用场景按照以下格式:APP——需传入应用市场上的APP名字-实际商品名称,天天爱消除-游戏充值。
    private String out_trade_no;        // 商户订单号        商户系统内部的订单号,32个字符内、可包含字母
    private String total_fee;            // 总金额            订单总金额,单位为分
    private String spbill_create_ip;    // 终端IP            用户端实际ip
    private String notify_url;            // 通知地址        接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。
    private String trade_type;            // 交易类型        支付类型
    private String partnerKey;
    private String attach;                // 附加数据        附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据

    private String prepay_id;            // 预支付订单号

 

controller作为一个restful接口供手机端调用,这个接口可以被ios,安卓等调用,只要微信提供了相应手机端的sdk,那就没有问题

@RequestMapping("/wxpay")
    @ResponseBody
    public LeeJSONResult wxpay(HttpServletRequest request, Model model) {
        try {
            // TODO 根据你的业务逻辑计算你需要支付的订单总额
            double totalFee = 1;
            // 生成交易流水,流水id需要传给微信,这个流水ID可以作为你的订单ID,由于我们的业务是多订单的,流水ID仅仅只是作为表关联
            // 需要保存货源id,需要的车辆数,订单id在通知成功后保存
            String payFlowId = sid.nextShort();
            SpPayFlowCargoSource payFlowCargoSource = new SpPayFlowCargoSource();
            payFlowCargoSource.setId(payFlowId);
            payFlowCargoSource.setFee(new BigDecimal(totalFee));
            payFlowCargoSource.setPayStatus(PayStatusEnum.NOT_PAID.value);    // 支付状态:未支付

            // 构建微信参数
            String spbill_create_ip = request.getRemoteAddr();        // 用户IP
            WXPrepay prePay = new WXPrepay();
            prePay.setAppid(WXPayContants.appId);
            prePay.setMch_id(WXPayContants.partnerId);
            prePay.setBody("demo - 微信支付");
            prePay.setOut_trade_no(payFlowId);
            // 这里要注意,微信支付是以分为单位,而系统是以元为单位,所以需要金额转换。题外话:曾经看到过京东和苏宁都有类似的bug,就是一个台手机和耳机都是要十几元,估计是金额转换出的问题
            prePay.setTotal_fee(String.valueOf(new BigDecimal(totalFee).multiply(new BigDecimal(100)).intValue()));
//            prePay.setTotal_fee("1");
            prePay.setSpbill_create_ip(spbill_create_ip);
            prePay.setNotify_url(notifyUrl);                    // 异步通知,这个下篇文章讲
            prePay.setTrade_type("APP");
            prePay.setAttach(payFlowId);                        // 存入交易流水id

            prePay.setPartnerKey(WXPayContants.partnerKey);

            // 获取预支付订单号
            String prepayId = prePay.submitXmlGetPrepayId();
            logger.info("获取的预支付订单是:" + prepayId);
            if (prepayId != null && prepayId.length() > 10) {
                // 生成微信支付参数,此处拼接为完整的JSON格式,符合支付调起传入格式
                String jsParam = WXPay.createPackageValue(WXPayContants.appId, WXPayContants.partnerKey, prepayId);
                System.out.println("jsParam=" + jsParam);
                // 此处可以添加订单的处理逻辑
                model.addAttribute("jsParam", jsParam);
                logger.info("生成的微信调起JS参数为:" + jsParam);

                payFlowCargoSource.setPrepayId(prepayId);
                spPayFlowCargoSourceService.savePayFlow(payFlowCargoSource);

                return LeeJSONResult.ok();
            } else {
                return LeeJSONResult.errorMsg("微信支付接口调用失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return LeeJSONResult.errorException(e.getMessage());
        }
    }

 

需要注意的是,微信后台接受的参数都是xml格式的,所以咱们的bean需要转换为xml再传给微信,最后调用成功,微信会封装一个xml传过来,咱们同样再解析一下获取预付单号就OK了

public String submitXmlGetPrepayId() {
        // 创建HttpClientBuilder
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        // HttpClient
        CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
        HttpPost httpPost = new HttpPost(unifiedorder);
        String xml = getPackage();
        StringEntity entity;
        try {
            entity = new StringEntity(xml, "utf-8");
            httpPost.setEntity(entity);
            HttpResponse httpResponse;
            // post请求
            httpResponse = closeableHttpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            if (httpEntity != null) {
                // 打印响应内容
                String result = EntityUtils.toString(httpEntity, "UTF-8");
                System.out.println(result);
                // 过滤
                result = result.replaceAll("<![CDATA[|]]>", "");
                String prepay_id = Jsoup.parse(result).select("prepay_id").html();
                this.prepay_id = prepay_id;
                if (prepay_id != null) {
                    return prepay_id;
                }
            }
            // 释放资源
            closeableHttpClient.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return prepay_id;
    }

 

其实不用这样的方式也行,把bean通过json的方式封装,最后让它自动转为xml,也是没有问题的,或者直接使用 restful webservice标准协议来接受xml和发送xml

时间: 2024-10-12 00:18:05

app端微信支付(二) - 生成预付单的相关文章

PHP开发APP端微信支付功能

用PHP开发APP端微信支付的一点个人心得 最近因为公司需求,要开发APP端上的微信支付,看了微信文档,感觉还不错,没有遇到太大的坑,需要注意的点不算太多. 写一个记事文档,作为备忘录. APP支付流程 从上面的图片中,可以看出来,需要注意的流程是一共是3部分: 第一部分:调用下单API,返回预支付订单,签名之后再返回信息(4.5.6.7) 第二部分:异步通知(15.16) 第三部分:最后的判断支付结果 最需要注意的就是第一部分:调用下单API,返回预支付订单,签名之后再返回信息 微信文档中有详

ios-使用微信支付的时候,一定要商户服务器先调用【统一下单API】生成预付单吗?

问题描述 使用微信支付的时候,一定要商户服务器先调用[统一下单API]生成预付单吗? 看了微信的demo和文档,它们的demo里的调用支付方法 都没有商品的名称 描述 价格这些信息, 我们公司android那边说不需要先调下单api,他们都直接调用支付宝支付, 不知道该怎么实现 + (NSString *)jumpToBizPay { //============================================================ // V3&V4支付流程实现 //

携程开启PC端微信支付功能 扫码即可支付

[导读]后续携程 还会将微信支付添加到携程旅游客户端,微信支付的大军日益壮大.携程开启PC端微信支付功能 扫码即可支付 腾讯科技讯(范晓东)2月19日消息, 携程旅行网于今日宣布正式开启其PC 端的微信支付服务,后续该服务将进一步延伸到携程旅行客户端.携程官方称,希望通过其网站和手机端实现微信支付功能为旅游消费群体带来全 新的支付体验.微信5.0推出微信支付以来,用户只需在微信"我的银行卡"选项中关联一张银行卡,并完成身份认证,即可将装有微信App的智能手机变成一个全能钱包,之后可购买

“乐视网TV版”推出业内第一家大屏App的“微信支付”功能

近日,智能电视首选装机应用"乐视网TV版"正式推出业内第一家大屏App的"微信支付"功能,这极大简化了大屏付费操作,实现了用户体验的优化升级.对于首次使用微信支付的用户,乐视网TV版还联手微信,送去了"立减15元"的优惠大礼.据了解,以往用户购买会员时,仅支持使用随硬件附带的充值码付款,且用遥控器输入,操作复杂.在支持微信支付功能后,您只需用手机或Pad上的微信客户端扫一扫屏幕上的二维码,即可在微信内轻松完成付款."目前大屏交互多是用遥

android端微信支付V3版本地签名统一下单详解_Android

满满的都是坑,因为服务器偷懒让客服端写统一下单,服务器只给了通知的url.微信的支付demo并没有统一下单的代码. 读此文前先阅读: https://pay.weixin.qq.com/wiki/doc/api/app/app.PHP?chapter=9_1 一步步的来  先根据统一下单的参数介绍工具: 1. 获取到当前的ip: <span style="font-size:14px;">public String getLocalIpAddress() { try { f

android端微信支付V3版本地签名统一下单详解

满满的都是坑,因为服务器偷懒让客服端写统一下单,服务器只给了通知的url.微信的支付demo并没有统一下单的代码. 读此文前先阅读: https://pay.weixin.qq.com/wiki/doc/api/app/app.PHP?chapter=9_1 一步步的来  先根据统一下单的参数介绍工具: 1. 获取到当前的ip: <span style="font-size:14px;">public String getLocalIpAddress() { try { f

嘀嘀用微信支付完成2100万单 总计补贴4亿元

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 2月12日,嘀嘀打车对外公布接入微信支付的总成绩单,包括嘀嘀打车自身运营状况,详细情况为: 1.1月10日至2月9日,嘀嘀打车中平均日微信支付订单数为70万单,微信支付订单总数约为2100万单. 2.嘀嘀打车开通服务的58个城市均有成功使用微信支付来支付打车费的记录,其中33个城市日均微信支付订单超过1万单. 3.嘀嘀打车过去30天日均订单为

【java】java反射机制,动态获取对象的属性和对应的参数值,并属性按照字典序排序,Field.setAccessible()方法的说明【可用于微信支付 签名生成】

方法1:通过get()方法获取属性值   package com.sxd.test.controller; public class FirstCa{ private Integer num; private String name; private Boolean flag; public Integer getNum() { return num; } public void setNum(Integer num) { this.num = num; } public String getN

app微信支付(一) - 微信支付基本业务流程解析

想必微信支付是现在很多朋友离不开的一个功能,不论是扫描支付还是公众号支付或者app端支付,基本的思路都是一样的,之前做过支付宝支付以及中国移动支付接口,这几天花时间讲讲微信支付吧 先看一下微信支付的时序图,这图是官方提供的 看上去步骤很多,其实仔细划分后就是4个步骤: <1> 生成预付单,用户点击支付后,需要经过自己的后台去调用微信后台生成一个预付单号,这个预付单号是用来跟随整个支付流程的,然后再展示确认支付页面 <2> 用户在确认支付页面看到相关的支付,点击确认支付按钮,然后手机