ホームページ > WeChat アプレット > WeChatの開発 > JsApi を介した Java による WeChat 支払いメソッドの実装の詳細な説明

JsApi を介した Java による WeChat 支払いメソッドの実装の詳細な説明

高洛峰
リリース: 2017-03-27 13:56:51
オリジナル
2690 人が閲覧しました

この記事では、Java が JsApi メソッドで WeChat 支払いを実装する方法について説明しています。コードの内容が詳細に説明されており、必要な友人は参照できます。

WeChat 支払いに JsApi を使用するには、まず WeChat から prepay_id を取得する必要があります。支払い完了後、JS API get_brand_wcpay_request:ok の戻り結果は、ユーザーが支払いを正常に完了した場合にのみ返されます。フロントエンドの対話は複雑であるため、get_brand_wcpay_request:cancel または get_brand_wcpay_request:fail は、ユーザーがエラーに遭遇したとき、または自発的に放棄したときに、詳細な区別なしに一律に処理できます。
サンプルコードは以下のとおりです:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

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();

}

ログイン後にコピー

上記のパラメータパッケージ入力はprepay_idです

以下はjsapiを呼び出すためのパラメータの取得についてです
JSAPIを呼び出すときは、ユーザーのopenidを取得する必要があります(trade_type=JSAPI、openidは必須のパラメーター。)
最初に、要求された オブジェクト:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

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);

 }

 }

}

ログイン後にコピー

を定義します。これは、一部のパラメーターが必須であり、一部はオプションであるためです。さらに、すべてのパラメータが渡されるまで符号を計算できないため、ここではビルダー モードが使用されます。ビルダーモードについて。

ネットワーク送信には httpclient を選択します。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

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;

 }

}

ログイン後にコピー

次に、一般的な入り口があります:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

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 は次のとおりです:

1

2

3

4

5

6

7

8

9

10

11

<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 による WeChat 支払いメソッドの実装の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート