Vue+SpringBoot實(shí)現(xiàn)支付寶沙箱支付的示例代碼
首先去下載支付寶沙箱的一系列東西,具體的配置什么的我就不說了,有很多博客都講了,還有螞蟻金服官方也說的很詳細(xì),我就直接說怎么樣把后端的支付頁面顯示到Vue前端來:
在你配置好AlipayConfig這個(gè)文件后,就可以寫前端的邏輯了,前端是采用支付寶的頁面如下:
下面展示一些 內(nèi)聯(lián)代碼片。
/* 以下是支付確認(rèn)html */
<div style="text=#000000 bgColor=#ffffff leftMargin=0 topMargin=4">
<header class="am-header">
<h1>支付確認(rèn)</h1>
</header>
<div id="main">
<!-- <form name="alipayment" :model="payObject" target="_blank"> -->
<div id="body1" class="show" name="divcontent">
<dl class="content">
<dt>商戶訂單號(hào) :</dt>
<dd>
<input
id="WIDout_trade_no"
name="WIDout_trade_no"
readonly="true"
:value="payObject.WIDout_trade_no"
/>
</dd>
<hr class="one_line" />
<dt>訂單名稱 :</dt>
<dd>
<input
id="WIDsubject"
name="WIDsubject"
readonly="true"
:value="payObject.WIDsubject"
/>
</dd>
<hr class="one_line" />
<dt>付款金額 :</dt>
<dd>
<input
id="WIDtotal_amount"
name="WIDtotal_amount"
readonly="true"
:value="payObject.WIDtotal_amount"
/>
</dd>
<hr class="one_line" />
<dt>商品描述:</dt>
<dd>
<input id="WIDbody" name="WIDbody" readonly="true" :value="payObject.WIDbody" />
</dd>
<hr class="one_line" />
<dd id="btn-dd">
<span class="new-btn-login-sp">
<button class="new-btn-login" style="text-align: center;" @click="paySub()">付 款</button>
</span>
<span class="note-help">如果您點(diǎn)擊“付款”按鈕,即表示您同意該次的執(zhí)行操作。</span>
</dd>
</dl>
</div>
<!-- </form> -->
</div>
</div>
我再加上這個(gè)頁面的css
/* 以下是支付確認(rèn)樣css*/
.am-header {
display: -webkit-box;
display: -ms-flexbox;
/* display: flex; */
width: 100%;
position: relative;
padding: 15px 0;
-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
background: #1d222d;
height: 50px;
text-align: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
box-pack: center;
-webkit-box-align: center;
-ms-flex-align: center;
box-align: center;
}
.am-header h1 {
-webkit-box-flex: 1;
-ms-flex: 1;
box-flex: 1;
line-height: 18px;
text-align: center;
font-size: 18px;
font-weight: 300;
color: #fff;
}
#main {
width: 100%;
margin: 0 auto;
font-size: 14px;
}
.show {
clear: left;
display: block;
}
.content {
margin-top: 5px;
}
.content dt {
width: 100px;
display: inline-block;
float: left;
margin-left: 20px;
color: #666;
font-size: 13px;
margin-top: 8px;
}
.content dd {
margin-left: 120px;
margin-bottom: 5px;
}
.content dd input {
width: 85%;
height: 28px;
border: 0;
-webkit-border-radius: 0;
-webkit-appearance: none;
inputoutline: none;
}
.one_line {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #eeeeee;
width: 100%;
margin-left: 20px;
}
#btn-dd {
margin: 20px;
text-align: center;
}
.new-btn-login-sp {
padding: 1px;
display: inline-block;
width: 75%;
}
.new-btn-login {
background-color: #02aaf1;
color: #ffffff;
font-weight: bold;
border: none;
width: 100%;
height: 50px;
border-radius: 5px;
font-size: 16px;
}
.note-help {
color: #999999;
font-size: 12px;
line-height: 100%;
margin-top: 5px;
width: 100%;
display: block;
}
當(dāng)然,在html頁面的數(shù)據(jù)是以下這樣定義的:
/*html用的數(shù)據(jù)*/
payObject: {
//支付數(shù)據(jù)
WIDsubject: 0,
WIDout_trade_no: "",
WIDtotal_amount: "",
WIDbody: ""
},
當(dāng)然,在你要打開支付這個(gè)頁面時(shí),你得用函數(shù)把這些數(shù)據(jù)進(jìn)行賦值,就是以下代碼,具體看注釋:
//去往支付頁面函數(shù)
payOrder() {
//this.payObject.WIDsubject這個(gè)我已經(jīng)在跳轉(zhuǎn)支付界面時(shí)把這個(gè)給設(shè)為訂單號(hào)了
//判斷oid(訂單號(hào))是否是數(shù)字
if (typeof this.payObject.WIDsubject != "string") {
//從sessionStorage拿出用戶的數(shù)據(jù)
const usertoken = sessionStorage.getItem("usertoken");
const user = JSON.parse(sessionStorage.getItem("user"));
// console.log(user)
//如果用戶正常(不為空)
if (usertoken != null) {
if (user != null) {
const uname = user.uname;
//我在這里去獲取哪個(gè)訂單需要支付
dishApi.payConfirm(this.payObject.WIDsubject).then(response => {
const resp = response.data;
if (resp.code === 200) {
//生成這個(gè)sNow數(shù)據(jù)
var vNow = new Date();
var sNow = "";
sNow += String(vNow.getFullYear());
sNow += String(vNow.getMonth() + 1);
sNow += String(vNow.getDate());
sNow += String(vNow.getHours());
sNow += String(vNow.getMinutes());
sNow += String(vNow.getSeconds());
sNow += String(vNow.getMilliseconds());
//綁定頁面的data數(shù)據(jù)
this.payObject.WIDout_trade_no = sNow; //綁定tradeno
this.payObject.WIDbody = uname;//我這里是綁定的用戶名
this.payObject.WIDsubject = resp.oid; //返回現(xiàn)在的訂單號(hào)值
this.payObject.WIDtotal_amount = resp.totalValue; //返回支付總價(jià)
} else {
this.$message({
message: resp.message,
type: "warning",
duration: 500 // 彈出停留時(shí)間
});
}
});
} else {
this.$message({
message: "請(qǐng)先登錄",
type: "warning",
duration: 1000 // 彈出停留時(shí)間
});
}
} else {
this.$message({
message: "請(qǐng)先登錄",
type: "warning",
duration: 1000 // 彈出停留時(shí)間
});
}
} else {
this.$message({
message: "支付錯(cuò)誤",
type: "warning",
duration: 1000 // 彈出停留時(shí)間
});
}
},
然后我在來說當(dāng)你點(diǎn)擊立即付款后怎么做(就是點(diǎn)擊付款調(diào)用paySub()函數(shù))
//支付開始
/給用戶提示
paySub() {
this.$message({
showClose: true,
message: "請(qǐng)?jiān)?分鐘內(nèi)完成支付",
duration: 5000 // 彈出停留時(shí)間
});
//前往支付
//這里向后端傳入你的支付數(shù)據(jù),就是剛才定義的和綁定的數(shù)據(jù)
dishApi
.pay(
this.payObject.WIDout_trade_no,
this.payObject.WIDtotal_amount,
this.payObject.WIDsubject,
this.payObject.WIDbody
)
.then(response => {
//后臺(tái)響應(yīng)后處理如下
const r = response.data;
if (r.code === 200) {
//這是后端響應(yīng)的r,我獲取了它的formaction,至于這里面是什么,我們后面說,
//獲取到的數(shù)據(jù)先存儲(chǔ)在sessionStorage中,為了將來的讀取
sessionStorage.setItem("payaction", r.formaction);
//然后就將頁面跳轉(zhuǎn)到支付的界面
window.open("#pay", "_blank");
} else {
this.$message({
message: resp.message,
type: "warning",
duration: 500 // 彈出停留時(shí)間
});
}
});
},
接下來就改springboot后端了:我們來寫上面這個(gè)dishApi.pay()訪問的后端是怎么樣的
@ResponseBody
@PostMapping("/AliPay")
//在這里接收前端傳來的數(shù)據(jù)payInfo
public Object goPay(@RequestBody JSONObject payInfo,HttpServletResponse response,HttpServletRequest request) throws IOException, AlipayApiException {
//首先在這里
JSONObject jsonObject = new JSONObject();
try {
//這里是解析前端傳來的數(shù)據(jù)
String WIDout_trade_no = payInfo.get("WIDout_trade_no").toString();
String WIDtotal_amount = payInfo.get("WIDtotal_amount").toString();
String WIDsubject = payInfo.get("WIDsubject").toString();
String WIDbody = payInfo.get("WIDbody").toString();
// System.out.println(WIDout_trade_no);System.out.println(WIDtotal_amount);System.out.println(WIDsubject);System.out.println(WIDbody);
//獲得初始化的AlipayClient
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
//設(shè)置請(qǐng)求參數(shù)
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
alipayRequest.setReturnUrl(AlipayConfig.return_url);
alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
// String out_trade_no = new String(request.getParameter("WIDout_trade_no").getBytes("ISO-8859-1"),"UTF-8");
// //付款金額,必填
// String total_amount = new String(request.getParameter("WIDtotal_amount").getBytes("ISO-8859-1"),"UTF-8");
// //訂單名稱,必填
// String subject = new String(request.getParameter("WIDsubject").getBytes("ISO-8859-1"),"UTF-8");
// //商品描述,可空
// String body = new String(request.getParameter("WIDbody").getBytes("ISO-8859-1"),"UTF-8");
String out_trade_no = WIDout_trade_no;
//付款金額,必填
String total_amount = WIDtotal_amount;
//訂單名稱,必填
String subject = WIDsubject;
//商品描述,可空
String body = WIDbody;
// 該筆訂單允許的最晚付款時(shí)間,逾期將關(guān)閉交易。取值范圍:1m~15d。m-分鐘,h-小時(shí),d-天,1c-當(dāng)天(1c-當(dāng)天的情況下,無論交易何時(shí)創(chuàng)建,都在0點(diǎn)關(guān)閉)。 該參數(shù)數(shù)值不接受小數(shù)點(diǎn), 如 1.5h,可轉(zhuǎn)換為 90m。
String timeout_express = "10m";
//例子去官方api找
alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\","
+ "\"total_amount\":\"" + total_amount + "\","
+ "\"subject\":\"" + subject + "\","
+ "\"body\":\"" + body + "\","
+ "\"timeout_express\":\"" + timeout_express + "\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
// //請(qǐng)求
String result = alipayClient.pageExecute(alipayRequest).getBody() ;
//這里以上都是支付寶的,接下來是我的
//接下來是一系列的字符串操作,總之就是給支付寶返回的result頁面的按鈕屬性設(shè)置為非hidden,并且添加了一些好看的屬性,然后取出來<script>標(biāo)簽(因?yàn)榍岸擞胿-html不能顯示<script>)最后將整個(gè)改造的result發(fā)給前端,就有了上面的前端將接收的內(nèi)容寫入sessionStorage的操作
String befAction = result;
StringBuffer aftAction = new StringBuffer(befAction);
aftAction = aftAction.reverse();
String midAction = aftAction.substring(68);
aftAction = new StringBuffer(midAction).reverse();
aftAction=aftAction.append(" width: 200px; padding:8px; background-color: #428bca; border-color: #357ebd; color: #fff; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius: 10px; -khtml-border-radius: 10px;text-align: center; vertical-align: middle; border: 1px solid transparent; font-weight: 900; font-size:125% \"> </form>");
jsonObject.put("formaction", aftAction);
jsonObject.put("message", StateCode.SUCCESS.getMessage());
jsonObject.put("code", StateCode.SUCCESS.getCode());
return jsonObject;
}catch (Exception e)
{
jsonObject.put("message", StateCode.SERVER_FAILED.getMessage());
jsonObject.put("code", StateCode.SERVER_FAILED.getCode());
return jsonObject;
}
}
在接下來就又是前端的操作了,由于剛才前端進(jìn)行了頁面跳轉(zhuǎn),所以我們接下來寫的是前端跳轉(zhuǎn)后的那個(gè)頁面:
//這是跳轉(zhuǎn)到的頁面的全部代碼
<template>
<div class="top">
<h1 class="top">收銀臺(tái)</h1>
<div v-html="payaction">
</div>
</div>
</template>
<script>
export default {
data() {
return {
payaction: ""
};
},
created() {
this.showPayPage();
},
methods: {
showPayPage() {
this.$nextTick(function() {
//我們直接把剛才寫在sessionStorage的頁面顯示在當(dāng)前頁面
this.payaction = sessionStorage.getItem("payaction");
//然后刪除sessionStorage的數(shù)據(jù)
sessionStorage.removeItem("payaction");
});
},
}
};
</script>
<style scoped>
.top{
margin-top: 50px;
text-align: center;
vertical-align: middle;
margin-bottom: 100px;
}
</style>
至此,所有代碼就結(jié)束了,你在這個(gè)頁面直接點(diǎn)擊支付按鈕就會(huì)跳轉(zhuǎn)到支付寶沙箱支付的界面了。
到此這篇關(guān)于Vue+SpringBoot實(shí)現(xiàn)支付寶沙箱支付的示例代碼的文章就介紹到這了,更多相關(guān)Vue+SpringBoot 支付寶沙箱支付內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue3中使用mock.js模擬數(shù)據(jù)的示例詳解
前后端同時(shí)開發(fā)的時(shí)候,后端接口數(shù)據(jù)沒有出來,前端可以使用mock模擬假數(shù)據(jù),所以下面小編就來為大家詳細(xì)介紹一下如何在Vue3中使用mock.js模擬數(shù)據(jù)吧2025-03-03
vue-router 控制路由權(quán)限的實(shí)現(xiàn)
這篇文章主要介紹了vue-router 控制路由權(quán)限的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
如何通過Vue自定義指令實(shí)現(xiàn)前端埋點(diǎn)詳析
埋點(diǎn)分析是網(wǎng)站分析的一種常用的數(shù)據(jù)采集方法,下面這篇文章主要給大家介紹了關(guān)于如何通過Vue自定義指令實(shí)現(xiàn)前端埋點(diǎn)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07
nginx+vue.js實(shí)現(xiàn)前后端分離的示例代碼
這篇文章主要介紹了nginx+vue.js實(shí)現(xiàn)前后端分離的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-02-02
vue.js的vue-cli腳手架中使用百度地圖API的實(shí)例
今天小編就為大家分享一篇關(guān)于vue.js的vue-cli腳手架中使用百度地圖API的實(shí)例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-01-01
nuxt.js添加環(huán)境變量,區(qū)分項(xiàng)目打包環(huán)境操作
這篇文章主要介紹了nuxt.js添加環(huán)境變量,區(qū)分項(xiàng)目打包環(huán)境操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-11-11

