>  기사  >  Java  >  Java는 JsApi 모드에서 WeChat 결제를 구현합니다.

Java는 JsApi 모드에서 WeChat 결제를 구현합니다.

黄舟
黄舟원래의
2016-12-28 11:20:541171검색

java는 WeChat 결제를 위한 JsApi 메소드를 구현합니다

WeChat 결제에 JsApi를 사용하려면 먼저 WeChat에서 PRepay_id를 얻은 다음 WeChat의 jsapi를 호출하여 결제를 완료해야 합니다. JS API get_brand_wcpay_request의 반환 결과: ok는 사용자가 성공적으로 결제를 완료한 경우에만 Returned에서 사용할 수 있습니다. 프런트엔드 상호작용의 복잡성으로 인해 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);        
      }    
      }
      }

일부 매개변수는 필수이고 일부 매개변수는 선택사항이기 때문입니다. 또한 모든 매개변수가 전달될 때까지 부호를 계산할 수 없으므로 여기서는 빌더 모드가 사용됩니다. 빌더 모드에 대해. 각 매개변수의 정의는 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에서 사용하세요. .

위챗 결제 JsApi 방식의 Java 구현 내용입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.