> ## Documentation Index
> Fetch the complete documentation index at: https://doc2.payloco.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Acquiring Basic Products

> Browse and filter all supported payment methods, regional coverage, and integration capabilities

export const PaymentMethodTable = () => {
  var OSS_URL = 'https://img-cdn-loco.payloco.com/json/all.json';
  var REGION_MAP = {
    AE: '中东',
    BH: '中东',
    EG: '中东',
    JO: '中东',
    KW: '中东',
    LB: '中东',
    OM: '中东',
    QA: '中东',
    SA: '中东',
    SY: '中东',
    YE: '中东',
    AR: '拉美',
    BR: '拉美',
    CL: '拉美',
    CO: '拉美',
    MX: '拉美',
    PE: '拉美',
    UY: '拉美',
    BO: '拉美',
    PY: '拉美',
    EC: '拉美',
    NG: '非洲',
    ZA: '非洲',
    KE: '非洲',
    GH: '非洲',
    TZ: '非洲',
    UG: '非洲',
    SN: '非洲',
    CI: '非洲',
    CM: '非洲',
    IN: '南亚',
    PK: '南亚',
    BD: '南亚',
    LK: '南亚',
    PH: '东南亚',
    ID: '东南亚',
    MY: '东南亚',
    TH: '东南亚',
    VN: '东南亚',
    SG: '东南亚',
    MM: '东南亚',
    KH: '东南亚',
    AT: '欧洲',
    BE: '欧洲',
    DE: '欧洲',
    ES: '欧洲',
    FR: '欧洲',
    GB: '欧洲',
    IT: '欧洲',
    NL: '欧洲',
    PL: '欧洲',
    PT: '欧洲',
    SE: '欧洲',
    CH: '欧洲',
    NO: '欧洲',
    DK: '欧洲',
    FI: '欧洲',
    US: '北美',
    CA: '北美',
    AU: '大洋洲',
    NZ: '大洋洲',
    TR: '中东欧',
    RU: '中东欧'
  };
  var COUNTRY_NAME = {
    AE: '阿联酋',
    BH: '巴林',
    EG: '埃及',
    JO: '约旦',
    KW: '科威特',
    LB: '黎巴嫩',
    OM: '阿曼',
    QA: '卡塔尔',
    SA: '沙特阿拉伯',
    SY: '叙利亚',
    YE: '也门',
    AR: '阿根廷',
    BR: '巴西',
    CL: '智利',
    CO: '哥伦比亚',
    MX: '墨西哥',
    PE: '秘鲁',
    UY: '乌拉圭',
    BO: '玻利维亚',
    PY: '巴拉圭',
    EC: '厄瓜多尔',
    NG: '尼日利亚',
    ZA: '南非',
    KE: '肯尼亚',
    GH: '加纳',
    TZ: '坦桑尼亚',
    UG: '乌干达',
    SN: '塞内加尔',
    CI: '科特迪瓦',
    CM: '喀麦隆',
    IN: '印度',
    PK: '巴基斯坦',
    BD: '孟加拉国',
    LK: '斯里兰卡',
    PH: '菲律宾',
    ID: '印度尼西亚',
    MY: '马来西亚',
    TH: '泰国',
    VN: '越南',
    SG: '新加坡',
    MM: '缅甸',
    KH: '柬埔寨',
    AT: '奥地利',
    BE: '比利时',
    DE: '德国',
    ES: '西班牙',
    FR: '法国',
    GB: '英国',
    IT: '意大利',
    NL: '荷兰',
    PL: '波兰',
    PT: '葡萄牙',
    SE: '瑞典',
    CH: '瑞士',
    NO: '挪威',
    DK: '丹麦',
    FI: '芬兰',
    US: '美国',
    CA: '加拿大',
    AU: '澳大利亚',
    NZ: '新西兰',
    TR: '土耳其',
    RU: '俄罗斯'
  };
  var IM_LABEL = {
    DIRECT_API: '纯API',
    HOSTED_CASHIER: '收银台',
    PAYMENT_LINK: '链接支付',
    DROP_IN: '前置组件'
  };
  var CAPS = [{
    key: 'refund',
    label: '退款'
  }, {
    key: 'partialRefund',
    label: '部分退款'
  }, {
    key: 'pmxToken',
    label: 'Token支付'
  }, {
    key: 'authCapture',
    label: 'AuthCapture'
  }];
  var IMS = ['DIRECT_API', 'HOSTED_CASHIER', 'PAYMENT_LINK', 'DROP_IN'];
  var PAGE_SIZE = 20;
  var sd = React.useState(null);
  var allData = sd[0];
  var setAllData = sd[1];
  var sl = React.useState(true);
  var loading = sl[0];
  var setLoading = sl[1];
  var se = React.useState('');
  var fetchErr = se[0];
  var setFetchErr = se[1];
  var fetchedRef = React.useRef(false);
  React.useEffect(function () {
    if (fetchedRef.current) return;
    fetchedRef.current = true;
    fetch(OSS_URL).then(function (r) {
      return r.json();
    }).then(function (j) {
      setAllData(j.data || j);
      setLoading(false);
    }).catch(function (e) {
      setFetchErr(e.message);
      setLoading(false);
    });
  }, []);
  var sth = React.useState(false);
  var isDark = sth[0];
  var setIsDark = sth[1];
  React.useEffect(function () {
    function check() {
      setIsDark(document.documentElement.classList.contains('dark'));
    }
    check();
    var obs = new MutationObserver(check);
    obs.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ['class']
    });
    return function () {
      obs.disconnect();
    };
  }, []);
  var c = isDark ? {
    panelBg: '#1e2433',
    panelBorder: '#2d3748',
    tableBg: '#141921',
    headerBg: '#1a2030',
    headerBorder: '#2d3748',
    rowEven: '#141921',
    rowOdd: '#181f2e',
    rowBorder: '#1e2433',
    textPrimary: '#e5e7eb',
    textSecondary: '#9ca3af',
    textMuted: '#6b7280',
    border: '#2d3748',
    inputBg: '#1e2433',
    inputBorder: '#374151',
    inputColor: '#e5e7eb',
    dropdownBg: '#1a2030',
    dropdownBorder: '#2d3748',
    selectedBg: '#2d1b69',
    selectedColor: '#a78bfa',
    badgeBg: '#2d1b69',
    badgeColor: '#a78bfa',
    btnBg: '#1e2433',
    btnColor: '#9ca3af',
    btnDisabledBg: '#141921',
    resetBg: '#1e2433',
    resetColor: '#9ca3af',
    resetBorder: '#374151',
    primary: '#7c3aed',
    tooltipBg: '#0d1117',
    tooltipBorder: '#2d3748',
    countColor: '#9ca3af',
    countStrong: '#e5e7eb',
    shadow: '0 8px 24px rgba(0,0,0,0.5)'
  } : {
    panelBg: '#f9fafb',
    panelBorder: '#e5e7eb',
    tableBg: 'white',
    headerBg: '#f9fafb',
    headerBorder: '#e5e7eb',
    rowEven: 'white',
    rowOdd: '#fafafa',
    rowBorder: '#f3f4f6',
    textPrimary: '#374151',
    textSecondary: '#6b7280',
    textMuted: '#9ca3af',
    border: '#e5e7eb',
    inputBg: 'white',
    inputBorder: '#e5e7eb',
    inputColor: '#374151',
    dropdownBg: 'white',
    dropdownBorder: '#e5e7eb',
    selectedBg: '#f3f0ff',
    selectedColor: '#612FFF',
    badgeBg: '#f3f0ff',
    badgeColor: '#612FFF',
    btnBg: 'white',
    btnColor: '#374151',
    btnDisabledBg: '#f9fafb',
    resetBg: 'white',
    resetColor: '#6b7280',
    resetBorder: '#d1d5db',
    primary: '#612FFF',
    tooltipBg: '#1e293b',
    tooltipBorder: 'transparent',
    countColor: '#6b7280',
    countStrong: '#111827',
    shadow: '0 8px 24px rgba(0,0,0,0.12)'
  };
  var s1 = React.useState('');
  var filterRegion = s1[0];
  var setFilterRegion = s1[1];
  var s2 = React.useState('');
  var filterCountry = s2[0];
  var setFilterCountry = s2[1];
  var s3 = React.useState('');
  var filterType = s3[0];
  var setFilterType = s3[1];
  var s4 = React.useState('');
  var filterMethod = s4[0];
  var setFilterMethod = s4[1];
  var s5 = React.useState('');
  var filterCurrency = s5[0];
  var setFilterCurrency = s5[1];
  var s6 = React.useState('');
  var filterCap = s6[0];
  var setFilterCap = s6[1];
  var s7 = React.useState('');
  var filterIM = s7[0];
  var setFilterIM = s7[1];
  var sp = React.useState(1);
  var page = sp[0];
  var setPage = sp[1];
  var stt = React.useState(null);
  var tooltip = stt[0];
  var setTooltip = stt[1];
  var sct = React.useState(null);
  var currTooltip = sct[0];
  var setCurrTooltip = sct[1];
  var so1 = React.useState(false);
  var open1 = so1[0];
  var setOpen1 = so1[1];
  var ss1 = React.useState('');
  var srch1 = ss1[0];
  var setSrch1 = ss1[1];
  var so2 = React.useState(false);
  var open2 = so2[0];
  var setOpen2 = so2[1];
  var ss2 = React.useState('');
  var srch2 = ss2[0];
  var setSrch2 = ss2[1];
  var so3 = React.useState(false);
  var open3 = so3[0];
  var setOpen3 = so3[1];
  var ss3 = React.useState('');
  var srch3 = ss3[0];
  var setSrch3 = ss3[1];
  var so4 = React.useState(false);
  var open4 = so4[0];
  var setOpen4 = so4[1];
  var ss4 = React.useState('');
  var srch4 = ss4[0];
  var setSrch4 = ss4[1];
  var so5 = React.useState(false);
  var open5 = so5[0];
  var setOpen5 = so5[1];
  var ss5 = React.useState('');
  var srch5 = ss5[0];
  var setSrch5 = ss5[1];
  var so6 = React.useState(false);
  var open6 = so6[0];
  var setOpen6 = so6[1];
  var ss6 = React.useState('');
  var srch6 = ss6[0];
  var setSrch6 = ss6[1];
  var so7 = React.useState(false);
  var open7 = so7[0];
  var setOpen7 = so7[1];
  var ss7 = React.useState('');
  var srch7 = ss7[0];
  var setSrch7 = ss7[1];
  function searchSelect(props) {
    var value = props.value, onChange = props.onChange, options = props.options;
    var placeholder = props.placeholder, open = props.open, setOpen = props.setOpen;
    var search = props.search, setSearch = props.setSearch;
    var displayOpts = options.filter(function (o) {
      var q = (search || '').toLowerCase();
      return (o.label || '').toLowerCase().indexOf(q) !== -1 || (o.value || '').toLowerCase().indexOf(q) !== -1;
    });
    var currentLabel = placeholder;
    for (var i = 0; i < options.length; i++) {
      if (options[i].value === value) {
        currentLabel = options[i].label;
        break;
      }
    }
    function pick(v) {
      onChange(v);
      setOpen(false);
      setSearch('');
    }
    return <div style={{
      position: 'relative',
      display: 'inline-block'
    }}>
        <div onClick={function () {
      setOpen(!open);
    }} style={{
      padding: '7px 10px',
      border: '1px solid ' + c.border,
      borderRadius: '8px',
      background: c.btnBg,
      fontSize: '13px',
      cursor: 'pointer',
      color: value ? c.textPrimary : c.textMuted,
      minWidth: '130px',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'space-between',
      gap: '6px',
      userSelect: 'none'
    }}>
          <span style={{
      flex: 1,
      overflow: 'hidden',
      textOverflow: 'ellipsis',
      whiteSpace: 'nowrap',
      textAlign: 'left'
    }}>{currentLabel}</span>
          <span style={{
      color: c.textMuted,
      fontSize: '10px',
      flexShrink: 0
    }}>{open ? '▲' : '▼'}</span>
        </div>
        {open ? <div>
            <div onClick={function () {
      pick('');
    }} style={{
      position: 'fixed',
      top: 0,
      left: 0,
      right: 0,
      bottom: 0,
      zIndex: 9998
    }} />
            <div style={{
      position: 'absolute',
      top: 'calc(100% + 4px)',
      left: 0,
      zIndex: 9999,
      background: c.dropdownBg,
      border: '1px solid ' + c.dropdownBorder,
      borderRadius: '10px',
      boxShadow: c.shadow,
      minWidth: '160px',
      overflow: 'hidden'
    }}>
              <div style={{
      padding: '8px 8px 4px'
    }}>
                <input value={search} onChange={function (e) {
      setSearch(e.target.value);
    }} placeholder="搜索..." style={{
      width: '100%',
      padding: '6px 10px',
      border: '1px solid ' + c.inputBorder,
      borderRadius: '6px',
      fontSize: '12px',
      outline: 'none',
      boxSizing: 'border-box',
      color: c.inputColor,
      background: c.inputBg
    }} />
              </div>
              <div style={{
      overflowY: 'auto',
      maxHeight: '200px'
    }}>
                <div onClick={function () {
      pick('');
    }} style={{
      padding: '8px 14px',
      cursor: 'pointer',
      color: c.textMuted,
      fontSize: '13px',
      background: value === '' ? c.selectedBg : 'transparent'
    }}>{placeholder}</div>
                {displayOpts.map(function (o) {
      return <div key={o.value} onClick={function () {
        pick(o.value);
      }} style={{
        padding: '8px 14px',
        cursor: 'pointer',
        fontSize: '13px',
        background: o.value === value ? c.selectedBg : 'transparent',
        color: o.value === value ? c.selectedColor : c.textPrimary
      }}>{o.label}</div>;
    })}
                {displayOpts.length === 0 ? <div style={{
      padding: '12px 14px',
      color: c.textMuted,
      fontSize: '13px'
    }}>无匹配结果</div> : null}
              </div>
            </div>
          </div> : null}
      </div>;
  }
  function getName(d) {
    if (d.targetOrg && d.targetOrg !== '*') return d.targetOrg;
    if (d.cardOrg) return d.cardOrg;
    return d.paymentMethodType;
  }
  function isOk(v) {
    return v === '1' || v === 'Y';
  }
  function fmtTime(s) {
    var n = parseInt(s) || 0;
    if (n >= 86400) return Math.round(n / 86400) + ' 天';
    if (n >= 3600) return Math.round(n / 3600) + ' 小时';
    if (n >= 60) return Math.round(n / 60) + ' 分钟';
    return n + ' 秒';
  }
  function fmtLimits(limits) {
    if (!limits || !limits.length) return '';
    return limits.map(function (l) {
      return l.limitValue + ' ' + l.currency;
    }).join(' / ');
  }
  var loadStyle = {
    padding: '60px',
    textAlign: 'center',
    fontSize: '14px',
    color: c.textMuted
  };
  if (loading) return <div style={loadStyle}>
      <div style={{
    fontSize: '24px',
    marginBottom: '12px'
  }}>⏳</div>
      <div>数据加载中...</div>
    </div>;
  if (fetchErr) return <div style={{
    padding: '40px',
    textAlign: 'center',
    fontSize: '13px',
    color: '#dc2626',
    background: 'rgba(220,38,38,0.06)',
    borderRadius: '12px',
    border: '1px solid rgba(220,38,38,0.2)'
  }}>
      <div style={{
    fontWeight: '600',
    marginBottom: '8px'
  }}>数据加载失败</div>
      <div style={{
    color: c.textMuted,
    marginBottom: '12px'
  }}>{fetchErr}</div>
      <div style={{
    fontSize: '12px',
    color: c.textMuted
  }}>请确认 OSS 已配置 CORS 跨域规则，允许当前域名访问。</div>
    </div>;
  if (!allData || !allData.length) return <div style={loadStyle}>暂无数据</div>;
  var allRegions = Array.from(new Set(allData.map(function (d) {
    return REGION_MAP[d.country] || '其他';
  }))).sort();
  var allCountries = Array.from(new Set(allData.map(function (d) {
    return d.country;
  }))).sort();
  var allTypes = Array.from(new Set(allData.map(function (d) {
    return d.paymentMethodType;
  }))).sort();
  var allMethods = Array.from(new Set(allData.map(getName))).filter(Boolean).sort();
  var allCurrencies = Array.from(new Set(allData.reduce(function (a, d) {
    return a.concat(d.currencies || []);
  }, []))).sort();
  var filtered = allData.filter(function (d) {
    if (filterRegion && (REGION_MAP[d.country] || '其他') !== filterRegion) return false;
    if (filterCountry && d.country !== filterCountry) return false;
    if (filterType && d.paymentMethodType !== filterType) return false;
    if (filterMethod && getName(d) !== filterMethod) return false;
    if (filterCurrency && (d.currencies || []).indexOf(filterCurrency) === -1) return false;
    if (filterCap && !isOk(d[filterCap])) return false;
    if (filterIM && (d.integrationMode || []).indexOf(filterIM) === -1) return false;
    return true;
  });
  var totalPages = Math.max(1, Math.ceil(filtered.length / PAGE_SIZE));
  var safePage = Math.min(page, totalPages);
  var pageData = filtered.slice((safePage - 1) * PAGE_SIZE, safePage * PAGE_SIZE);
  function applyFilter(setter) {
    return function (v) {
      setter(v);
      setPage(1);
    };
  }
  function resetFilters() {
    setFilterRegion('');
    setFilterCountry('');
    setFilterType('');
    setFilterMethod('');
    setFilterCurrency('');
    setFilterCap('');
    setFilterIM('');
    setPage(1);
  }
  function exportCSV() {
    var h = ['支付方式类型', '支付方式', '国家/地区', '所属区域', '支付币种', '限额', '关单时间', '退款', '部分退款', 'Token支付', 'AuthCapture', '纯API', '收银台', '链接支付', '前置组件'];
    var rows = filtered.map(function (d) {
      var modes = d.integrationMode || [];
      return [d.paymentMethodType, getName(d), COUNTRY_NAME[d.country] || d.country, REGION_MAP[d.country] || '其他', (d.currencies || []).join('/'), fmtLimits(d.limits), fmtTime(d.closeOrderTime), isOk(d.refund) ? '支持' : '不支持', isOk(d.partialRefund) ? '支持' : '不支持', isOk(d.pmxToken) ? '支持' : '不支持', isOk(d.authCapture) ? '支持' : '不支持', modes.indexOf('DIRECT_API') !== -1 ? '支持' : '不支持', modes.indexOf('HOSTED_CASHIER') !== -1 ? '支持' : '不支持', modes.indexOf('PAYMENT_LINK') !== -1 ? '支持' : '不支持', modes.indexOf('DROP_IN') !== -1 ? '支持' : '不支持'];
    });
    var lines = [h].concat(rows).map(function (r) {
      return r.map(function (cell) {
        return '"' + String(cell).replace(/"/g, '""') + '"';
      }).join(',');
    });
    var blob = new Blob(['﻿' + lines.join('\n')], {
      type: 'text/csv;charset=utf-8;'
    });
    var url = URL.createObjectURL(blob);
    var a = document.createElement('a');
    a.href = url;
    a.download = '支付能力.csv';
    a.click();
    URL.revokeObjectURL(url);
  }
  var hasFilter = filterRegion || filterCountry || filterType || filterMethod || filterCurrency || filterCap || filterIM;
  var thStyle = {
    padding: '10px 16px',
    textAlign: 'left',
    fontWeight: '600',
    color: c.textSecondary,
    whiteSpace: 'nowrap',
    fontSize: '12px',
    borderBottom: '2px solid ' + c.headerBorder
  };
  var tdBase = {
    padding: '10px 16px',
    verticalAlign: 'middle',
    color: c.textPrimary,
    whiteSpace: 'nowrap'
  };
  var disabledPrev = safePage <= 1, disabledNext = safePage >= totalPages;
  var pbtn = function (dis) {
    return {
      padding: '6px 12px',
      border: '1px solid ' + c.border,
      borderRadius: '6px',
      background: dis ? c.btnDisabledBg : c.btnBg,
      cursor: dis ? 'default' : 'pointer',
      fontSize: '13px',
      color: dis ? c.textMuted : c.textPrimary
    };
  };
  var regionOpts = allRegions.map(function (r) {
    return {
      value: r,
      label: r
    };
  });
  var countryOpts = allCountries.map(function (ct) {
    return {
      value: ct,
      label: (COUNTRY_NAME[ct] || ct) + ' (' + ct + ')'
    };
  });
  var typeOpts = allTypes.map(function (t) {
    return {
      value: t,
      label: t
    };
  });
  var methodOpts = allMethods.map(function (m) {
    return {
      value: m,
      label: m
    };
  });
  var currencyOpts = allCurrencies.map(function (cu) {
    return {
      value: cu,
      label: cu
    };
  });
  var capOpts = CAPS.map(function (cp) {
    return {
      value: cp.key,
      label: cp.label
    };
  });
  var imOpts = IMS.map(function (i) {
    return {
      value: i,
      label: IM_LABEL[i]
    };
  });
  return <div style={{
    fontFamily: 'system-ui,sans-serif',
    padding: '2px 0 24px 0'
  }}>

      {tooltip ? <div style={{
    position: 'fixed',
    left: tooltip.x,
    top: tooltip.y,
    zIndex: 99999,
    background: c.tooltipBg,
    color: '#e5e7eb',
    borderRadius: '10px',
    padding: '12px 16px',
    fontSize: '12px',
    lineHeight: '1.9',
    pointerEvents: 'none',
    boxShadow: '0 8px 24px rgba(0,0,0,0.4)',
    maxWidth: '280px',
    border: '1px solid ' + c.tooltipBorder
  }}>
          <div style={{
    fontWeight: '700',
    marginBottom: '6px',
    color: '#94a3b8',
    fontSize: '11px',
    letterSpacing: '0.05em'
  }}>API PARAMS</div>
          <div><span style={{
    color: '#94a3b8'
  }}>Country: </span>{tooltip.d.country}</div>
          <div><span style={{
    color: '#94a3b8'
  }}>paymentMethodType: </span>{tooltip.d.paymentMethodType}</div>
          <div><span style={{
    color: '#94a3b8'
  }}>targetOrg: </span>{tooltip.d.targetOrg !== '*' ? tooltip.d.targetOrg : ''}</div>
          <div><span style={{
    color: '#94a3b8'
  }}>allowedCardOrg: </span>{tooltip.d.cardOrg || ''}</div>
        </div> : null}

      {currTooltip ? <div style={{
    position: 'fixed',
    left: currTooltip.x,
    top: currTooltip.y,
    zIndex: 99999,
    background: c.tooltipBg,
    color: '#e5e7eb',
    borderRadius: '10px',
    padding: '12px 14px',
    fontSize: '12px',
    pointerEvents: 'none',
    boxShadow: '0 8px 24px rgba(0,0,0,0.4)',
    maxWidth: '260px',
    border: '1px solid ' + c.tooltipBorder
  }}>
          <div style={{
    fontWeight: '700',
    marginBottom: '8px',
    color: '#94a3b8',
    fontSize: '11px',
    letterSpacing: '0.05em'
  }}>支付币种（共 {currTooltip.currencies.length} 种）</div>
          <div style={{
    display: 'flex',
    flexWrap: 'wrap',
    gap: '5px'
  }}>
            {currTooltip.currencies.map(function (cu) {
    return <span key={cu} style={{
      padding: '2px 8px',
      background: 'rgba(124,58,237,0.25)',
      color: '#c4b5fd',
      borderRadius: '4px',
      fontSize: '11px',
      fontWeight: '600'
    }}>{cu}</span>;
  })}
          </div>
        </div> : null}

      {}
      <div style={{
    background: c.panelBg,
    border: '1px solid ' + c.panelBorder,
    borderRadius: '12px',
    padding: '20px 24px',
    marginBottom: '16px'
  }}>
        <div style={{
    display: 'flex',
    flexWrap: 'wrap',
    gap: '10px',
    marginBottom: '12px'
  }}>
          {searchSelect({
    value: filterRegion,
    onChange: applyFilter(setFilterRegion),
    options: regionOpts,
    placeholder: '所属区域',
    open: open1,
    setOpen: setOpen1,
    search: srch1,
    setSearch: setSrch1
  })}
          {searchSelect({
    value: filterCountry,
    onChange: applyFilter(setFilterCountry),
    options: countryOpts,
    placeholder: '国家/地区',
    open: open2,
    setOpen: setOpen2,
    search: srch2,
    setSearch: setSrch2
  })}
          {searchSelect({
    value: filterType,
    onChange: applyFilter(setFilterType),
    options: typeOpts,
    placeholder: '支付方式类型',
    open: open3,
    setOpen: setOpen3,
    search: srch3,
    setSearch: setSrch3
  })}
          {searchSelect({
    value: filterMethod,
    onChange: applyFilter(setFilterMethod),
    options: methodOpts,
    placeholder: '支付方式',
    open: open4,
    setOpen: setOpen4,
    search: srch4,
    setSearch: setSrch4
  })}
          {searchSelect({
    value: filterCurrency,
    onChange: applyFilter(setFilterCurrency),
    options: currencyOpts,
    placeholder: '币种',
    open: open5,
    setOpen: setOpen5,
    search: srch5,
    setSearch: setSrch5
  })}
          {searchSelect({
    value: filterCap,
    onChange: applyFilter(setFilterCap),
    options: capOpts,
    placeholder: '相关能力',
    open: open6,
    setOpen: setOpen6,
    search: srch6,
    setSearch: setSrch6
  })}
          {searchSelect({
    value: filterIM,
    onChange: applyFilter(setFilterIM),
    options: imOpts,
    placeholder: '集成模式',
    open: open7,
    setOpen: setOpen7,
    search: srch7,
    setSearch: setSrch7
  })}
        </div>
        <div style={{
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    flexWrap: 'wrap',
    gap: '10px'
  }}>
          <div>{hasFilter ? <button onClick={resetFilters} style={{
    padding: '7px 14px',
    border: '1px solid ' + c.resetBorder,
    borderRadius: '8px',
    background: c.resetBg,
    color: c.resetColor,
    cursor: 'pointer',
    fontSize: '13px'
  }}>重置筛选</button> : null}</div>
          <div style={{
    display: 'flex',
    alignItems: 'center',
    gap: '12px'
  }}>
            <span style={{
    fontSize: '13px',
    color: c.countColor
  }}>共 <strong style={{
    color: c.countStrong
  }}>{filtered.length}</strong> 条</span>
            <button onClick={exportCSV} style={{
    padding: '7px 18px',
    background: c.primary,
    color: 'white',
    border: 'none',
    borderRadius: '8px',
    cursor: 'pointer',
    fontSize: '13px',
    fontWeight: '600'
  }}>导出 CSV</button>
          </div>
        </div>
      </div>

      {}
      <div style={{
    border: '1px solid ' + c.panelBorder,
    borderRadius: '12px',
    overflow: 'hidden'
  }}>
        <div style={{
    overflowX: 'auto',
    background: c.tableBg
  }}>
          <table style={{
    width: '100%',
    fontSize: '13px',
    tableLayout: 'auto'
  }}>
            <thead>
              <tr style={{
    background: c.headerBg
  }}>
                <th style={thStyle}>支付方式类型</th>
                <th style={thStyle}>
                  <div>支付方式</div>
                  <div style={{
    fontWeight: '400',
    fontSize: '10px',
    color: c.textMuted,
    marginTop: '2px',
    whiteSpace: 'normal'
  }}>悬停图标可查看 API 参数</div>
                </th>
                <th style={thStyle}>国家/地区</th>
                <th style={thStyle}>所属区域</th>
                <th style={thStyle}>支付币种</th>
                <th style={thStyle}>限额</th>
                <th style={thStyle}>关单时间</th>
                <th style={thStyle}>相关能力</th>
                <th style={thStyle}>集成模式</th>
              </tr>
            </thead>
            <tbody>
              {pageData.map(function (d, i) {
    var modes = d.integrationMode || [];
    var bg = i % 2 === 0 ? c.rowEven : c.rowOdd;
    var curs = d.currencies || [];
    return <tr key={d.id || i} style={{
      borderBottom: '1px solid ' + c.rowBorder,
      background: bg
    }}>
                    <td style={tdBase}>
                      <span style={{
      display: 'inline-block',
      padding: '3px 8px',
      background: c.badgeBg,
      color: c.badgeColor,
      borderRadius: '5px',
      fontSize: '11px',
      fontWeight: '600'
    }}>{d.paymentMethodType}</span>
                    </td>
                    <td style={{
      padding: '10px 16px',
      verticalAlign: 'middle'
    }}>
                      <div style={{
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'flex-start',
      gap: '4px',
      minWidth: '80px',
      cursor: 'pointer'
    }} onMouseEnter={function (e) {
      var rect = e.currentTarget.getBoundingClientRect();
      setTooltip({
        d: d,
        x: rect.right + 10,
        y: rect.top
      });
    }} onMouseLeave={function () {
      setTooltip(null);
    }}>
                        {d.logoUrl ? <img src={d.logoUrl} alt={getName(d)} style={{
      height: '26px',
      maxWidth: '90px',
      objectFit: 'contain',
      filter: isDark ? 'brightness(0.9)' : ''
    }} onError={function (e) {
      e.target.style.display = 'none';
    }} /> : null}
                        <span style={{
      fontWeight: '600',
      fontSize: '12px',
      color: c.textPrimary
    }}>{getName(d)}</span>
                      </div>
                    </td>
                    <td style={tdBase}>{COUNTRY_NAME[d.country] || d.country}</td>
                    <td style={tdBase}>{REGION_MAP[d.country] || '其他'}</td>
                    <td style={tdBase}>
                      {curs.length > 1 ? <span onMouseEnter={function (e) {
      var rect = e.currentTarget.getBoundingClientRect();
      setCurrTooltip({
        currencies: curs,
        x: rect.left,
        y: rect.bottom + 6
      });
    }} onMouseLeave={function () {
      setCurrTooltip(null);
    }} style={{
      cursor: 'help',
      display: 'inline-flex',
      alignItems: 'center',
      gap: '5px'
    }}>
                          <span>{curs[0]}</span>
                          <span style={{
      padding: '1px 6px',
      background: c.badgeBg,
      color: c.badgeColor,
      borderRadius: '4px',
      fontSize: '11px',
      fontWeight: '600'
    }}>+{curs.length - 1}</span>
                        </span> : <span>{curs[0] || ''}</span>}
                    </td>
                    <td style={{
      padding: '10px 16px',
      verticalAlign: 'middle',
      color: c.textPrimary,
      whiteSpace: 'nowrap'
    }}>{fmtLimits(d.limits)}</td>
                    <td style={tdBase}>{fmtTime(d.closeOrderTime)}</td>
                    <td style={{
      padding: '10px 16px',
      verticalAlign: 'middle'
    }}>
                      <div style={{
      display: 'flex',
      flexWrap: 'wrap',
      gap: '4px',
      minWidth: '130px'
    }}>
                        {CAPS.map(function (cap) {
      var ok = isOk(d[cap.key]);
      return <span key={cap.key} style={{
        display: 'inline-flex',
        alignItems: 'center',
        gap: '3px',
        padding: '2px 7px',
        borderRadius: '4px',
        fontSize: '11px',
        fontWeight: '500',
        background: ok ? 'rgba(34,197,94,0.12)' : 'rgba(248,113,113,0.10)',
        color: ok ? '#16a34a' : '#dc2626',
        whiteSpace: 'nowrap'
      }}><span style={{
        fontWeight: '700'
      }}>{ok ? '✓' : '✗'}</span>{cap.label}</span>;
    })}
                      </div>
                    </td>
                    <td style={{
      padding: '10px 16px',
      verticalAlign: 'middle'
    }}>
                      <div style={{
      display: 'flex',
      flexWrap: 'wrap',
      gap: '4px',
      minWidth: '130px'
    }}>
                        {IMS.map(function (mode) {
      var ok = modes.indexOf(mode) !== -1;
      return <span key={mode} style={{
        display: 'inline-flex',
        alignItems: 'center',
        gap: '3px',
        padding: '2px 7px',
        borderRadius: '4px',
        fontSize: '11px',
        fontWeight: '500',
        background: ok ? 'rgba(34,197,94,0.12)' : 'rgba(248,113,113,0.10)',
        color: ok ? '#16a34a' : '#dc2626',
        whiteSpace: 'nowrap'
      }}><span style={{
        fontWeight: '700'
      }}>{ok ? '✓' : '✗'}</span>{IM_LABEL[mode]}</span>;
    })}
                      </div>
                    </td>
                  </tr>;
  })}
            </tbody>
          </table>
          {filtered.length === 0 ? <div style={{
    padding: '60px',
    textAlign: 'center',
    color: c.textMuted,
    fontSize: '14px'
  }}>暂无匹配数据</div> : null}
        </div>
      </div>

      {}
      {totalPages > 1 ? <div style={{
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    gap: '8px',
    marginTop: '16px',
    flexWrap: 'wrap'
  }}>
          <button onClick={function () {
    setPage(1);
  }} disabled={disabledPrev} style={pbtn(disabledPrev)}>«</button>
          <button onClick={function () {
    setPage(function (p) {
      return Math.max(1, p - 1);
    });
  }} disabled={disabledPrev} style={pbtn(disabledPrev)}>‹ 上一页</button>
          <span style={{
    fontSize: '13px',
    color: c.countColor,
    padding: '0 4px'
  }}>
            第 <strong style={{
    color: c.countStrong
  }}>{safePage}</strong> / <strong style={{
    color: c.countStrong
  }}>{totalPages}</strong> 页
            <span style={{
    color: c.textMuted,
    marginLeft: '6px'
  }}>（{(safePage - 1) * PAGE_SIZE + 1}–{Math.min(safePage * PAGE_SIZE, filtered.length)} / {filtered.length} 条）</span>
          </span>
          <button onClick={function () {
    setPage(function (p) {
      return Math.min(totalPages, p + 1);
    });
  }} disabled={disabledNext} style={pbtn(disabledNext)}>下一页 ›</button>
          <button onClick={function () {
    setPage(totalPages);
  }} disabled={disabledNext} style={pbtn(disabledNext)}>»</button>
        </div> : null}

    </div>;
};

It supports filtering by multiple dimensions such as region, country, payment method type, and currency. Hovering over the payment method icon will display the corresponding API request parameters.

<PaymentMethodTable />
