pay.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. <template>
  2. <view class="app w-full">
  3. <view class="price-box dflex-c dflex-flow-c">
  4. <view>支付金额</view>
  5. <view class="price fs-xxxl margin-top-sm">{{money}}</view>
  6. </view>
  7. <view class="pay-type-list">
  8. <!-- #ifdef MP-WEIXIN -->
  9. <view class="type-item dflex-b pos-r padding-tb-sm" @click="changePayType('微信支付')">
  10. <text class="iconfont iconweixin"></text>
  11. <view class="item flex1">
  12. <text class="tit">微信支付</text>
  13. <text>推荐使用</text>
  14. </view>
  15. <label class="radio">
  16. <radio value="" color="#FF6A6C" :checked="pay_way == '微信支付'" :disabled="money <= 0" />
  17. </radio>
  18. </label>
  19. </view>
  20. <!-- #endif -->
  21. <!-- #ifdef MP-ALIPAY -->
  22. <view class="type-item dflex-b pos-r padding-tb-sm" @click="changePayType('支付宝')">
  23. <text class="iconfont iconalipay"></text>
  24. <view class="item flex1">
  25. <text class="tit">支付宝支付</text>
  26. <text>推荐使用</text>
  27. </view>
  28. <label class="radio">
  29. <radio value="" color="#FF6A6C" :checked="pay_way == '支付宝'" :disabled="money <= 0" />
  30. </radio>
  31. </label>
  32. </view>
  33. <!-- #endif -->
  34. <!-- #ifdef MP-BAIDU -->
  35. <view class="type-item dflex-b pos-r padding-tb-sm" @click="changePayType('百度钱包')">
  36. <text class="iconfont iconbaidu"></text>
  37. <view class="item flex1">
  38. <text class="tit">百度钱包</text>
  39. <text>推荐使用</text>
  40. </view>
  41. <label class="radio">
  42. <radio value="" color="#FF6A6C" :checked="pay_way == '百度钱包'" :disabled="money <= 0" />
  43. </radio>
  44. </label>
  45. </view>
  46. <!-- #endif -->
  47. <!-- #ifdef MP-QQ -->
  48. <view class="type-item dflex-b pos-r padding-tb-sm" @click="changePayType('QQ钱包')">
  49. <text class="iconfont iconqq"></text>
  50. <view class="item flex1">
  51. <text class="tit">QQ钱包</text>
  52. <text>推荐使用</text>
  53. </view>
  54. <label class="radio">
  55. <radio value="" color="#FF6A6C" :checked="pay_way == 'QQ钱包'" :disabled="money <= 0" />
  56. </radio>
  57. </label>
  58. </view>
  59. <!-- #endif -->
  60. <!-- #ifdef MP-TOUTIAO -->
  61. <view class="type-item dflex-b pos-r padding-tb-sm" @click="changePayType('头条支付', '微信支付', 'MWEB')">
  62. <text class="iconfont icontoutiao"></text>
  63. <view class="item flex1">
  64. <text class="tit">收银台</text>
  65. <text>推荐使用</text>
  66. </view>
  67. <label class="radio">
  68. <radio value="wxpay" color="#ff6a6c" colors="#ff6a6c" :checked="pay_way == '头条支付' && pay_trade_type == 'MWEB'"
  69. :disabled="money <= 0" />
  70. </radio>
  71. </label>
  72. </view>
  73. <!-- #endif -->
  74. <!-- #ifdef H5 || MP-360 -->
  75. <view class="type-item dflex-b pos-r padding-tb-sm" @click="changePayType('微信支付', '微信支付', 'NATIVE')">
  76. <text class="iconfont iconweixin"></text>
  77. <view class="item flex1">
  78. <text class="tit">微信支付</text>
  79. <text>推荐使用 扫一扫 微信支付二维码</text>
  80. </view>
  81. <label class="radio">
  82. <radio value="wxpay" color="#ff6a6c" colors="#ff6a6c" :checked="pay_way == '微信支付' && pay_trade_type == 'NATIVE'" :disabled="money <= 0" /></radio>
  83. </label>
  84. </view>
  85. <view class="qrcode tac padding-tb">
  86. <use-qrcode
  87. :onval="true"
  88. :val="qrcode"
  89. qrsize="200"
  90. @result="qrcode_rs"
  91. ></use-qrcode>
  92. </view>
  93. <view v-if="time_remaining" class="dflex-c">
  94. <use-count-down :show-days="false" separator="zh" separator-color="#333" color="#fff" bg-color="#333" font-size="24" :timestamp="time_remaining" @end="ontimeend"></use-count-down>
  95. </view>
  96. <!-- #endif -->
  97. </view>
  98. <view class="padding w-full margin-top-big pos-a" style="bottom: 30rpx;">
  99. <view class="dflex-b border-radius-big">
  100. <!-- #ifndef H5 || MP-360 -->
  101. <view class="tac padding-tb-sm flex1 bg-base-pay" :class="is_submit === 1 ? 'bg-disabled' : ''" @click="confirm">{{pay_tip}}</view>
  102. <!-- #endif -->
  103. <!-- #ifdef H5 || MP-360 -->
  104. <view class="tac padding-tb-sm flex1 bg-base-pay" :class="is_submit === 1 ? 'bg-disabled' : ''" @click="check">{{pay_tip}}</view>
  105. <!-- #endif -->
  106. </view>
  107. </view>
  108. </view>
  109. </template>
  110. <script>
  111. import {
  112. getapipay
  113. } from '../../utils/api_user.js'
  114. import common from '../../../static/comon.js'
  115. export default {
  116. data() {
  117. return {
  118. money: 0,
  119. is_submit: 0,
  120. // 平台支付方式
  121. pay_way: '微信支付',
  122. // 原始支付方式 微信支付 支付宝支付
  123. pay_original: '',
  124. // JSAPI,NATIVE,APP,H5支付固定传 MWEB
  125. pay_trade_type: '',
  126. pay_tip: '确认支付',
  127. qrcode: '',
  128. time_remaining: 0,
  129. order_id:'',
  130. // out_order_no:'',//订单编号
  131. };
  132. },
  133. computed: {
  134. },
  135. onLoad(options) {
  136. this.money = options.money || 0;
  137. this.order_id = options.order_id;
  138. this.loadData();
  139. // #ifdef MP-WEIXIN
  140. this.pay_way = '微信支付';
  141. this.pay_original = '微信支付';
  142. this.pay_trade_type = 'JSAPI';
  143. // #endif
  144. // #ifdef MP-ALIPAY
  145. this.pay_way = '支付宝';
  146. this.pay_original = '支付宝支付';
  147. this.pay_trade_type = '';
  148. // #endif
  149. // #ifdef MP-BAIDU
  150. this.pay_way = '百度钱包';
  151. // #endif
  152. // #ifdef MP-QQ
  153. this.pay_way = 'QQ钱包';
  154. // #endif
  155. // #ifdef MP-TOUTIAO
  156. this.$api.timerout(() => {
  157. this.pay_way = '头条支付';
  158. this.pay_original = '微信支付';
  159. this.pay_trade_type = 'MWEB';
  160. }, 0)
  161. // #endif
  162. // #ifdef H5 || MP-360
  163. this.$api.timerout(() => {
  164. this.pay_way = '微信支付';
  165. this.pay_original = '微信支付';
  166. this.pay_trade_type = 'NATIVE';
  167. }, 0)
  168. this.pay_tip = '已完成支付';
  169. // #endif
  170. },
  171. methods: {
  172. qrcode_rs(res) {
  173. },
  174. loadData() {
  175. let _this = this;
  176. },
  177. //选择支付方式
  178. changePayType(type, original, trade_type) {
  179. if (this.money <= 0) return;
  180. this.pay_way = type;
  181. if (original) this.pay_original = original;
  182. if (trade_type) this.pay_trade_type = trade_type;
  183. if(this.pay_trade_type == 'NATIVE') {
  184. this.loadQRCode();
  185. }
  186. },
  187. //确认支付
  188. confirm() {
  189. if (this.is_submit) return;
  190. this.is_submit = 1;
  191. let _this = this;
  192. //获取小程序支付参数
  193. var data=_this.order_id
  194. getapipay(data).then((res) => {
  195. if(res.success){
  196. if(res.data){
  197. var pay_datas={}
  198. pay_datas = {
  199. timeStamp:res.data.timeStamp,
  200. nonceStr:res.data.nonceStr,
  201. package:res.data.packageStr,
  202. signType:res.data.signType,
  203. paySign:res.data.paySign
  204. };
  205. // 检查当前 session 是否有效
  206. if(uni.canIUse('checkSession')){
  207. uni.checkSession({
  208. success() {
  209. // 调用支付
  210. _this.topayment(pay_datas, _this.order_id);
  211. },
  212. fail() {
  213. // 当前 session 无效,调用 uni.login 获取数据
  214. uni.login({
  215. success() {
  216. // 调用支付
  217. _this.topayment(pay_datas, _this.order_id);
  218. },
  219. fail() {
  220. }
  221. })
  222. },
  223. })
  224. } else {
  225. // 调用支付
  226. _this.topayment(pay_datas, _this.order_id);
  227. }
  228. }else {
  229. uni.setStorage({
  230. key: '__order_state',
  231. data: '待付款',
  232. success(res) {
  233. console.log(res);
  234. },
  235. complete() {
  236. _this.$api.toorder();
  237. }
  238. });
  239. }
  240. return;
  241. }
  242. _this.$api.timerout(() => {
  243. if (typeof res.msg === 'object') {
  244. res.msg = res.msg.errorMessage;
  245. }
  246. _this.$api.msg(res.msg, 5000);
  247. _this.is_submit = 0;
  248. }, 800);
  249. })
  250. },
  251. topayment(pay_datas, order_id) {
  252. let _this = this;
  253. console.log(pay_datas)
  254. wx.requestPayment({
  255. ...pay_datas,
  256. success: function(pres) {
  257. // #ifdef MP-TOUTIAO
  258. if (pres.code !== 0) {
  259. _this.is_submit = 0;
  260. switch (pres.code) {
  261. case 1:
  262. _this.$api.msg('支付超时,请重新支付');
  263. break;
  264. case 2:
  265. _this.$api.msg('已取消,请重新支付');
  266. break;
  267. case 3:
  268. _this.$api.msg('支付关闭,请重新支付');
  269. break;
  270. case 4:
  271. _this.$api.msg('支付取消,请重新支付');
  272. break;
  273. case 9:
  274. default:
  275. _this.$api.msg('支付失败,请重新支付');
  276. break;
  277. }
  278. return;
  279. }
  280. // #endif
  281. uni.redirectTo({
  282. url: `/packageShang/pages/pay/success?order_id=${order_id}`
  283. });
  284. return;
  285. },
  286. fail: function(err) {
  287. console.log('requestPayment fail:', err);
  288. uni.setStorage({
  289. key: '__order_state',
  290. data: '待付款',
  291. success(res) {
  292. console.log(res);
  293. },
  294. complete() {
  295. _this.$api.toorder();
  296. }
  297. });
  298. }
  299. });
  300. },
  301. // 检测订单支付状态
  302. check(){
  303. let _this = this;
  304. _this.$func.usemall.call("order/paystate", {
  305. order_id: _this.order_id
  306. }).then(res => {
  307. // 商户后端查询的微信支付状态,通知收银台支付结果
  308. /*
  309. 0:支付成功
  310. 1:支付超时
  311. 2:支付失败
  312. 3:支付关闭
  313. 9:订单状态未知/未支付
  314. */
  315. if (res.code == 200) {
  316. let code = 9;
  317. let trade_state = res.datas.trade_state || "";
  318. if (res.datas.pay_state == '已付款') {
  319. code = 0
  320. } else if (trade_state == 'SUCCESS') {
  321. code = 0;
  322. } else if (trade_state == 'NOTPAY' || trade_state == 'PAYERROR') {
  323. code = 2;
  324. } else if (trade_state == 'CLOSED') {
  325. code = 3;
  326. }
  327. switch (code) {
  328. case 0:
  329. uni.redirectTo({
  330. url: `/pages/pay/success?order_id=${_this.order_id}`
  331. });
  332. break;
  333. case 1:
  334. _this.$api.msg('支付超时,请重新支付', 3500);
  335. break;
  336. case 2:
  337. _this.$api.msg('已取消,请重新支付', 3500);
  338. break;
  339. case 3:
  340. _this.$api.msg('支付关闭,请重新支付', 3500);
  341. break;
  342. case 4:
  343. _this.$api.msg('支付取消,请重新支付', 3500);
  344. break;
  345. case 9:
  346. default:
  347. _this.$api.msg('支付失败,请重新支付', 3500);
  348. break;
  349. }
  350. return;
  351. }
  352. }).catch(err => {
  353. });
  354. },
  355. // #ifdef H5 || MP-360
  356. loadQRCode(){
  357. let _this = this;
  358. let obj = {
  359. order_id: _this.order_id,
  360. pay_way: _this.pay_way,
  361. pay_original: _this.pay_original,
  362. pay_trade_type: _this.pay_trade_type,
  363. };
  364. uni.showLoading({
  365. title: '请求中'
  366. })
  367. // this.$api.alert('二维码支付开发中');
  368. _this.$func.usemall.call('order/pay', obj).then(res => {
  369. console.log('支付接口', obj);
  370. uni.hideLoading();
  371. if (res.code === 200) {
  372. if (res.datas) {
  373. _this.qrcode = res.datas.codeUrl;
  374. _this.time_remaining = res.datas.time_remaining;
  375. } else {
  376. uni.setStorage({
  377. key: '__order_state',
  378. data: '待付款',
  379. success(res) {
  380. console.log(res);
  381. },
  382. complete() {
  383. _this.$api.toorder();
  384. }
  385. });
  386. }
  387. return;
  388. }
  389. _this.$api.timerout(() => {
  390. _this.$api.msg(res.msg, 5000);
  391. _this.is_submit = 0;
  392. }, 800);
  393. });
  394. },
  395. ontimeend(){
  396. let _this = this;
  397. uni.showModal({
  398. title: '提示',
  399. content: '支付二维码已过期',
  400. confirmText: '重新生成',
  401. success: function (res) {
  402. if (res.confirm) {
  403. _this.loadQRCode();
  404. } else if (res.cancel) {
  405. console.log('用户点击取消');
  406. }
  407. }
  408. });
  409. },
  410. // #endif
  411. }
  412. }
  413. </script>
  414. <style lang='scss'>
  415. @import url('/packageShang/components/iconfont/iconfont.css');
  416. @import url('/packageShang/common/common.scss');
  417. .app { }
  418. .price-box {
  419. height: 266rpx;
  420. font-size: 28rpx;
  421. color: #909399;
  422. }
  423. .pay-type-list {
  424. padding-left: 60rpx;
  425. padding-right: 60rpx;
  426. .type-item {
  427. height: 120rpx;
  428. font-size: 30rpx;
  429. }
  430. .iconfont {
  431. width: 100rpx;
  432. font-size: 52rpx;
  433. }
  434. .iconhuiyuan {
  435. color: #fe8e2e;
  436. }
  437. .iconweixin {
  438. color: #36cb59;
  439. }
  440. .iconalipay {
  441. color: #01aaef;
  442. }
  443. .iconqq {
  444. color: #13c6fe;
  445. }
  446. .iconbaidu {
  447. color: #306cff;
  448. }
  449. .icontoutiao {
  450. color: #f85959;
  451. }
  452. .tit {
  453. font-size: $font-lg;
  454. /* color: $font-color-dark; */
  455. margin-bottom: 4rpx;
  456. }
  457. .item {
  458. display: flex;
  459. flex-direction: column;
  460. font-size: $font-sm;
  461. color: $font-color-light;
  462. }
  463. }
  464. </style>