25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

566 lines
25 KiB

  1. import * as React from "react";
  2. import * as HttpUtils from "utils/HttpUtils";
  3. import * as UrlUtils from "utils/ApiPathConst";
  4. import Loadable from 'components/Loadable';
  5. const MultiPaymentWindow = Loadable(React.lazy(() => import('./MultiPaymentWindow')));
  6. const DataGrid = Loadable(React.lazy(() => import('./Details_Public/DataGrid')));
  7. // const FPS = Loadable(React.lazy(() => import('./FPS')));
  8. import { useEffect, useState } from "react";
  9. import { useNavigate, useLocation } from "react-router-dom";
  10. // import * as FormatUtils from "utils/FormatUtils";
  11. // const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
  12. import {getBowserType, local, preferpaymentmethods} from "auth/utils";
  13. import {
  14. Button,
  15. Grid,
  16. Typography,
  17. Stack,
  18. Box,
  19. Dialog, DialogTitle, DialogContent, DialogActions,
  20. } from '@mui/material';
  21. import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'
  22. import {ThemeProvider} from "@emotion/react";
  23. import {PNSPS_BUTTON_THEME} from "../../themes/buttonConst";
  24. import {
  25. FormattedMessage,
  26. useIntl
  27. } from "react-intl";
  28. const BackgroundHead = {
  29. backgroundImage: `url(${titleBackgroundImg})`,
  30. width: '100%',
  31. height: '100%',
  32. backgroundSize: 'contain',
  33. backgroundRepeat: 'no-repeat',
  34. backgroundColor: '#0C489E',
  35. backgroundPosition: 'right'
  36. }
  37. const Index = () => {
  38. const navigate = useNavigate()
  39. const location = useLocation();
  40. const intl = useIntl();
  41. const { locale } = intl;
  42. // const local = {en:"en-us", zh:"zh-hk", cn:"zh-cn"};
  43. // const preferpaymentmethods = ['visa', 'mastercard', 'pps', 'creditcard', 'fps'];
  44. const [totalAmount, setTotalAmount] = useState(0);
  45. const [appIds, setAppIds] = useState([]);
  46. //statusWindow
  47. const [open, setOpen] = useState(false);
  48. const [availableMethods, setAvailableMethods] = useState([]);
  49. const [paymentLimit, setPaymentLimit] = useState([]);
  50. const [transactionData, setTransactionData] = useState({});
  51. const [fpsStatus, setFPSStatus] = useState({});
  52. const [creditCardStatus, setCreditCardStatus] = useState({});
  53. const [unionPayStatus, setUnionPayStatus] = useState({});
  54. const [ppsStatus, setPPSStatus] = useState({});
  55. const [selectedPaymentMethod, setSelectedPaymentMethod] = useState("");
  56. const [confirmPayment, setConfirmPayment] = useState(false);
  57. const [afterConfirmPayment, setAfterConfirmPayment] = useState(false);
  58. const [itemList, setItemList] = useState([]);
  59. const [onReady, setOnReady] = useState(false);
  60. const [onPayment, setOnPayment] = useState(false);
  61. const [isFullScreen, setIsFullScreen] = useState(false);
  62. const [expiryDateErrText, setExpiryDateErrText] = React.useState("");
  63. const [expiryDateErr, setExpiryDateErr] = React.useState(false);
  64. const [browserType, setBrowserType] = React.useState("");
  65. const mobileBrowser = "Mobile";
  66. const desktopBrowser = "Desktop";
  67. useEffect(() => {
  68. setAppIds(location.state?.appIdList ?? [])
  69. setTotalAmount(location.state?.amount ?? 2000)
  70. localStorage.removeItem("webtoken");
  71. localStorage.removeItem("transactionid");
  72. localStorage.removeItem("paymentId");
  73. if (getBowserType() === "PC_Browser"){
  74. setIsFullScreen(false)
  75. setBrowserType(desktopBrowser)
  76. } else {
  77. setIsFullScreen(true)
  78. setBrowserType(mobileBrowser)
  79. }
  80. }, []);
  81. useEffect(() => {
  82. if (appIds != [] && appIds.length > 0)
  83. getAppList();
  84. }, [appIds]);
  85. // const handleClose = () => {
  86. // // handleReset()
  87. // setOpen(false);
  88. // // getTransactionId()
  89. // // getAvailablePayment()
  90. // };
  91. const paymentClick = () => {
  92. setTotalAmount(totalAmount);
  93. setSelectedPaymentMethod("")
  94. setConfirmPayment(false)
  95. if (totalAmount > 0) {
  96. getAvailablePayment()
  97. getTransactionId()
  98. setOpen(true)
  99. }
  100. };
  101. useEffect(() => {
  102. if (afterConfirmPayment) {
  103. setOnPayment(true)
  104. // setOpen(false);
  105. // let transactionid = "";
  106. // let webtoken = "";
  107. let page = "";
  108. let stateParams = {};
  109. let paymentMethod = "";
  110. if (selectedPaymentMethod === "FPS") {
  111. page = '/paymentPage/fps';
  112. stateParams = { state: { amount: totalAmount, transactionid: transactionData.transactionid, webtoken: transactionData.webtoken } }
  113. paymentMethod = "04,BCFP,FPS";
  114. } else if (selectedPaymentMethod === "Visa") {
  115. page = '/paymentPage/card';
  116. stateParams = { state: { amount: totalAmount, transactionid: transactionData.transactionid, webtoken: transactionData.webtoken, type: "Visa", paymentMethod: "02,BCMP,CreditCard" } }
  117. paymentMethod = "02,BCMP,CreditCard";
  118. } else if (selectedPaymentMethod === "MasterCard") {
  119. page = '/paymentPage/card';
  120. stateParams = { state: { amount: totalAmount, transactionid: transactionData.transactionid, webtoken: transactionData.webtoken, type: "MasterCard", paymentMethod: "02,BCMP,CreditCard" } }
  121. paymentMethod = "02,BCMP,CreditCard";
  122. } else if (selectedPaymentMethod === "JCB") {
  123. page = '/paymentPage/card';
  124. stateParams = { state: { amount: totalAmount, transactionid: transactionData.transactionid, webtoken: transactionData.webtoken, type: "JCB", paymentMethod: "02,BCMP,CreditCard" } }
  125. paymentMethod = "02,BCMP,CreditCard";
  126. } else if (selectedPaymentMethod === "UnionPay") {
  127. page = '/paymentPage/card';
  128. stateParams = { state: { amount: totalAmount, transactionid: transactionData.transactionid, webtoken: transactionData.webtoken, type: "UnionPay", paymentMethod: "03,BCMP,CreditCard" } }
  129. paymentMethod = "03,BCMP,CreditCard";
  130. } else if (selectedPaymentMethod === "PPS") {
  131. page = '/paymentPage/card';
  132. stateParams = { state: { amount: totalAmount, transactionid: transactionData.transactionid, webtoken: transactionData.webtoken, type: "PPS", paymentMethod: "01,PPSB,PPS" } }
  133. paymentMethod = "01,PPSB,PPS";
  134. }
  135. if (paymentMethod != "") {
  136. HttpUtils.post({
  137. url: UrlUtils.PAYMENT_CREATE,
  138. params: {
  139. transNo: transactionData.transactionid,
  140. payMethod: paymentMethod,
  141. payAmount: totalAmount,
  142. appIdList: location.state?.appIdList ?? [],
  143. webtoken: transactionData.webtoken
  144. },
  145. onSuccess: function (responData) {
  146. localStorage.removeItem("paymentId");
  147. localStorage.setItem("paymentId", responData.id)
  148. setOnPayment(false)
  149. navigate(page, stateParams);
  150. }
  151. });
  152. }
  153. // For testing
  154. // if (paymentMethod != "") {
  155. // HttpUtils.post({
  156. // url: UrlUtils.PAYMENT_CREATE,
  157. // params: {
  158. // transNo: "test0002",
  159. // payMethod: paymentMethod,
  160. // payAmount: totalAmount,
  161. // appIdList: location.state?.appIdList ?? [],
  162. // webtoken: "test000234123412341234123412354212312412341234124123124124124123124123124124"
  163. // },
  164. // onSuccess: function (responData) {
  165. // localStorage.removeItem("paymentId");
  166. // localStorage.setItem("paymentId", responData.id)
  167. // navigate(page, stateParams);
  168. // }
  169. // });
  170. // }
  171. }
  172. }, [afterConfirmPayment]);
  173. const getAvailablePayment = () =>{
  174. HttpUtils.post({
  175. url: UrlUtils.PAYMENT_AVAILABLE_PAYMENT,
  176. params: {
  177. "locale": locale === 'en' ?local.en:locale === 'zh-HK' ?local.zh:local.cn,
  178. "amount": totalAmount,
  179. // "eserviceids": [
  180. // "<eserviceid>", "<eserviceid>"
  181. // ],
  182. "preferpaymentmethods": preferpaymentmethods
  183. },
  184. onSuccess: (responseData) => {
  185. let availableMethods = responseData.availablepaymentmethods;
  186. setAvailableMethods(availableMethods);
  187. HttpUtils.get({
  188. url: UrlUtils.PAYMENT_LIMIT_SETTING_LIST,
  189. params: {},
  190. onSuccess: (responseData) => {
  191. // console.log(responseData)
  192. setPaymentLimit(responseData)
  193. },
  194. onError: () =>{
  195. // setOnReady(true)
  196. }
  197. });
  198. },
  199. onError: () =>{
  200. setOnReady(true)
  201. }
  202. });
  203. HttpUtils.get({
  204. url: UrlUtils.PAYMENT_LIMIT_SETTING_LIST,
  205. params: {},
  206. onSuccess: (responseData) => {
  207. // console.log(responseData)
  208. setPaymentLimit(responseData)
  209. },
  210. onError: () =>{
  211. // setOnReady(true)
  212. }
  213. });
  214. // const responseData = {
  215. // "availablepaymentmethods": [
  216. // {
  217. // "active": "Y",
  218. // "code": "04,BCFP,FPS",
  219. // "pointstonote": [
  220. // {
  221. // "content": "Please take note of the transaction reference number or PRINT this page for making enquiry on the payment status when necessary.",
  222. // "order": 10,
  223. // "type": "INFO"
  224. // },
  225. // {
  226. // "content": "After pressing the 'Pay' button, please DO NOT leave this e-service until you receive the acknowledgement page, otherwise your transaction may not be successful.",
  227. // "order": 11,
  228. // "type": "INFO"
  229. // }
  230. // ],
  231. // "subtype": "FPS"
  232. // },
  233. // {
  234. // "active": "Y",
  235. // "code": "02,BCMP,CreditCard",
  236. // "pointstonote": [
  237. // {
  238. // "content": "Please take note of the transaction reference number or PRINT this page for making enquiry on the payment status when necessary.",
  239. // "order": 10,
  240. // "type": "INFO"
  241. // },
  242. // {
  243. // "content": "After pressing the 'Pay' button, please DO NOT leave this e-service until you receive the acknowledgement page, otherwise your transaction may not be successful.",
  244. // "order": 11,
  245. // "type": "INFO"
  246. // },
  247. // {
  248. // "content": "Merchant Name is applicable to credit card payment method only.",
  249. // "order": 40,
  250. // "type": "INFO"
  251. // },
  252. // {
  253. // "content": "Under exceptional conditions, a refund may need to be arranged. If the payment is made by Credit Card, the refund can normally be made to the Credit Card account that is used for the payment.",
  254. // "order": 41,
  255. // "type": "INFO"
  256. // },
  257. // {
  258. // "content": "Some users may receive an error page or have to wait for several minutes before they get a response from the credit card payment gateway. If you experience such a problem, please wait a moment and retry, or change to use other available payment methods. We apologise for any inconvenience caused.",
  259. // "order": 42,
  260. // "type": "INFO"
  261. // },
  262. // {
  263. // "content": "Different credit card issuers may have implemented different mechanisms to authenticate the cardholder's identity during online payment. Please contact your card issuer if you want to learn more about the J/Secure, MasterCard SecureCode and Verified by Visa service. ",
  264. // "order": 43,
  265. // "type": "INFO"
  266. // }
  267. // ],
  268. // "subtype": "CreditCard",
  269. // "supportedcard": [
  270. // "JCB",
  271. // "MasterCard",
  272. // "Visa"
  273. // ]
  274. // },
  275. // {
  276. // "active": "Y",
  277. // "code": "03,BCMP,CreditCard",
  278. // "pointstonote": [
  279. // {
  280. // "content": "Please take note of the transaction reference number or PRINT this page for making enquiry on the payment status when necessary.",
  281. // "order": 10,
  282. // "type": "INFO"
  283. // },
  284. // {
  285. // "content": "After pressing the 'Pay' button, please DO NOT leave this e-service until you receive the acknowledgement page, otherwise your transaction may not be successful.",
  286. // "order": 11,
  287. // "type": "INFO"
  288. // },
  289. // {
  290. // "content": "Merchant Name is applicable to credit card payment method only.",
  291. // "order": 40,
  292. // "type": "INFO"
  293. // },
  294. // {
  295. // "content": "Under exceptional conditions, a refund may need to be arranged. If the payment is made by Credit Card, the refund can normally be made to the Credit Card account that is used for the payment.",
  296. // "order": 41,
  297. // "type": "INFO"
  298. // },
  299. // {
  300. // "content": "Some users may receive an error page or have to wait for several minutes before they get a response from the credit card payment gateway. If you experience such a problem, please wait a moment and retry, or change to use other available payment methods. We apologise for any inconvenience caused.",
  301. // "order": 42,
  302. // "type": "INFO"
  303. // },
  304. // {
  305. // "content": "Different credit card issuers may have implemented different mechanisms to authenticate the cardholder's identity during online payment. Please contact your card issuer if you want to learn more about the J/Secure, MasterCard SecureCode and Verified by Visa service. ",
  306. // "order": 43,
  307. // "type": "INFO"
  308. // }
  309. // ],
  310. // "subtype": "CreditCard",
  311. // "supportedcard": [
  312. // "UnionPay"
  313. // ]
  314. // },
  315. // {
  316. // "active": "Y",
  317. // "code": "01,PPSB,PPS",
  318. // "pointstonote": [
  319. // {
  320. // "content": "Please take note of the transaction reference number or PRINT this page for making enquiry on the payment status when necessary.",
  321. // "order": 10,
  322. // "type": "INFO"
  323. // },
  324. // {
  325. // "content": "After pressing the 'Pay' button, please DO NOT leave this e-service until you receive the acknowledgement page, otherwise your transaction may not be successful.",
  326. // "order": 11,
  327. // "type": "INFO"
  328. // },
  329. // {
  330. // "content": "PPS Shop&Buy (PPS) does not support payment via browsers of mobile devices (including mobile phones and tablets) at the moment. If you wish to pay by PPS, please change to use desktop computer. ",
  331. // "order": 21,
  332. // "type": "INFO"
  333. // }
  334. // ],
  335. // "subtype": "PPS"
  336. // }
  337. // ]
  338. // };
  339. // let availableMethods = responseData.availablepaymentmethods;
  340. // setAvailableMethods(availableMethods);
  341. }
  342. useEffect(() => {
  343. // console.log(availableMethods)
  344. if (availableMethods.length > 0) {
  345. availableMethods.forEach((method) => {
  346. if (method.subtype === "FPS") {
  347. if (totalAmount<1){
  348. // method["minLimit"] = true
  349. setFPSStatus(method)
  350. }
  351. else if (totalAmount>9999999.99){
  352. // method["maxLimit"] = true
  353. setFPSStatus(method)
  354. } else {
  355. // method["minLimit"] = true
  356. // method["maxLimit"] = true
  357. // console.log(method)
  358. setFPSStatus(method)
  359. }
  360. } else if (method.subtype === "CreditCard") {
  361. method.supportedcard.forEach((supportedcard) => {
  362. if (supportedcard === "JCB" || supportedcard === "MasterCard" || supportedcard === "Visa") {
  363. setCreditCardStatus(method)
  364. } else {
  365. if (supportedcard === "UnionPay") {
  366. setUnionPayStatus(method)
  367. }
  368. }
  369. })
  370. } else if (method.subtype === "PPS") {
  371. setPPSStatus(method)
  372. }
  373. });
  374. setOnReady(true)
  375. }
  376. }, [availableMethods]);
  377. const getTransactionId = () => {
  378. HttpUtils.get({
  379. url: UrlUtils.PAYMENT_TRANSACTION_ID,
  380. onSuccess: (responseData) => {
  381. // const transactionData = responseData;
  382. setTransactionData(responseData)
  383. }
  384. });
  385. }
  386. // useEffect(() => {
  387. // if (availableMethods.length > 0 && Object.keys(transactionData).length > 0) {
  388. // setOnReady(true)
  389. // }
  390. // }, [transactionData, availableMethods]);
  391. const getAppList = () => {
  392. HttpUtils.post({
  393. url: UrlUtils.PAYMENT_APP_LIST,
  394. params: {
  395. appIds: appIds
  396. },
  397. onSuccess: (responseData) => {
  398. setItemList(responseData)
  399. }
  400. });
  401. }
  402. // const selectedPaymentMethodHandle = (method) => () => {
  403. // setSelectedPaymentMethod(method);
  404. // };
  405. // const confirmPaymentHandle = () => () => {
  406. useEffect(() => {
  407. if (confirmPayment){
  408. HttpUtils.post({
  409. url: UrlUtils.POST_CHECK_APP_EXPRITY_DATE,
  410. params: {
  411. ids: appIds
  412. },
  413. onSuccess: (responData) => {
  414. if (responData.success == true) {
  415. setAfterConfirmPayment(true);
  416. return;
  417. }
  418. let str = "";
  419. responData.msg.forEach((item) => {
  420. str += "App: " + item.appNo + ", 到期日: " + DateUtils.datetimeStr_Cht(item.expiryDate) + "\n";
  421. });
  422. setExpiryDateErrText(str.split('\n').map(str => <>{str}<br/></>));
  423. setExpiryDateErr(true);
  424. }
  425. });
  426. }
  427. }, [confirmPayment]);
  428. const getMethodImgClass = (method) => {
  429. return selectedPaymentMethod == method || selectedPaymentMethod == "" ? "" : "grayscale";
  430. }
  431. return (
  432. <Grid container sx={{ minHeight: '110vh', backgroundColor: '#fff' }} direction="column" justifyContent="flex-start" alignItems="center" >
  433. <Grid item xs={12} width="100%">
  434. <div style={BackgroundHead} width="100%">
  435. <Stack direction="row" height='70px'>
  436. <Typography ml={15} color='#FFF' variant="h4" sx={{ pt: 2 }}>
  437. <FormattedMessage id="publicNoticePayment"/>
  438. </Typography>
  439. </Stack>
  440. </div>
  441. </Grid>
  442. {/*row 1*/}
  443. <Grid item xs={12} md={12} width="100%">
  444. <Grid container justifyContent="center" spacing={2} sx={{ p: 2 }} alignitems="stretch" >
  445. <Grid item xs={12} md={11} style={{ height: '100%' }}>
  446. <Box xs={12} md={12} sx={{ p: 4, border: '3px solid #eee', borderRadius: '10px' }} >
  447. <DataGrid
  448. recordList={itemList}
  449. />
  450. </Box>
  451. </Grid>
  452. </Grid>
  453. </Grid>
  454. <Grid item xs={12} md={12} width="100%">
  455. <Stack direction="row" justifyContent="flex-end" alignItems="flex-start" spacing={2} mr={{xs:2,md:12}} >
  456. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  457. <Button
  458. component="span"
  459. variant="contained"
  460. // color="error"
  461. onClick={() => paymentClick()}
  462. sx={{ mt: 4 }}
  463. >
  464. <FormattedMessage id="pay"/>
  465. </Button>
  466. <Button
  467. component="span"
  468. variant="contained"
  469. // color="error"
  470. onClick={() => { navigate("/publicNotice") }}
  471. sx={{ mt: 4 }}
  472. >
  473. <FormattedMessage id="cancel"/>
  474. </Button>
  475. </ThemeProvider>
  476. </Stack>
  477. </Grid>
  478. {/*row 2*/}
  479. <div>
  480. <Dialog
  481. open={expiryDateErr}
  482. onClose={() => setExpiryDateErr(false)}
  483. PaperProps={{
  484. sx: {
  485. minWidth: '40vw',
  486. maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' },
  487. maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' }
  488. }
  489. }}
  490. >
  491. <DialogTitle></DialogTitle>
  492. <Typography variant="h2" style={{ padding: '16px' }}>
  493. <FormattedMessage id ="MSG.actionFail"/>
  494. </Typography>
  495. <DialogContent style={{ display: 'flex', }}>
  496. <Stack direction="column" justifyContent="space-between">
  497. {
  498. expiryDateErrText
  499. }
  500. </Stack>
  501. </DialogContent>
  502. <DialogActions>
  503. <Button onClick={() => setExpiryDateErr(false)}><Typography variant="h5">
  504. <FormattedMessage id="close"/>
  505. </Typography></Button>
  506. </DialogActions>
  507. </Dialog>
  508. </div>
  509. <MultiPaymentWindow open={open}
  510. setOpen={setOpen}
  511. availableMethods={availableMethods}
  512. paymentLimit={paymentLimit}
  513. transactionData={transactionData}
  514. totalAmount={totalAmount}
  515. fpsStatus={fpsStatus}
  516. creditCardStatus={creditCardStatus}
  517. unionPayStatus={unionPayStatus}
  518. ppsStatus={ppsStatus}
  519. setSelectedPaymentMethod={setSelectedPaymentMethod}
  520. selectedPaymentMethod={selectedPaymentMethod}
  521. setConfirmPayment={setConfirmPayment}
  522. getMethodImgClass = {getMethodImgClass}
  523. onReady = {onReady}
  524. locale = {locale}
  525. isFullScreen={isFullScreen}
  526. appIds={appIds}
  527. // appNo={itemList.appNo}
  528. browserType={browserType}
  529. onPayment={onPayment}
  530. />
  531. </Grid >
  532. );
  533. }
  534. export default Index;