1、申請
需要準備的材料
- 認證的服務號,300塊一年認證費用
- 營業執照
- 公司對公銀行賬號
1、先申請服務號
2、通過後,申請微信支付
微信支付不同行業需要收手續費,一般0.6%
2、配置
之前沒有接觸過,看官網文件呼叫的圖也是一臉懵,只知道有個預下單的操作獲取prepay_id,使用者支付完成之後,有微信回撥的操作。
公眾號和商戶平臺需要配置項
- 支付需要獲取使用者的openid,因此在公眾號設定-功能設定-網頁授權域名中加入域名
加入域名時,需要將下載的檔案放到專案中,使填寫的域名能訪問到。我是放到了靜態資源中,沒有寫其他目錄,直接使用域名就可訪問。
- 商戶平臺中公眾號支付需要配置域名,產品中心-開發配置-支付配置
- 商戶平臺中需要設定API金鑰和API證書,因為是第一次設定,所以需要按照提示操作,若已經有了金鑰和證書,那就不要設定了。
3、開發
流程:
使用者--->>開啟頁面確認授權獲取CODE--->>跳轉到訂單頁面--->>點選支付--->>將CODE傳送到後臺獲取openid,拼裝商品引數,呼叫微信預下單,獲取到prepay_id,並將prepay_id傳送到前端--->>獲取prepay_id拉起支付介面,輸入密碼--->>支付成功,微信回撥介面,並通知微信交易成功,停止微信回撥。
後臺配置
- 1、需要將商戶平臺配置的證書檔案和公眾號設定的授權檔案,放到專案中
- 2、配置公眾號相關資訊
後臺程式碼
關鍵後臺程式碼
@Autowired
private BestPayServiceImpl bestPayService;
private static final String get_openid="https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";
@Autowired
private WechatAccountConfig accountConfig;
/**
* 授權獲取CODE
* @return
*/
@GetMapping(value = "/pay")
public ModelAndView pay() {
return new ModelAndView("authon.html");
}
/**
* 發起支付
* 通過code, 獲取openid,
*/
@GetMapping(value = "/goodspay")
public ModelAndView goodspay(@RequestParam("code") String code,String money,
Map<String, Object> map) {
String uri=String.format(get_openid,accountConfig.getMpAppId(),accountConfig.getSecret(),code);
log.info("【獲取openid】request={}", uri);
String json=HttpUtil.get(uri);
log.info("【獲取openid】request={}", json);
JSONObject jsonobj=JSONObject.parseObject(json);
log.info("openid={}",jsonobj.get("openid"));
String openid= (String) jsonobj.get("openid");
return pay(openid,money,map);
}
/**
* 發起支付
*/
public ModelAndView pay(String openid,String money,
Map<String, Object> map) {
PayRequest request = new PayRequest();
Random random = new Random();
//支付請求引數
request.setPayTypeEnum(BestPayTypeEnum.WXPAY_H5);
request.setOrderId(String.valueOf(random.nextInt(1000000000)));
if(StringUtils.isNotEmpty(money)){
request.setOrderAmount(new Double(money));
}else{
request.setOrderAmount(0.01);
}
request.setOrderName("支付測試");
request.setOpenid(openid);
log.info("【發起支付】request={}", JsonUtil.toJson(request));
PayResponse payResponse = bestPayService.pay(request);
log.info("【發起支付】response={}", JsonUtil.toJson(payResponse));
map.put("payResponse", payResponse);
return new ModelAndView("pay/create", map);
}
/**
* 非同步回撥
*/
@PostMapping(value = "/notify")
public ModelAndView notify(@RequestBody String notifyData) throws Exception {
log.info("【非同步回撥】request={}", notifyData);
PayResponse response = bestPayService.asyncNotify(notifyData);
log.info("【非同步回撥】response={}", JsonUtil.toJson(response));
return new ModelAndView("pay/success");
}
複製程式碼
前端程式碼
獲取使用者授權頁面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>授權跳轉中....</title>
</head>
<script>
var appid = "wxdaa292459af12ea1";
var redirect_uri = encodeURIComponent("http://ixq66a.natappfree.cc/goods.html");
window.location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appid + "&redirect_uri=" + redirect_uri + "&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect"
</script>
<body>
</body>
</html>
複製程式碼
點選支付頁面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>轉賬</title>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<link rel="stylesheet" href="//res.layui.com/layui/dist/css/layui.css" media="all">
</head>
<body>
<form action="/goodspay" method="get">
<input value="" id="code1" name="code" hidden/>
<fieldset class="layui-elem-field site-demo-button" style="margin-top: 20%;margin-bottom: -30%;">
<legend style="font-size: 50px;">下單支付0.01元</legend>
<div style="margin-top: 70px;margin-left: 20px;margin-right: 20px;margin-bottom: 30px;">
<button class="layui-btn layui-btn-primary" style="width: 100%;height: auto;background-color: #36e0d2;
font-size: 100px;">微信支付</button>
</div>
</fieldset>
</form>
<form action="/goodspay" method="get" style="padding-top: 15%;">
<input value="" id="code2" name="code" hidden/>
<fieldset class="layui-elem-field site-demo-button" style="margin-top: 30%;margin-bottom: -30%;">
<legend style="font-size: 50px;">輸入金額下單支付</legend>
<input value="" id="money" name="money" style="width: 50%;height: 100px;font-size: 100px;" placeholder="輸入金額"/>
<div style="margin-top: 70px;margin-left: 20px;margin-right: 20px;margin-bottom: 30px;">
<button class="layui-btn layui-btn-primary" style="width: 100%;height: auto;background-color: #36e0d2;
font-size: 100px;">微信支付</button>
</div>
</fieldset>
</form>
<script>
//轉碼
function parse_url(url) { //定義函式
var pattern = /(\w+)=(\w+)/ig; //定義正規表示式
var parames = {}; //定義陣列
url.replace(pattern, function (a, b, c) {
parames[b] = c;
});
return parames; //返回這個陣列.
}
//獲取當前url 取到code
var url = window.location.href;
var params = parse_url(url);
$("#code1").val(params.code);
$("#code2").val(params.code);
</script>
</body>
</html>
複製程式碼
拉起支付頁面
<script>
function onBridgeReady(){
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId":"${payResponse.appId}", //公眾號名稱,由商戶傳入
"timeStamp":"${payResponse.timeStamp}", //時間戳,自1970年以來的秒數
"nonceStr":"${payResponse.nonceStr}", //隨機串
"package":"${payResponse.packAge}",
"signType":"MD5", //微信簽名方式:
"paySign":"${payResponse.paySign}" //微信簽名
},
function(res){
if(res.err_msg == "get_brand_wcpay_request:ok" ) {
alert('支付成功');
}else if(res.err_msg == "get_brand_wcpay_request:cancel") {
alert('支付過程中使用者取消');
}else if(res.err_msg == "get_brand_wcpay_request:fail") {
alert('支付失敗');
}else {
alert('未知異常');
}
WeixinJSBridge.call('closeWindow');
}
);
}
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();
}
</script>
複製程式碼
GIT地址
因專案是建立在別人專案基礎上更改的,所以保留了原作者。 github.com/litblank/Wx…