Heim > Web-Frontend > H5-Tutorial > Analyse der Verwendung von H5 zum Anrufen und Bezahlen öffentlicher WeChat-Kontozahlungen

Analyse der Verwendung von H5 zum Anrufen und Bezahlen öffentlicher WeChat-Kontozahlungen

不言
Freigeben: 2018-06-11 17:05:44
Original
4015 Leute haben es durchsucht

这篇文章主要为大家详细介绍了微信公众号支付H5调用支付,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

最近项目需要微信支付,然后看了下微信公众号支付,虽然不难,但是细节还是需要注意的,用了大半天时间写了个demo,并且完整的测试了一下支付流程,下面分享一下微信公众号支付的经验。

一、配置公众号微信支付  

需要我们配置微信公众号支付地址和测试白名单。

  

比如:支付JS页面的地址为 http://www.xxx.com/shop/pay/
            那此处配置www.xxx.com/shop/pay/

二、开发流程

借用微信公众号支付api(地址 http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=7_4),我们需要开发的为红色标记出的。如下:

   

三、向微信服务器端下订单

调用统一下单接口,这样就能获取微信支付的prepay_id(http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=9_1)。

在调用该接口前有几个字段是H5支付必须填写的openid

3.1 获取openid

可以通过网页授权形式(http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html)

在微信中发送如下链接     

https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx520c15f417810387&redirect_uri=要跳转的下订单的url&response_type=code&scope=snsapi_base&state=123#wechat_redirect

 3.2 后台支付

代码如下,包含预处理订单,支付订单等接口。

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

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

package org.andy.controller;

  

import java.io.ByteArrayInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.UnsupportedEncodingException;

import java.util.Date;

import java.util.HashMap;

import java.util.Iterator;

import java.util.Map;

import java.util.Map.Entry;

import java.util.Random;

  

import javax.servlet.ServletInputStream;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

  

import org.apache.commons.codec.digest.DigestUtils;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.xmlpull.v1.XmlPullParser;

import org.xmlpull.v1.XmlPullParserException;

import org.xmlpull.v1.XmlPullParserFactory;

  

import com.fasterxml.jackson.databind.JsonNode;

import com.gson.oauth.Oauth;

import com.gson.oauth.Pay;

import com.gson.util.HttpKit;

import com.gson.util.Tools;

import org.andy.util.DatetimeUtil;

import org.andy.util.JsonUtil;

import org.andy.util.SessionUtil;

import org.andy.util.WebUtil;

  

@Controller

@RequestMapping("/pay")

public class WXPayController {

  

 @RequestMapping(value = "wxprepay")

 public void jspay(HttpServletRequest request, HttpServletResponse response, String callback) throws Exception {

 // 获取openid

 String openId = SessionUtil.getAtt(request, "openId");

 if (openId == null) {

 openId = getUserOpenId(request);

 }

  

 String appid = "wx16691fcb0523c1a4";

 String partnerid = "22223670";

 String paternerKey = "fjfjfjfjf1234567FFFFFFFFF1234567";

  

 String out_trade_no = getTradeNo();

 Map<String, String> paraMap = new HashMap<String, String>();

 paraMap.put("appid", appid);

 paraMap.put("attach", "测试支付");

 paraMap.put("body", "测试购买Beacon支付");

 paraMap.put("mch_id", partnerid);

 paraMap.put("nonce_str", create_nonce_str());

 paraMap.put("openid", openId);

 paraMap.put("out_trade_no", out_trade_no);

 paraMap.put("spbill_create_ip", getAddrIp(request));

 paraMap.put("total_fee", "1");

 paraMap.put("trade_type", "JSAPI");

 paraMap.put("notify_url", "http://www.xxx.co/wxpay/pay/appPay_notify.shtml");

 String sign = getSign(paraMap, paternerKey);

 paraMap.put("sign", sign);

  

 // 统一下单 https://api.mch.weixin.qq.com/pay/unifiedorder

 String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

  

 String xml = ArrayToXml(paraMap, false);

  

 String xmlStr = HttpKit.post(url, xml);

  

 // 预付商品id

 String prepay_id = "";

  

 if (xmlStr.indexOf("SUCCESS") != -1) {

 Map<String, String> map = doXMLParse(xmlStr);

 prepay_id = (String) map.get("prepay_id");

 }

  

 Map<String, String> payMap = new HashMap<String, String>();

 payMap.put("appId", appid);

 payMap.put("timeStamp", create_timestamp());

 payMap.put("nonceStr", create_nonce_str());

 payMap.put("signType", "MD5");

 payMap.put("package", "prepay_id=" + prepay_id);

 String paySign = getSign(payMap, paternerKey);

  

 payMap.put("pg", prepay_id);

 payMap.put("paySign", paySign);

  

  

 WebUtil.response(response, WebUtil.packJsonp(callback, JsonUtil.warpJsonNodeResponse(JsonUtil.objectToJsonNode(payMap)).toString()));

 }

  

 @RequestMapping(value = "appPay")

 public void appPay(HttpServletRequest request, HttpServletResponse response, String body, String detail, String total_fee, String spbill_create_ip,

 String notify_url, String trade_type, String callback) throws Exception {

  

 String appid = "wx16691fcb0523c1a4";

 String partnerid = "22223670";

 String paternerKey = "fjfjfjfjf1234567FFFFFFFFF1234567";

  

 String out_trade_no = getTradeNo();

 Map<String, String> paraMap = new HashMap<String, String>();

 paraMap.put("appid", appid);

 paraMap.put("body", body);

 paraMap.put("mch_id", partnerid);

 paraMap.put("nonce_str", create_nonce_str());

 paraMap.put("out_trade_no", out_trade_no);

 paraMap.put("spbill_create_ip", spbill_create_ip);

 paraMap.put("total_fee", total_fee);

 paraMap.put("trade_type", trade_type);

 paraMap.put("notify_url", notify_url);

 String sign = getSign(paraMap, paternerKey);

 paraMap.put("sign", sign);

  

 // 统一下单 https://api.mch.weixin.qq.com/pay/unifiedorder

 String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

  

 String xml = ArrayToXml(paraMap, false);

  

 String xmlStr = HttpKit.post(url, xml);

  

 // 预付商品id

 String prepay_id = "";

  

 Map<String, String> map = doXMLParse(xmlStr);

 if (xmlStr.indexOf("SUCCESS") != -1) {

 prepay_id = (String) map.get("prepay_id");

 }

  

 String result_code = map.get("result_code");

 String err_code_des = map.get("err_code_des");

 Map<String, String> payMap = new HashMap<String, String>();

 payMap.put("appid", appid);

 payMap.put("partnerid", partnerid);

 payMap.put("prepayid", prepay_id);

 payMap.put("package", "Sign=WXPay");

 payMap.put("noncestr", create_nonce_str());

 payMap.put("timestamp", create_timestamp());

 String paySign = getSign(payMap, paternerKey);

  

 payMap.put("sign", paySign);

 payMap.put("result_code", result_code);

 payMap.put("err_code_des", err_code_des);

  

  

 WebUtil.response(response, WebUtil.packJsonp(callback, JsonUtil.warpJsonNodeResponse(JsonUtil.objectToJsonNode(payMap)).toString()));

 }

  

 @RequestMapping("/appPay_notify")

 public void appPayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception{

 //String xml = "<xml><appid><![CDATA[wxb4dc385f953b356e]]></appid><bank_type><![CDATA[CCB_CREDIT]]></bank_type><cash_fee><![CDATA[1]]></cash_fee><fee_type><![CDATA[CNY]]></fee_type><is_subscribe><![CDATA[Y]]></is_subscribe><mch_id><![CDATA[1228442802]]></mch_id><nonce_str><![CDATA[1002477130]]></nonce_str><openid><![CDATA[o-HREuJzRr3moMvv990VdfnQ8x4k]]></openid><out_trade_no><![CDATA[1000000000051249]]></out_trade_no><result_code><![CDATA[SUCCESS]]></result_code><return_code><![CDATA[SUCCESS]]></return_code><sign><![CDATA[1269E03E43F2B8C388A414EDAE185CEE]]></sign><time_end><![CDATA[20150324100405]]></time_end><total_fee>1</total_fee><trade_type><![CDATA[JSAPI]]></trade_type><transaction_id><![CDATA[1009530574201503240036299496]]></transaction_id></xml>";

 response.setCharacterEncoding("UTF-8");

 response.setContentType("text/xml");

 ServletInputStream in = request.getInputStream();

 String xmlMsg = Tools.inputStream2String(in);

  

 Map<String, String> map = doXMLParse(xmlMsg);

 String return_code = map.get("return_code");

 String return_msg = map.get("return_msg");

  

 map = new HashMap<String, String>();

 map.put("return_code", return_code);

 map.put("return_msg", return_msg);

  

 //响应xml

 String resXml = ArrayToXml(map, true);

 response.getWriter().write(resXml);

 }

  

 @RequestMapping("/orderquery.do")

 public void orderquery(HttpServletRequest request, HttpServletResponse response, String transaction_id, String out_trade_no, String callback) throws Exception{

  

 String url = "https://api.mch.weixin.qq.com/pay/orderquery";

  

 String appid = "wx16691fcb0523c1a4";

 String partnerid = "22223670";

 String paternerKey = "fjfjfjfjf1234567FFFFFFFFF1234567";

  

 Map<String, String> map = new HashMap<String, String>();

 map.put("appid", appid);

 map.put("mch_id", partnerid);

 if(transaction_id != null && !transaction_id.equals("")){

 map.put("transaction_id", transaction_id);

 }else {

 map.put("out_trade_no", out_trade_no);

 }

 map.put("nonce_str", create_nonce_str());

 String paySign = getSign(map, paternerKey);

 map.put("sign", paySign);

  

 String xml = ArrayToXml(map, false);

 String xmlStr = HttpKit.post(url, xml);

  

 Map<String, String> orderMap = doXMLParse(xmlStr);

  

  

 WebUtil.response(response, WebUtil.packJsonp(callback, JsonUtil.warpJsonNodeResponse(JsonUtil.objectToJsonNode(orderMap)).toString()));

 }

  

 /**

 * map转成xml

 *

 * @param arr

 * @return

 */

 public String ArrayToXml(Map<String, String> parm, boolean isAddCDATA) {

 StringBuffer strbuff = new StringBuffer(<xml>);

 if (parm != null ) {

 for (Entry<String, String> entry : parm.entrySet()) {

 strbuff.append("<").append(entry.getKey()).append(">");

 if (isAddCDATA) {

  strbuff.append(<![CDATA[).append(entry.getValue()).append(]]>);

 }else {

  strbuff.append(entry.getValue());

 }

 strbuff.append("<").append(entry.getKey()).append(">");

 }

 }

 return strbuff.append(</xml>).toString();

 }

  

 // 获取openId

 private String getUserOpenId(HttpServletRequest request) throws Exception {

 String code = request.getParameter("code");

 if (code == null) {

 String openId = request.getParameter("openId");

 return openId;

 }

 Oauth o = new Oauth();

 String token = o.getToken(code);

 JsonNode node = JsonUtil.StringToJsonNode(token);

 String openId = node.get("openid").asText();

 return openId;

 }

  

 private String create_nonce_str() {

 String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

 String res = "";

 for (int i = 0; i < 16; i++) {

 Random rd = new Random();

 res += chars.charAt(rd.nextInt(chars.length() - 1));

 }

 return res;

 }

  

 private String getAddrIp(HttpServletRequest request){

 return request.getRemoteAddr();

 }

  

 private String create_timestamp() {

 return Long.toString(System.currentTimeMillis() / 1000);

 }

  

 private String getTradeNo(){

 String timestamp = DatetimeUtil.formatDate(new Date(), DatetimeUtil.DATETIME_PATTERN);

 return "HZNO" + timestamp;

 }

  

 private String getSign(Map<String, String> params, String paternerKey )

 throws UnsupportedEncodingException {

 String string1 = Pay.createSign(params, false);

 String stringSignTemp = string1 + "&key=" + paternerKey;

 String signValue = DigestUtils.md5Hex(stringSignTemp).toUpperCase();

 return signValue;

 }

  

 private Map<String, String> doXMLParse(String xml)

 throws XmlPullParserException, IOException {

  

 InputStream inputStream = new ByteArrayInputStream(xml.getBytes());

  

 Map<String, String> map = null;

  

 XmlPullParser pullParser = XmlPullParserFactory.newInstance()

 .newPullParser();

  

 pullParser.setInput(inputStream, "UTF-8"); // 为xml设置要解析的xml数据

  

 int eventType = pullParser.getEventType();

  

 while (eventType != XmlPullParser.END_DOCUMENT) {

 switch (eventType) {

 case XmlPullParser.START_DOCUMENT:

 map = new HashMap<String, String>();

 break;

  

 case XmlPullParser.START_TAG:

 String key = pullParser.getName();

 if (key.equals("xml"))

  break;

  

 String value = pullParser.nextText();

 map.put(key, value);

  

 break;

  

 case XmlPullParser.END_TAG:

 break;

  

 }

  

 eventType = pullParser.next();

  

 }

  

 return map;

 }

  

}

Nach dem Login kopieren

wxprepay.shtm接口是预处理订单接口向微信服务器下订单。
appPay.shtml接口是支付接口。
appPay_notify.shtml接口是微信支付后异步通知结果接口。
orderquery.shtml接口是订单查询接口

3.3、涉及到的工具类
SessionUtil.java工具类

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

package org.andy.util;

  

import javax.servlet.http.HttpServletRequest;

  

  

public class SessionUtil {

 public static void addAtt(HttpServletRequest request, String key, Object value){

 request.getSession().setAttribute(key, value);

 }

  

 public static void removeAtt(HttpServletRequest request, String key){

 request.getSession().removeAttribute(key);

 }

  

 public static String getAtt(HttpServletRequest request, String key){

 return (String)request.getSession().getAttribute(key);

 }

  

 public static Object getAttObj(HttpServletRequest request, String key){

 return request.getSession().getAttribute(key);

 }

  

 public static String optAtt(HttpServletRequest request, String key, String value){

 String r = (String)request.getSession().getAttribute(key);

 if (r == null){

 r = value;

 }

 return r;

 }

  

}

Nach dem Login kopieren

HttpKit 网络请求工具类

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

/**

 * https 请求 微信为https的请求

 *

 * @author andy

 * @date 2015-10-9 下午2:40:19

 */

public class HttpKit {

 private static final String DEFAULT_CHARSET = "UTF-8";

 /**

 * @return 返回类型:

 * @throws IOException

 * @throws UnsupportedEncodingException

 * @throws NoSuchProviderException

 * @throws NoSuchAlgorithmException

 * @throws KeyManagementException

 * @description 功能描述: get 请求

 */

 public static String get(String url, Map<String, String> params, Map<String, String> headers) throws IOException, ExecutionException, InterruptedException {

 AsyncHttpClient http = new AsyncHttpClient();

 AsyncHttpClient.BoundRequestBuilder builder = http.prepareGet(url);

 builder.setBodyEncoding(DEFAULT_CHARSET);

 if (params != null && !params.isEmpty()) {

 Set<String> keys = params.keySet();

 for (String key : keys) {

 builder.addQueryParameter(key, params.get(key));

 }

 }

  

 if (headers != null && !headers.isEmpty()) {

 Set<String> keys = headers.keySet();

 for (String key : keys) {

 builder.addHeader(key, params.get(key));

 }

 }

 Future<Response> f = builder.execute();

 String body = f.get().getResponseBody(DEFAULT_CHARSET);

 http.close();

 return body;

 }

  

 /**

 * @return 返回类型:

 * @throws IOException

 * @throws UnsupportedEncodingException

 * @throws NoSuchProviderException

 * @throws NoSuchAlgorithmException

 * @throws KeyManagementException

 * @description 功能描述: get 请求

 */

 public static String get(String url) throws KeyManagementException, NoSuchAlgorithmException, NoSuchProviderException, UnsupportedEncodingException, IOException, ExecutionException, InterruptedException {

 return get(url, null);

 }

  

 /**

 * @return 返回类型:

 * @throws IOException

 * @throws NoSuchProviderException

 * @throws NoSuchAlgorithmException

 * @throws KeyManagementException

 * @throws UnsupportedEncodingException

 * @description 功能描述: get 请求

 */

 public static String get(String url, Map<String, String> params) throws KeyManagementException, NoSuchAlgorithmException, NoSuchProviderException, UnsupportedEncodingException, IOException, ExecutionException, InterruptedException {

 return get(url, params, null);

 }

  

 /**

 * @return 返回类型:

 * @throws IOException

 * @throws NoSuchProviderException

 * @throws NoSuchAlgorithmException

 * @throws KeyManagementException

 * @description 功能描述: POST 请求

 */

 public static String post(String url, Map<String, String> params) throws IOException, ExecutionException, InterruptedException {

 AsyncHttpClient http = new AsyncHttpClient();

 AsyncHttpClient.BoundRequestBuilder builder = http.preparePost(url);

 builder.setBodyEncoding(DEFAULT_CHARSET);

 if (params != null && !params.isEmpty()) {

 Set<String> keys = params.keySet();

 for (String key : keys) {

 builder.addParameter(key, params.get(key));

 }

 }

 Future<Response> f = builder.execute();

 String body = f.get().getResponseBody(DEFAULT_CHARSET);

 http.close();

 return body;

 }

  

 public static String post(String url, String s) throws IOException, ExecutionException, InterruptedException {

 AsyncHttpClient http = new AsyncHttpClient();

 AsyncHttpClient.BoundRequestBuilder builder = http.preparePost(url);

 builder.setBodyEncoding(DEFAULT_CHARSET);

 builder.setBody(s);

 Future<Response> f = builder.execute();

 String body = f.get().getResponseBody(DEFAULT_CHARSET);

 http.close();

 return body;

 }

  

}

Nach dem Login kopieren

支付工具类pay.java

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

/**

 * 支付相关方法

 * @author andy

 *

 */

public class Pay {

  

 // 发货通知接口

 private static final String DELIVERNOTIFY_URL = "https://api.weixin.qq.com/pay/delivernotify?access_token=";

  

 /**

 * 参与 paySign 签名的字段包括:appid、timestamp、noncestr、package 以及 appkey。

 * 这里 signType 并不参与签名微信的Package参数

 * @param params

 * @return

 * @throws UnsupportedEncodingException

 */

 public static String getPackage(Map<String, String> params) throws UnsupportedEncodingException {

 String partnerKey = ConfKit.get("partnerKey");

 String partnerId = ConfKit.get("partnerId");

 String notifyUrl = ConfKit.get("notify_url");

 // 公共参数

 params.put("bank_type", "WX");

 params.put("attach", "yongle");

 params.put("partner", partnerId);

 params.put("notify_url", notifyUrl);

 params.put("input_charset", "UTF-8");

 return packageSign(params, partnerKey);

 }

  

 /**

 * 构造签名

 * @param params

 * @param encode

 * @return

 * @throws UnsupportedEncodingException

 */

 public static String createSign(Map<String, String> params, boolean encode) throws UnsupportedEncodingException {

 Set<String> keysSet = params.keySet();

 Object[] keys = keysSet.toArray();

 Arrays.sort(keys);

 StringBuffer temp = new StringBuffer();

 boolean first = true;

 for (Object key : keys) {

 if (first) {

 first = false;

 } else {

 temp.append("&");

 }

 temp.append(key).append("=");

 Object value = params.get(key);

 String valueString = "";

 if (null != value) {

 valueString = value.toString();

 }

 if (encode) {

 temp.append(URLEncoder.encode(valueString, "UTF-8"));

 } else {

 temp.append(valueString);

 }

 }

 return temp.toString();

 }

  

 /**

 * @param params

 * @param paternerKey

 * @return

 * @throws UnsupportedEncodingException

 */

 private static String packageSign(Map<String, String> params, String paternerKey) throws UnsupportedEncodingException {

 String string1 = createSign(params, false);

 String stringSignTemp = string1 + "&key=" + paternerKey;

 String signValue = DigestUtils.md5Hex(stringSignTemp).toUpperCase();

 String string2 = createSign(params, true);

 return string2 + "&sign=" + signValue;

 }

  

 /**

 * 支付签名

 * @param timestamp

 * @param noncestr

 * @param packages

 * @return

 * @throws UnsupportedEncodingException

 */

 public static String paySign(String timestamp, String noncestr,String packages) throws UnsupportedEncodingException {

 Map<String, String> paras = new HashMap<String, String>();

 paras.put("appid", ConfKit.get("AppId"));

 paras.put("timestamp", timestamp);

 paras.put("noncestr", noncestr);

 paras.put("package", packages);

 paras.put("appkey", ConfKit.get("paySignKey"));

 // appid、timestamp、noncestr、package 以及 appkey。

 String string1 = createSign(paras, false);

 String paySign = DigestUtils.shaHex(string1);

 return paySign;

 }

  

 /**

 * 支付回调校验签名

 * @param timestamp

 * @param noncestr

 * @param openid

 * @param issubscribe

 * @param appsignature

 * @return

 * @throws UnsupportedEncodingException

 */

 public static boolean verifySign(long timestamp,

 String noncestr, String openid, int issubscribe, String appsignature) throws UnsupportedEncodingException {

 Map<String, String> paras = new HashMap<String, String>();

 paras.put("appid", ConfKit.get("AppId"));

 paras.put("appkey", ConfKit.get("paySignKey"));

 paras.put("timestamp", String.valueOf(timestamp));

 paras.put("noncestr", noncestr);

 paras.put("openid", openid);

 paras.put("issubscribe", String.valueOf(issubscribe));

 // appid、appkey、productid、timestamp、noncestr、openid、issubscribe

 String string1 = createSign(paras, false);

 String paySign = DigestUtils.shaHex(string1);

 return paySign.equalsIgnoreCase(appsignature);

 }

  

 /**

 * 发货通知签名

 * @param paras

 * @return

 * @throws UnsupportedEncodingException

 *

 * @参数 appid、appkey、openid、transid、out_trade_no、deliver_timestamp、deliver_status、deliver_msg;

 */

 private static String deliverSign(Map<String, String> paras) throws UnsupportedEncodingException {

 paras.put("appkey", ConfKit.get("paySignKey"));

 String string1 = createSign(paras, false);

 String paySign = DigestUtils.shaHex(string1);

 return paySign;

 }

  

  

 /**

 * 发货通知

 * @param access_token

 * @param openid

 * @param transid

 * @param out_trade_no

 * @return

 * @throws IOException

 * @throws NoSuchProviderException

 * @throws NoSuchAlgorithmException

 * @throws KeyManagementException

 * @throws InterruptedException

 * @throws ExecutionException

 */

  

 public static boolean delivernotify(String access_token, String openid, String transid, String out_trade_no) throws IOException, ExecutionException, InterruptedException {

 Map<String, String> paras = new HashMap<String, String>();

 paras.put("appid", ConfKit.get("AppId"));

 paras.put("openid", openid);

 paras.put("transid", transid);

 paras.put("out_trade_no", out_trade_no);

 paras.put("deliver_timestamp", (System.currentTimeMillis() / 1000) + "");

 paras.put("deliver_status", "1");

 paras.put("deliver_msg", "ok");

 // 签名

 String app_signature = deliverSign(paras);

 paras.put("app_signature", app_signature);

 paras.put("sign_method", "sha1");

 String json = HttpKit.post(DELIVERNOTIFY_URL.concat(access_token), JSONObject.toJSONString(paras));

 if (StringUtils.isNotBlank(json)) {

 JSONObject object = JSONObject.parseObject(json);

 if (object.containsKey("errcode")) {

 int errcode = object.getIntValue("errcode");

 return errcode == 0;

 }

 }

 return false;

 }

}

Nach dem Login kopieren

流转化Tools.java工具类

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

public final class Tools {

  

 public static final String inputStream2String(InputStream in) throws UnsupportedEncodingException, IOException{

 if(in == null)

 return "";

  

 StringBuffer out = new StringBuffer();

 byte[] b = new byte[4096];

 for (int n; (n = in.read(b)) != -1;) {

 out.append(new String(b, 0, n, "UTF-8"));

 }

 return out.toString();

 }

  

 public static final boolean checkSignature(String token,String signature,String timestamp,String nonce){

 List<String> params = new ArrayList<String>();

 params.add(token);

 params.add(timestamp);

 params.add(nonce);

 Collections.sort(params,new Comparator<String>() {

 @Override

 public int compare(String o1, String o2) {

 return o1.compareTo(o2);

 }

 });

 String temp = params.get(0)+params.get(1)+params.get(2);

 return SHA1.encode(temp).equals(signature);

 }

}

Nach dem Login kopieren

相应前端数据工具WebUtil.java工具类

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

public class WebUtil {

  

 public static Object getSessionAttribute(HttpServletRequest req, String key) {

 Object ret = null;

  

 try {

 ret = req.getSession(false).getAttribute(key);

 } catch (Exception e) {

 }

 return ret;

 }

  

 public static void response(HttpServletResponse response, String result) {

 try {

 response.setContentType("application/json;charset=utf-8");

 response.getWriter().write(result);

 } catch (IOException e) {

 e.printStackTrace();

 }

  

 }

  

 public static void response(HttpServletResponse response, ResponseMessage result) {

 try {

 response.setContentType("application/json;charset=utf-8");

 response.getWriter().write(JsonUtil.objectToJsonNode(result).toString());

 } catch (Exception e) {

 e.printStackTrace();

 }

 }

  

 public static String packJsonp(String callback, String json) {

 if (json == null) {

 json = "";

 }

 if (callback == null || callback.isEmpty()) {

 return json;

 }

  

 return callback + "&&" + callback + &#39;(&#39; + json + &#39;)&#39;;

 }

  

 public static String packJsonp(String callback, ResponseMessage response) {

 String json = null;

 if (response == null) {

 json = "";

 } else {

 json = JsonUtil.objectToJsonNode(response).toString();

 }

 if (callback == null || callback.isEmpty()) {

 return json;

 }

  

 return callback + "&&" + callback + &#39;(&#39; + json + &#39;)&#39;;

 }

}

Nach dem Login kopieren

Json转换工具JsonUtil.java

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

public class JsonUtil {

  

 public static ObjectNode warpJsonNodeResponse(JsonNode obj){

 ObjectNode objectNode=createObjectNode();

 objectNode.put("code", 1);

 objectNode.put("response", obj);

 return objectNode;

 }

  

 public static JsonNode objectToJsonNode(Object obj){

 try {

 ObjectMapper objectMapper = new ObjectMapper();

 String objJson=objectMapper.writeValueAsString(obj);

 JsonNode jsonNode = objectMapper.readTree(objJson);

 return jsonNode;

 } catch (JsonProcessingException e) {

 e.printStackTrace();

 } catch (IOException e) {

 // TODO Auto-generated catch block

 e.printStackTrace();

 }

 return null;

 }

  

}

Nach dem Login kopieren

四、微信H5调起支付

这个url需要后台实现,其实现功能如下:
1、接受微信服务器端发送的支付结果。
2、向微信服务器发送支付结果

具体 参考微信aip(http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=9_7)
具体代码如下:
4.1、授权向后台发起生成统一下订单页面
wxrepay.jsp

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

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

<%

 String path = request.getContextPath();

 String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";

 long t = System.currentTimeMillis();

%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta charset="utf-8" />

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />

<meta name="apple-mobile-web-app-capable" content="yes" />

<meta name="apple-mobile-web-app-status-bar-style" content="black" />

<meta name="format-detection" content="telephone=no" />

<title>微信公众号支付</title>

<link href="../css/css.css?t=<%=t%>" rel="stylesheet" type="text/css">

</head>

  

<body>

 <p class="index_box">

 <p class="apply_name">商品</p>

  

  

 <p class="branch_con">

 <ul>

 <li><span class="name">beacon 1分钱 1只</span></li>

 <li><span class="name">测试支付信息</span></li>

 </ul>

 <p class="cz_btn"><a href="javascript:reppay();" class="btn_1">确定购买</a></p>

 </p>

 </p>

  

 <script type="text/javascript" src="../js/common.js?t=<%=t%>"></script>

 <script type="text/javascript" >

  

 var code = urlparameter("code");

  

 function reppay(){

  

 ajaxUtil({}, mainpath+"/pay/wxprepay.shtml?code=" + code, repay);

  

 }

  

 function repay(response){

 var info = response;

 var url = "wxpay?appId=" + info.appId + "&timeStamp=" +info.timeStamp + "&nonceStr=" + info.nonceStr +

  "&pg=" +info.pg + "&signType=" +info.signType + "&paySign=" +info.paySign;

  

 window.location.href= url + "&showwxpaytitle=1";

 }

  

  

  

 </script>

</body>

</html>

Nach dem Login kopieren

首先是请求服务端wxprepay.shml接口,后台向微信支付平台获取支付订单信息,返回前台,wxpay.jsp页面
4.2、确认支付页面

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

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

<%

 String path = request.getContextPath();

 String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";

 long t = System.currentTimeMillis();

%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta charset="utf-8" />

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />

<meta name="apple-mobile-web-app-capable" content="yes" />

<meta name="apple-mobile-web-app-status-bar-style" content="black" />

<meta name="format-detection" content="telephone=no" />

<title>微信公众号支付</title>

<link href="../css/css.css?t=<%=t%>" rel="stylesheet" type="text/css">

</head>

  

<body>

 <p class="index_box">

 <p class="apply_name">微信js支付测试</p>

  

  

 <p class="branch_con">

 <ul>

 <li><span class="name">测试支付信息</span></li>

 </ul>

 <p class="cz_btn"><a href="javascript:pay();" class="btn_1">立即支付</a></p>

 </p>

 </p>

  

 <script type="text/javascript" src="../js/common.js?t=<%=t%>"></script>

 <script type="text/javascript">

  

 var appId = urlparameter("appId");

 var timeStamp = urlparameter("timeStamp");

 var nonceStr = urlparameter("nonceStr");

 var pg = urlparameter("pg");

 var signType = urlparameter("signType");

 var paySign = urlparameter("paySign");

  

  

 function onBridgeReady(){

  

 WeixinJSBridge.invoke(

 &#39;getBrandWCPayRequest&#39;, {

  "appId" : appId, //公众号名称,由商户传入

  "timeStamp": timeStamp, //时间戳,自1970年以来的秒数

  "nonceStr" : nonceStr, //随机串

  "package" : "prepay_id=" + pg,

  "signType" : signType, //微信签名方式:

  "paySign" : paySign //微信签名

 },

   

 function(res){

  if(res.err_msg == "get_brand_wcpay_request:ok" ) {

   

  alert("支付成功");

  } // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回 ok,但并不保证它绝对可靠。

 }

 );

 }

  

  

 function pay(){

  

 if (typeof WeixinJSBridge == "undefined"){

 if( document.addEventListener ){

  document.addEventListener(&#39;WeixinJSBridgeReady&#39;, onBridgeReady, false);

 }else if (document.attachEvent){

  document.attachEvent(&#39;WeixinJSBridgeReady&#39;, onBridgeReady);

  document.attachEvent(&#39;onWeixinJSBridgeReady&#39;, onBridgeReady);

 }

 }else{

 onBridgeReady();

 }

  

 }

 </script>

</body>

</html>

Nach dem Login kopieren

4.2、前台涉及到的工具类
javascript工具类common.js,样式css.css就不贴了没意义。

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

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439

440

441

442

443

444

445

446

447

448

449

450

451

452

453

454

455

456

457

458

459

460

461

462

463

464

465

466

467

468

469

470

471

472

473

474

475

var path="wxpay";

var mainpath = "/wxpay";

var appid = "wx16691fcb0523c1a4";

var urlpre = "http://www.xxx.com/wxpay/page";

var urlhost = "http://www.xxx.com/";

  

$(document).ready(function(){

 $(".refresher").click(function(){

 refresh();

 });

 $("#goback").click(function(){

 goback();

 });

});

function popupMsg(msg){

 alert(msg);

}

function printUtilViaGet(panel, requestdata, ajaxurl, printfunction){

 $.ajax({

 type: &#39;GET&#39;,

 url: ajaxurl,

 data: requestdata,

 cache:false,

 dataType:"json",

 async: false,

 success: function(response) {

 if (response.code){

 if (panel != null && panel.length > 0){

  $(panel).html("");

  if (printfunction != null)

  $(panel).html(printfunction(response.response));

 }

 return true;

 } else {

 //alert(response.reason);

 }

 },

 error: function(x, e) {

 //alert("error", x);

 },

 complete: function(x) {

 //alert("call complete");

 }

 });

 return false;

}

  

function ajaxUtilViaGet(requestdata, ajaxurl, succFunction, failFunction){

 $.ajax({

 url: ajaxurl,

 type: "GET",

 dataType: "json",

 cache:false,

 data: requestdata,

 async: false,

 success: function(response) {

 if (response.code){

 if (succFunction != null)

  succFunction(response.response);

 } else {

 if (failFunction != null)

  failFunction(response.response);

 }

 },

 error: function(x, e) {

 //alert("error", x);

 },

 complete: function(x) {

 }

 });

 return false;

}

function printUtil(panel, requestdata, ajaxurl, printfunction, ajaxasync) {

 if (isEmpty(ajaxasync)) {

 ajaxasync = false;

 }

 $.ajax({

 type : &#39;POST&#39;,

 url : ajaxurl,

 data : requestdata,

 cache : false,

 dataType : "json",

 async : ajaxasync,

 success : function(response) {

 if (response.code) {

 if (panel != null && panel.length > 0) {

  $(panel).html("");

  if (printfunction != null)

  $(panel).html(printfunction(response.response));

 }

 return true;

 } else {

 // alert(response.reason);

 }

 },

 error : function(x, e) {

 // alert("error", x);

 },

 complete : function(x) {

 // alert("call complete");

 }

 });

 return false;

}

function appendUtil(panel, requestdata, ajaxurl, printfunction, ajaxasync) {

 if (isEmpty(ajaxasync)) {

 ajaxasync = false;

 }

 $.ajax({

 type : &#39;POST&#39;,

 url : ajaxurl,

 data : requestdata,

 cache : false,

 dataType : "json",

 async : ajaxasync,

 success : function(response) {

 if (response.code) {

 if (panel != null && panel.length > 0) {

  if (printfunction != null)

  $(panel).append(printfunction(response.response));

 }

 return true;

 } else {

 // alert(response.reason);

 }

 },

 error : function(x, e) {

 // alert("error", x);

 },

 complete : function(x) {

 // alert("call complete");

 }

 });

 return false;

}

  

function ajaxUtilAsync(requestdata, ajaxurl, succFunction, failFunction) {

 $.ajax({

 url : ajaxurl,

 type : "POST",

 dataType : "json",

 cache : false,

 data : requestdata,

 async : true,

 success : function(response) {

 if (typeof response.code == "number") {

 if (response.code > 0) {

  if (succFunction != null)

  succFunction(response.response);

 } else {

  if (failFunction != null)

  failFunction(response.response);

 }

 } else {

 if (response.result) {

  if (succFunction != null)

  succFunction(response.response);

 } else {

  if (failFunction != null)

  failFunction(response.response);

 }

 }

 },

 error : function(x, e) {

 // alert("error", x);

 },

 complete : function(x) {

 }

 });

 return false;

}

  

function ajaxUtil(requestdata, ajaxurl, succFunction, failFunction){

 $.ajax({

 url: ajaxurl,

 type: "POST",

 dataType: "json",

 cache:false,

 data: requestdata,

 async: false,

 success: function(response) {

 if (typeof response.code == "number"){

 if (response.code > 0){

  if (succFunction != null)

  succFunction(response.response);

 } else {

  if (failFunction != null)

  failFunction(response.response);

 }

 } else {

 if (response.result){

  if (succFunction != null)

  succFunction(response.response);

 } else {

  if (failFunction != null)

  failFunction(response.response);

 }

 }

 },

 error: function(x, e) {

 //alert("error", x);

 },

 complete: function(x) {

 }

 });

 return false;

}

function loadSelection(panel, requestdata, ajaxurl, itemName){

 ajaxUtil(requestdata, ajaxurl, function(response){

 var list = response.list;

 for (var i = 0;i<list.length;i++){

 $(panel).append("<option value=&#39;"+list[i][itemName]+"&#39;>"+list[i][itemName]+"</option>");

 }

 }, null);

}

function ajaxSubmitRefresh(formId) {

 var hideForm = $(formId);

 var options = {

 dataType : "json",

 beforeSubmit : function() {

 },

 success : function(result) {

 if (result.result){

 showMsg("提交成功");

 } else {

 alert("提交失败!");

 }

 },

 error : function(result) {

 alert("提交失败!");

 }

 };

 hideForm.ajaxSubmit(options);

}

function ajaxSubmitWithJump(formId, nextPage) {

 var hideForm = $(formId);

 var options = {

 dataType : "json",

 beforeSubmit : function() {

 },

 success : function(result) {

 if (result.result){

 alert("提交成功");

 window.location.href = nextPage;

 } else {

 alert("提交失败!");

 }

 },

 error : function(result) {

 alert("提交失败!");

 }

 };

 hideForm.ajaxSubmit(options);

}

function refresh(){

 window.location.href = window.location.href;

}

function goback(){

 history.go(-1);

}

function urlparameter(paras){

 var url = location.href;

 var paraString = url.substring(url.indexOf("?")+1,url.length).split("&");

 var paraObj = {};

 for (var i=0; j=paraString[i]; i++){

 paraObj[j.substring(0,j.indexOf("=")).toLowerCase()] = j.substring(j.indexOf("=")+1,j.length);

 }

 var returnValue = paraObj[paras.toLowerCase()];

 if(typeof(returnValue)=="undefined"){

 return "";

 }else{

 return returnValue;

 }

}

String.prototype.endWith=function(str){

 if(str==null||str==""||this.length==0||str.length>this.length)

 return false;

 if(this.substring(this.length-str.length)==str)

 return true;

 else

 return false;

 return true;

 };

  

 String.prototype.startWith=function(str){

 if(str==null||str==""||this.length==0||str.length>this.length)

 return false;

 if(this.substr(0,str.length)==str)

 return true;

 else

 return false;

 return true;

 };

  

  

function getFileUrl(sourceId) {

 var url = "";

 if (navigator.userAgent.indexOf("MSIE")>=1) { // IE

 url = document.getElementById(sourceId).value;

 } else if(navigator.userAgent.indexOf("Firefox")>0) { // Firefox

 url = window.URL.createObjectURL(document.getElementById(sourceId).files.item(0));

 } else if(navigator.userAgent.indexOf("Chrome")>0) { // Chrome

 url = window.URL.createObjectURL(document.getElementById(sourceId).files.item(0));

 }

 return url;

}

  

function preImg(sourceId, targetId) {

 var url = getFileUrl(sourceId);

 var imgPre = document.getElementById(targetId);

 imgPre.src = url;

}

  

function initWX(){

 $.ajax({

 url:mainpath+&#39;/wechatjs.do&#39;,

 type:&#39;POST&#39;,

 dataType:&#39;json&#39;,

 async: false,

 data: {url:location.href.split(&#39;#&#39;)[0]},

 success:function(result){

 console.log(result);

 var data=result[&#39;response&#39;][&#39;map&#39;];

 if(result[&#39;code&#39;]==1){

 wx.config({

  debug: false,

  appId:data[&#39;appId&#39;],

  timestamp:data[&#39;timestamp&#39;],

  nonceStr:data[&#39;nonceStr&#39;],

  signature:data[&#39;signature&#39;],

  jsApiList: [&#39;onMenuShareTimeline&#39;,&#39;onMenuShareAppMessage&#39;,&#39;getLocation&#39;, &#39;onMenuShareQQ&#39;, &#39;onMenuShareWeibo&#39;]

 });

 }else{

 alert("fail to get code");

 window.alert(&#39;fail&#39;);

 };

 }

 });

}

var EARTH_RADIUS = 6378137.0; //单位M

var PI = Math.PI;

  

function getRad(d){

 return d*PI/180.0;

}

function getGreatCircleDistance(lat1,lng1,lat2,lng2){

 var radLat1 = getRad(lat1);

 var radLat2 = getRad(lat2);

  

 var a = radLat1 - radLat2;

 var b = getRad(lng1) - getRad(lng2);

  

 var s = 2*Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2) + Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2),2)));

 s = s*EARTH_RADIUS;

 s = Math.round(s*10000)/10000.0;

 s = Math.round(s);

 return s;

}

//对Date的扩展,将 Date 转化为指定格式的String

//月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符,

//年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)

//例子:

//(new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423

//(new Date()).Format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18

Date.prototype.format = function(fmt)

{ //author: meizz

var o = {

 "M+" : this.getMonth()+1,  //月份

 "d+" : this.getDate(),  //日

 "h+" : this.getHours(),  //小时

 "m+" : this.getMinutes(),  //分

 "s+" : this.getSeconds(),  //秒

 "q+" : Math.floor((this.getMonth()+3)/3), //季度

 "S" : this.getMilliseconds() //毫秒

};

if(/(y+)/.test(fmt))

 fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));

for(var k in o)

 if(new RegExp("("+ k +")").test(fmt))

fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));

return fmt;

};

  

//判断为空

function isEmpty(src){

 if(("undefined" == typeof src) || (src == null) || ($.trim(src) == "") ){

 return true;

 }

 return false;

}

  

//判断不为空

function notEmpty(src){

 return !isEmpty(src);

}

  

//微信页面授权 snsapi_base方式

function wecharauto2burl(url) {

 return "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appid

 + "&redirect_uri=" + encodeURIComponent(url)

 + "&response_type=code&scope=snsapi_base&state=xybank#wechat_redirect";

}

  

//页面授权针对snsapi_base方式授权的url

function wecharauto2baseurl(url) {

 return wecharauto2burl(urlpre+url);

}

  

//页面授权针对snsapi_userinfo方式授权的url

function wecharauto2userinfourl(url) {

 return "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appid

 + "&redirect_uri=" + encodeURIComponent(urlpre+url)

 + "&response_type=code&scope=snsapi_userinfo&state=xybank#wechat_redirect";

}

  

  

//微信分享 此方法需放在wx.ready中

function shareWeChat(title, link, imgUrl, desc){

 wx.onMenuShareTimeline({

 title: title, // 分享标题

 link: link, // 分享链接

 imgUrl: imgUrl, // 分享图标

 success: function () {

 // 用户确认分享后执行的回调函数

 },

 cancel: function () {

 // 用户取消分享后执行的回调函数

 }

 });

  

 //分享给朋友

 wx.onMenuShareAppMessage({

 title: title, // 分享标题

 desc: desc, // 分享描述

 link: link, // 分享链接

 imgUrl: imgUrl, // 分享图标

 type: &#39;link&#39;, // 分享类型,music、video或link,不填默认为link

 dataUrl: &#39;&#39;, // 如果type是music或video,则要提供数据链接,默认为空

 success: function () {

 // 用户确认分享后执行的回调函数

 },

 cancel: function () {

 // 用户取消分享后执行的回调函数

 }

 });

  

 //分享到QQ

 wx.onMenuShareQQ({

 title: title, // 分享标题

 desc: desc, // 分享描述

 link: link, // 分享链接

 imgUrl: imgUrl, // 分享图标

 success: function () {

 // 用户确认分享后执行的回调函数

 },

 cancel: function () {

 // 用户取消分享后执行的回调函数

 }

 });

  

 //分享到腾讯微博

 wx.onMenuShareWeibo({

 title: title, // 分享标题

 desc: desc, // 分享描述

 link: link, // 分享链接

 imgUrl: imgUrl, // 分享图标

 success: function () {

 // 用户确认分享后执行的回调函数

 },

 cancel: function () {

 // 用户取消分享后执行的回调函数

  

 }

 });

}

Nach dem Login kopieren

五、支付结果

公众号调起效果如下:


支付成功后,微信服务器得到后台的Notify通知后,会发微信说明支付信息,支付凭证如下:


后续会全部更新微信app支付,微信支付退款,微信企业向个人付款,支付宝相关支付。而且会上传全部代码到csdn资源下载处,尽请关注。

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

Das obige ist der detaillierte Inhalt vonAnalyse der Verwendung von H5 zum Anrufen und Bezahlen öffentlicher WeChat-Kontozahlungen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage