Compare commits
3 Commits
a9bb11f080
...
9d4d2f1ea8
| Author | SHA1 | Date |
|---|---|---|
|
|
9d4d2f1ea8 | |
|
|
29b28a389e | |
|
|
6aa9a0658b |
|
|
@ -6,32 +6,16 @@ function formatCurrencyIDR(amount: number) {
|
||||||
return new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', maximumFractionDigits: 0 }).format(amount)
|
return new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', maximumFractionDigits: 0 }).format(amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
function useCountdown(expireAt: number) {
|
|
||||||
const [now, setNow] = React.useState(() => Date.now())
|
|
||||||
React.useEffect(() => {
|
|
||||||
const id = setInterval(() => setNow(Date.now()), 1000)
|
|
||||||
return () => clearInterval(id)
|
|
||||||
}, [])
|
|
||||||
const remainMs = Math.max(0, expireAt - now)
|
|
||||||
const totalSec = Math.floor(remainMs / 1000)
|
|
||||||
const hh = String(Math.floor(totalSec / 3600)).padStart(2, '0')
|
|
||||||
const mm = String(Math.floor((totalSec % 3600) / 60)).padStart(2, '0')
|
|
||||||
const ss = String(totalSec % 60).padStart(2, '0')
|
|
||||||
return `${hh}:${mm}:${ss}`
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PaymentSheetProps {
|
export interface PaymentSheetProps {
|
||||||
merchantName?: string
|
merchantName?: string
|
||||||
orderId: string
|
orderId: string
|
||||||
amount: number
|
amount: number
|
||||||
expireAt: number // epoch ms
|
|
||||||
customerName?: string
|
customerName?: string
|
||||||
children?: React.ReactNode
|
children?: React.ReactNode
|
||||||
showStatusCTA?: boolean
|
showStatusCTA?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export function PaymentSheet({ merchantName = 'Simaya', orderId, amount, expireAt, customerName, children, showStatusCTA = true }: PaymentSheetProps) {
|
export function PaymentSheet({ merchantName = 'Simaya', orderId, amount, customerName, children, showStatusCTA = true }: PaymentSheetProps) {
|
||||||
const countdown = useCountdown(expireAt)
|
|
||||||
const [expanded, setExpanded] = React.useState(true)
|
const [expanded, setExpanded] = React.useState(true)
|
||||||
return (
|
return (
|
||||||
<div className="max-w-md">
|
<div className="max-w-md">
|
||||||
|
|
|
||||||
|
|
@ -215,7 +215,6 @@ export function CheckoutPage() {
|
||||||
}
|
}
|
||||||
const orderId = orderIdRef.current
|
const orderId = orderIdRef.current
|
||||||
const amount = 3500000
|
const amount = 3500000
|
||||||
const expireAt = Date.now() + 59 * 60 * 1000 + 32 * 1000 // 00:59:32
|
|
||||||
const [selected, setSelected] = React.useState<PaymentMethod | null>(null)
|
const [selected, setSelected] = React.useState<PaymentMethod | null>(null)
|
||||||
const [currentStep, setCurrentStep] = React.useState<1 | 2>(1)
|
const [currentStep, setCurrentStep] = React.useState<1 | 2>(1)
|
||||||
const [isBusy, setIsBusy] = React.useState(false)
|
const [isBusy, setIsBusy] = React.useState(false)
|
||||||
|
|
@ -259,7 +258,7 @@ export function CheckoutPage() {
|
||||||
</Alert>
|
</Alert>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<PaymentSheet merchantName="Simaya" orderId={orderId} amount={amount} expireAt={expireAt} customerName={form.name} showStatusCTA={modalClosed}>
|
<PaymentSheet merchantName="Simaya" orderId={orderId} amount={amount} customerName={form.name} showStatusCTA={modalClosed}>
|
||||||
{/* Wizard 2 langkah: Step 1 (Form Dummy) → Step 2 (Payment - Snap/Core auto-detect) */}
|
{/* Wizard 2 langkah: Step 1 (Form Dummy) → Step 2 (Payment - Snap/Core auto-detect) */}
|
||||||
{currentStep === 1 && (
|
{currentStep === 1 && (
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
|
|
|
||||||
|
|
@ -241,7 +241,6 @@ export function PayPage() {
|
||||||
merchantName={merchantName}
|
merchantName={merchantName}
|
||||||
orderId={orderId || (token ?? '')}
|
orderId={orderId || (token ?? '')}
|
||||||
amount={amount}
|
amount={amount}
|
||||||
expireAt={expireAt}
|
|
||||||
showStatusCTA={false}
|
showStatusCTA={false}
|
||||||
>
|
>
|
||||||
<div className="space-y-4 px-4 py-6">
|
<div className="space-y-4 px-4 py-6">
|
||||||
|
|
@ -271,7 +270,6 @@ export function PayPage() {
|
||||||
merchantName={merchantName}
|
merchantName={merchantName}
|
||||||
orderId={orderId}
|
orderId={orderId}
|
||||||
amount={amount}
|
amount={amount}
|
||||||
expireAt={expireAt}
|
|
||||||
showStatusCTA={currentStep === 2}
|
showStatusCTA={currentStep === 2}
|
||||||
>
|
>
|
||||||
<div className="space-y-4 px-4 py-6">
|
<div className="space-y-4 px-4 py-6">
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ export function PaymentStatusPage() {
|
||||||
|
|
||||||
const statusText = data?.status ?? 'pending'
|
const statusText = data?.status ?? 'pending'
|
||||||
const isFinal = ['settlement', 'capture', 'expire', 'cancel', 'deny', 'refund', 'chargeback'].includes(statusText)
|
const isFinal = ['settlement', 'capture', 'expire', 'cancel', 'deny', 'refund', 'chargeback'].includes(statusText)
|
||||||
const isSuccess = statusText === 'settlement' || statusText === 'capture'
|
|
||||||
function sanitizeUrl(u?: string) {
|
function sanitizeUrl(u?: string) {
|
||||||
return (u || '').replace(/[`\s]+$/g, '').replace(/^\s+|\s+$/g, '').replace(/`/g, '')
|
return (u || '').replace(/[`\s]+$/g, '').replace(/^\s+|\s+$/g, '').replace(/`/g, '')
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue