关于微信支付(一)

微信支付有两种方式

1.第三方网站弹出二维码客户扫描支付

2.在微信内部H5直接发起支付

这篇文章先讲 第一种最常用的 弹出二维码支付

二维码支付

大概流程如下

用户选择支付->后台程序创建订单->请求微信同意下单接口(除了常规参数还需要一个接口这个URL是用户支付完成后通知你的接口)->提交成功后 微信返回参数其中有一个链接,这个链接转成二维码 用户扫描就可以支付了

此时支付流程已经结束

如果用户支付了 微信就会调用你的URL 通知你,你需要返回给微信 一个信息(大概意思就是 告诉微信我知道了) 不然微信会一直 请求你

<!--more-->

准备工作

URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder

参数:

字段名 变量名 必填 类型 示例值 描述
公众账号ID appid String(32) wxd678efh567hg6787 微信支付分配的公众账号ID(企业号corpid即为此appId)
商户号 mch_id String(32) 1230000109 微信支付分配的商户号
设备号 device_info String(32) 013467007045764 自定义参数,可以为终端设备号(门店号或收银设备ID),PC网页或公众号内支付可以传"WEB"
随机字符串 nonce_str String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS 随机字符串,长度要求在32位以内。推荐随机数生成算法
签名 sign String(32) C380BEC2BFD727A4B6845133519F3AD6 通过签名算法计算得出的签名值,详见签名生成算法
签名类型 sign_type String(32) MD5 签名类型,默认为MD5,支持HMAC-SHA256和MD5。
商品描述 body String(128) 腾讯充值中心-QQ会员充值 商品简单描述,该字段请按照规范传递,具体请见参数规定
商品详情 detail String(6000) 商品详细描述,对于使用单品优惠的商户,改字段必须按照规范上传,详见“单品优惠参数说明”
附加数据 attach String(127) 深圳分店 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用。
商户订单号 out_trade_no String(32) 20150806125346 商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。详见商户订单号
标价币种 fee_type String(16) CNY 符合ISO 4217标准的三位字母代码,默认人民币:CNY,详细列表请参见货币类型
标价金额 total_fee Int 88 订单总金额,单位为分,详见支付金额
终端IP spbill_create_ip String(16) 123.12.12.123 APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP。
交易起始时间 time_start String(14) 20091225091010 订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则
交易结束时间 time_expire String(14) 20091227091010 订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。订单失效时间是针对订单号而言的,由于在请求支付的时候有一个必传参数prepay_id只有两小时的有效期,所以在重入时间超过2小时的时候需要重新请求下单接口获取新的prepay_id。其他详见时间规则建议:最短失效时间间隔大于1分钟
订单优惠标记 goods_tag String(32) WXG 订单优惠标记,使用代金券或立减优惠功能时需要的参数,说明详见代金券或立减优惠
通知地址 notify_url String(256) http://www.weixin.qq.com/wxpay/pay.php 异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。
交易类型 trade_type String(16) JSAPI JSAPI 公众号支付NATIVE 扫码支付APP APP支付说明详见参数规定
商品ID product_id String(32) 12235413214070356458058 trade_type=NATIVE时(即扫码支付),此参数必传。此参数为二维码中包含的商品ID,商户自行定义。
指定支付方式 limit_pay String(32) no_credit 上传此参数no_credit--可限制用户不能使用信用卡支付
用户标识 openid String(128) oUpF8uMuAJO_M2pxb1Q9zNjWeS6o trade_type=JSAPI时(即公众号支付),此参数必传,此参数为微信用户在商户对应appid下的唯一标识。openid如何获取,可参考【获取openid】。企业号请使用【企业号OAuth2.0接口】获取企业号内成员userid,再调用【企业号userid转openid接口】进行转换
-场景信息 scene_info String(256) {"store_info" : {"id": "SZTX001","name": "腾大餐厅","area_code": "440305","address": "科技园中一路腾讯大厦" }} 该字段用于上报场景信息,目前支持上报实际门店信息。该字段为JSON对象数据,对象格式为{"store_info":{"id": "门店ID","name": "名称","area_code": "编码","address": "地址" }} ,字段详细说明请点击行前的+展开
-门店id id String(32) SZTX001 门店唯一标识
-门店名称 name String(64) 腾讯大厦腾大餐厅 门店名称
-门店行政区划码 area_code String(6) 440305 门店所在地行政区划码,详细见《最新县及县以上行政区划代码》
-门店详细地址 address String(128) 科技园中一路腾讯大厦 门店详细地址

举例如下:

<xml><appid>wx2421b1c4370ec43b</appid><attach>支付测试</attach><body>JSAPI支付测试</body><mch_id>10000100</mch_id><detail><![CDATA[{ "goods_detail":[ { "goods_id":"iphone6s16G", "wxpay_goods_id":"1001", "goods_name":"iPhone6s 16G", "quantity":1, "price":528800, "goods_category":"123456", "body":"苹果手机" }, { "goods_id":"iphone6s32G", "wxpay_goods_id":"1002", "goods_name":"iPhone6s 32G", "quantity":1, "price":608800, "goods_category":"123789", "body":"苹果手机" } ] }]]></detail><nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str><notify_url>http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php</notify_url><openid>oUpF8uMuAJO_M2pxb1Q9zNjWeS6o</openid><out_trade_no>1415659990</out_trade_no><spbill_create_ip>14.23.150.211</spbill_create_ip><total_fee>1</total_fee><trade_type>JSAPI</trade_type><sign>0CB01533B8C1EF103065174F50BCA001</sign></xml>

这里 我发现请求参数太多了 所以我把所有请求参数 返回参数都做成了对象,首先是微信同意下单 参数接口

/*** 统一下单请求参数(必填)* @author An**/
public class UnifiedOrderRequest {private String appid;               //公众账号IDprivate String mch_id;              //商户号private String nonce_str;           //随机字符串private String sign;                //签名private String body;                //商品描述private String out_trade_no;        //商户订单号private String total_fee;           //总金额private String spbill_create_ip;    //终端IPprivate String notify_url;          //通知地址private String trade_type;          //交易类型public String getAppid() {return appid;}public void setAppid(String appid) {this.appid = appid;}public String getMch_id() {return mch_id;}public void setMch_id(String mch_id) {this.mch_id = mch_id;}public String getNonce_str() {return nonce_str;}public void setNonce_str(String nonce_str) {this.nonce_str = nonce_str;}public String getSign() {return sign;}public void setSign(String sign) {this.sign = sign;}public String getBody() {return body;}public void setBody(String body) {this.body = body;}public String getOut_trade_no() {return out_trade_no;}public void setOut_trade_no(String out_trade_no) {this.out_trade_no = out_trade_no;}public String getTotal_fee() {return total_fee;}public void setTotal_fee(String total_fee) {this.total_fee = total_fee;}public String getSpbill_create_ip() {return spbill_create_ip;}public void setSpbill_create_ip(String spbill_create_ip) {this.spbill_create_ip = spbill_create_ip;}public String getNotify_url() {return notify_url;}public void setNotify_url(String notify_url) {this.notify_url = notify_url;}public String getTrade_type() {return trade_type;}public void setTrade_type(String trade_type) {this.trade_type = trade_type;}
}
/*** 统一下单请求参数(非必填)* @author An**/
public class UnifiedOrderRequestExt extends UnifiedOrderRequest{private String device_info;         //设备号private String detail;              //商品详情private String attach;              //附加数据private String fee_type;            //货币类型private String time_start;          //交易起始时间private String time_expire;         //交易结束时间private String goods_tag;           //商品标记private String product_id;          //商品IDprivate String limit_pay;           //指定支付方式private String openid;              //用户标识public String getDevice_info() {return device_info;}public void setDevice_info(String device_info) {this.device_info = device_info;}public String getDetail() {return detail;}public void setDetail(String detail) {this.detail = detail;}public String getAttach() {return attach;}public void setAttach(String attach) {this.attach = attach;}public String getFee_type() {return fee_type;}public void setFee_type(String fee_type) {this.fee_type = fee_type;}public String getTime_start() {return time_start;}public void setTime_start(String time_start) {this.time_start = time_start;}public String getTime_expire() {return time_expire;}public void setTime_expire(String time_expire) {this.time_expire = time_expire;}public String getGoods_tag() {return goods_tag;}public void setGoods_tag(String goods_tag) {this.goods_tag = goods_tag;}public String getProduct_id() {return product_id;}public void setProduct_id(String product_id) {this.product_id = product_id;}public String getLimit_pay() {return limit_pay;}public void setLimit_pay(String limit_pay) {this.limit_pay = limit_pay;}public String getOpenid() {return openid;}public void setOpenid(String openid) {this.openid = openid;}
}

准备两个工具类

1.MD5加密工具类

public class WeChatMD5{/*** * @see    MD5加密* @param origin 被加密字符串* @param input_charset 字符串编码方式* @return*/public static String MD5Encode(String origin,String input_charset){return DigestUtils.md5Hex(getContentBytes(origin, input_charset));}/*** 签名字符串* @param text 需要签名的字符串* @param sign 签名结果* @param key 密钥* @param input_charset 编码格式* @return 签名结果*/public static boolean verify(String text, String sign, String input_charset) {String mysign = DigestUtils.md5Hex(getContentBytes(text, input_charset)).toUpperCase();if(mysign.equals(sign)) {return true;}else {return false;}}/*** @param content* @param charset* @return* @throws SignatureException* @throws UnsupportedEncodingException */private static byte[] getContentBytes(String content, String charset) {if (charset == null || "".equals(charset)) {return content.getBytes();}try {return content.getBytes(charset);} catch (UnsupportedEncodingException e) {throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);}}
}

2.微信支付工具类

public class WeChatPayUtil {/*** 生成随机字符串* @param length 长度* @return*/public static String getRandomString(int length) {  String base = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";         Random random = new Random();         StringBuffer sb = new StringBuffer();      for (int i = 0; i < length; i++) {         int number = random.nextInt(base.length());         sb.append(base.charAt(number));         }         return sb.toString();         }/*** 统一下单生成签名* @param unifiedOrderRequest* @return*/public static String createSign(UnifiedOrderRequestExt unifiedOrderRequest) {//根据规则创建可排序的map集合SortedMap<String, String> packageParams = new TreeMap<String, String>();packageParams.put("appid", unifiedOrderRequest.getAppid());packageParams.put("body", unifiedOrderRequest.getBody());packageParams.put("mch_id", unifiedOrderRequest.getMch_id());packageParams.put("nonce_str", unifiedOrderRequest.getNonce_str());packageParams.put("notify_url", unifiedOrderRequest.getNotify_url());packageParams.put("out_trade_no", unifiedOrderRequest.getOut_trade_no());packageParams.put("spbill_create_ip", unifiedOrderRequest.getSpbill_create_ip());packageParams.put("trade_type", unifiedOrderRequest.getTrade_type());packageParams.put("total_fee", unifiedOrderRequest.getTotal_fee());packageParams.put("attach", unifiedOrderRequest.getAttach());if(unifiedOrderRequest.getOpenid()!=null){packageParams.put("openid",unifiedOrderRequest.getOpenid());}StringBuffer sb = new StringBuffer();Set<Entry<String, String>> es = packageParams.entrySet();//字典序Iterator<Entry<String, String>> it = es.iterator();while (it.hasNext()) {Entry<String, String> entry = (Entry<String, String>) it.next();String key = (String) entry.getKey();String value = (String) entry.getValue();//为空不参与签名、参数名区分大小写if (null != value && !"".equals(value) && !"sign".equals(key)&& !"key".equals(key)) {sb.append(key + "=" + value + "&");}}//微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置String key=Config.getStringValue("key");System.out.println(packageParams);sb.append("key=" +key);String sign = WeChatMD5.MD5Encode(sb.toString(), "utf-8") .toUpperCase();//MD5加密System.out.println(sign);return sign;}public static String createSign(UnifiedOrderSelect unifiedOrderRequest) {//根据规则创建可排序的map集合SortedMap<String, String> packageParams = new TreeMap<String, String>();packageParams.put("appid", unifiedOrderRequest.getAppid());packageParams.put("mch_id", unifiedOrderRequest.getMch_id());packageParams.put("out_trade_no", unifiedOrderRequest.getOut_trade_no());packageParams.put("nonce_str", unifiedOrderRequest.getNonce_str());StringBuffer sb = new StringBuffer();Set<Entry<String, String>> es = packageParams.entrySet();//字典序Iterator<Entry<String, String>> it = es.iterator();while (it.hasNext()) {Entry<String, String> entry = (Entry<String, String>) it.next();String key = (String) entry.getKey();String value = (String) entry.getValue();//为空不参与签名、参数名区分大小写if (null != value && !"".equals(value) && !"sign".equals(key)&& !"key".equals(key)) {sb.append(key + "=" + value + "&");}}//微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置String key=Config.getStringValue("key");System.out.println(packageParams);sb.append("key=" +key);String sign = WeChatMD5.MD5Encode(sb.toString(), "utf-8") .toUpperCase();//MD5加密System.out.println(sign);return sign;}
}

其中有一个生成随机字符串的 函数还有一个签名的函数,签名一会用到在讲

@Component
public class WeChatPay {static Log log =LogFactory.getLog(WeChatPay.class);//同意下单APIpublic static final String PAYURL="https://api.mch.weixin.qq.com/pay/unifiedorder";//查询订单APIpublic static final String SELECT="https://api.mch.weixin.qq.com/pay/orderquery";public static void main(String[] args) {}/*** 生成订单方法* @param body 订单详情* @param orderId 订单号* @param money 价格/元* @param ip 用户端IP* @return*/public String createOrderInfo(String body,String orderId,float money,String key,String tradeType,String openid) {String ip="";//生成订单对象String resule="";try {ip = InetAddress.getLocalHost().getHostAddress().toString();log.info("=.=生成订单开始(body="+body+",orderId="+orderId+",money="+money+",ip="+ip+")=.=");String appid=Config.getStringValue("appID");String mchId=Config.getStringValue("mch_id");UnifiedOrderRequestExt unifiedOrderRequest = new UnifiedOrderRequestExt();unifiedOrderRequest.setAppid(appid);//公众账号IDunifiedOrderRequest.setMch_id(mchId);//商户号if(openid!=null){unifiedOrderRequest.setOpenid(openid);}unifiedOrderRequest.setAttach(orderId+","+key);//自定义参数 通知的时候修改成功和支付时间unifiedOrderRequest.setNonce_str(WeChatPayUtil.getRandomString(11));//随机字符串unifiedOrderRequest.setBody(body);//商品描述unifiedOrderRequest.setOut_trade_no(orderId);//商户订单号Float f = new Float(money*100);int money1 = f.intValue();unifiedOrderRequest.setTotal_fee(money1+""); //单位分所以成100unifiedOrderRequest.setSpbill_create_ip(ip);//终端IPunifiedOrderRequest.setNotify_url(Config.getStringValue("notifyUrl"));//通知地址unifiedOrderRequest.setTrade_type(tradeType);//JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付unifiedOrderRequest.setSign(WeChatPayUtil.createSign(unifiedOrderRequest));//签名//将订单对象转为xml格式XStream xStream = new XStream(new XppDriver(new XmlFriendlyNameCoder("_-", "_")));xStream.alias("xml", UnifiedOrderRequest.class);//根元素名需要是xmlresule = xStream.toXML(unifiedOrderRequest);System.out.println("XML="+resule);} catch (Exception e) {log.info("=.=创建订单异常"+e.getMessage());e.printStackTrace();}log.info("=.=生成订单结束=.=");return resule;}/*** 统一下单* @param orderInfo 订单信息* @return*/public static UnifiedOrderRespose httpOrder(String orderInfo) {try {log.info("=.=同意下单开始=.=");HttpURLConnection conn = (HttpURLConnection) new URL(PAYURL).openConnection();//加入数据  conn.setRequestMethod("POST");  conn.setDoOutput(true);  BufferedOutputStream buffOutStr = new BufferedOutputStream(conn.getOutputStream());  buffOutStr.write(orderInfo.getBytes());buffOutStr.flush();  buffOutStr.close();  //获取输入流  BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));  String line = null;  StringBuffer sb = new StringBuffer();  while((line = reader.readLine())!= null){  sb.append(line);  }  XStream xStream = new XStream(new XppDriver(new XmlFriendlyNameCoder("_-", "_")));//将请求返回的内容通过xStream转换为UnifiedOrderRespose对象xStream.alias("xml", UnifiedOrderRespose.class);UnifiedOrderRespose unifiedOrderRespose = (UnifiedOrderRespose) xStream.fromXML(sb.toString());//根据微信文档return_code 和result_code都为SUCCESS的时候才会返回code_urlif(null!=unifiedOrderRespose  && "SUCCESS".equals(unifiedOrderRespose.getReturn_code())  && "SUCCESS".equals(unifiedOrderRespose.getResult_code())){log.info("=.=同意下单成功=.=");return unifiedOrderRespose;}else{log.info("=.=调用微信参数错误=.="+unifiedOrderRespose.getReturn_msg()+"code"+unifiedOrderRespose.getReturn_code());return null;}} catch (Exception e) {log.info("=.=调用统一下单接口异常"+e.getLocalizedMessage());e.printStackTrace();}return null;}/*** 创建查询订单* @param outTradeNo* @return*/public String createOrderSelect(String outTradeNo){//String ip="";//生成订单对象String resule="";try {String appid=Config.getStringValue("appID");String mchId=Config.getStringValue("mch_id");UnifiedOrderSelect unifiedOrderRequest = new UnifiedOrderSelect();unifiedOrderRequest.setAppid(appid);//公众账号IDunifiedOrderRequest.setMch_id(mchId);//商户号unifiedOrderRequest.setNonce_str(WeChatPayUtil.getRandomString(11));//随机字符串unifiedOrderRequest.setOut_trade_no(outTradeNo);//商户订单号unifiedOrderRequest.setSign(WeChatPayUtil.createSign(unifiedOrderRequest));//签名//将订单对象转为xml格式XStream xStream = new XStream(new XppDriver(new XmlFriendlyNameCoder("_-", "_")));xStream.alias("xml", UnifiedOrderRequest.class);//根元素名需要是xmlresule = xStream.toXML(unifiedOrderRequest);System.out.println("XML="+resule);} catch (Exception e) {log.info("=.=创建订单异常"+e.getMessage());e.printStackTrace();}log.info("=.=生成订单结束=.=");return resule;}/*** 请求查询订单* @param orderInfo*/public static UnifiedOrderSelectRespose httpSelectOrder(String orderInfo){try {log.info("=.=查询订单开始=.=");HttpURLConnection conn = (HttpURLConnection) new URL(SELECT).openConnection();log.info("SELECT"+SELECT);//加入数据  conn.setRequestMethod("POST");  conn.setDoOutput(true);  BufferedOutputStream buffOutStr = new BufferedOutputStream(conn.getOutputStream());  buffOutStr.write(orderInfo.getBytes());buffOutStr.flush();  buffOutStr.close();  //获取输入流  BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));  String line = null;  StringBuffer sb = new StringBuffer();  while((line = reader.readLine())!= null){  sb.append(line);  }  XStream xStream = new XStream(new XppDriver(new XmlFriendlyNameCoder("_-", "_")));//将请求返回的内容通过xStream转换为UnifiedOrderRespose对象xStream.alias("xml", UnifiedOrderSelectRespose.class);log.info("xml="+sb.toString());UnifiedOrderSelectRespose unifiedOrderSelectRespose = (UnifiedOrderSelectRespose) xStream.fromXML(sb.toString());//根据微信文档return_code 和result_code都为SUCCESS的时候才会返回code_urlif(null!=unifiedOrderSelectRespose  && "SUCCESS".equals(unifiedOrderSelectRespose.getReturn_code())  && "SUCCESS".equals(unifiedOrderSelectRespose.getResult_code())){log.info("=.=查询订单成功=.=");return unifiedOrderSelectRespose;}else{log.info("=.=调用微信参数错误=.="+unifiedOrderSelectRespose.getReturn_msg()+"code"+unifiedOrderSelectRespose.getReturn_code());return null;}} catch (Exception e) {log.info("=.=调用统一下单接口异常"+e.getLocalizedMessage());e.printStackTrace();}return null;}
}

创建订单

createOrderInfo(String body,String orderId,float money,String key,String tradeType,String openid)

这个方法就是创建订单,等同于拼XML只不过我这里是封装成对象 然后利用XStream讲对象转成XML

其中有一个OpenId 这个是为了便于以后 微信号内部支付的暂时用不到,所以穿null,这里

商品详情 会显示在用户扫码后提示给用户 你购买的是什么

orderId必须是唯一的,不然同样的订单号无法生成

money是商品价格单位分

key 这里是我的一个参数,我利用WebSocket即使修改页面 告诉用户支付完成

tradeType 类型 SAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付 这里我们传NATIVE

微信签名

这个方法没什么说的,无非是set set set 其中unifiedOrderRequest.setSign(WeChatPayUtil.createSign(unifiedOrderRequest))

微信的签名是一个比较重要的东西

这里可以看我微信工具类的代码

具体流程如下

第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。

特别注意以下重要规则:

  1. ◆ 参数名ASCII码从小到大排序(字典序);
  2. ◆ 如果参数的值为空不参与签名;
  3. ◆ 参数名区分大小写;
  4. ◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
  5. ◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段

第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。

说白了 就是把你所有参数 按照字典序 排序一下 然后拼上key 然后MD5运算一下得到一个字符串

如果签名总是错误可以利用 签名验证工具

创建订单后 就该提交订单了调用UnifiedOrderRespose(Stirng info) 方法

调用同意下单接口

讲上一步拼接后的XML提交给UnifiedOrderRespose

UnifiedOrderRespose 也没什么说的这里我把接收到的值也转换成了对象

/*** 统一下单返回参数* @author An**/
public class UnifiedOrderRespose {private String return_code;             //返回状态码private String return_msg;              //返回信息/* 以下字段在return_code为SUCCESS的时候有返回*/private String appid;                   //公众账号IDprivate String mch_id;                  //商户号private String device_info;             //设备号private String nonce_str;               //随机字符串private String sign;                    //签名private String result_code;             //业务结果private String err_code;                //错误代码private String err_code_des;           //错误代码描述/* 以下字段在return_code 和result_code都为SUCCESS的时候有返回  */private String trade_type;              //交易类型private String prepay_id;               //预支付交易会话标识private String code_url;                //二维码链接public String getReturn_code() {return return_code;}public void setReturn_code(String return_code) {this.return_code = return_code;}public String getReturn_msg() {return return_msg;}public void setReturn_msg(String return_msg) {this.return_msg = return_msg;}public String getAppid() {return appid;}public void setAppid(String appid) {this.appid = appid;}public String getMch_id() {return mch_id;}public void setMch_id(String mch_id) {this.mch_id = mch_id;}public String getDevice_info() {return device_info;}public void setDevice_info(String device_info) {this.device_info = device_info;}public String getNonce_str() {return nonce_str;}public void setNonce_str(String nonce_str) {this.nonce_str = nonce_str;}public String getSign() {return sign;}public void setSign(String sign) {this.sign = sign;}public String getResult_code() {return result_code;}public void setResult_code(String result_code) {this.result_code = result_code;}public String getErr_code() {return err_code;}public void setErr_code(String err_code) {this.err_code = err_code;}public String getErr_code_des() {return err_code_des;}public void setErr_code_des(String err_code_des) {this.err_code_des = err_code_des;}public String getTrade_type() {return trade_type;}public void setTrade_type(String trade_type) {this.trade_type = trade_type;}public String getPrepay_id() {return prepay_id;}public void setPrepay_id(String prepay_id) {this.prepay_id = prepay_id;}public String getCode_url() {return code_url;}public void setCode_url(String code_url) {this.code_url = code_url;}}

这里的 code_url 就是二维码链接 你可以用你的方式转换成二维码,如果没有好的解决方案,可以参考我的其他博客 将URL利用JS 转换成二维码 填充DIV

注意:prepay_id这个参数是微信内部支付需要的东西

接收支付信息

这样二维码就弹出来了,客户开始扫码 如果扫码支付成功,微信就会调用我们的通知接口

//用于回信回调更改支付状态
@RequestMapping("/weChatUpdRecharge")
public void weChatUpdRecharge(HttpServletRequest request,HttpServletResponse response){log.info("=.=微信异步通知开始=.=");// 获取post传输的数据String request_xml = "";UnifiedOrderCallback unifiedOrderCallback=null;try {ServletInputStream inputStram = request.getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader(inputStram));String temp = "";while ((temp = br.readLine()) != null) {request_xml = request_xml + temp;}log.info("=.=微信返回结果=.=" + request_xml);XStream xStream = new XStream(new XppDriver(new XmlFriendlyNameCoder("_-", "_")));//将请求返回的内容通过xStream转换为UnifiedOrderRespose对象xStream.alias("xml", UnifiedOrderCallback.class);unifiedOrderCallback = (UnifiedOrderCallback) xStream.fromXML(request_xml);WechatCallback wechatCallback=new WechatCallback();wechatCallback.setId(0);wechatCallback.setBankType(unifiedOrderCallback.getBank_type());wechatCallback.setErrCode(unifiedOrderCallback.getErr_code());wechatCallback.setErrCodeDes(unifiedOrderCallback.getErr_code_des());wechatCallback.setOpenid(unifiedOrderCallback.getOpenid());wechatCallback.setOutTradeNo(unifiedOrderCallback.getOut_trade_no());wechatCallback.setRechargeNumber(unifiedOrderCallback.getAttach().split(",")[0]);wechatCallback.setResultCode(unifiedOrderCallback.getResult_code());wechatCallback.setTimeEnd(unifiedOrderCallback.getTime_end());wechatCallback.setTotalFee(Integer.parseInt(unifiedOrderCallback.getTotal_fee()));wechatCallback.setTransactionId(unifiedOrderCallback.getTransaction_id());log.info("=.=记录交易记录=.=");wechatCallbackMapper.insert(wechatCallback);log.info("=.=修改订单信息=.=");log.info("=.=判断该订单是否被手动支付完成=.=");Recharge recharge= rechargeService.selRechargeByNum(wechatCallback.getRechargeNumber());if(recharge.getStatus()==0){rechargeService.updRechargeSuccess(wechatCallback.getRechargeNumber(),unifiedOrderCallback.getTime_end());}else{log.info("=.=该订单已被手动完成=.=订单号:"+wechatCallback.getRechargeNumber());}//通知webSocket支付成功,刷新 页面通知用户您已支付成功log.info("=.=开始通知页面刷新支付已成功=.=");String websocketKey=unifiedOrderCallback.getAttach().split(",")[1];Session session=(Session) ChatServer.map.get(websocketKey);System.out.println("session==========="+session);session.getAsyncRemote().sendText("=.=");ChatServer.map.remove(websocketKey);} catch (Exception e) {log.info("=.=异常了=.="+e.getMessage());} finally{log.info("=.=告诉微信,我已经知道了=.=");try {response.getWriter().write("<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>");} catch (IOException e) {e.printStackTrace();}}}

这样一套流程就走完了

public class UnifiedOrderCallback {private String appid;//应用IDprivate String mch_id;//mch_idprivate String device_info;//设备号private String nonce_str;//随机字符串private String sign;//签名private String result_code;//业务结果private String err_code;//错误代码private String err_code_des;//错误代码描述private String openid;//用户标识private String is_subscribe;//是否关注公众账号private String trade_type;//交易类型private String bank_type;//付款银行    private String total_fee;//总金额private String fee_type;//货币种类private String cash_fee;//现金支付金额private String cash_fee_type;//现金支付货币类型private String coupon_fee;//代金券金额private String coupon_count;//代金券使用数量private String coupon_id_$n;//代金券IDprivate String coupon_fee_$n;//单个代金券支付金额private String transaction_id;//微信支付订单号private String out_trade_no;//商户订单号private String attach;//商家数据包private String time_end;//支付完成时间private String return_code;//返回状态码private String return_msg;//返回信息public String getDevice_info() {return device_info;}public void setDevice_info(String device_info) {this.device_info = device_info;}public String getErr_code() {return err_code;}public void setErr_code(String err_code) {this.err_code = err_code;}public String getErr_code_des() {return err_code_des;}public void setErr_code_des(String err_code_des) {this.err_code_des = err_code_des;}public String getCash_fee_type() {return cash_fee_type;}public void setCash_fee_type(String cash_fee_type) {this.cash_fee_type = cash_fee_type;}public String getCoupon_fee() {return coupon_fee;}public void setCoupon_fee(String coupon_fee) {this.coupon_fee = coupon_fee;}public String getCoupon_count() {return coupon_count;}public void setCoupon_count(String coupon_count) {this.coupon_count = coupon_count;}public String getCoupon_id_$n() {return coupon_id_$n;}public void setCoupon_id_$n(String coupon_id_$n) {this.coupon_id_$n = coupon_id_$n;}public String getCoupon_fee_$n() {return coupon_fee_$n;}public void setCoupon_fee_$n(String coupon_fee_$n) {this.coupon_fee_$n = coupon_fee_$n;}public String getReturn_msg() {return return_msg;}public void setReturn_msg(String return_msg) {this.return_msg = return_msg;}public String getAppid() {return appid;}public void setAppid(String appid) {this.appid = appid;}public String getAttach() {return attach;}public void setAttach(String attach) {this.attach = attach;}public String getBank_type() {return bank_type;}public void setBank_type(String bank_type) {this.bank_type = bank_type;}public String getCash_fee() {return cash_fee;}public void setCash_fee(String cash_fee) {this.cash_fee = cash_fee;}public String getFee_type() {return fee_type;}public void setFee_type(String fee_type) {this.fee_type = fee_type;}public String getIs_subscribe() {return is_subscribe;}public void setIs_subscribe(String is_subscribe) {this.is_subscribe = is_subscribe;}public String getMch_id() {return mch_id;}public void setMch_id(String mch_id) {this.mch_id = mch_id;}public String getNonce_str() {return nonce_str;}public void setNonce_str(String nonce_str) {this.nonce_str = nonce_str;}public String getOpenid() {return openid;}public void setOpenid(String openid) {this.openid = openid;}public String getOut_trade_no() {return out_trade_no;}public void setOut_trade_no(String out_trade_no) {this.out_trade_no = out_trade_no;}public String getResult_code() {return result_code;}public void setResult_code(String result_code) {this.result_code = result_code;}public String getReturn_code() {return return_code;}public void setReturn_code(String return_code) {this.return_code = return_code;}public String getSign() {return sign;}public void setSign(String sign) {this.sign = sign;}public String getTime_end() {return time_end;}public void setTime_end(String time_end) {this.time_end = time_end;}public String getTotal_fee() {return total_fee;}public void setTotal_fee(String total_fee) {this.total_fee = total_fee;}public String getTrade_type() {return trade_type;}public void setTrade_type(String trade_type) {this.trade_type = trade_type;}public String getTransaction_id() {return transaction_id;}public void setTransaction_id(String transaction_id) {this.transaction_id = transaction_id;}}

转载于:https://my.oschina.net/yanhaohub/blog/3065906

关于微信支付(二维码支付)相关推荐

  1. JAVA实现的微信扫描二维码支付

    支付项目采用springMvc+Dubbo架构实现,只对外提供接口. 话说,为什么微信支付比支付宝来的晚了那么一点,一句话,那一阵挺忙的,然后就没有时间整理,最近做完支付宝支付,顺便也把微信支付的也整 ...

  2. iOS - 需求 - 微信扫描二维码支付(草稿)

    首先先讲一下这个流程: 1.商户即公司,根据微信官方支付的规则,为不同的商品或者是订单号生成不同的链接,将链接转换成二维码. 2.用户扫描二维码 3.微信客户端引导用户完成支付 4.用户完成支付,用户 ...

  3. 怎样在前端实现微信/支付宝二维码支付?

    首先在终端中下载qrcode,[npm install qrcode] 在script区域中导入 qrcode:[import qrcode from 'qrcode'] 在自定义的方法中调用toDa ...

  4. 微信二维码支付快速入门

    目录 一.二维码生成插件qrious 二.HttpClient 三.微信扫码支付 1.申请步骤 2.开发文档 四.入门Demo 1.工程搭建 2.myStudy-pay-interface 3.myS ...

  5. 梦行扫码付(收银台条码支付 微信钱包条码支付 支付宝二维码支付 手机APP钱包支付 PHP扫码支付 )

    适用于:各行各业(如,超市 餐厅 收费站 等各类收费处) 平台管理员篇 扫码付管理 (收银台条码支付) 全站收款账号 (微信钱包条码支付) 全站收款记录 (支付宝二维码支付) 商家篇 我的扫码付 (支 ...

  6. 微信的支付(二维码,APP)

    1. 2. private static $WeixinConfig = array( 'wxAppId' => 'xxxxx', 'wxMchId' => 'xxxx', // 商户号 ...

  7. 支付二维码整合 - 三码合一支持支付宝、QQ、微信

    支付二维码整合 - 三码合一支持支付宝.QQ.微信 1. 前提:获取各个二维码的具体内容 在写代码前,我们需要先获取不同支付方式的二维码内容.很简单,只需要打开各个支付码,截图,然后随便找个可以扫码的 ...

  8. 前端 js 微信 支付二维码

    这里使用了 js 以及一个网上的工具包,巨j2简单的生成了微信的支付二维码 文章目录 这里使用了 js 以及一个网上的工具包,巨j2简单的生成了微信的支付二维码 下载微信二维码包 生成微信二维码 事后 ...

  9. 微信支付二维码上添加logo

    工具类的使用,分享给大家.先看效果: 无logo时: 有logo时: import java.awt.image.BufferedImage; import java.io.File; import ...

最新文章

  1. SQL Server 2005 学习笔记系列文章
  2. android利用反射调用截屏api,Android利用反射机制调用截屏方法和获取屏幕宽高的方法...
  3. c语言 判断日期时间_C语言中不得不知的那些“关键字”和“控制语句”
  4. “七层架构”-----实践篇-登录小实例
  5. SAP CRM Long text unit test preparation
  6. java.lang.stackoverflowerror_java.lang.StackOverflowError——如何解决StackOverflowError错误
  7. MySQL的乱码解决方案
  8. java获取net地址 本机
  9. oracle group by 取最新的一条_大国智能制造全文免费阅读_大国智能制造最新章节_乌溪小道的小说...
  10. java mysql emoj报错_MySQL插入emoji表情报错 SQLException: Incorrect string value 的两种解决方案...
  11. JAVA→封装类Wrapper、字符串String及其方法、==与equals()、正则表达式、StringBuilder与StringBuffer、内嵌类
  12. 象棋名手手机版2019最新版_象棋名手64核比赛冠军版2019
  13. 为什么倡导企业使用电子招投标?
  14. SAP那些事-理论篇-5-SAP玩你还是你玩SAP
  15. CAD转JPG如何才能清晰?来看这两个方法
  16. java秒抢商品_Java秒杀系统实战系列~待秒杀商品列表与详情功能开发
  17. html中显示框框中对勾,word对号怎么打 word怎么设置在方框里打对号
  18. PLSQL登录时怎么输入数据库地址
  19. 关于java文件乱码解决
  20. JS验证身份证号码合法性

热门文章

  1. 隐私求交| Simple, Fast Malicious Multiparty Private Set Intersection
  2. 怎样在python的turtle中输入文字_如何用Python的turtle库写出自己的名字?
  3. linux基本功系列-help命令实战
  4. MATLAB设计指定频率的陷波器
  5. Android 前后端交互
  6. 我以为我很菜,虽然我确实很菜,但现在我菜的理直气壮~
  7. 稳压电源技术指标,摘录
  8. Abp框架从零开始(基于.Net Core 2.2) 小记(二) 简单的文件上传
  9. 橱柜效果图-橱柜图片
  10. 统计“总计”和 导出excel表格