瀏覽代碼

add multi payment select page

master
Alex Cheung 1 年之前
父節點
當前提交
e327c8a231
共有 3 個檔案被更改,包括 482 行新增64 行删除
  1. +157
    -0
      src/pages/Payment/MultiPaymentWindow.js
  2. +320
    -64
      src/pages/Payment/index.js
  3. +5
    -0
      src/routes/PublicUserRoutes.js

+ 157
- 0
src/pages/Payment/MultiPaymentWindow.js 查看文件

@@ -0,0 +1,157 @@
import {
useEffect,
useState
} from "react";

// material-ui
import {
Button,
FormLabel,
Stack,
Typography,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
Grid
} from '@mui/material';
import { useFormik, FormikProvider } from 'formik';
import * as yup from 'yup';


const MultiPaymentWindow = (props) => {

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

useEffect(() => {
console.log(props.fpsStatus)
console.log(props.creditCardStatus)
console.log(props.unionPayStatus)
console.log(props.ppsStatus)
if(props.availableMethods.length > 0){
setContent(
<Grid container spacing={2} direction="column" justifyContent="space-between" alignItems="flex-start">
<Grid item xs={12} md={12}>
<Grid container >
<Grid item>
<FormLabel sx={{ fontSize: "16px", color: "#000000", textAlign: "center" }}>
交易參考編號:
</FormLabel>
</Grid>
<Grid item>
<FormLabel sx={{ fontSize: "16px", color: "#000000", textAlign: "center" }}>
{props.transactionData.transicationId}
</FormLabel>
</Grid>
</Grid>
</Grid>
<Grid item xs={12} md={12}>
<Grid container >
<Grid item>
<FormLabel sx={{ fontSize: "16px", color: "#000000", textAlign: "center" }}>
付款金額:
</FormLabel>
</Grid>
<Grid item>
<FormLabel sx={{ fontSize: "16px", color: "#000000", textAlign: "center" }}>
{"HK$ "+props.totalAmount}
</FormLabel>
</Grid>
</Grid>
</Grid>
<Grid item xs={12} md={12}>
<Grid container spacing={1} direction="row" justifyContent="flex-start" alignItems="center">
<Grid item>
<FormLabel sx={{ fontSize: "16px", color: "#000000", textAlign: "center" }}>
付款方式:
</FormLabel>
</Grid>
<Grid item>
<Button variant="contained" color="success" disabled={props.fpsStatus.active === "N"}>
FPS
</Button>
</Grid>
<Grid item>
<Button variant="contained" color="success" disabled={props.creditCardStatus.active === "N"}>
Visa
</Button>
</Grid>
<Grid item>
<Button variant="contained" color="success" disabled={props.unionPayStatus.active === "N"}>
Mastercard
</Button>
</Grid>
<Grid item>
<Button variant="contained" color="success" disabled={props.ppsStatus.active === "N"}>
PPS
</Button>
</Grid>
</Grid>
</Grid>
</Grid>
)
}else{
setContent(
<Grid container direction="row" justifyContent="center" alignItems="center">
<FormLabel sx={{ fontSize: "20px", color: "#000000", textAlign: "center" }}>
付款功能現在不可用。
</FormLabel>
</Grid>
)
}
}, [props.open]);

const formik = useFormik({
initialValues: ({
username: '',
}),
validationSchema: yup.object().shape({
}),
});

return (
<Dialog
open={props.open}
onClose={props.handleClose}
fullWidth={true}
maxWidth={'xl'}
>
<DialogTitle >
<Grid container>
<Grid item>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography variant="h4">
{windowTitle}
</Typography>
</Stack>
</Grid>
</Grid>
</DialogTitle>
<FormikProvider value={formik}>
<form>
<DialogContent>
<DialogContentText>
{content}
</DialogContentText>
</DialogContent>
</form>
</FormikProvider>
<Stack direction="row" justifyContent="space-around">
<DialogActions>
<Button variant="contained" onClick={props.handleClose} autoFocus >
取消
</Button>
</DialogActions>
<DialogActions>
<Button variant="contained" color="success" >
確認
</Button>
</DialogActions>
</Stack>
</Dialog>
);
};

export default MultiPaymentWindow;

+ 320
- 64
src/pages/Payment/index.js 查看文件

@@ -1,90 +1,346 @@
import * as React from "react";
import { lazy } from 'react';
import * as HttpUtils from "utils/HttpUtils";
import Loadable from 'components/Loadable';
const FPS = Loadable(React.lazy(() => import('./FPS')));
const MultiPaymentWindow = Loadable(lazy(() => import('./MultiPaymentWindow')));
// const FPS = Loadable(React.lazy(() => import('./FPS')));
import {useEffect, useState} from "react";

const Index = ({amount}) => {
const getAvailablePaymentUrl = "/api/payment/availability";
const getTransactionIdUrl = "/api/payment/transaction";
import {
Button,
Grid,
Typography,
Stack
} from '@mui/material';

React.useEffect({

}, []);

const local = {en:"en-us", zh:"zh-hk", cn:"zh-cn"};
const preferpaymentmethods = ['visa','mastercard','pps','creditcard','fps'];

const getAvailablePayment = () => {
HttpUtils.post({
url: getAvailablePaymentUrl,
params: {
"locale": local.zh,
"amount": amount,
// "eserviceids": [
// "<eserviceid>", "<eserviceid>"
// ],
"preferpaymentmethods": preferpaymentmethods
},
onSuccess: (responseData)=>{

let availableMethods = responseData.availablepaymentmethods;

availableMethods.forEach((method)=>{
if("CreditCard" === method.subtype){
import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'
const BackgroundHead = {
backgroundImage: `url(${titleBackgroundImg})`,
width: '100%',
height: '100%',
backgroundSize: 'contain',
backgroundRepeat: 'no-repeat',
backgroundColor: '#0C489E',
backgroundPosition: 'right'
}

}
});
const Index = () => {
// const getAvailablePaymentUrl = "/payment/api/payment/availability";
const getTransactionIdUrl = "/payment/api/payment/transaction";

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

/*
//statusWindow
const [open, setOpen] = useState(false);

'pps' for PPS, ‘creditcard’ for Visa / MasterCard /
JCB / UnionPay (FI code = BCMP), and for backward
compatibility - 'visa' for Visa (FI code = BOCI),
'mastercard' for MasterCard (FI code = BOCI)
useEffect(() => {
if(id > 0 ){
setTotalAmount(2000)
}
}, []);

const handleClose = () => {
// handleReset()
setOpen(false);
};

{
"availablepaymentmethods": [
{
"code": "<code>", // e.g. "02,BCMP,ApplePay" = "PAYMENT_MTD_CODE, FI_CODE, subtype"
"subtype": "<subtype>", //ApplePay, AndroidPay, Visa, MasterCard, CreditCard, PPS, eChq
"active":"<active>",//Y/N
"pointstonote":[
{
"type":"<type>",
"content":"<content>",
"order":<order>
} , ...
]
"supportedcard"
:[
"<cardtype>",... //Visa, MasterCard
]
},...
const paymentClick = () => {
setTotalAmount(totalAmount);
if (totalAmount>0){
setOpen(true)
getAvailablePayment()
getTransactionId()
}
};
const getAvailablePayment = () => {
const responseData = {
"availablepaymentmethods": [
{
"active": "Y",
"code": "04,BCFP,FPS",
"pointstonote": [
{
"content": "Please take note of the transaction reference number or PRINT this page for making enquiry on the payment status when necessary.",
"order": 10,
"type": "INFO"
},
{
"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.",
"order": 11,
"type": "INFO"
}
],
"subtype": "FPS"
},
{
"active": "Y",
"code": "02,BCMP,CreditCard",
"pointstonote": [
{
"content": "Please take note of the transaction reference number or PRINT this page for making enquiry on the payment status when necessary.",
"order": 10,
"type": "INFO"
},
{
"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.",
"order": 11,
"type": "INFO"
},
{
"content": "Merchant Name is applicable to credit card payment method only.",
"order": 40,
"type": "INFO"
},
{
"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.",
"order": 41,
"type": "INFO"
},
{
"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.",
"order": 42,
"type": "INFO"
},
{
"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. ",
"order": 43,
"type": "INFO"
}
],
"subtype": "CreditCard",
"supportedcard": [
"JCB",
"MasterCard",
"Visa"
]
}
*/
}
});
},
{
"active": "N",
"code": "03,BCMP,CreditCard",
"pointstonote": [
{
"content": "Please take note of the transaction reference number or PRINT this page for making enquiry on the payment status when necessary.",
"order": 10,
"type": "INFO"
},
{
"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.",
"order": 11,
"type": "INFO"
},
{
"content": "Merchant Name is applicable to credit card payment method only.",
"order": 40,
"type": "INFO"
},
{
"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.",
"order": 41,
"type": "INFO"
},
{
"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.",
"order": 42,
"type": "INFO"
},
{
"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. ",
"order": 43,
"type": "INFO"
}
],
"subtype": "CreditCard",
"supportedcard": [
"UnionPay"
]
},
{
"active": "Y",
"code": "01,PPSB,PPS",
"pointstonote": [
{
"content": "Please take note of the transaction reference number or PRINT this page for making enquiry on the payment status when necessary.",
"order": 10,
"type": "INFO"
},
{
"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.",
"order": 11,
"type": "INFO"
},
{
"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. ",
"order": 21,
"type": "INFO"
}
],
"subtype": "PPS"
}
]
};
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)
}
});
}

// 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)
// }
// });
// }
// }
// });
}

const getTransactionId = () => {
HttpUtils.get({
url: getTransactionIdUrl,
onSuccess: (responseData)=>{
/*
{
"transactionid":"<transactionid",
"webtoken":"<webtoken>"
}
*/
const transactionData = responseData;
setTransactionData(transactionData)
}
});
}

// 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 (
<FPS />
<Grid container sx={{ minHeight: '110vh', backgroundColor: '#fff' }} direction="column" justifyContent="flex-start" alignItems="center" >
<Grid item xs={12} width="100%">
<div style={BackgroundHead} width="100%">
<Stack direction="row" height='70px'>
<Typography ml={15} color='#FFF' variant="h4" sx={{ pt: 2 }}>公共啟事:付款</Typography>
</Stack>
</div>
</Grid>
{/*row 1*/}
<Grid item xs={12} md={12} >
<Grid container justifyContent="flex-start" alignItems="center" >
<center>
<Grid item xs={12} md={12} >

<Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}>
<br />
支付金額
<br />
$ {totalAmount}
</Typography>

<Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}>
<Button
component="span"
variant="contained"
size="large"
// color="error"
onClick={()=>paymentClick()}
sx={{ m: 4 }}
>付款</Button>
</Typography>
</Grid>
</center>
</Grid>
<MultiPaymentWindow open={open}
handleClose={handleClose}
availableMethods={availableMethods}
transactionData={transactionData}
totalAmount={totalAmount}
fpsStatus={fpsStatus}
creditCardStatus={creditCardStatus}
unionPayStatus={unionPayStatus}
ppsStatus={ppsStatus}
/>
</Grid>
{/*row 2*/}
</Grid >
);
}


+ 5
- 0
src/routes/PublicUserRoutes.js 查看文件

@@ -14,6 +14,7 @@ const PublicNoticeDetail = Loadable(lazy(() => import('pages/PublicNotice/Detail
const ProofReply = Loadable(lazy(() => import('pages/Proof/Reply_Public')));
const ProofSearch = Loadable(lazy(() => import('pages/Proof/Search_Public')));
const ProofPayment = Loadable(lazy(() => import('pages/Proof/Payment')));
const Payment_Multi = Loadable(lazy(() => import('pages/Payment')));
const Payment_FPS = Loadable(lazy(() => import('pages/Payment/FPS')));

// ==============================|| MAIN ROUTING ||============================== //
@@ -61,6 +62,10 @@ const PublicDashboard = {
path: 'proof/pay/:id',
element: <ProofPayment/>
},
{
path: 'payment',
element: <Payment_Multi/>
},
{
path: 'payment/fps',
element: <Payment_FPS/>


Loading…
取消
儲存