知識
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價(jià)值,我們在追求其視覺表現(xiàn)的同時(shí),更側(cè)重于功能的便捷,營銷的便利,運(yùn)營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏壧峁┍憬莸闹С郑?
您當(dāng)前位置>首頁 » 新聞資訊 » 公眾號相關(guān) >
Java 微信公眾號支付(JSAPI)
發(fā)表時(shí)間:2020-10-19
發(fā)布人:葵宇科技
瀏覽次數(shù):50
1:微信公眾平臺:https://mp.weixin.qq.com/ 企業(yè)郵箱賬號注冊申請;
2:找到接口權(quán)限,設(shè)置網(wǎng)頁授權(quán);
網(wǎng)頁授權(quán)域名:
這里重點(diǎn)注意 設(shè)置域名:需要下載這個(gè)txt文件,微信會在設(shè)置完域名之后調(diào)用域名下的文件訪問內(nèi)容。
注:這里提供一個(gè)小得解決方案:
內(nèi)網(wǎng)穿透設(shè)置免費(fèi)域名: natapp.exe;百度教程。設(shè)置一個(gè)當(dāng)前開發(fā)項(xiàng)目端口得免費(fèi)域名。
下載微信得txt文件拿到里面得內(nèi)容,提供一個(gè)Get接口。
@RestController
@RequestMapping("/MP_verify_RiguI1gGI9QyALmH.txt")
public class WxTxtController {
@GetMapping()
public String txt() {
return "RiguI1gGI9QyALmH";
}
這樣就可以保證網(wǎng)頁授權(quán)域名通過微信驗(yàn)證。
3.微信商戶平臺申請開通支付:https://pay.weixin.qq.com/
通過之后,需要得配置:賬戶中心-API證書;產(chǎn)品中心-開發(fā)配置-公眾號支付授權(quán)目錄 可以是:"http:natapp.exe生成得免費(fèi)域名/index/",
參數(shù)介紹:
APPID:公共號ID;
SECRET:公眾號secret;
MCH_ID:支付商戶ID;
PATER_NER_KEY:支付密鑰;就是API安全這個(gè)里面那個(gè)32位得;
接下來進(jìn)入貼代碼:
獲取code:CALL_BACK_URL:就是生成得免費(fèi)域名;
/**
* 微信公眾平臺授權(quán)登錄
*
* @param response
* @return
* @throws IOException
*/
@PostMapping("/publicLogin")
@ResponseBody
public AjaxResult login(HttpServletResponse response) throws IOException {
//回調(diào)的url
String redirect_uri = URLEncoder.encode(CALL_BACK_URL + "/api/wxBusiness/publicCallBack", "UTF-8");
String url = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
"appid=APPID" +
"&redirect_uri=REDIRECT_URI" +
"&response_type=code" +
"&scope=SCOPE" +
"&state=123#wechat_redirect";
return AjaxResult.success(url.replace("APPID", APPID).replace("REDIRECT_URI", redirect_uri).replace("SCOPE", "snsapi_userinfo"));
}
/**
* 微信公眾平臺回調(diào)
*
* @param modelMap
* @param req
* @param resp
* @return
* @throws Exception
*/
@RequestMapping(value = "/publicCallBack", method = RequestMethod.GET)
@ResponseBody
public AjaxResult callBack(ModelMap modelMap, HttpServletRequest req, HttpServletResponse resp) throws Exception {
String code = req.getParameter("code");
return AjaxResult.success(code);
}
其實(shí)這些代碼前端寫 也是沒問題得。
拿到code:調(diào)用微信統(tǒng)一下單接口:
JSAPI:官方文檔 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1
下載Java包 然后把那些wxPay得文件引入項(xiàng)目;
/**
* @param request
* @param code
* @return Map
* @Description 微信瀏覽器內(nèi)微信支付/公眾號支付(JSAPI)
*/
@RequestMapping(value = "/orders", method = RequestMethod.GET)
@ResponseBody
public AjaxResult orders(HttpServletRequest request, String code) {
try {
//訂單號
String orderNumber = DateUtils.dateTimeNow(DateUtils.YYYYMMDDHHMMSS + "" + (int) (Math.random() * 10000));
//頁面獲取openId接口
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + APPID
+ "&secret=" + SECRET
+ "&code=" + code
+ "&grant_type=authorization_code";
JSONObject jsonObject = HttpUtils.doGetJson(url);
/*
{ "access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE"
}
*/
String openid = jsonObject.getString("openid");
LOGGER.info("openId:" + openid);
//拼接統(tǒng)一下單地址參數(shù)
Map<String, String> paraMap = new HashMap<String, String>();
//獲取請求ip地址
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
if (ip.indexOf(",") != -1) {
String[] ips = ip.split(",");
ip = ips[0].trim();
}
String nonceStr = WXPayUtil.generateNonceStr();
LOGGER.info("nonce_str:"+nonceStr);
paraMap.put("appid", APPID);
paraMap.put("body", ORDER_BODY);
paraMap.put("mch_id", MCH_ID);
paraMap.put("nonce_str", nonceStr);
paraMap.put("openid", openid);
paraMap.put("out_trade_no", orderNumber);//訂單號
paraMap.put("spbill_create_ip", ip);
paraMap.put("total_fee", "1");
paraMap.put("trade_type", "JSAPI");
paraMap.put("notify_url", " http://dtpbuf.natappfree.cc/api/wxBusiness/callback");// 此路徑是微信服務(wù)器調(diào)用支付結(jié)果通知路徑隨意寫
String sign = WXPayUtil.generateSignature(paraMap, PATER_NER_KEY);
LOGGER.info("微信sign:" + sign);/*
LOGGER.info("驗(yàn)簽:"+WXPayUtil.isSignatureValid(sign,PATER_NER_KEY));*/
paraMap.put("sign", sign);
String xml = WXPayUtil.mapToXml(paraMap);//將所有參數(shù)(map)轉(zhuǎn)xml格式
// 統(tǒng)一下單 https://api.mch.weixin.qq.com/pay/unifiedorder
String unifiedorder_url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
String xmlStr = HttpUtils.sendPost(unifiedorder_url, xml);//發(fā)送post請求"統(tǒng)一下單接口"返回預(yù)支付id:prepay_id
LOGGER.info("xml:" + xmlStr);
//以下內(nèi)容是返回前端頁面的json數(shù)據(jù)
String prepay_id = "";//預(yù)支付id
String nonce_str="";
if (xmlStr.indexOf("SUCCESS") != -1) {
Map<String, String> map = WXPayUtil.xmlToMap(xmlStr);
prepay_id = (String) map.get("prepay_id");
nonce_str=(String) map.get("nonce_str");
}
Map<String, String> payMap = new HashMap<String, String>();
payMap.put("appId", APPID);
payMap.put("timeStamp", WXPayUtil.getCurrentTimestamp() + "");
payMap.put("nonceStr", nonceStr);
payMap.put("package", "prepay_id=" + prepay_id);
payMap.put("signType", "MD5");
String paySign = WXPayUtil.generateSignature(payMap, PATER_NER_KEY);
payMap.put("paySign", paySign);
/**
* 訂單初始化
*/
SysOrderInfo orderInfo = new SysOrderInfo();
orderInfo.setOrderNumber(orderNumber);
orderInfo.setOrderBody(OrderConstants.ORDER_CLASS_BODY);
orderInfo.setOpenId(openid);
orderInfo.setOrderStatus(OrderConstants.ORDER_STATUS_NOT);
orderInfo.setOrderType(OrderConstants.ORDER_TYPE_LEARN);
orderInfo.setOrderTradeType(OrderConstants.ORDER_TRADE_JS_API);
orderInfo.setOrderPrice(BigDecimal.valueOf(OrderConstants.ORDER_PRICE));
orderInfoService.insertSysOrderInfo(orderInfo);
orderWxVo orderWxVo = new orderWxVo();
orderWxVo.setAppId(APPID);
orderWxVo.setTimeStamp(WXPayUtil.getCurrentTimestamp() + "");
orderWxVo.setNonceStr(nonceStr);
orderWxVo.setSignType("MD5");
orderWxVo.setPackages("prepay_id=" + prepay_id);
orderWxVo.setPaySign(paySign);
return AjaxResult.success(orderWxVo);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
直接拿著用就可以。這里幾個(gè)小坑:①:nonceStr 這個(gè)參數(shù) 統(tǒng)一下單 簽名 和返回前端得參數(shù)二次簽名 得是同一個(gè)字符串。
②:code只能用一次;③:SignType必須是MD5;修改微信提供得wxPay里得
public WXPay(final WXPayConfig config, final String notifyUrl, final boolean autoReport, final boolean useSandbox) throws Exception {
this.config = config;
this.notifyUrl = notifyUrl;
this.autoReport = autoReport;
this.useSandbox = useSandbox;
if (useSandbox) {
this.signType = SignType.MD5; // 沙箱環(huán)境
}
else {
this.signType = SignType.MD5;
}
this.wxPayRequest = new WXPayRequest(config);
}
重點(diǎn):else {
this.signType = SignType.MD5;
}
回調(diào):
/**
* 支付回調(diào)
*
* @param request
* @param response
* @return
*/
@RequestMapping("callback")
public String callBack(HttpServletRequest request, HttpServletResponse response) {
InputStream is = null;
try {
is = request.getInputStream();//獲取請求的流信息(這里是微信發(fā)的xml格式所有只能使用流來讀)
String xml = WXPayUtil.inputStream2String(is, "UTF-8");
Map<String, String> notifyMap = WXPayUtil.xmlToMap(xml);//將微信發(fā)的xml轉(zhuǎn)map
if (notifyMap.get("return_code").equals("SUCCESS")) {
if (notifyMap.get("result_code").equals("SUCCESS")) {
String orderNumber = notifyMap.get("out_trade_no");//商戶訂單號
LOGGER.info("回調(diào)訂單號:"+orderNumber);
/**
* 自己的業(yè)務(wù)處理
*/
}
}
//告訴微信服務(wù)器收到信息了,不要在調(diào)用回調(diào)action了========這里很重要回復(fù)微信服務(wù)器信息用流發(fā)送一個(gè)xml即可
response.getWriter().write("<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>");
is.close();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
js得代碼 官網(wǎng)里有:
這個(gè)只有在微信內(nèi)置瀏覽器能識別這個(gè)方法。WeixinJSBridge..invoke。
相關(guān)案例查看更多
相關(guān)閱讀
- 大理網(wǎng)站建設(shè)公司
- 汽車報(bào)廢系統(tǒng)
- 小程序被騙退款成功
- 汽車報(bào)廢回收軟件
- 云南小程序開發(fā)推薦
- 昆明網(wǎng)站建設(shè)公司
- 汽車回收系統(tǒng)
- 河南小程序制作
- 網(wǎng)站建設(shè)服務(wù)
- vue開發(fā)小程序
- 網(wǎng)站建設(shè)專家
- 云南網(wǎng)站建設(shè)首頁
- 小程序
- 云南小程序代建
- 云南小程序開發(fā)制作公司
- 云南網(wǎng)站建設(shè)
- 模版消息
- web開發(fā)
- 云南網(wǎng)站建設(shè)電話
- 搜索排名
- 昆明網(wǎng)站設(shè)計(jì)
- 云南網(wǎng)站建設(shè)一條龍
- 小程序開發(fā)公司
- 小程序設(shè)計(jì)
- 網(wǎng)站建設(shè)列表網(wǎng)
- 網(wǎng)站開發(fā)哪家好
- 網(wǎng)站上首頁
- 云南etc微信小程序
- 服務(wù)器
- 云南科技公司