Show transaction ID and gateway refs in order payment details.

Surface Meshkee transaction id, ZarinPal track/authority, card pan, and paid time in the transactions modal.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-10-02 22:15:12 +03:30
co-authored by Cursor
parent 016dd0b081
commit bc1c5f0747
4 changed files with 84 additions and 9 deletions
@@ -49,14 +49,34 @@
.txMeta { .txMeta {
display: grid; display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 6px 16px; gap: 8px 16px;
font-size: 12px; font-size: 12px;
color: var(--text-secondary); color: var(--text-secondary);
} }
.txMetaItem {
display: flex;
flex-direction: column;
gap: 2px;
min-width: 0;
}
.txMetaLabel {
font-size: 11px;
font-weight: 600;
color: var(--text-muted);
}
.txMetaItem strong { .txMetaItem strong {
color: var(--text-primary); color: var(--text-primary);
font-weight: 600; font-weight: 600;
word-break: break-all;
}
.txMono {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
font-size: 12px;
letter-spacing: 0.01em;
} }
.statusBadge { .statusBadge {
@@ -96,7 +96,12 @@ export function OrderTransactionsModal({ open, order, onClose }: OrderTransactio
if (!mounted || !order) return null if (!mounted || !order) return null
function transactionDetails(transaction: OrderTransaction) { function transactionDetails(transaction: OrderTransaction) {
const rows: { label: string; value: string; isStatus?: boolean }[] = [ const rows: { label: string; value: string; isStatus?: boolean; mono?: boolean }[] = [
{
label: t('orderTransactions.transactionId'),
value: transaction.id,
mono: true,
},
{ {
label: t('orderTransactions.status'), label: t('orderTransactions.status'),
value: t(STATUS_KEYS[transaction.status] ?? 'orderTransactions.status.pending'), value: t(STATUS_KEYS[transaction.status] ?? 'orderTransactions.status.pending'),
@@ -108,6 +113,13 @@ export function OrderTransactionsModal({ open, order, onClose }: OrderTransactio
}, },
] ]
if (transaction.paidAt) {
rows.push({
label: t('orderTransactions.paidAt'),
value: formatDateTime(transaction.paidAt, dateLocale),
})
}
if (transaction.type === 'pos' && transaction.posType) { if (transaction.type === 'pos' && transaction.posType) {
rows.push({ label: t('orderTransactions.posType'), value: transaction.posType }) rows.push({ label: t('orderTransactions.posType'), value: transaction.posType })
} }
@@ -116,11 +128,38 @@ export function OrderTransactionsModal({ open, order, onClose }: OrderTransactio
rows.push({ label: t('orderTransactions.account'), value: transaction.transferAccount }) rows.push({ label: t('orderTransactions.account'), value: transaction.transferAccount })
} }
if (transaction.transferRefNumber) { if (transaction.transferRefNumber) {
rows.push({ label: t('orderTransactions.refCode'), value: transaction.transferRefNumber }) rows.push({
label: t('orderTransactions.refCode'),
value: transaction.transferRefNumber,
mono: true,
})
} }
} }
if (transaction.type === 'e_payment_gate' && transaction.gatewayType) { if (transaction.type === 'e_payment_gate') {
rows.push({ label: t('orderTransactions.gateway'), value: transaction.gatewayType }) if (transaction.gatewayType) {
rows.push({ label: t('orderTransactions.gateway'), value: transaction.gatewayType })
}
if (transaction.gatewayTrackId) {
rows.push({
label: t('orderTransactions.gatewayTrackId'),
value: transaction.gatewayTrackId,
mono: true,
})
}
if (transaction.gatewayRef) {
rows.push({
label: t('orderTransactions.gatewayRef'),
value: transaction.gatewayRef,
mono: true,
})
}
if (transaction.cardPan) {
rows.push({
label: t('orderTransactions.cardPan'),
value: transaction.cardPan,
mono: true,
})
}
} }
if (transaction.notes) { if (transaction.notes) {
rows.push({ label: t('orderTransactions.notes'), value: transaction.notes }) rows.push({ label: t('orderTransactions.notes'), value: transaction.notes })
@@ -176,13 +215,15 @@ export function OrderTransactionsModal({ open, order, onClose }: OrderTransactio
<div className={styles.txMeta}> <div className={styles.txMeta}>
{details.map((detail) => ( {details.map((detail) => (
<div key={detail.label} className={styles.txMetaItem}> <div key={detail.label} className={styles.txMetaItem}>
{detail.label}:{' '} <span className={styles.txMetaLabel}>{detail.label}</span>
{detail.isStatus ? ( {detail.isStatus ? (
<span className={`${styles.statusBadge} ${statusClass(transaction.status)}`}> <span className={`${styles.statusBadge} ${statusClass(transaction.status)}`}>
{detail.value} {detail.value}
</span> </span>
) : ( ) : (
<strong>{detail.value}</strong> <strong className={detail.mono ? styles.txMono : undefined}>
{detail.value}
</strong>
)} )}
</div> </div>
))} ))}
+12 -2
View File
@@ -1296,12 +1296,17 @@ const en = {
'orderTransactions.title': 'Transaction details', 'orderTransactions.title': 'Transaction details',
'orderTransactions.empty': 'No payment transactions recorded for this order.', 'orderTransactions.empty': 'No payment transactions recorded for this order.',
'orderTransactions.transactionId': 'Transaction ID',
'orderTransactions.status': 'Status', 'orderTransactions.status': 'Status',
'orderTransactions.date': 'Date', 'orderTransactions.date': 'Created',
'orderTransactions.paidAt': 'Paid at',
'orderTransactions.posType': 'POS type', 'orderTransactions.posType': 'POS type',
'orderTransactions.account': 'Account number', 'orderTransactions.account': 'Account number',
'orderTransactions.refCode': 'Ref code', 'orderTransactions.refCode': 'Ref code',
'orderTransactions.gateway': 'Gateway', 'orderTransactions.gateway': 'Gateway',
'orderTransactions.gatewayTrackId': 'Gateway tracking ID',
'orderTransactions.gatewayRef': 'Gateway authority / ref',
'orderTransactions.cardPan': 'Card number',
'orderTransactions.notes': 'Notes', 'orderTransactions.notes': 'Notes',
'orderTransactions.summary': '{count} {txLabel}', 'orderTransactions.summary': '{count} {txLabel}',
'orderTransactions.one': 'transaction', 'orderTransactions.one': 'transaction',
@@ -4171,12 +4176,17 @@ const fa: Record<MessageKey, string> = {
'orderTransactions.title': 'جزئیات تراکنش', 'orderTransactions.title': 'جزئیات تراکنش',
'orderTransactions.empty': 'تراکنش پرداختی برای این سفارش ثبت نشده است.', 'orderTransactions.empty': 'تراکنش پرداختی برای این سفارش ثبت نشده است.',
'orderTransactions.transactionId': 'شناسه تراکنش',
'orderTransactions.status': 'وضعیت', 'orderTransactions.status': 'وضعیت',
'orderTransactions.date': 'تاریخ', 'orderTransactions.date': 'زمان ایجاد',
'orderTransactions.paidAt': 'زمان پرداخت',
'orderTransactions.posType': 'نوع کارتخوان', 'orderTransactions.posType': 'نوع کارتخوان',
'orderTransactions.account': 'شماره حساب', 'orderTransactions.account': 'شماره حساب',
'orderTransactions.refCode': 'کد پیگیری', 'orderTransactions.refCode': 'کد پیگیری',
'orderTransactions.gateway': 'درگاه', 'orderTransactions.gateway': 'درگاه',
'orderTransactions.gatewayTrackId': 'کد پیگیری درگاه',
'orderTransactions.gatewayRef': 'کد مرجع / Authority',
'orderTransactions.cardPan': 'شماره کارت',
'orderTransactions.notes': 'یادداشت', 'orderTransactions.notes': 'یادداشت',
'orderTransactions.summary': '{count} {txLabel}', 'orderTransactions.summary': '{count} {txLabel}',
'orderTransactions.one': 'تراکنش', 'orderTransactions.one': 'تراکنش',
@@ -49,6 +49,10 @@ export interface OrderTransaction {
amount: number amount: number
posType: string | null posType: string | null
gatewayType: string | null gatewayType: string | null
gatewayRef: string | null
gatewayTrackId: string | null
cardPan: string | null
paidAt: string | null
transferAccount: string | null transferAccount: string | null
transferRefNumber: string | null transferRefNumber: string | null
notes: string | null notes: string | null