支付模块-第三方APP如何拉取微信小程序支付(编码篇)

Posted TGB-Earnest

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了支付模块-第三方APP如何拉取微信小程序支付(编码篇)相关的知识,希望对你有一定的参考价值。

【前言】

            今天终于测试了一下获取到了miniPayReRuest,那我就分享一下了。

【实现过程】

    (1)获取参数     

static String wxXcxUrl = "https://api-mop.chinaums.com/v1/netpay/wx/unified-order";

 因为我这个接口是小程序调取的,获取的参数第一个是从小程序获取的code值,第二个参数是服务传给小程序,然后小程序再传给服务的orderId。

   /**
     * app下单方法-微信小程序
     *
     * @param wxXcxPayInfo
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "App下单-微信小程序", notes = "App下单-微信小程序")
    @PostMapping("/wxXcxPay")
    public String placeAnOrderWxXcxPay(WxXcxPayInfo wxXcxPayInfo) throws Exception 

        String code = wxXcxPayInfo.getCode();
        String orderId = wxXcxPayInfo.getOrderId();


        //1、首先,我们要根据code值获取到OpenId
       String openId =wxXcxService.getOpenId(code);
      
        //2、根据订单号获取商品的金额,然后传给银联的接口,返回获取MiniPayRequest,再将openId和参数一起返回。
//        Order orderSellCount = orderService.getSellCountByOrderId(Long.valueOf(orderId));
//        String payNum = orderSellCount.getPayNum();
          Long payNumIs =1L;
//        Long payNumIs = Long.valueOf(payNum);

        AppXiaDanDTO appXiaDanDTO = new AppXiaDanDTO();
        //获取支付的金额
//        appXiaDanDTO.setPlatformAmount(BigDecimal.valueOf(payNumIs));
        appXiaDanDTO.setTotalAmount(BigDecimal.valueOf(1));
        //报文请求时间
        appXiaDanDTO.setRequestTimestamp(DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
        //商户订单号
//        appXiaDanDTO.setMerOrderId(orderId);
        appXiaDanDTO.setMerOrderId(Util.getMerOrderId(msgSrcId));
        //商户号
        appXiaDanDTO.setMid(mid);
        //终端号
        appXiaDanDTO.setTid(tid);
        //微信子商户appId
//        appXiaDanDTO.setSubAppId("");
        appXiaDanDTO.setSubAppId("");
        //用户子标识-微信必传
//        appXiaDanDTO.setSubOpenId("");
        appXiaDanDTO.setSubOpenId(openId);
        //交易类型
        appXiaDanDTO.setTradeType("MINI");
        //业务类型
        appXiaDanDTO.setInstMid("MINIDEFAULT");
        appXiaDanDTO.setPlatformAmount(BigDecimal.valueOf(1));
        String appXiaDanDTOJson = JSONObject.toJSONString(appXiaDanDTO);
        String send = appXiaDanService.send(wxXcxUrl, appXiaDanDTOJson);
        return send;
    

这个code的目的就是为了获取OpenId,orderId看你们自己项目的需求即可。

(2)获取OpenId

@Service
@Slf4j
public class WxXcxServiceImpl implements WxXcxService 

    @Override
    public String getOpenId(String code) throws  Exception 
        //通过code值获取到OpenId
        Map<String,Object> rtnMap = new HashMap<String,Object>();
        String url = "https://api.weixin.qq.com/sns/jscode2session";
        url+="?appid=";
        url+="&secret=";
        url+="&js_code="+code;
        url+="&grant_type=authorization_code";
        String res = null;
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        //Get方式
        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = null;
        //配置信息
        RequestConfig requestConfig = RequestConfig.custom()
                                    .setConnectTimeout(5000)
                                    .setConnectionRequestTimeout(5000)
                                    .setSocketTimeout(5000)
                                    .setRedirectsEnabled(false).build();
        httpGet.setConfig(requestConfig);
        response = httpClient.execute(httpGet);
        //从响应模型中获取响应实体
        HttpEntity responseEntity = response.getEntity();
        System.out.println("响应状态为"+response.getStatusLine());
        if (responseEntity !=null)
            res = EntityUtils.toString(responseEntity);
            System.out.println("响应内容长度为"+responseEntity.getContentLength());
            System.out.println("响应内容为"+res);
        
        //释放资源
        if (httpClient!=null)
            httpClient.close();
        
        if (response!=null)
            response.close();
        
        JSONObject jo = JSON.parseObject(res);
        String openid = jo.getString("openid");
        System.out.println("openid"+openid);
        return openid;


//        return  null;
    

(3) 银联的鉴权

@Slf4j
@Service
@AllArgsConstructor
public class AppXiaDanServiceImpl implements AppXiaDanService 
    static String appId = "";
    static String appKey ="";
    static String authorization;

    @Override
    public String send(String url, String entity) throws Exception 
        authorization = getOpenBodySig(appId,appKey,entity);
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        httpPost.addHeader("Authorization",authorization);
        StringEntity se = new StringEntity(entity,"UTF-8");
        se.setContentType("application/json");
        httpPost.setEntity(se);
        CloseableHttpResponse response = httpClient.execute(httpPost);
        HttpEntity entity1 = response.getEntity();
        String resStr = null;
        if (entity1!=null)
            resStr = EntityUtils.toString(entity1,"UTF-8");
        
        httpClient.close();
        response.close();
        return resStr;
    
    public static String getOpenBodySig(String appId,String appKey,String body) throws Exception
        String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        String nonce = UUID.randomUUID().toString().replace("-", "");
        byte[] data = body.getBytes("UTF-8");
        InputStream is  = new ByteArrayInputStream(data);
        String bodyDigest = testSHA256(is);
        String st1_C=appId+timestamp+nonce+bodyDigest;
        byte[] localSignature = hmacSHA256(st1_C.getBytes(), appKey.getBytes());
        String localSignatureStr =Base64.encodeBase64String(localSignature); //Signature
        return  ("OPEN-BODY-SIG AppId=" + "\\"" + appId + "\\"" + ", Timestamp=" + "\\"" + timestamp + "\\"" + ", Nonce=" + "\\"" + nonce + "\\"" + ", Signature=" + "\\"" + localSignatureStr + "\\"");
    

    private static byte[] hmacSHA256(byte[] data, byte[] key) throws NoSuchAlgorithmException, InvalidKeyException 
        String algorithm = "HmacSHA256";
        Mac mac = Mac.getInstance(algorithm);
        mac.init(new SecretKeySpec(key,algorithm));
        return mac.doFinal(data);
    

    /**
     * 进行加密
     * @param is
     * @return 加密后的结果
     */
    private static String testSHA256(InputStream is) 
        try 
            return DigestUtil.sha256Hex(is);
         catch (Exception e) 
            e.printStackTrace();
        
        return null;
    

【测试返回】

在这时候测试之前还需要营业执照和身份证和微信实名认证

测试结果: 

以上是关于支付模块-第三方APP如何拉取微信小程序支付(编码篇)的主要内容,如果未能解决你的问题,请参考以下文章

微信小程序如何接入微信支付

微信小程序一般去哪里对接一些商品接口

APP支付微信支付,Java后台开发

微信小程序怎么调用微信支付接口

App微信支付 iOS 微信支付 小程序支付 微信公众号支付

微信小程序 方法调用?