index.tsx 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. import request from '@/helpers/request';
  2. import { browser, getHttpOrigin, getUrlCode, moneyFormat } from '@/helpers/utils';
  3. import { goAliAuth, goWechatAuth } from '@/state';
  4. import numeral from 'numeral';
  5. import { Button, Cell, CellGroup, Icon, showToast } from 'vant';
  6. import { defineComponent, onMounted, reactive } from 'vue';
  7. import { useRoute } from 'vue-router';
  8. import styles from './index.module.less';
  9. export default defineComponent({
  10. name: 'pay-define',
  11. setup() {
  12. const route = useRoute();
  13. const state = reactive({
  14. browserStatus: false,
  15. errorText: '',
  16. code: null as any,
  17. pay_channel: route.query.pay_channel as any,
  18. wxAppId: route.query.wxAppId as any,
  19. paymentType: route.query.paymentType as any,
  20. alipayAppId: route.query.alipayAppId as any,
  21. body: route.query.body as any,
  22. price: route.query.price as any,
  23. orderNo: route.query.orderNo as any,
  24. userId: route.query.userId as any,
  25. payInfo: {} as any,
  26. isYeePay: false // 是否为易宝支付
  27. });
  28. const getPayment = async () => {
  29. try {
  30. if (parseFloat(state.price) <= 0) {
  31. showToast('支付金额异常');
  32. return;
  33. }
  34. const payMap: any = {
  35. merOrderNo: state.orderNo,
  36. paymentChannel: state.pay_channel, // 支付渠道
  37. userId: state.userId,
  38. code: state.code,
  39. wxPubAppId: state.wxAppId
  40. };
  41. // 判断是否是微信公众号支付
  42. // if (state.pay_channel == 'wx_pub') {
  43. // payMap.code = state.code;
  44. // }
  45. const { data } = await request.post(
  46. '/edu-app/open/userOrder/executePayment',
  47. {
  48. hideLoading: false,
  49. data: {
  50. ...payMap
  51. }
  52. }
  53. );
  54. state.isYeePay = data.paymentVender?.indexOf('yeepay') !== -1;
  55. scanCodePay(data.reqParams);
  56. } catch (e) {
  57. //
  58. console.log(e);
  59. }
  60. };
  61. const scanCodePay = (data: any) => {
  62. // 判断支付方式 如果是 test 模式 支付用测试url 否则用生产url
  63. if (state.pay_channel == 'alipay_qr') {
  64. if (state.isYeePay) {
  65. tradePay(data.prePayTn);
  66. } else {
  67. const url =
  68. data.prod_mode === 'false'
  69. ? data.expend.qrcode_url +
  70. '?payment_id=' +
  71. data.id +
  72. '&pay_channel=' +
  73. data.pay_channel
  74. : data.expend.qrcode_url;
  75. window.location.href = url;
  76. }
  77. } else if (state.pay_channel == 'wx_pub') {
  78. const tempPayInfo = state.isYeePay
  79. ? JSON.parse(data.prePayTn)
  80. : JSON.parse(data.expend.pay_info);
  81. state.payInfo = tempPayInfo;
  82. if (typeof (window as any).WeixinJSBridge == 'undefined') {
  83. if (document.addEventListener) {
  84. document.addEventListener(
  85. 'WeixinJSBridgeReady',
  86. onBridgeReady,
  87. false
  88. );
  89. } else if ((document as any).attachEvent) {
  90. (document as any)
  91. .attachEvent(
  92. 'WeixinJSBridgeReady',
  93. onBridgeReady
  94. )(document as any)
  95. .attachEvent('onWeixinJSBridgeReady', onBridgeReady);
  96. }
  97. } else {
  98. onBridgeReady();
  99. }
  100. }
  101. };
  102. // 由于js的载入是异步的,所以可以通过该方法,当AlipayJSBridgeReady事件发生后,再执行callback方法
  103. const ready = (callback: any) => {
  104. if ((window as any).AlipayJSBridge) {
  105. callback && callback();
  106. } else {
  107. document.addEventListener('AlipayJSBridgeReady', callback, false);
  108. }
  109. };
  110. const tradePay = (tradeNO: any) => {
  111. ready(function () {
  112. // 通过传入交易号唤起快捷调用方式(注意tradeNO大小写严格)
  113. (window as any).AlipayJSBridge.call(
  114. 'tradePay',
  115. {
  116. tradeNO: tradeNO
  117. },
  118. function (data: any) {
  119. if ('9000' == data.resultCode) {
  120. window.location.replace(
  121. getHttpOrigin() +
  122. '/classroom-app/#/payment-result?orderNo=' +
  123. state.orderNo
  124. );
  125. } else {
  126. window.location.replace(
  127. getHttpOrigin() +
  128. '/classroom-app/#/payment-result?orderNo=' +
  129. state.orderNo
  130. );
  131. }
  132. //使用的支付宝内置api实现关闭H5
  133. (window as any).AlipayJSBridge.call('closeWebview');
  134. }
  135. );
  136. });
  137. };
  138. const onBridgeReady = () => {
  139. const payInfo = state.payInfo;
  140. // let orderNo = state.orderNo
  141. (window as any).WeixinJSBridge.invoke(
  142. 'getBrandWCPayRequest',
  143. {
  144. appId: payInfo.appId, //公众号名称,由商户传入
  145. timeStamp: payInfo.timeStamp, //时间戳,自1970年以来的秒数
  146. nonceStr: payInfo.nonceStr, //随机串
  147. package: payInfo.package,
  148. signType: payInfo.signType, //微信签名方式:
  149. paySign: payInfo.paySign //微信签名
  150. },
  151. (res: any) => {
  152. // if(res.err_msg == "get_brand_wcpay_request:ok" ){
  153. // 使用以上方式判断前端返回,微信团队郑重提示:
  154. //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
  155. // } else
  156. if (
  157. res.err_msg == 'get_brand_wcpay_request:cancel' ||
  158. res.err_msg == 'get_brand_wcpay_request:fail'
  159. ) {
  160. window.location.replace(
  161. getHttpOrigin() +
  162. '/classroom-app/#/payment-result?orderNo=' +
  163. state.orderNo
  164. );
  165. } else {
  166. // 使用以上方式判断前端返回,微信团队郑重提示:
  167. //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
  168. // alert('支付成功')
  169. window.location.replace(
  170. getHttpOrigin() +
  171. '/classroom-app/#/payment-result?orderNo=' +
  172. state.orderNo
  173. );
  174. }
  175. }
  176. );
  177. };
  178. // const goAuth = () => {
  179. // // 用户授权
  180. // const urlNow = encodeURIComponent(window.location.href)
  181. // const scope = 'snsapi_base' //snsapi_userinfo //静默授权 用户无感知
  182. // const appid = state.wxAppId || 'wx8654c671631cfade'
  183. // const url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${urlNow}&response_type=code&scope=${scope}&state=STATE&connect_redirect=1#wechat_redirect`
  184. // window.location.replace(url)
  185. // }
  186. const init = () => {
  187. const pay_channel = state.pay_channel;
  188. const isYeePay = state.paymentType.indexOf('yeepay') !== -1;
  189. if (browser().weixin) {
  190. if (pay_channel === 'wx_pub') {
  191. //授权
  192. const code = getUrlCode();
  193. if (code) {
  194. state.code = code; // 赋值code码
  195. } else {
  196. goWechatAuth(state.wxAppId);
  197. }
  198. state.browserStatus = true;
  199. document.title = '微信支付';
  200. } else if (pay_channel == 'alipay_qr') {
  201. state.errorText = '请使用支付宝扫码';
  202. }
  203. } else if (browser().alipay) {
  204. if (pay_channel === 'wx_pub') {
  205. state.errorText = '请使用微信扫码';
  206. } else if (pay_channel == 'alipay_qr') {
  207. // 支付宝支付
  208. // 易宝才需要
  209. if (isYeePay) {
  210. //授权
  211. const code = getUrlCode('auth_code');
  212. if (code) {
  213. state.code = code; // 赋值code码
  214. } else {
  215. goAliAuth(state.alipayAppId);
  216. }
  217. }
  218. state.browserStatus = true;
  219. document.title = '支付宝支付';
  220. }
  221. } else {
  222. state.errorText = '请在微信或支付宝客户端打开';
  223. }
  224. state.errorText && (document.title = 'ERROR');
  225. };
  226. onMounted(() => {
  227. console.log(state);
  228. init();
  229. });
  230. return () => (
  231. <div class={styles.paydefine}>
  232. {state.browserStatus && (
  233. <div class={styles.container}>
  234. <div class={styles.amount}>
  235. <span>¥ </span>
  236. {moneyFormat(state.price)}
  237. </div>
  238. <CellGroup inset>
  239. <Cell
  240. title="订单信息"
  241. value={state.body}
  242. valueClass={styles.values}></Cell>
  243. <Cell
  244. title="支付方式"
  245. value={
  246. state.pay_channel === 'wx_pub' ? '微信' : '支付宝'
  247. }></Cell>
  248. <Cell
  249. title="实付金额"
  250. value={`¥ ${moneyFormat(state.price)}元`}></Cell>
  251. </CellGroup>
  252. <Button
  253. type="primary"
  254. block
  255. size="large"
  256. onClick={getPayment}
  257. round>
  258. 立即支付
  259. </Button>
  260. </div>
  261. )}
  262. {!state.browserStatus && (
  263. <div class={styles.container}>
  264. <div class={styles['error-text']}>
  265. {state.errorText && (
  266. <Icon class={styles['error-icon']} name="warning-o" />
  267. )}
  268. {state.errorText}
  269. </div>
  270. </div>
  271. )}
  272. </div>
  273. );
  274. }
  275. });