Java通过JsApi方式实现微信支付_java

要使用JsApi进行微信支付,首先要从微信获得一个prepay_id,然后通过调用微信的jsapi完成支付,JS API的返回结果get_brand_wcpay_request:ok仅在用户成功完成支付时返回。由于前端交互复杂,get_brand_wcpay_request:cancel或者get_brand_wcpay_request:fail可以统一处理为用户遇到错误或者主动放弃,不必细化区分。
示例代码如下:

function onBridgeReady(){
 WeixinJSBridge.invoke(
 'getBrandWCPayRequest', {
  "appId" : "wx2421b1c4370ec43b", //公众号名称,由商户传入
  "timeStamp":" 1395712654",  //时间戳,自1970年以来的秒数
  "nonceStr" : "e61463f8efa94090b1f366cccfbbb444", //随机串
  "package" : "u802345jgfjsdfgsdg888",
  "signType" : "MD5",  //微信签名方式:
  "paySign" : "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名
 },
 function(res){
  if(res.err_msg == "get_brand_wcpay_request:ok" ) {} // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回 ok,但并不保证它绝对可靠。
 }
 );
}
if (typeof WeixinJSBridge == "undefined"){
 if( document.addEventListener ){
 document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
 }else if (document.attachEvent){
 document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
 document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
 }
}else{
 onBridgeReady();
}

以上传入的参数package,即为prepay_id

下面讲的是获得参数来调用jsapi
我们调用JSAPI时,必须获得用户的openid,(trade_type=JSAPI,openid为必填参数。)
首先定义一个请求的对象:

package com.unstoppedable.protocol;

import com.unstoppedable.common.Configure;
import com.unstoppedable.common.HttpService;
import com.unstoppedable.common.RandomStringGenerator;
import com.unstoppedable.common.Signature;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class UnifiedOrderReqData {

 private String appid;
 private String mch_id;
 private String device_info;
 private String nonce_str;
 private String sign;
 private String body;
 private String detail;
 private String attach;
 private String out_trade_no;
 private String fee_type;
 private int total_fee;
 private String spbill_create_ip;
 private String time_start;
 private String time_expire;
 private String goods_tag;
 private String notify_url;
 private String trade_type;
 private String product_id;
 private String limit_pay;
 private String openid;

 private UnifiedOrderReqData(UnifiedOrderReqDataBuilder builder) {
 this.appid = builder.appid;
 this.mch_id = builder.mch_id;
 this.device_info = builder.device_info;
 this.nonce_str = RandomStringGenerator.getRandomStringByLength(32);
 this.body = builder.body;
 this.detail = builder.detail;
 this.attach = builder.attach;
 this.out_trade_no = builder.out_trade_no;
 this.fee_type = builder.fee_type;
 this.total_fee = builder.total_fee;
 this.spbill_create_ip = builder.spbill_create_ip;
 this.time_start = builder.time_start;
 this.time_expire = builder.time_expire;
 this.goods_tag = builder.goods_tag;
 this.notify_url = builder.notify_url;
 this.trade_type = builder.trade_type;
 this.product_id = builder.product_id;
 this.limit_pay = builder.limit_pay;
 this.openid = builder.openid;
 this.sign = Signature.getSign(toMap());
 }

 public void setAppid(String appid) {
 this.appid = appid;
 }

 public void setMch_id(String mch_id) {
 this.mch_id = mch_id;
 }

 public void setDevice_info(String device_info) {
 this.device_info = device_info;
 }

 public void setNonce_str(String nonce_str) {
 this.nonce_str = nonce_str;
 }

 public void setSign(String sign) {
 this.sign = sign;
 }

 public void setBody(String body) {
 this.body = body;
 }

 public void setDetail(String detail) {
 this.detail = detail;
 }

 public void setAttach(String attach) {
 this.attach = attach;
 }

 public void setOut_trade_no(String out_trade_no) {
 this.out_trade_no = out_trade_no;
 }

 public void setFee_type(String fee_type) {
 this.fee_type = fee_type;
 }

 public void setTotal_fee(int total_fee) {
 this.total_fee = total_fee;
 }

 public void setSpbill_create_ip(String spbill_create_ip) {
 this.spbill_create_ip = spbill_create_ip;
 }

 public void setTime_start(String time_start) {
 this.time_start = time_start;
 }

 public void setTime_expire(String time_expire) {
 this.time_expire = time_expire;
 }

 public void setGoods_tag(String goods_tag) {
 this.goods_tag = goods_tag;
 }

 public void setNotify_url(String notify_url) {
 this.notify_url = notify_url;
 }

 public void setTrade_type(String trade_type) {
 this.trade_type = trade_type;
 }

 public void setProduct_id(String product_id) {
 this.product_id = product_id;
 }

 public void setLimit_pay(String limit_pay) {
 this.limit_pay = limit_pay;
 }

 public void setOpenid(String openid) {
 this.openid = openid;
 }

 public Map<String, Object> toMap() {
 Map<String, Object> map = new HashMap<String, Object>();
 Field[] fields = this.getClass().getDeclaredFields();
 for (Field field : fields) {
  Object obj;
  try {
  obj = field.get(this);
  if (obj != null) {
   map.put(field.getName(), obj);
  }
  } catch (IllegalArgumentException e) {
  e.printStackTrace();
  } catch (IllegalAccessException e) {
  e.printStackTrace();
  }
 }
 return map;
 }

 public static class UnifiedOrderReqDataBuilder {
 private String appid;
 private String mch_id;
 private String device_info;
 private String body;
 private String detail;
 private String attach;
 private String out_trade_no;
 private String fee_type;
 private int total_fee;
 private String spbill_create_ip;
 private String time_start;
 private String time_expire;
 private String goods_tag;
 private String notify_url;
 private String trade_type;
 private String product_id;
 private String limit_pay;
 private String openid;

 public UnifiedOrderReqDataBuilder(String appid, String mch_id, String body, String out_trade_no, Integer total_fee,
      String spbill_create_ip, String notify_url, String trade_type) {
  if (appid == null) {
  throw new IllegalArgumentException("传入参数appid不能为null");
  }
  if (mch_id == null) {
  throw new IllegalArgumentException("传入参数mch_id不能为null");
  }
  if (body == null) {
  throw new IllegalArgumentException("传入参数body不能为null");
  }
  if (out_trade_no == null) {
  throw new IllegalArgumentException("传入参数out_trade_no不能为null");
  }
  if (total_fee == null) {
  throw new IllegalArgumentException("传入参数total_fee不能为null");
  }
  if (spbill_create_ip == null) {
  throw new IllegalArgumentException("传入参数spbill_create_ip不能为null");
  }
  if (notify_url == null) {
  throw new IllegalArgumentException("传入参数notify_url不能为null");
  }
  if (trade_type == null) {
  throw new IllegalArgumentException("传入参数trade_type不能为null");
  }
  this.appid = appid;
  this.mch_id = mch_id;
  this.body = body;
  this.out_trade_no = out_trade_no;
  this.total_fee = total_fee;
  this.spbill_create_ip = spbill_create_ip;
  this.notify_url = notify_url;
  this.trade_type = trade_type;
 }

 public UnifiedOrderReqDataBuilder setDevice_info(String device_info) {
  this.device_info = device_info;
  return this;
 }

 public UnifiedOrderReqDataBuilder setDetail(String detail) {
  this.detail = detail;
  return this;
 }

 public UnifiedOrderReqDataBuilder setAttach(String attach) {
  this.attach = attach;
  return this;
 }

 public UnifiedOrderReqDataBuilder setFee_type(String fee_type) {
  this.fee_type = fee_type;
  return this;
 }

 public UnifiedOrderReqDataBuilder setTime_start(String time_start) {
  this.time_start = time_start;
  return this;
 }

 public UnifiedOrderReqDataBuilder setTime_expire(String time_expire) {
  this.time_expire = time_expire;
  return this;
 }

 public UnifiedOrderReqDataBuilder setGoods_tag(String goods_tag) {
  this.goods_tag = goods_tag;
  return this;
 }

 public UnifiedOrderReqDataBuilder setProduct_id(String product_id) {
  this.product_id = product_id;
  return this;
 }

 public UnifiedOrderReqDataBuilder setLimit_pay(String limit_pay) {
  this.limit_pay = limit_pay;
  return this;
 }

 public UnifiedOrderReqDataBuilder setOpenid(String openid) {
  this.openid = openid;
  return this;
 }

 public UnifiedOrderReqData build() {

  if("JSAPI".equals(this.trade_type) && this.openid == null) {
  throw new IllegalArgumentException("当传入trade_type为JSAPI时,openid为必填参数");
  }
  if("NATIVE".equals(this.trade_type) && this.product_id == null) {
  throw new IllegalArgumentException("当传入trade_type为NATIVE时,product_id为必填参数");
  }
  return new UnifiedOrderReqData(this);
 }
 }

}

因为有些参数为必填,有些参数为选填。而且sign要等所有参数传入之后才能计算的出,所以这里用了builder模式。关于builder模式。

我们选用httpclient进行网络传输。

package com.unstoppedable.common;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.ConnectionPoolTimeoutException;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.security.KeyStore;

/**
 * Created by hupeng on 2015/7/28.
 */
public class HttpService {
 private static Log logger = LogFactory.getLog(HttpService.class);

 private static CloseableHttpClient httpClient = buildHttpClient();

 //连接超时时间,默认10秒
 private static int socketTimeout = 5000;

 //传输超时时间,默认30秒
 private static int connectTimeout = 5000;

 private static int requestTimeout = 5000;

 public static CloseableHttpClient buildHttpClient() {

 try {
  KeyStore keyStore = KeyStore.getInstance("PKCS12");
  FileInputStream instream = new FileInputStream(new File(Configure.getCertLocalPath()));//加载本地的证书进行https加密传输
  try {
  keyStore.load(instream, Configure.getCertPassword().toCharArray());//设置证书密码
  } finally {
  instream.close();
  }

  // Trust own CA and all self-signed certs
  SSLContext sslcontext = SSLContexts.custom()
   .loadKeyMaterial(keyStore, Configure.getCertPassword().toCharArray())
   .build();
  // Allow TLSv1 protocol only
  SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
   sslcontext,
   new String[]{"TLSv1"},
   null,
   SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);

  RequestConfig requestConfig = RequestConfig.custom()
   .setConnectTimeout(connectTimeout)
   .setConnectionRequestTimeout(requestTimeout)
   .setSocketTimeout(socketTimeout).build();

  httpClient = HttpClients.custom()
   .setDefaultRequestConfig(requestConfig)
   .setSSLSocketFactory(sslsf)
   .build();

  return httpClient;
 } catch (Exception e) {
  throw new RuntimeException("error create httpclient......", e);
 }
 }

 public static String doGet(String requestUrl) throws Exception {
 HttpGet httpget = new HttpGet(requestUrl);
 try {

  logger.debug("Executing request " + httpget.getRequestLine());
  // Create a custom response handler
  ResponseHandler<String> responseHandler = new ResponseHandler<String>() {

  @Override
  public String handleResponse(
   final HttpResponse response) throws ClientProtocolException, IOException {
   int status = response.getStatusLine().getStatusCode();
   if (status >= 200 && status < 300) {
   HttpEntity entity = response.getEntity();
   return entity != null ? EntityUtils.toString(entity) : null;
   } else {
   throw new ClientProtocolException("Unexpected response status: " + status);
   }
  }

  };

  return httpClient.execute(httpget, responseHandler);
 } finally {
  httpget.releaseConnection();
 }
 }

 public static String doPost(String url, Object object2Xml) {

 String result = null;

 HttpPost httpPost = new HttpPost(url);

 //解决XStream对出现双下划线的bug
 XStream xStreamForRequestPostData = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));

 //将要提交给API的数据对象转换成XML格式数据Post给API
 String postDataXML = xStreamForRequestPostData.toXML(object2Xml);

 logger.info("API,POST过去的数据是:");
 logger.info(postDataXML);

 //得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
 StringEntity postEntity = new StringEntity(postDataXML, "UTF-8");
 httpPost.addHeader("Content-Type", "text/xml");
 httpPost.setEntity(postEntity);

 //设置请求器的配置

 logger.info("executing request" + httpPost.getRequestLine());

 try {
  HttpResponse response = httpClient.execute(httpPost);

  HttpEntity entity = response.getEntity();

  result = EntityUtils.toString(entity, "UTF-8");

 } catch (ConnectionPoolTimeoutException e) {
  logger.error("http get throw ConnectionPoolTimeoutException(wait time out)", e);

 } catch (ConnectTimeoutException e) {
  logger.error("http get throw ConnectTimeoutException", e);

 } catch (SocketTimeoutException e) {
  logger.error("http get throw SocketTimeoutException", e);

 } catch (Exception e) {
  logger.error("http get throw Exception", e);

 } finally {
  httpPost.abort();
 }

 return result;
 }
}

然后是我们的总入口:

package com.unstoppedable.service;

import com.unstoppedable.common.Configure;
import com.unstoppedable.common.HttpService;
import com.unstoppedable.common.XMLParser;
import com.unstoppedable.protocol.UnifiedOrderReqData;
import org.xml.sax.SAXException;

import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.util.Map;

/**
 * Created by hupeng on 2015/7/28.
 */
public class WxPayApi {

 public static Map<String,Object> UnifiedOrder(UnifiedOrderReqData reqData) throws IOException, SAXException, ParserConfigurationException {
 String res = HttpService.doPost(Configure.UNIFIED_ORDER_API, reqData);
 return XMLParser.getMapFromXML(res);
 }

 public static void main(String[] args) throws Exception {
 UnifiedOrderReqData reqData = new UnifiedOrderReqData.UnifiedOrderReqDataBuilder("appid", "mch_id", "body", "out_trade_no", 1, "spbill_create_ip", "notify_url", "JSAPI").setOpenid("openid").build();
 System.out.println(UnifiedOrder(reqData));

 }
}

返回的xml为:

<xml>
 <return_code><![CDATA[SUCCESS]]></return_code>
 <return_msg><![CDATA[OK]]></return_msg>
 <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
 <mch_id><![CDATA[10000100]]></mch_id>
 <nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str>
 <sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign>
 <result_code><![CDATA[SUCCESS]]></result_code>
 <prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>
 <trade_type><![CDATA[JSAPI]]></trade_type>
</xml>

return_code 和result_code都为SUCCESS的时候会返回我们需要的prepay_id。。。,然后在jsapi中使用他就可以了。。

本文已被整理到了《JavaScript微信开发技巧汇总》,欢迎大家学习阅读。

为大家推荐现在关注度比较高的微信小程序教程一篇:《微信小程序开发教程》小编为大家精心整理的,希望喜欢。

以上就是本文的全部内容,希望对大家的学习有所帮助。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java
, 微信支付
JsApi方式
微信jsapi支付 java、微信支付java实现、java实现微信支付功能、java实现支付宝接口、java实现支付宝支付,以便于您获取更多的相关知识。

时间: 2024-12-22 10:03:05

Java通过JsApi方式实现微信支付_java的相关文章

JAVA实现 SpringMVC方式的微信接入、实现简单的自动回复功能_java

前端时间小忙了一阵,微信公众号的开发,从零开始看文档,踩了不少坑,也算是熬过来了,最近考虑做一些总结,方便以后再开发的时候回顾,也给正在做相关项目的同学做个参考. 其实做过一遍之后会发现也不难,大致思路:用户消息和开发者需要的事件推送都会通过微信方服务器发起一个请求,转发到你在公众平台配置的服务器url地址,微信方将带上signature,timestamp,nonce,echostr四个参数,我们自己服务器通过拼接公众平台配置的token,以及传上来的timestamp,nonce进行SHA1

JAVA实现 springMVC方式的微信接入、实现消息自动回复实例_java

前段时间小忙了一阵,微信公众号的开发,从零开始看文档,踩了不少坑,也算是熬过来了,最近考虑做一些总结,方便以后再开发的时候回顾,也给正在做相关项目的同学做个参考. 1.思路 微信接入:用户消息和开发者需要的事件推送都会通过微信方服务器发起一个请求,转发到你在公众平台配置的服务器url地址,微信方将带上signature,timestamp,nonce,echostr四个参数,我们自己服务器通过拼接公众平台配置的token,以及传上来的timestamp,nonce进行SHA1加密后匹配signa

Java基于TCP方式的二进制文件传输_java

一个基于Java Socket协议之上文件传输的完整示例,基于TCP通信完成. 除了基于TCP的二进制文件传输,还演示了JAVA Swing的一些编程技巧,Demo程序 实现主要功能有以下几点: 1.基于Java Socket的二进制文件传输(包括图片,二进制文件,各种文档work,PDF) 2.SwingWorker集合JProgressBar显示实时传输/接受完成的百分比 3.其它一些Swing多线程编程技巧 首先来看一下整个Dome的Class之间的关系图: 下面按照上图来详细解释各个类的

微信支付java版本之获取Access_token_java

access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token.开发者需要进行妥善保存.access_token的存储至少要保留512个字符空间.access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效.  公众平台的API调用所需的access_token的使用及生成方式说明: 1.为了保密appsecrect,第三方需要一个access_token获取和刷新的中控服务器.而其他业务逻辑服务器所使用的a

C#开发微信门户及应用(40)--使用微信JSAPI实现微信支付功能

在我前面的几篇博客,有介绍了微信支付.微信红包.企业付款等各种和支付相关的操作,不过上面都是基于微信普通API的封装,本篇随笔继续微信支付这一主题,继续介绍基于微信网页JSAPI的方式发起的微信支付功能实现,微信的JSAPI相对于普通的API操作,调试没有那么方便,而且有时候有些错误需要反复核实.本篇随笔基于实际的微信网页支付案例,对微信JSAPI的支付实现进行介绍. 1.微信JS-SDK的知识 在我前面<C#开发微信门户及应用(39)--使用微信JSSDK实现签到的功能>介绍的内容里面,有介

皮皮微商城接入微信支付,完成O2O闭环

微信支付是O2O闭环利器,微信支付横扫市场,将成为唯一能与支付宝争锋的移动支付解决方案.微信支付,是值得每一个企业.商家关注的焦点! 或许,微信5.0的微信支付的横空出世,便决定了腾讯与阿里必有一战.以至马云放狠话要"杀到南极洲"去,虽然表面上马云是借炮轰微信去推来往,实际背后还隐藏着其对微信支付.微信电商的深深的忧虑. 腾讯CEO马化腾对微信支付的定义是,只需将微信账户绑定银行卡就可以在微信内公众号.APP 以及身边随时可见的二维码,简便.快捷地完成付款,从而为商业场景在手机中的闭环

微信支付java版本之JSAPI支付+发送模板消息_java

本文为大家分享了java版本之JSAPI支付+发送模板消息的相关资料,供大家参考,具体内容如下 1.工具类 工具类见:微信支付JAVA版本之Native付款 2.公众账号设置 3.代码实现  openId:openId为用户与该公众账号之间代表用户的唯一标示  以下类中涉及到生成token,关闭订单接口调用,获取配置文件信息,和工具类,在其他文章中有具体代码实现  package com.zhrd.bussinss.platform.controller.rest; import java.io

微信支付H5调用支付详解(java版)_java

最近项目需要微信支付,然后看了下微信公众号支付,,虽然不难,但是细节还是需要注意的,用了大半天时间写了个demo,并且完整的测试了一下支付流程,下面分享一下微信公众号支付的经验. 一.配置公众号微信支付  需要我们配置微信公众号支付地址和测试白名单. 比如:支付JS页面的地址为 http://www.xxx.com/shop/pay/ 那此处配置www.xxx.com/shop/pay/ 二.开发流程 借用微信公众号支付api(地址 http://pay.weixin.qq.com/wiki/d

Java微信支付之公众号支付、扫码支付实例_java

微信支付现在已经变得越来越流行了,随之也出现了很多以可以快速接入微信支付为噱头的产品,不过方便之余也使得我们做东西慢慢依赖第三方,丧失了独立思考的能力,这次打算分享下我之前开发过的微信支付. 一 .H5公众号支付 要点:正确获取openId以及统一下单接口,正确处理支付结果通知,正确配置支付授权目录 H5的支付方式是使用较为广泛的方式,这种支付方式主要用于微信内自定义菜单的网页,依赖手机上安装的微信客户端,高版本的微信才支持微信支付,下面按我的流程注意说明 1  编写用于支付的页面,由于是测试用