Java는 JsApi 모드에서 WeChat 결제를 구현합니다.
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)를 참고해주세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Java의 난수 생성기 안내. 여기서는 예제를 통해 Java의 함수와 예제를 통해 두 가지 다른 생성기에 대해 설명합니다.

Java의 Weka 가이드. 여기에서는 소개, weka java 사용 방법, 플랫폼 유형 및 장점을 예제와 함께 설명합니다.

자바의 암스트롱 번호 안내 여기에서는 일부 코드와 함께 Java의 Armstrong 번호에 대한 소개를 논의합니다.

Java의 Smith Number 가이드. 여기서는 정의, Java에서 스미스 번호를 확인하는 방법에 대해 논의합니다. 코드 구현의 예.

이 기사에서는 가장 많이 묻는 Java Spring 면접 질문과 자세한 답변을 보관했습니다. 그래야 면접에 합격할 수 있습니다.

Java 8은 스트림 API를 소개하여 데이터 컬렉션을 처리하는 강력하고 표현적인 방법을 제공합니다. 그러나 스트림을 사용할 때 일반적인 질문은 다음과 같은 것입니다. 기존 루프는 조기 중단 또는 반환을 허용하지만 스트림의 Foreach 메소드는이 방법을 직접 지원하지 않습니다. 이 기사는 이유를 설명하고 스트림 처리 시스템에서 조기 종료를 구현하기위한 대체 방법을 탐색합니다. 추가 읽기 : Java Stream API 개선 스트림 foreach를 이해하십시오 Foreach 메소드는 스트림의 각 요소에서 하나의 작업을 수행하는 터미널 작동입니다. 디자인 의도입니다
