微信支付

微信支付

微信支付主要调用两个接口,下单的接口和查询订单的接口

因为涉及到微信扫码支付,所以调用下单接口后,根据返回值里的URL设置到二维码里面、

当付款页面一加载就调用下单接口,

然后二维码一生成就去调用查询订单的接口,查询付款状态。

JS代码
// 创建订单 生成二维码
$scope.createNative = function () {
   // 控制重新生成二维码 需要一个变量控制
   $scope.flag = false;
   payService.createNative().success(function (response) {
       $scope.resultMap = response;
       // response.code_url
       // payImg
       new QRious({
           element: document.getElementById('payImg'),
           size: 300,
           value: response.code_url, // 调用腾讯支付接口后传来的URL
           level: 'L'
       })

       // 一生成二维码就查询订单状态
       $scope.queryOrder(response.out_trade_no);//传入订单号
   })
};
// 查询订单状态
   $scope.queryOrder = function (out_trade_no) {
       payService.queryOrder(out_trade_no).success(function (response) {
           if (response.success) {
               // 跳转到登录成功的页面 传入付款的金额
               location.href = "paysuccess.html#?total_fee=" + $scope.resultMap.total_fee;
           } else {
               // 支付失败
               if (response.message == '支付失败') {
                   location.href = "payfail.html";
               }
               if (response.message == '二维码失效') {
                   $scope.flag = true;
               }
           }
       })
   }

   $scope.showMoney = function () {
       $scope.total_fee = $location.search()['total_fee'];
   }
HTML
<div class="checkout py-container  pay">
  <div class="checkout-tit">
     <h4 class="fl tit-txt"><span class="success-icon"></span><span  class="success-info">订单提交成功,请您及时付款!订单号:{{resultMap.out_trade_no}}</span></h4>
                <span class="fr"><em class="sui-lead">应付金额:</em><em  class="orange money">¥{{(resultMap.total_fee/100).toFixed(2)}}</em></span>
     <div class="clearfix"></div>
  </div>          
  <div class="checkout-steps">
     <div class="fl weixin">微信支付</div>
                <div class="fl sao">
        <p ng-if="flag" class="red">二维码已过期,刷新页面重新获取二维码。<button ng-click="createNative()">重新获取二维码</button></p>
                    <div ng-if="!flag" class="fl code">
                        <img id="payImg">
                        <div class="saosao">
                            <p>请使用微信扫一扫</p>
                            <p>扫描二维码支付</p>
                        </div>
                    </div>
                    <div class="fl phone">
                    </div>
                </div>
                <div class="clearfix"></div>
      <p><a href="pay.html" target="_blank">> 其他支付方式</a></p>
  </div>
</div>
Controller代码
// 生成订单
@RequestMapping("/createNative")
public Map createNative() {
   return payService.createNative(SecurityContextHolder.getContext().getAuthentication().getName());
}

// 查询订单
@RequestMapping("/queryOrder")
public Result queryOrder(String out_trade_no) {
   try {
       // 5分钟=300秒=100次
       int times = 0;
       while (times < 100) {
           Map resultMap = payService.queryOrder(out_trade_no);
           if (resultMap.get("trade_state").equals("SUCCESS")) {
               // int i = 2/0;
               String transactionId = (String) resultMap.get("transaction_id");// 流水号
               // 支付成功后修改支付日志和订单的状态
       payService.updateOrder(SecurityContextHolder.getContext().getAuthentication().getName(), transactionId);
               return new Result(true, "");
           }
           Thread.sleep(3000);
           times++;
           System.out.println("times:" + times);
       }
   } catch (Exception e) {
       e.printStackTrace();
       return new Result(false, "支付失败");
   }
   return new Result(false, "二维码失效");
}
Service
@Service
@Transactional
public class payServiceImpl implements PayService {
   @Value("${appid}")
   private String appid; //公众号
   @Value("${partner}")
   private String partner; //商户号
   @Value("${partnerkey}")
   private String partnerkey; //商户号密码
   @Value("${notifyurl}")
   private String notifyurl;// 回调地址
   @Autowired
   private IdWorker idWorker;
   @Autowired
   private RedisTemplate redisTemplate;
   @Autowired
   private TbPayLogMapper payLogMapper;
   @Autowired
   private TbOrderMapper orderMapper;
 
   @Override
   public Map createNative(String userId) {
       // long out_trade_no = idWorker.nextId();
       TbPayLog payLog = (TbPayLog) redisTemplate.boundHashOps("payLog").get(userId);
       String out_trade_no = payLog.getOutTradeNo(); // 从Redis里面获取订单号
       // 调用统一下单API
       HttpClient httpClient = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
       Map<String, String> paramMap = new HashMap<String, String>();
       // 公众账号ID   appid  是  String(32) wxd678efh567hg6787 微信支付分配的公众账号ID(企业号corpid即为此appId)
       paramMap.put("appid", appid);
       // 商户号  mch_id 是  String(32) 1230000109 微信支付分配的商户号
       paramMap.put("mch_id", partner);
       // 随机字符串    nonce_str  是  String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS   随机字符串,长度要求在32位以内。推荐随机数生成算法
       String nonceStr = WXPayUtil.generateNonceStr();
       paramMap.put("nonce_str", nonceStr);
       // 商品描述 body   是  String(128)    腾讯充值中心-QQ会员充值 商品简单描述,该字段请按照规范传递,具体请见参数规定
       paramMap.put("body", "支付");
       // 商户订单号    out_trade_no   是  String(32) 20150806125346
       paramMap.put("out_trade_no", out_trade_no);
       // 标价金额 total_fee  是  Int    88 订单总金额,单位为分,详见支付金额
       // TODO paramMap.put("total_fee", payLog.getTotalFee()+"");//真实的代码
       paramMap.put("total_fee", "1"); //测试代码
       // 终端IP spbill_create_ip   是  String(16) 123.12.12.123  APP和网页支付提交用户端ip,Native支付填调用微
       paramMap.put("spbill_create_ip", "127.0.0.1");
       // 通知地址 notify_url 是  String(256)    http://www.weixin.qq.com/wxpay/pay.php 异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。
       paramMap.put("notify_url", notifyurl);
       // 交易类型 trade_type 是  String(16) JSAPI        JSAPI -JSAPI支付        NATIVE -Native支付        APP -APP支付
       paramMap.put("trade_type", "NATIVE");
       // 签名 sign 是 String(32) C380BEC2BFD727A4B6845133519F3AD6   通过签名算法计算得出的签名值,详见签名生成算法
       try {
           String paramXml = WXPayUtil.generateSignedXml(paramMap, partnerkey);//生成签名并且把map、转成xml
           httpClient.setXmlParam(paramXml);
           httpClient.post();
           //     int w = 3/0;
           String content = httpClient.getContent();
           Map<String, String> resultMap = WXPayUtil.xmlToMap(content);
           // 页面上需要的金额和订单号
           resultMap.put("out_trade_no", out_trade_no);
           // resultMap.put("total_fee", "1");
           resultMap.put("total_fee", payLog.getTotalFee() + "");
           return resultMap;
       } catch (Exception e) {
           e.printStackTrace();
           return null;
       }
   }

   // 查询订单
   @Override
   public Map queryOrder(String out_trade_no) throws Exception {
       //调用查询订单的支付状态API
       HttpClient httpClient = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
       Map<String, String> paramMap = new HashMap<String, String>();
       // 公众账号ID   appid  是  String(32) wxd678efh567hg6787 微信支付分配的公众账号ID(企业号corpid即为此appId)
       paramMap.put("appid", appid);
       // 商户号  mch_id 是  String(32) 1230000109 微信支付分配的商户号
       paramMap.put("mch_id", partner);
       // 随机字符串    nonce_str  是  String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS   随机字符串,长度要求在32位以内。推荐随机数生成算法
       String nonceStr = WXPayUtil.generateNonceStr();
       paramMap.put("nonce_str", nonceStr);
       // 商户订单号    out_trade_no   是  String(32) 20150806125346
       paramMap.put("out_trade_no", out_trade_no);
       // 签名   sign   是  String(32) C380BEC2BFD727A4B6845133519F3AD6   通过签名算法计算得出的签名值,详见签名生成算法
       String paramXml = WXPayUtil.generateSignedXml(paramMap, partnerkey);//生成签名并且把map、转成xml
       httpClient.setXmlParam(paramXml);
       httpClient.post();
       String content = httpClient.getContent();
       Map<String, String> resultMap = WXPayUtil.xmlToMap(content);
       return resultMap;
   }

   // 支付成功需要修改支付日志表和订单表
   @Override
   public void updateOrder(String userId, String transactionId) {
       // 需要修改的表:
       // tb_pay_log
       TbPayLog payLog = (TbPayLog) redisTemplate.boundHashOps("payLog").get(userId);
       payLog.setPayTime(new Date()); //支付时间
       payLog.setTransactionId(transactionId); //微信交易流水号
       payLogMapper.updateByPrimaryKey(payLog);
       //    tb_order
       // `status` varchar(1) COLLATE utf8_bin DEFAULT NULL COMMENT '状态:1、未付款,2、已付款,3、未发货,4、已发货,5、交易成功,6、交易关闭,7、待评价',
       //  `update_time` datetime DEFAULT NULL COMMENT '订单更新时间',
       //  `payment_time` datetime DEFAULT NULL COMMENT '付款时间',
       String[] orderIds = payLog.getOrderList().split(",");
       for (String orderId : orderIds) {
           TbOrder tbOrder = orderMapper.selectByPrimaryKey(Long.parseLong(orderId));
           tbOrder.setStatus("2");
           tbOrder.setUpdateTime(new Date());
           tbOrder.setPaymentTime(new Date());
           orderMapper.updateByPrimaryKey(tbOrder);
       }
       redisTemplate.boundHashOps("payLog").delete(userId);//清空当前用户的支付日志
       // 清空购物车
        redisTemplate.boundHashOps("cartList").delete(userId);
   }
}
<!--weixinpay.properties-->
appid=XXXX
partner=XXXX
partnerkey=XXXX
notifyurl=http://eeweww2.ngrok.io/WeChatPay/WeChatPayNotify

发表评论