ソースを参照

FPS update

master
Alex Cheung 1年前
コミット
e20135e800
4個のファイルの変更150行の追加88行の削除
  1. +2
    -0
      src/auth/utils.js
  2. +74
    -35
      src/pages/Payment/FPS/FPS.js
  3. +46
    -10
      src/pages/Payment/MultiPaymentWindow.js
  4. +28
    -43
      src/pages/Payment/index.js

+ 2
- 0
src/auth/utils.js ファイルの表示

@@ -12,6 +12,8 @@ export const hostPath = `http://${hostname}:${hostPort}`;
//export const apiPath = `http://192.168.0.112:8090/api`; //export const apiPath = `http://192.168.0.112:8090/api`;
export const apiPath = `${hostPath}/api`; export const apiPath = `${hostPath}/api`;
//export const apiPath = `/api`; //export const apiPath = `/api`;
export const paymentPath = `https://pnspsdev.gld.gov.hk/payment`;



export const isUserLoggedIn = () => { export const isUserLoggedIn = () => {
return localStorage.getItem('userData') && localStorage.getItem(useJwt.jwtConfig.storageTokenKeyName); return localStorage.getItem('userData') && localStorage.getItem(useJwt.jwtConfig.storageTokenKeyName);


+ 74
- 35
src/pages/Payment/FPS/FPS.js ファイルの表示

@@ -9,6 +9,9 @@ import * as React from "react";
import * as HttpUtils from "utils/HttpUtils"; import * as HttpUtils from "utils/HttpUtils";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import FpsIcon from "assets/images/icons/fps.svg"; import FpsIcon from "assets/images/icons/fps.svg";
import { useLocation } from 'react-router-dom';
import {paymentPath} from "auth/utils";
// import {poll} from "utils/Utils";


import Loadable from 'components/Loadable'; import Loadable from 'components/Loadable';
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
@@ -28,53 +31,56 @@ const BackgroundHead = {


const Index = () => { const Index = () => {
const navigate = useNavigate() const navigate = useNavigate()
const location = useLocation();


const [fpsqrcodeimgUrl, setFpsqrcodeimgUrl] = React.useState();
const [paymentData, setPaymentData] = React.useState({});
const [onReady, setOnReady] = React.useState(false); const [onReady, setOnReady] = React.useState(false);
const [paymentid, setPaymentid] = React.useState("");
const [fpsmerchanttimeoutdatetime, setFpsmerchanttimeoutdatetime] = React.useState("");
const [fpsqrcodeimgbase64, setFpsqrcodeimgbase64] = React.useState("");
const [fpsqrcodeurl, setFpsqrcodeurl] = React.useState("");


const loadPaymentUrl = "/api/payment/wallet/fps"; const loadPaymentUrl = "/api/payment/wallet/fps";
const cancelPaymentUrl = "/api/payment/cancelpayment"; const cancelPaymentUrl = "/api/payment/cancelpayment";
const paymentStatusApi = "/api/payment/status/";
// const payloadUrl = "/api/payment/wallet/fps/enquiryfpspayload/"; // const payloadUrl = "/api/payment/wallet/fps/enquiryfpspayload/";
// const receiverUrl = "/noti-api/payment/payment-notification"; // const receiverUrl = "/noti-api/payment/payment-notification";


React.useEffect(() => { React.useEffect(() => {
setFpsqrcodeimgbase64("")
if(location.state != undefined){
setPaymentData(location.state)
}
loadForm(); loadForm();
}, []); }, []);


React.useEffect(() => { React.useEffect(() => {
setOnReady(true); setOnReady(true);
}, [fpsqrcodeimgUrl]);
}, [fpsqrcodeimgbase64]);




const loadForm = () => { const loadForm = () => {

HttpUtils.post({ HttpUtils.post({
url: loadPaymentUrl,
url: paymentPath+loadPaymentUrl,
params:{ params:{
"transactionid": "<transactionid>",
"webtoken": "<webtoken>",
"paymentmethod": "<paymentmethodcode>",
"transactionid": paymentData.transactionid,
"webtoken": paymentData.webtoken,
"paymentmethod":"04,BCFP,FPS",
"order": { "order": {
"totalamount":"<totalamount>",
"currency":"<currency>",
"totalamount":paymentData.amount,
"currency":"HKD",
"orderdetail": "orderdetail":
[ [
{ {
"itemid": "<itemid>",
"qty":"<qty>",
"unitprice":"<unitprice>",
"amount":"<amount>"
},
{
"itemid": "<itemid>",
"qty":"<qty>",
"unitprice":"<unitprice>",
"amount":"<amount>"
"itemid": "1",
"qty":"1",
"unitprice":paymentData.amount,
"amount":paymentData.amount
}, },
] ]
}, },
"locale":"<locale>",
"eserviceid":"<eserviceid>"
// "locale":"<locale>",
// "eserviceid":"<eserviceid>"
}, },
onSuccess: function(responseData){ onSuccess: function(responseData){
/* /*
@@ -86,27 +92,60 @@ const Index = () => {
"fpsqrcodeurl": "<fpsqrcodeurl>" "fpsqrcodeurl": "<fpsqrcodeurl>"
} }
*/ */

setFpsqrcodeimgUrl(responseData.fpsqrcodeurl);
setFpsqrcodeimgbase64(responseData.fpsqrcodeimgbase64);
setPaymentid(responseData.paymentid);
setFpsmerchanttimeoutdatetime(responseData.fpsmerchanttimeoutdatetime);
const parsedUrl = new URL(responseData.fpsqrcodeurl);
const fpsqrcodeurl = parsedUrl.pathname
setFpsqrcodeurl(fpsqrcodeurl)
polling()
} }
}); });
} }


const getPaymentStatus = () => {
HttpUtils.post({
url: paymentPath+paymentStatusApi+paymentid,
params:{
"apprefid": paymentData.transactionid,
"webtoken": paymentData.webtoken,
},
onSuccess: function(responseData){
const paymentstatuscode = responseData.paymentdetail.result.paymentstatuscode;
if (paymentstatuscode === 'APPR') {
const timestamp = '?t=' + Date.now();
window.top.location.href = payment.config.domain + payment.config.ackPagePath + timestamp;
} else if (paymentstatuscode === 'CANC') {
window.top.location.href = payment.config.domain + payment.config.indexPagePath;
} else {
window.top.location.href = payment.config.domain + payment.config.errPagePath;
}
},
onError: function(){
cancelPayment()
}
});
};

useEffect(() => {
const timeOut = fpsmerchanttimeoutdatetime=now()?500:null;
const interval = setInterval(() => {
getPaymentStatus();
console.log("test");
}, timeOut);
return () => clearInterval(interval);
}, []);

const cancelPayment = ()=>{ const cancelPayment = ()=>{
HttpUtils.post({ HttpUtils.post({
url: cancelPaymentUrl,
url: paymentPath+cancelPaymentUrl,
params:{ params:{
"transactionid": "<transactionid>",
"webtoken": "<webtoken>",
"paymentid": "<paymentid>"
"transactionid": paymentData.transactionid,
"webtoken": paymentData.webtoken,
"paymentid": paymentid
}, },
onSuccess: function(){ onSuccess: function(){
/*
{
"resultcode": "<resultcode>",
"reason": "<reason>"
}
*/
navigate("/dashboard"); navigate("/dashboard");
} }
}); });
@@ -165,13 +204,13 @@ const Index = () => {
<br /> <br />
支付金額 支付金額
<br /> <br />
$
{"$HK " + paymentData.amount}
</Typography> </Typography>


<Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}> <Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}>
請掃描以下二維碼 請掃描以下二維碼
<br /> <br />
<img src={fpsqrcodeimgUrl} alt="QR Code"/>
<img src={fpsqrcodeimgbase64} alt="QR Code"/>
<br /> <br />
二維碼有效期限10分鐘 二維碼有效期限10分鐘
<br /> <br />


+ 46
- 10
src/pages/Payment/MultiPaymentWindow.js ファイルの表示

@@ -24,12 +24,27 @@ const MultiPaymentWindow = (props) => {


const windowTitle = "請選擇付款方式"; const windowTitle = "請選擇付款方式";
const [content, setContent] = useState(); const [content, setContent] = useState();
const [paymentMethod, setPaymentMethod] = useState("");


useEffect(() => { useEffect(() => {
console.log(props.fpsStatus)
console.log(props.creditCardStatus)
console.log(props.unionPayStatus)
console.log(props.ppsStatus)
console.log(paymentMethod)
}, [paymentMethod]);

const selectedPaymentMethodHandle = (method) => () =>{
setPaymentMethod(method)
props.setSelectedPaymentMethod(method);
};

const confirmPaymentHandle = () => () =>{
props.setConfirmPayment(true);
};


useEffect(() => {
if(props.selectedPaymentMethod === ""){
setPaymentMethod("")
}
setPaymentMethod
if(props.availableMethods.length > 0){ if(props.availableMethods.length > 0){
setContent( setContent(
<Grid container spacing={2} direction="column" justifyContent="space-between" alignItems="flex-start"> <Grid container spacing={2} direction="column" justifyContent="space-between" alignItems="flex-start">
@@ -69,27 +84,48 @@ const MultiPaymentWindow = (props) => {
</FormLabel> </FormLabel>
</Grid> </Grid>
<Grid item> <Grid item>
<Button variant="contained" color="success" disabled={props.fpsStatus.active === "N"}>
<Button variant="contained" color="success" onClick={selectedPaymentMethodHandle("FPS")} disabled={props.fpsStatus.active === "N"}>
FPS FPS
</Button> </Button>
</Grid> </Grid>
<Grid item> <Grid item>
<Button variant="contained" color="success" disabled={props.creditCardStatus.active === "N"}>
<Button variant="contained" color="success" onClick={selectedPaymentMethodHandle("Visa")} disabled={props.creditCardStatus.active === "N"}>
Visa Visa
</Button> </Button>
</Grid> </Grid>
<Grid item> <Grid item>
<Button variant="contained" color="success" disabled={props.unionPayStatus.active === "N"}>
<Button variant="contained" color="success" onClick={selectedPaymentMethodHandle("Mastercard")} disabled={props.creditCardStatus.active === "N"}>
Mastercard Mastercard
</Button> </Button>
</Grid> </Grid>
<Grid item> <Grid item>
<Button variant="contained" color="success" disabled={props.ppsStatus.active === "N"}>
<Button variant="contained" color="success" onClick={selectedPaymentMethodHandle("UnionPay")} disabled={props.unionPayStatus.active === "N"}>
UnionPay
</Button>
</Grid>
<Grid item>
<Button variant="contained" color="success" onClick={selectedPaymentMethodHandle("PPS")} disabled={props.ppsStatus.active === "N"}>
PPS PPS
</Button> </Button>
</Grid> </Grid>
</Grid> </Grid>
</Grid> </Grid>
{paymentMethod !=""?
<Grid item xs={12} md={12}>
<Grid container direction="row" justifyContent="flex-start" alignItems="center">
<Grid item>
<FormLabel sx={{ fontSize: "16px", color: "#000000", textAlign: "center" }}>
已選擇付款方式:
</FormLabel>
</Grid>
<Grid item>
<FormLabel sx={{ fontSize: "16px", color: "#000000", textAlign: "center" }}>
{paymentMethod}
</FormLabel>
</Grid>
</Grid>
</Grid>
: null}
</Grid> </Grid>
) )
}else{ }else{
@@ -101,7 +137,7 @@ const MultiPaymentWindow = (props) => {
</Grid> </Grid>
) )
} }
}, [props.open]);
}, [props.open,paymentMethod]);


const formik = useFormik({ const formik = useFormik({
initialValues: ({ initialValues: ({
@@ -145,7 +181,7 @@ const MultiPaymentWindow = (props) => {
</Button> </Button>
</DialogActions> </DialogActions>
<DialogActions> <DialogActions>
<Button variant="contained" color="success" >
<Button variant="contained" color="success" onClick={confirmPaymentHandle()} disabled={paymentMethod === ""}>
確認 確認
</Button> </Button>
</DialogActions> </DialogActions>


+ 28
- 43
src/pages/Payment/index.js ファイルの表示

@@ -5,6 +5,8 @@ import Loadable from 'components/Loadable';
const MultiPaymentWindow = Loadable(lazy(() => import('./MultiPaymentWindow'))); const MultiPaymentWindow = Loadable(lazy(() => import('./MultiPaymentWindow')));
// const FPS = Loadable(React.lazy(() => import('./FPS'))); // const FPS = Loadable(React.lazy(() => import('./FPS')));
import {useEffect, useState} from "react"; import {useEffect, useState} from "react";
import {useNavigate} from "react-router-dom";
import {paymentPath} from "auth/utils";


import { import {
Button, Button,
@@ -27,20 +29,24 @@ const BackgroundHead = {
const Index = () => { const Index = () => {
// const getAvailablePaymentUrl = "/payment/api/payment/availability"; // const getAvailablePaymentUrl = "/payment/api/payment/availability";
const getTransactionIdUrl = "/payment/api/payment/transaction"; const getTransactionIdUrl = "/payment/api/payment/transaction";
const navigate = useNavigate()


// const local = {en:"en-us", zh:"zh-hk", cn:"zh-cn"}; // const local = {en:"en-us", zh:"zh-hk", cn:"zh-cn"};
// const preferpaymentmethods = ['visa','mastercard','pps','creditcard','fps']; // const preferpaymentmethods = ['visa','mastercard','pps','creditcard','fps'];
const [totalAmount,setTotalAmount] = useState(0); const [totalAmount,setTotalAmount] = useState(0);
const id =1; const id =1;
//statusWindow
const [open, setOpen] = useState(false);
const [availableMethods,setAvailableMethods] = useState([]); const [availableMethods,setAvailableMethods] = useState([]);
const [transactionData,setTransactionData] = useState({}); const [transactionData,setTransactionData] = useState({});
const [fpsStatus,setFPSStatus] = useState({}); const [fpsStatus,setFPSStatus] = useState({});
const [creditCardStatus,setCreditCardStatus] = useState({}); const [creditCardStatus,setCreditCardStatus] = useState({});
const [unionPayStatus,setUnionPayStatus] = useState({}); const [unionPayStatus,setUnionPayStatus] = useState({});
const [ppsStatus,setPPSStatus] = useState({}); const [ppsStatus,setPPSStatus] = useState({});

//statusWindow
const [open, setOpen] = useState(false);
const [selectedPaymentMethod, setSelectedPaymentMethod] = useState("");
const [confirmPayment, setConfirmPayment] = useState(false);


useEffect(() => { useEffect(() => {
if(id > 0 ){ if(id > 0 ){
@@ -55,12 +61,25 @@ const Index = () => {


const paymentClick = () => { const paymentClick = () => {
setTotalAmount(totalAmount); setTotalAmount(totalAmount);
setSelectedPaymentMethod("")
setConfirmPayment(false)
if (totalAmount>0){ if (totalAmount>0){
setOpen(true) setOpen(true)
getAvailablePayment() getAvailablePayment()
getTransactionId() getTransactionId()
} }
}; };

useEffect(() => {
if (confirmPayment){
setOpen(false);
if(selectedPaymentMethod === "FPS"){
navigate('/payment/fps', {state:{amount:totalAmount,transactionid:"",webtoken:""} });
// navigate('/payment/fps', {state:{amount:totalAmount,transactionid:transactionData.transactionid,webtoken:transactionData.webtoken} });
}
}
}, [confirmPayment]);
const getAvailablePayment = () => { const getAvailablePayment = () => {
const responseData = { const responseData = {
@@ -125,7 +144,7 @@ const Index = () => {
] ]
}, },
{ {
"active": "N",
"active": "Y",
"code": "03,BCMP,CreditCard", "code": "03,BCMP,CreditCard",
"pointstonote": [ "pointstonote": [
{ {
@@ -211,7 +230,7 @@ const Index = () => {
} }


// HttpUtils.post({ // HttpUtils.post({
// url: getAvailablePaymentUrl,
// url: paymentPath+getAvailablePaymentUrl,
// params: { // params: {
// // "locale": local.zh,; // // "locale": local.zh,;
// "amount": totalAmount, // "amount": totalAmount,
@@ -248,7 +267,7 @@ const Index = () => {


const getTransactionId = () => { const getTransactionId = () => {
HttpUtils.get({ HttpUtils.get({
url: getTransactionIdUrl,
url: paymentPath+getTransactionIdUrl,
onSuccess: (responseData)=>{ onSuccess: (responseData)=>{
const transactionData = responseData; const transactionData = responseData;
setTransactionData(transactionData) setTransactionData(transactionData)
@@ -256,43 +275,6 @@ const Index = () => {
}); });
} }


// const startFPSTransaction = () => {
// HttpUtils.post({
// url: getAvailablePaymentUrl,
// params: {
// // "locale": local.zh,;
// "amount": totalAmount,
// // "eserviceids": [
// // "<eserviceid>", "<eserviceid>"
// // ],
// "preferpaymentmethods": preferpaymentmethods
// },
// onSuccess: (responseData)=>{
// let availableMethods = responseData.availablepaymentmethods;
// setAvailableMethods(availableMethods);
// if (availableMethods.length>0){
// availableMethods.forEach((method)=>{
// if(method.subtype === "FPS" ){
// setFPSStatus(method)
// }else if (method.subtype === "CreditCard"){
// method.supportedcard.forEach((supportedcard)=>{
// if (supportedcard === "JCB" || supportedcard === "MasterCard" || supportedcard === "Visa"){
// setCreditCardStatus(method)
// } else {
// if (supportedcard === "UnionPay"){
// setUnionPayStatus(method)
// }
// }
// })
// }else if (method.subtype === "PPS" ){
// setPPSStatus(method)
// }
// });
// }
// }
// });
// }

return ( return (
<Grid container sx={{ minHeight: '110vh', backgroundColor: '#fff' }} direction="column" justifyContent="flex-start" alignItems="center" > <Grid container sx={{ minHeight: '110vh', backgroundColor: '#fff' }} direction="column" justifyContent="flex-start" alignItems="center" >
<Grid item xs={12} width="100%"> <Grid item xs={12} width="100%">
@@ -337,6 +319,9 @@ const Index = () => {
creditCardStatus={creditCardStatus} creditCardStatus={creditCardStatus}
unionPayStatus={unionPayStatus} unionPayStatus={unionPayStatus}
ppsStatus={ppsStatus} ppsStatus={ppsStatus}
setSelectedPaymentMethod={setSelectedPaymentMethod}
selectedPaymentMethod={selectedPaymentMethod}
setConfirmPayment={setConfirmPayment}
/> />
</Grid> </Grid>
{/*row 2*/} {/*row 2*/}


読み込み中…
キャンセル
保存