JAVA微信小程序(嵌套h5)支付

代码基于IJPay-0.8.jar开发,主要是比较省事

JAVA代码:
package com.fh.controller.wx;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.fh.entity.system.PageData;
import com.fh.kit.ApiResponse;
import com.fh.plugins.util.HttpClientUtils;
import com.fh.plugins.util.JsonUtils;
import com.fh.service.app.JFSService;
import com.jpay.ext.kit.HttpKit;
import com.jpay.ext.kit.IpKit;
import com.jpay.ext.kit.PaymentKit;
import com.jpay.weixin.api.WxPayApi;
import com.jpay.weixin.api.WxPayApiConfig;
import com.jpay.weixin.api.WxPayApiConfigKit;

@Controller
@RequestMapping("/wc")
public class WxPayController {
    private Logger log = Logger.getLogger(WxPayController.class);
    // 小程序的appID
    private static final String appID = "";
    private static final String appSecret = "";
    // 支付的ID
    private static final String mchID = "1486736012";// 商户号ID
    private static final String partnerKey = "";// 微信支付商户密钥
    private String notify_url = "https://xxx/jfs/wc/pay_notify.do";//支付回调。

    @Resource(name = "jfsServices")
    private JFSService jfsServices;

    public static WxPayApiConfig getApiConfig() {
        return WxPayApiConfig.New()
                .setAppId(appID)
                .setMchId(mchID)
                .setPaternerKey(partnerKey)
                .setPayModel(WxPayApiConfig.PayModel.BUSINESSMODEL);
    }
    //组装支付参数
    @ResponseBody
    @RequestMapping(value = "/xcxpay.do", method = { RequestMethod.GET, RequestMethod.POST })
    public ApiResponse xcxpay(HttpServletRequest request, HttpServletResponse response, String code, String orderid, String serviceorderid, String type) {
        try {
            String out_trade_no = "JFS" + String.valueOf(System.currentTimeMillis());
            String openId = accessToken(request, appID, appSecret, code);
            if (StringUtils.hasText(openId)) {
                String ip = IpKit.getRealIp(request);
                WxPayApiConfigKit.putApiConfig(getApiConfig());
                String payType = "道路救援";
                String totalFee = "1";//1表示一分钱(单位为分)
                    // 商家数据包
                    Map<String, String> maps = new HashMap<String, String>();
                    maps.put("orderid", orderid);
                    maps.put("serviceorderid", serviceorderid);
                    maps.put("type", type);
                    maps.put("out_trade_no", out_trade_no);
                    String attach = JsonUtils.toJson(maps);

                    Map<String, String> params = WxPayApiConfigKit
                            .getWxPayApiConfig()
                            .setOpenId(openId)
                            .setAttach(attach)//设置附加数据,在查询API和支付通知中原样返回
                            .setBody(payType)
                            .setSpbillCreateIp(ip)
                            .setTotalFee(getMoney(totalFee))
                            .setTradeType(WxPayApi.TradeType.JSAPI)
                            .setNotifyUrl(notify_url)
                            .setOutTradeNo(out_trade_no)// 商户订单号
                            .build();
                    log.info("params-->" + params);
                    String xmlResult = WxPayApi.pushOrder(false, params);
                    log.info("xmlResult - - - - -- " + xmlResult);
                    Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
                    String return_code = result.get("return_code");
                    if (!PaymentKit.codeIsOK(return_code)) {
                        log.info("return_code is null");
                        return new ApiResponse(ApiResponse.Status.ERROR.getCode(), "return_code is null", null);
                    }

                    String result_code = result.get("result_code");
                    if (!PaymentKit.codeIsOK(result_code)) {
                        log.info("result_code is null");
                        return new ApiResponse(ApiResponse.Status.ERROR.getCode(), "result_code is null", null);
                    }
                    // 以下字段在return_code 和result_code都为SUCCESS的时候有返回
                    String prepay_id = result.get("prepay_id");
                    // 封装调起微信支付的参数https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_7&index=5
                    Map<String, String> packageParams = new HashMap<String, String>();
                    packageParams.put("appId", WxPayApiConfigKit.getWxPayApiConfig().getAppId());
                    packageParams.put("timeStamp", System.currentTimeMillis() / 1000 + "");
                    packageParams.put("nonceStr", System.currentTimeMillis() + "");
                    packageParams.put("package", "prepay_id=" + prepay_id);
                    packageParams.put("signType", "MD5");
                    String packageSign = PaymentKit.createSign(packageParams, WxPayApiConfigKit.getWxPayApiConfig().getPaternerKey());
                    packageParams.put("sign", packageSign);

                    // 更新订单表信息,状态为待付款,并保存商户订单号
                  //  jfsServices.paySuccess("1", out_trade_no, orderid);

                    log.info("小程序支付的参数:-->" + packageParams);
                    return new ApiResponse(ApiResponse.Status.SUCCESS.getCode(), "success", packageParams);
                } else {
                    log.info("参数为空:-->payType:" + payType + "\ttotalFee:" + totalFee);
                }
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ApiResponse(ApiResponse.Status.ERROR.getCode(), "error", null);
    }

    /**
     * 微信支付跟支付回调是分开的。支付回调通常是微信收款成功后,让你处理支付成功后的业务逻辑,微信会访问这个地址8次,直到notify_url返回个SUCCESS。
     * @param request
     * @param orderid
     * @param serviceorderid
     * @return
     */
    @RequestMapping(value = "/pay_notify.do", method = { RequestMethod.POST, RequestMethod.GET })
    public void pay_notify(HttpServletRequest req, HttpServletResponse resp) {
        try {

            // 支付结果通用通知文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7
            String xmlMsg = HttpKit.readData(req);
            log.info("pay notice  支付成功后回调---------" + xmlMsg);
            Map<String, String> params = PaymentKit.xmlToMap(xmlMsg);
            String result_code = params.get("result_code");

            WxPayApiConfigKit.setThreadLocalWxPayApiConfig(getApiConfig());

            // 保存订单支付回调信息
            //String out_trade_no = params.get("out_trade_no");
            //String transaction_id = params.get("transaction_id");
           // jfsServices.saveWxPayInfo(out_trade_no, transaction_id, xmlMsg);

            // 注意重复通知的情况,同一订单号可能收到多次通知,请注意一定先判断订单状态
            // 避免已经成功、关闭、退款的订单被再次更新
            if (PaymentKit.verifyNotify(params, WxPayApiConfigKit.getWxPayApiConfig().getPaternerKey())) {
                if ("SUCCESS".equals(result_code)) {
                    // 更新订单信息
                    String attach = params.get("attach");
                    log.info("商家数据包:" + attach);
                    Map<String, Object> maps = JsonUtils.parseJson(attach, Map.class);
                    String orderid = "" + maps.get("orderid");
                    jfsServices.paySuccess("2", out_trade_no, orderid);// 支付成功

                    String result = HttpClientUtils.sendPost("https://xxxx/jfs/JFSUser/paySuccess", maps);
                    log.info("result:" + result);
                    // 发送通知(必须严格按照微信的格式返回,必须按下面用流的形式返回按此不会多次回调)
                    try {
                        PrintWriter out = resp.getWriter();
                        out.write("<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>");
                        out.flush();
                        out.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            // return "";
        
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 通过微信用户的code换取网页授权access_token
     * @return
     * @throws IOException
     * @throwsS
     */
    @SuppressWarnings("unchecked")
    public String accessToken(HttpServletRequest request, String appID, String secret, String code) {
        try {
            String openid = (String) request.getSession().getAttribute("openid");
            if (StringUtils.hasText(openid)) {
                return openid;
            } else {
                String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appID + "&secret=" + appSecret + "&js_code=" + code + "&grant_type=authorization_code";
                HttpClient client = HttpClientBuilder.create().build();
                HttpPost post = new HttpPost(url);
                HttpResponse res = client.execute(post);
                if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                    HttpEntity entity = res.getEntity();
                    String str = EntityUtils.toString(entity, "utf-8");
                    log.info("jscode2session:" + str);
                    Map<String, String> jsonOb = JsonUtils.parseJson(str, Map.class);
                    openid = (String) jsonOb.get("openid");
                    if (StringUtils.hasText(openid)) {
                        request.getSession().setAttribute("openid", openid);
                        return openid;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 元转换成分
     * @param amount
     * @return
     */
    public static String getMoney(String amount) {
        if (StringUtils.isEmpty(amount)) {
            return "";
        }
        // 金额转化为分为单位
        // 处理包含, ¥ 或者$的金额
        String currency = amount.replaceAll("\\$|\\¥|\\,", "");
        int index = currency.indexOf(".");
        int length = currency.length();
        Long amLong = 0l;
        if (index == -1) {
            amLong = Long.valueOf(currency + "00");
        } else if (length - index >= 3) {
            amLong = Long.valueOf((currency.substring(0, index + 3)).replace(".", ""));
        } else if (length - index == 2) {
            amLong = Long.valueOf((currency.substring(0, index + 2)).replace(".", "") + 0);
        } else {
            amLong = Long.valueOf((currency.substring(0, index + 1)).replace(".", "") + "00");
        }
        return amLong.toString();
    }

}
小程序代码(嵌套的H5代码)
Page({
  data: {
    url: ''
  },
  onLoad: function (options) {
    //初始化页面
    if (options.ptype=='pay'){//H5页面调起微信小程序页面,根据传过来的参数ptype判断是否为支付。
        wx.login({
          success: function (res) {
            console.log(res);
            //登录成功
            if (res.code) {
              //调取后台支付参数
              wx.request({
                url: "https://xxx/jfs/wc/xcxpay.do",
                data: {
                  type: options.type,
                  code: res.code,
                  orderid: options.orderid,
                  serviceorderid: options.serviceorderid,
                },
                method: 'GET',
                success: function (res1) {
                  console.log(res1.data.code);
                  if (res1.data.code == 0) {
                    var ret = res1.data.data;
                    console.log(ret.timeStamp);
                    wx.requestPayment({
                      "timeStamp": ret.timeStamp,
                      "package": ret.package,
                      "paySign": ret.sign,
                      "signType": ret.signType,
                      "nonceStr": ret.nonceStr,
                      "paySign": ret.sign,
                      'success': function (r) {//支付成功
                        console.log('success:' + JSON.stringify(r));
                        //跳转到成功页面
                        wx.navigateTo({
                          url: '/pages/index/index?url=https://xxx/success.html',
                          success: function () {
                            console.log('success')
                          }
                        });
                      },
                      'fail': function (r) { //支付失败
                        console.log('fail:' + JSON.stringify(r));
                        //提示支付失败
                        wx.showToast({
                          title: '支付失败:' + JSON.stringify(r),
                          icon: 'none',
                        });
                        //返回付款页面
                        wx.navigateBack({
                          delta: 1
                        });
                      },
                      'complete': function (r) {
                        console.log('complete:' + JSON.stringify(r));
                      }
                    });
                  } else {
                    console.log('获取支付信息失败!' + res1.message)
                  }
                }
              });
            } else {
              console.log('获取用户登录态失败!' + res.errMsg)
            }
          }
        });
      }else{
        var url = options.url ? decodeURIComponent(options.url) : 'https://xxx/index.html'
        this.setData({ url: url });
      }
  },
  onShareAppMessage: (res) => {//分享页面
    return {
      title: '聚福社',
      path: 'pages/index/index?url=' + encodeURIComponent(res.webViewUrl),
      success: (res) => {
        console.log("转发成功");
      },
      fail: (res) => {
        console.log("转发失败");  
      }
    }
  }  
})

<view class="page-body">
    <view class="page-section page-section-gap">
        <web-view src="{{url}}"></web-view>
    </view>
</view>
H5页面调起微信小程序支付代码
       if(window.__wxjs_environment === 'miniprogram') {
            wx.miniProgram.navigateTo({
               url:"/pages/index/index?orderid=" + orderid + "&serviceorderid=" + rid +  "&type=rescures&ptype=pay"
            });
      } else {
            console.log("请在小程序中打开");
      }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值