Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

277 lignes
11 KiB

  1. // material-ui
  2. import {
  3. Grid,
  4. Typography,
  5. Stack,
  6. Button,
  7. } from '@mui/material';
  8. import * as React from "react";
  9. import * as HttpUtils from "utils/HttpUtils";
  10. import { useNavigate } from "react-router-dom";
  11. import FpsIcon from "assets/images/icons/fps.svg";
  12. import { useLocation } from 'react-router-dom';
  13. import {paymentPath} from "auth/utils";
  14. // import {poll} from "utils/Utils";
  15. import Loadable from 'components/Loadable';
  16. const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
  17. import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'
  18. const BackgroundHead = {
  19. backgroundImage: `url(${titleBackgroundImg})`,
  20. width: '100%',
  21. height: '100%',
  22. backgroundSize: 'contain',
  23. backgroundRepeat: 'no-repeat',
  24. backgroundColor: '#0C489E',
  25. backgroundPosition: 'right'
  26. }
  27. // ==============================|| DASHBOARD - DEFAULT ||============================== //
  28. const Index = () => {
  29. const navigate = useNavigate()
  30. const location = useLocation();
  31. const [locationData, setLocationData] = React.useState({});
  32. const [paymentData, setPaymentData] = React.useState({});
  33. const [onReady, setOnReady] = React.useState(false);
  34. const [responeData, setResponeDataData] = React.useState({});
  35. const [fpsTransctionData, setFpsTransctionData] = React.useState({});
  36. const [fpsmerchanttimeoutdatetime, setFpsmerchanttimeoutdatetime] = React.useState("");
  37. const [timeDownCount, setTimeDownCount] = React.useState(0);
  38. // const [fpsqrcodeurl, setFpsqrcodeurl] = React.useState("");
  39. // const pasgPath = 'https://fps.payapps.hkicl.com.hk'; //PRD
  40. // const pasgPath = 'https://sim.fps.payapps.hkicl.com.hk'; //Testing
  41. const loadPaymentUrl = "/api/payment/wallet/fps";
  42. const cancelPaymentUrl = "/api/payment/cancelpayment";
  43. const paymentStatusApi = "/api/payment/status/";
  44. // const payloadUrl = "/api/payment/wallet/fps/enquiryfpspayload/";
  45. // const receiverUrl = "/noti-api/payment/payment-notification";
  46. //timer
  47. const currentTimer = React.useRef();
  48. const [time, setTime] = React.useState(0);
  49. React.useEffect(() => {
  50. console.log (location.state)
  51. if(Object.keys(location.state).length > 0){
  52. console.log (location.state)
  53. setLocationData(location.state)
  54. }
  55. }, []);
  56. React.useEffect(() => {
  57. console.log (locationData)
  58. if (Object.keys(locationData).length > 0){
  59. setPaymentData(locationData)
  60. // loadForm();
  61. }
  62. }, [locationData]);
  63. React.useEffect(() => {
  64. console.log (paymentData)
  65. if (Object.keys(paymentData).length > 0){
  66. loadForm();
  67. }
  68. }, [paymentData]);
  69. React.useEffect(() => {
  70. console.log(responeData)
  71. if(Object.keys(responeData).length > 0 && fpsmerchanttimeoutdatetime!=""){
  72. setFpsTransctionData(responeData)
  73. }
  74. }, [responeData]);
  75. React.useEffect(() => {
  76. console.log(fpsTransctionData)
  77. if(Object.keys(fpsTransctionData).length > 0 ){
  78. setOnReady(true);
  79. currentTimer.current = setInterval(() => {
  80. setTime((prevTime) => prevTime + 1);
  81. }, 1000);
  82. return () => clearInterval(currentTimer.current);
  83. }
  84. }, [fpsTransctionData]);
  85. const loadForm = () => {
  86. // const timeoutdatetime = "2023-10-26T09:04:30Z[UTC]"
  87. // const convertedDateString = timeoutdatetime.replace("[UTC]", "");
  88. // setFpsmerchanttimeoutdatetime(convertedDateString)
  89. // setPaymentid("C202310268000681")
  90. // setPaymentstatuscode("APPR")
  91. HttpUtils.post({
  92. url: paymentPath+loadPaymentUrl,
  93. params:{
  94. "transactionid": paymentData.transactionid,
  95. "webtoken": paymentData.webtoken,
  96. "paymentmethod":"04,BCFP,FPS",
  97. "order": {
  98. "totalamount":paymentData.amount,
  99. "currency":"HKD",
  100. "orderdetail":
  101. [
  102. {
  103. "itemid": "1",
  104. "qty":"1",
  105. "unitprice":paymentData.amount,
  106. "amount":paymentData.amount
  107. },
  108. ]
  109. },
  110. // "locale":"<locale>",
  111. // "eserviceid":"<eserviceid>"
  112. },
  113. onSuccess: function(responseData){
  114. /*
  115. {
  116. "paymentid": "<paymentid>",
  117. "paymentstatus": "<paymentstatus>",
  118. "fpsmerchanttimeoutdatetime": <fpsmerchanttimeoutdatetime>,
  119. "fpsqrcodeimgbase64": "<fpsqrcodeimgbase64>",
  120. "fpsqrcodeurl": "<fpsqrcodeurl>"
  121. }
  122. */
  123. setResponeDataData(responseData)
  124. const timeoutdatetime = responseData.fpsmerchanttimeoutdatetime
  125. const convertedDateString = timeoutdatetime.replace("[UTC]", "");
  126. setFpsmerchanttimeoutdatetime(convertedDateString)
  127. // const parsedUrl = new URL(responseData.fpsqrcodeurl);
  128. // const fpsqrcodeurl = parsedUrl.pathname;
  129. // const openPASGUrl = pasgPath + '?pay_req_obj=' + encodeURIComponent(responseData.fpsqrcodeurl) + '&callback='
  130. // + encodeURIComponent(paymentPath + payment.config.fpscallbackPage);
  131. // setFpsqrcodeurl(openPASGUrl)
  132. }
  133. });
  134. }
  135. const getPaymentStatus = () => {
  136. HttpUtils.post({
  137. url: paymentPath+paymentStatusApi+paymentData.transactionid,
  138. params:{
  139. "apprefid": paymentData.transactionid,
  140. "webtoken": paymentData.webtoken,
  141. },
  142. onSuccess: function(responseData){
  143. const paymentstatuscode = responseData.paymentdetail.result.paymentstatuscode;
  144. if (paymentstatuscode != "" && paymentstatuscode != "INPR" ){
  145. if (paymentstatuscode === 'APPR') {
  146. const timestamp = Date.now();
  147. navigate('/paymentPage/fps/ackpage', {state:{transactionDateTime:timestamp,transactionid:paymentData.transactionid,webtoken:paymentData.webtoken} });
  148. } else if (paymentstatuscode === 'CANC') {
  149. // window.top.location.href = paymentPath + payment.config.indexPagePath;
  150. navigate('/paymentPage');
  151. } else {
  152. // window.top.location.href = paymentPath + payment.config.errPagePath;
  153. alert("ERROR")
  154. }
  155. }
  156. },
  157. onError: function(){
  158. cancelPayment()
  159. // clearInterval(currentTimer.current);
  160. }
  161. });
  162. };
  163. React.useEffect(() => {
  164. const timeOutDate = new Date(fpsmerchanttimeoutdatetime);
  165. const currentTime = new Date;
  166. console.log(time)
  167. console.log(timeOutDate)
  168. console.log(currentTime)
  169. console.log(timeOutDate.getTime()-currentTime.getTime())
  170. setTimeDownCount(timeOutDate.getTime()-currentTime.getTime())
  171. getPaymentStatus();
  172. if (timeOutDate.getTime()<currentTime.getTime()){
  173. console.log("stop");
  174. clearInterval(currentTimer.current);
  175. cancelPayment()
  176. }
  177. },[time])
  178. const cancelPayment = ()=>{
  179. HttpUtils.post({
  180. url: paymentPath+cancelPaymentUrl,
  181. params:{
  182. "transactionid": paymentData.transactionid,
  183. "webtoken": paymentData.webtoken,
  184. "paymentid": fpsTransctionData.paymentid
  185. },
  186. onSuccess: function(){
  187. navigate("/dashboard");
  188. }
  189. });
  190. }
  191. return (
  192. !onReady ?
  193. <LoadingComponent />
  194. :
  195. (
  196. <Grid container sx={{ minHeight: '110vh', backgroundColor: '#fff' }} direction="column" justifyContent="flex-start" alignItems="center" >
  197. <Grid item xs={12} width="100%">
  198. <div style={BackgroundHead} width="100%">
  199. <Stack direction="row" height='70px'>
  200. <Typography ml={15} color='#FFF' variant="h4" sx={{ pt: 2 }}>公共啟事:FPS付款</Typography>
  201. </Stack>
  202. </div>
  203. </Grid>
  204. {/*row 1*/}
  205. <Grid item xs={12} md={12} >
  206. <Grid container justifyContent="flex-start" alignItems="center" >
  207. <center>
  208. <Grid item xs={12} md={12} >
  209. <Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}>
  210. <img src={FpsIcon} width="80" height="80" alt="FPS"></img>
  211. <br />
  212. 支付金額
  213. <br />
  214. {"$HK " + paymentData.amount}
  215. </Typography>
  216. <Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}>
  217. 請掃描以下二維碼
  218. <br />
  219. <img src={fpsTransctionData.fpsqrcodeimgbase64} alt="QR Code"/>
  220. <br />
  221. 二維碼有效期限3分鐘
  222. <br />
  223. 請在規定時間內完成付款流程
  224. <br />
  225. {"剩餘時間:"+timeDownCount}
  226. </Typography>
  227. <Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}>
  228. <Button
  229. component="span"
  230. variant="contained"
  231. size="large"
  232. color="error"
  233. onClick={()=>{
  234. cancelPayment();
  235. }}
  236. sx={{ m: 4 }}
  237. >取消付款</Button>
  238. </Typography>
  239. </Grid>
  240. </center>
  241. </Grid>
  242. </Grid>
  243. {/*row 2*/}
  244. </Grid >
  245. )
  246. );
  247. };
  248. export default Index;