微信公众号支付Java DEMO

微信公众号支付,java实现:

       

由于网络上又已经写好的例子,java环境的DEMO

https://github.com/louiseliu/weixin-pay

当里面的配置文件说得不清楚,下面进行补充。

 

1. 系统调试环境配置:

1.1  配置动态域名:

使用ngrok配置环境;配置ngrok.cfg内容如下:

server_addr: "tunnel.mobi:44433"

trust_host_root_certs: true

1.2 启动ngrok,windows下用cmd

>cd ngrok

>ngrok -config ngrok.cfg-subdomain hc 80

启动后访问地址为hc.tunnel.mobi

1.3  修改sts的tomcat的端口为80

微信支付只访问80端口。

 

Configure.java文件中配置信息:

1.4获取微信的关键配置参数详解

1.4.1.appid       微信公众平台-开发者中心-配置项-开发者ID

1.4.2.appSecret


1.4.3.微信支付商户号mchid=1267692501

微信支付、商户平台—账户信息--基本账户信息


1.4.4 subMchID受理模式下给予商户分配的子商户号,默认可填””

 

1.4.5. key

位置:微信支付、商户平台—账户设置—API安全—API密钥

输入一个32位的字母数字组成的字符串。


1.4.6         certLocalPath

位置:微信支付、商户平台—账户设置—API安全—API证书



certLocalPath=”绝对路径下的apiclient_cert.p12”

下载后的*.p12文件需要windows上可以直接双击导入系统,导入过程中会提示输入证书密码,证书密码默认为您的商户ID(mchID)

证书的导入:

微信支付接口中,涉及资金回滚的接口会使用到商户证书,包括退款、撤销接口。商家在申请微信支付成功后,收到的相应邮件后,可以按照指引下载API证书,也可以按照以下路径下载:

微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->证书下载 。证书文件有四个,

apiclient_cert.p12是商户证书文件,除PHP外的开发均使用此证书文件。

双击apiclient_cert.p12文件,

windows上可以直接双击导入系统,导入过程中会提示输入证书密码,证书密码默认为您的商户ID(如:1267692501)

 

1.4.7         certPassword=mchID

也可以在上面的导入p12的文件时,重新设置密码,注意此处的密码不能为空,因为空密码会报错。

 

1.4.8         notifyCallbackUrl

默认回调地址预订单生成完成后的回调地址.

notifyCallbackUrl=http://hc.tunnel.mobi/shopapi/weixin/authorize/UnifiedorderCallBack

 

1.5配置用户消息,和开发者需要的事件推送。

1.5.1在微信开发者mp.weixin.qq.com,找到开发者中心—配置项—服务器配置


1.5.2开发账号里面找到。

开发者中心,在这里再找“网页账号”修改hc.tunnel.mobi

服务器配置中,URL(服务器地址)修改为http://hc.tunnel.mobi/shopapi/weixin/verify

Token(令牌)为:weixinCourse


1.5.3开发者中心—配置项中查找网页账号 设置对应的回调地址:


1.5.4微信验证的控制方法:

    /**

     * 微信验证

     * 请填写接口配置信息,此信息需要你有自己的服务器资源,填写的URL需要正确响应微信发送的Token验证

     * 验证服务器地址的有效性

     * 开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带四个参数:

     * 参数  描述

     * signature   微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。

     * timestamp   时间戳

     * nonce   随机数

     * echostr 随机字符串

     * @return

     * @throwsIOException

     */

    @RequestMapping(value = "/weixin/verify",method = RequestMethod.GET)

    public voidweixinVerify(Model model, WeixinVerifyDto verify, HttpServletResponse response) throwsIOException{

       PrintWriter out = response.getWriter();

       if (SignUtil.checkSignature(verify.getSignature(), verify.getTimestamp(),verify.getNonce())) { 

           model.addAttribute("echoStr", verify.getEchostr());

           out.print(verify.getEchostr());

       }

       //return "verify";

       out.close(); 

       out = null;

    }

SignUtil

import java.security.MessageDigest;

importjava.security.NoSuchAlgorithmException;

import java.util.Arrays;

 

public class SignUtil {

   // 与接口配置信息中的Token要一致

   private static String token = "weixinCourse";

 

   /**

    * 验证签名

    *

    * @param signature

    * @param timestamp

    * @param nonce

    * @return

    */

   public static boolean checkSignature(String signature, String timestamp,

           String nonce) {

       String[] arr = new String[] { token, timestamp, nonce };

       // 将token、timestamp、nonce三个参数进行字典序排序

       Arrays.sort(arr);

       StringBuilder content = new StringBuilder();

       for (int i = 0; i < arr.length; i++) {

           content.append(arr[i]);

       }

       MessageDigest md = null;

       String tmpStr = null;

 

       try {

           md =MessageDigest.getInstance("SHA-1");

           // 将三个参数字符串拼接成一个字符串进行sha1加密

           byte[] digest = md.digest(content.toString().getBytes());

           tmpStr = byteToStr(digest);

       } catch (NoSuchAlgorithmException e) {

           e.printStackTrace();

       }

 

       content = null;

       // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信

       return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;

    }

 

   /**

    * 将字节数组转换为十六进制字符串

    *

    * @param byteArray

     * @return

    */

   private static String byteToStr(byte[] byteArray) {

       String strDigest = "";

       for (int i = 0; i < byteArray.length; i++) {

           strDigest += byteToHexStr(byteArray[i]);

       }

       return strDigest;

    }

 

   /**

    * 将字节转换为十六进制字符串

    *

    * @param mByte

    * @return

    */

   private static String byteToHexStr(byte mByte) {

       char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',

                'B', 'C', 'D', 'E', 'F' };

       char[] tempArr = new char[2];

       tempArr[0] = Digit[(mByte >>> 4) & 0X0F];

       tempArr[1] = Digit[mByte & 0X0F];

 

       String s = new String(tempArr);

       return s;

    }

}

 

WeixinVerifyDto

/**

 * 开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带四个参数:

 * 开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。

 * 加密/校验流程如下:

 * 1. tokentimestampnonce三个参数进行字典序排序

 * 2. 将三个参数字符串拼接成一个字符串进行sha1加密

 * 3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

 * @author HuangC

 *

 */

public classWeixinVerifyDto {

   /**

     * 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。

     */

   privateString signature;

   /**

     * 时间戳

     */

   privateString timestamp;

   /**

     * 随机数

     */

   privateString nonce;

   /**

     * 随机字符串

     */

   privateString echostr;

 

   publicString getSignature() {

        return signature;

   }

   publicvoidsetSignature(String signature){

        this.signature = signature;

   }

   publicString getTimestamp() {

        return timestamp;

   }

   publicvoidsetTimestamp(String timestamp){

        this.timestamp = timestamp;

   }

   publicString getNonce() {

        return nonce;

   }

   publicvoidsetNonce(String nonce){

        this.nonce = nonce;

   }

   publicString getEchostr() {

        return echostr;

   }

   publicvoidsetEchostr(String echostr){

        this.echostr = echostr;

   }

}

2.测试:

找到PayUtils这个文件。增加下面的代码:

   publicstaticvoidmain(String[] args){

        PayPackage payPackage = new PayPackage();

        PayQrCode qrCode = new PayQrCode("3214123423");

        payPackage.setAppid(Configure.getAppid());

        payPackage.setAttach("test");

        payPackage.setBody("JSAPI测试支付");

        payPackage.setNonce_str(qrCode.getNonce_str());

        payPackage.setMch_id(qrCode.getMch_id());

        payPackage.setOpenid("o0IrGwYeRrTbko6LlV0rOoanJHbc");

        payPackage.setOut_trade_no(UUID.randomUUID().toString().replace("-", ""));

        payPackage.setProduct_id(qrCode.getProduct_id());

        payPackage.setSpbill_create_ip("14.23.150.211");

        payPackage.setTotal_fee("1");

        payPackage.setTrade_type("JSAPI");

       String replyXml = PayUtils.generatePayNativeReplyXML(payPackage);

    }

如果顺利的话就能获取下面的xml格式的String

<xml><return_code><![CDATA[SUCCESS]]></return_code>

           <return_msg><![CDATA[OK]]></return_msg>

           <appid><![CDATA[wxc5952d6707163051]]></appid>

           <mch_id><![CDATA[1267692501]]></mch_id>

           <nonce_str><![CDATA[W0hfWAbtLZFoD1ve]]></nonce_str>

           <sign><![CDATA[823932B441E438B74C83E537BCA141AE]]></sign>

           <result_code><![CDATA[SUCCESS]]></result_code>

           <prepay_id><![CDATA[wx2015090617140717bdc800320309813499]]></prepay_id>

           <trade_type><![CDATA[JSAPI]]></trade_type>

           </xml>

  • 6
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值