搜索
首页Javajava教程Java实现JsApi方式的微信支付

java实现JsApi方式的微信支付

要使用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详细文档见:https://pay.weixin.QQ.com/wiki/doc/api/jsapi.php?chapter=7_7

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

package com.unstoppedable.protocol;import com.thoughtworks.xstream.annotations.XStreamAlias;import com.unstoppedable.common.Configure;import com.
unstoppedable.common.RandomStringGenerator;import com.unstoppedable.common.Signature;import java.lang.reflect.Field;import java.util.HashMap;
import java.util.Map;@XStreamAlias("xml")
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 String getAppid() 
{        
return appid;    
}    
public String getMch_id() 
{        
return mch_id;    
}    
public String getDevice_info() 
{        return device_info;    
}    
public String getNonce_str() 
{        
return nonce_str;    
}    
public String getSign() 
{        
return sign;    
}    
public String getBody() 
{       
 return body;   
 }    
 public String getDetail() 
 {       
  return detail;    
  }    
  public String getAttach() 
  {        
  return attach;    
  }    
  public String getOut_trade_no() 
  {        
  return out_trade_no;    
  }    
  public String getFee_type() 
  {        
  return fee_type;    
  }    
  public int getTotal_fee() 
  {       
   return total_fee;    
   }    
   public String getSpbill_create_ip() 
   {        
   return spbill_create_ip;    
   }    
   public String getTime_start() 
   {        
   return time_start;    
   }    
   public String getTime_expire() 
   {        
   return time_expire;    
   }    
   public String getGoods_tag() 
   {        
   return goods_tag;    
   }    
   public String getNotify_url() 
   {        return notify_url;    
   }   
    public String getTrade_type() 
    {        return trade_type;    
    }    
    public String getProduct_id() 
    {        return product_id;    
    }    
    public String getLimit_pay() 
    {        return limit_pay;    
    }    
    public String getOpenid() 
    {        
    return 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;        
      /**         
      * 使用配置中的 appid 和  mch_id         
      *         
      * @param body         
      * @param out_trade_no         
      * @param total_fee         
      * @param spbill_create_ip         
      * @param notify_url         
      * @param trade_type         
      */        
      public UnifiedOrderReqDataBuilder(String body, String out_trade_no, Integer total_fee,                                          
      String spbill_create_ip, String notify_url, String trade_type) 
      {            
      this(Configure.getAppid(), 
      Configure.getMchid(), 
      body, 
      out_trade_no, 
      total_fee,                    
      spbill_create_ip, notify_url, trade_type);        
      }        
      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模式。关于每个参数的定义,参考说明文档https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

我们选用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中使用他就可以了。。

 以上就是Java实现JsApi方式的微信支付的内容,更多相关内容请关注PHP中文网(www.php.cn)!


声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
如何将Maven或Gradle用于高级Java项目管理,构建自动化和依赖性解决方案?如何将Maven或Gradle用于高级Java项目管理,构建自动化和依赖性解决方案?Mar 17, 2025 pm 05:46 PM

本文讨论了使用Maven和Gradle进行Java项目管理,构建自动化和依赖性解决方案,以比较其方法和优化策略。

如何使用适当的版本控制和依赖项管理创建和使用自定义Java库(JAR文件)?如何使用适当的版本控制和依赖项管理创建和使用自定义Java库(JAR文件)?Mar 17, 2025 pm 05:45 PM

本文使用Maven和Gradle之类的工具讨论了具有适当的版本控制和依赖关系管理的自定义Java库(JAR文件)的创建和使用。

如何使用咖啡因或Guava Cache等库在Java应用程序中实现多层缓存?如何使用咖啡因或Guava Cache等库在Java应用程序中实现多层缓存?Mar 17, 2025 pm 05:44 PM

本文讨论了使用咖啡因和Guava缓存在Java中实施多层缓存以提高应用程序性能。它涵盖设置,集成和绩效优势,以及配置和驱逐政策管理最佳PRA

如何将JPA(Java持久性API)用于具有高级功能(例如缓存和懒惰加载)的对象相关映射?如何将JPA(Java持久性API)用于具有高级功能(例如缓存和懒惰加载)的对象相关映射?Mar 17, 2025 pm 05:43 PM

本文讨论了使用JPA进行对象相关映射,并具有高级功能,例如缓存和懒惰加载。它涵盖了设置,实体映射和优化性能的最佳实践,同时突出潜在的陷阱。[159个字符]

Java的类负载机制如何起作用,包括不同的类载荷及其委托模型?Java的类负载机制如何起作用,包括不同的类载荷及其委托模型?Mar 17, 2025 pm 05:35 PM

Java的类上载涉及使用带有引导,扩展程序和应用程序类负载器的分层系统加载,链接和初始化类。父代授权模型确保首先加载核心类别,从而影响自定义类LOA

如何将Java的RMI(远程方法调用)用于分布式计算?如何将Java的RMI(远程方法调用)用于分布式计算?Mar 11, 2025 pm 05:53 PM

本文解释了用于构建分布式应用程序的Java的远程方法调用(RMI)。 它详细介绍了接口定义,实现,注册表设置和客户端调用,以解决网络问题和安全性等挑战。

如何使用Java的插座API进行网络通信?如何使用Java的插座API进行网络通信?Mar 11, 2025 pm 05:53 PM

本文详细介绍了用于网络通信的Java的套接字API,涵盖了客户服务器设置,数据处理和关键考虑因素,例如资源管理,错误处理和安全性。 它还探索了性能优化技术,我

如何在Java中创建自定义网络协议?如何在Java中创建自定义网络协议?Mar 11, 2025 pm 05:52 PM

本文详细介绍了创建自定义Java网络协议。 它涵盖协议定义(数据结构,框架,错误处理,版本控制),实现(使用插座),数据序列化和最佳实践(效率,安全性,维护

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器