Browse Source

クレジットカード対応

develop
sosuke.iwabuchi 1 year ago
parent
commit
88bbd688ea
11 changed files with 309 additions and 1 deletions
  1. +2
    -0
      src/api/auth.ts
  2. +10
    -1
      src/api/customer.ts
  3. +4
    -0
      src/api/index.ts
  4. +35
    -0
      src/api/robot-payment.ts
  5. +4
    -0
      src/api/url.ts
  6. +83
    -0
      src/pages/dashboard/robot-payment/creditcard/register.tsx
  7. +128
    -0
      src/pages/dashboard/user/change-payment-method-creditcard-order.tsx
  8. +19
    -0
      src/pages/dashboard/user/detail.tsx
  9. +3
    -0
      src/pages/index.ts
  10. +4
    -0
      src/routes/path.ts
  11. +17
    -0
      src/routes/sub/dashboard.tsx

+ 2
- 0
src/api/auth.ts View File

@@ -10,6 +10,8 @@ export type Me = {
address: string;
phone_no: string;
customer_code: string;
can_pay_by_creditcard: boolean;
can_apply_to_change_payment_method_creditcard: boolean;
};

type MeResponse = {


+ 10
- 1
src/api/customer.ts View File

@@ -51,7 +51,7 @@ export const orderCustomerInfoUpdate = async (
return res;
};

// -------利用者情報変更申請---------------
// -------口座振替登録用パラメータ取得---------------
export type GetRegisterBankAccountStartParamResponse = {
data: {
url: string;
@@ -65,3 +65,12 @@ export const getRegisterBankAccountStartParam = async () => {
});
return res;
};

// -------クレジットカード利用申請---------------
export const orderChangePaymentMetodCreditcard = async (param: {}) => {
const res = await request({
url: getUrl(ApiId.CUSTOMER_CHANGE_PAYMENT_METHOD_CREDITCARD_ORDER),
method: HttpMethod.POST,
});
return res;
};

+ 4
- 0
src/api/index.ts View File

@@ -53,6 +53,10 @@ export const ApiId = {
VERIFY_CHANGE_EMAIL: id++,
CUSTOMER_UPDATE_INFO_ORDER: id++,
CUSTOMER_REGISTER_BANK_ACCOUNT_START_PARAM: id++,
CUSTOMER_CHANGE_PAYMENT_METHOD_CREDITCARD_ORDER: id++,

// ロボットペイメント関連
ROBOT_PAYMENT_CREDITCARD_TOKEN_CHECK: id++,
} as const;
export type ApiId = (typeof ApiId)[keyof typeof ApiId];



+ 35
- 0
src/api/robot-payment.ts View File

@@ -0,0 +1,35 @@
import { APICommonResponse, ApiId, HttpMethod, makeParam, request } from "api";
import { getUrl } from "./url";

// -------領収証一覧取得---------------
export type CheckTokenRequest = {
token: string;
};
export type CheckTokenResponse = {
data: {
url: string;
shop_code: string;
customer_code: string;
token: string;
payment_type: string;
job_type: string;
tax: string;
send_fee: string;
amount: string;
interval: string;
payment_day: string;
auto_amount: string;
target_date: string;
email: string;
phone_number: string;
order_no: string;
};
} & APICommonResponse;
export const checkToken = async (data: CheckTokenRequest) => {
const res = await request<CheckTokenResponse>({
url: getUrl(ApiId.ROBOT_PAYMENT_CREDITCARD_TOKEN_CHECK),
method: HttpMethod.POST,
data: makeParam(data),
});
return res;
};

+ 4
- 0
src/api/url.ts View File

@@ -50,8 +50,12 @@ const urls = {
[A.START_CHANGE_EMAIL]: "email/change/start",
[A.VERIFY_CHANGE_EMAIL]: "email/change/verify",
[A.CUSTOMER_UPDATE_INFO_ORDER]: "customer/update-info-order",
[A.CUSTOMER_CHANGE_PAYMENT_METHOD_CREDITCARD_ORDER]:
"customer/change-payment-method-creditcard-order",
[A.CUSTOMER_REGISTER_BANK_ACCOUNT_START_PARAM]:
"customer/bank-account-register/start",
[A.ROBOT_PAYMENT_CREDITCARD_TOKEN_CHECK]:
"robot-payment/creditcard/token/check",
};

const prefixs = {


+ 83
- 0
src/pages/dashboard/robot-payment/creditcard/register.tsx View File

@@ -0,0 +1,83 @@
import { Typography } from "@mui/material";
import { CheckTokenResponse, checkToken } from "api/robot-payment";
import useAPICall from "hooks/useAPICall";
import useDashboard from "hooks/useDashBoard";
import { PageID, TabID } from "pages";
import { useEffect, useRef, useState } from "react";
import { useParams } from "react-router-dom";

export default function Register() {
const { setHeaderTitle, setTabs } = useDashboard(
PageID.DASHBOARD_ROBOT_PAYMENT_CREDITCARD_REGISTER,
TabID.NONE
);
const { token: paramToken } = useParams();

const [result, setResult] = useState<boolean | null>(null);
const [res, setRes] = useState<CheckTokenResponse | null>(null);

const form = useRef<HTMLFormElement>(null);

const { callAPI: callCheckToken } = useAPICall({
apiMethod: checkToken,
backDrop: true,
onSuccess: (response) => {
setResult(true);
setRes(response);
},
onFailed: () => {
setResult(false);
},
});

useEffect(() => {
if (paramToken) {
callCheckToken({ token: paramToken });
} else {
setResult(false);
}
}, [paramToken]);

useEffect(() => {
if (form.current && res) {
form.current.submit();
}
}, [form, res]);

useEffect(() => {
setHeaderTitle("クレジットカード登録");
setTabs(null);
}, [setHeaderTitle, setTabs]);

if (result === null) {
return null;
}
if (result === false) {
return <Typography>無効なURLです</Typography>;
}
if (res === null) {
return null;
}

const { data } = res;
return (
<form id="target-form" ref={form} action={data.url}>
<p>遷移中...</p>
<input type="hidden" name="aid" value={data.shop_code} />
<input type="hidden" name="cod" value={data.order_no} />
<input type="hidden" name="am" value={data.amount} />
<input type="hidden" name="tx" value={data.tax} />
<input type="hidden" name="sf" value={data.send_fee} />
<input type="hidden" name="jb" value={data.job_type} />
<input type="hidden" name="actp" value={data.interval} />
<input type="hidden" name="acam" value={data.auto_amount} />
<input type="hidden" name="ac1" value={data.payment_day} />
<input type="hidden" name="customer_code" value={data.customer_code} />
<input type="hidden" name="token" value={data.token} />
<input type="hidden" name="payment_type" value={data.payment_type} />
<input type="hidden" name="em" value={data.email} />
<input type="hidden" name="pn" value={data.phone_number} />
<input type="hidden" name="ac4" value={data.target_date} />
</form>
);
}

+ 128
- 0
src/pages/dashboard/user/change-payment-method-creditcard-order.tsx View File

@@ -0,0 +1,128 @@
import {
Box,
Button,
Stack,
Table,
TableBody,
TableCell,
TableRow,
Typography,
} from "@mui/material";
import { HasChildren } from "@types";
import {
orderChangePaymentMetodCreditcard,
orderCustomerInfoUpdate,
startChangeEmail,
} from "api/customer";
import RequireChip from "components/chip/RequireChip";
import InputAlert from "components/form/InputAlert";
import TextFieldEx from "components/form/TextFieldEx";
import { FormProvider, RHFTextField } from "components/hook-form";
import StackRow from "components/stack/StackRow";
import useAPICall from "hooks/useAPICall";
import useAuth from "hooks/useAuth";
import useDashboard from "hooks/useDashBoard";
import useNavigateCustom from "hooks/useNavigateCustom";
import useSnackbarCustom from "hooks/useSnackbarCustom";
import { PageID, TabID } from "pages";
import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { getPath } from "routes/path";

type AreaBoxProps = {
label: string;
require?: boolean;
} & HasChildren;
function AreaBox({ label, children, require }: AreaBoxProps) {
return (
<Box>
<StackRow>
<Typography variant="subtitle1">〇{label}</Typography>
<RequireChip require={require ?? false} />
</StackRow>
{children}
</Box>
);
}

type FormProps = {
name: string;
name_kana: string;
zip_code: string;
address: string;
phone_no: string;
memo: string;
};

export default function ChangePaymentMethodCreditcardOrder() {
const { setHeaderTitle, setTabs } = useDashboard(
PageID.DASHBOARD_USER_CHANGE_PAYMENT_METHOD_CREDITCARD_ORDER,
TabID.NONE
);

const { navigateWhenChanged } = useNavigateCustom();

const { user } = useAuth();

const [mode, setMode] = useState<"confirm" | "done">("confirm");

const { error } = useSnackbarCustom();

const { callAPI: callOrderChangePaymentMetodCreditcard } = useAPICall({
apiMethod: orderChangePaymentMetodCreditcard,
backDrop: true,
onSuccess: () => {
setMode("done");
},
onFailed: () => {
error("失敗しました");
},
});

const send = () => {
callOrderChangePaymentMetodCreditcard({});
};

useEffect(() => {
setHeaderTitle("利用者情報変更申請");
setTabs(null);
}, []);

useEffect(() => {
if (user && user.can_pay_by_creditcard === false) {
navigateWhenChanged(getPath(PageID.DASHBOARD_OVERVIEW));
}
}, [user]);

if (user?.can_pay_by_creditcard !== true) {
return null;
}

if (mode === "done") {
return (
<Stack spacing={2}>
<Box>申請を行いました。受理をお待ちください。</Box>
</Stack>
);
}

return (
<Box sx={{ mt: 1 }}>
<Stack spacing={2}>
<Box>
<Typography>クレジットカードの登録申請を行います。</Typography>
<Typography>申請受理後に、登録用のURLをメール送信します。</Typography>
<Typography>
メール送信までに数営業日を要する場合がございます。
</Typography>
</Box>
<Box></Box>
<StackRow spacing={2}>
<Button onClick={send} variant="contained">
申請する
</Button>
</StackRow>
</Stack>
</Box>
);
}

+ 19
- 0
src/pages/dashboard/user/detail.tsx View File

@@ -1,4 +1,5 @@
import { Box, Button, Paper, Stack, Typography } from "@mui/material";
import useAuth from "hooks/useAuth";
import useDashboard from "hooks/useDashBoard";
import useNavigateCustom from "hooks/useNavigateCustom";
import { PageID, TabID } from "pages";
@@ -13,6 +14,8 @@ export default function UserDetail() {

const { navigateWhenChanged } = useNavigateCustom();

const { user } = useAuth();

useEffect(() => {
setHeaderTitle("利用者情報");
setTabs(null);
@@ -56,6 +59,22 @@ export default function UserDetail() {
口座情報変更
</Button>
</Box>
{user?.can_apply_to_change_payment_method_creditcard && (
<Box>
<Button
variant="contained"
onClick={() => {
navigateWhenChanged(
getPath(
PageID.DASHBOARD_USER_CHANGE_PAYMENT_METHOD_CREDITCARD_ORDER
)
);
}}
>
クレジットカード登録
</Button>
</Box>
)}
</Stack>
</Paper>
);


+ 3
- 0
src/pages/index.ts View File

@@ -31,6 +31,9 @@ export const PageID = {
DASHBOARD_USER_CHANGE_EMAIL_START: id++,
DASHBOARD_USER_UPDATE_USER_INFO: id++,
DASHBOARD_USER_BANK_REGISTER: id++,
DASHBOARD_USER_CHANGE_PAYMENT_METHOD_CREDITCARD_ORDER: id++,

DASHBOARD_ROBOT_PAYMENT_CREDITCARD_REGISTER: id++,

SEASON_TICKET_CONTRACT_SELECTION_ENTRY: id++,
SEASON_TICKET_CONTRACT_ENTRY_CANCEL: id++,


+ 4
- 0
src/routes/path.ts View File

@@ -68,6 +68,10 @@ const PATHS_DASHBOARD = {
"/dashboard/update/user/info",
[makePathKey(PageID.DASHBOARD_USER_BANK_REGISTER)]:
"/dashboard/update/user/back-register",
[makePathKey(PageID.DASHBOARD_USER_CHANGE_PAYMENT_METHOD_CREDITCARD_ORDER)]:
"/dashboard/order/user/payment-method/creditcard",
[makePathKey(PageID.DASHBOARD_ROBOT_PAYMENT_CREDITCARD_REGISTER)]:
"/dashboard/robot-payment/creditcard/register/:token",
};

const PATHS = {


+ 17
- 0
src/routes/sub/dashboard.tsx View File

@@ -31,6 +31,15 @@ export default function DashboardRoutes(): RouteObject[] {
const BankRegister = Loadable(
lazy(() => import("pages/dashboard/user/bank-register"))
);
const ChangePaymentMethodCreditcardOrder = Loadable(
lazy(
() =>
import("pages/dashboard/user/change-payment-method-creditcard-order")
)
);
const RobotPaymentCreditcardRegister = Loadable(
lazy(() => import("pages/dashboard/robot-payment/creditcard/register"))
);

const allChildren = [
{
@@ -66,6 +75,14 @@ export default function DashboardRoutes(): RouteObject[] {
pageId: PageID.DASHBOARD_USER_BANK_REGISTER,
element: <BankRegister />,
},
{
pageId: PageID.DASHBOARD_USER_CHANGE_PAYMENT_METHOD_CREDITCARD_ORDER,
element: <ChangePaymentMethodCreditcardOrder />,
},
{
pageId: PageID.DASHBOARD_ROBOT_PAYMENT_CREDITCARD_REGISTER,
element: <RobotPaymentCreditcardRegister />,
},
];
return allChildren.map(({ pageId, ...others }) => ({
...others,


Loading…
Cancel
Save