+
+ API 调试工具
+
+
+ 填写商户 API 客户端的 AppKey 与 Secret,选择接口并发送请求。签名在浏览器端使用 Web Crypto API 计算。
+
+
+ {!import.meta.env.DEV && (
+
+ )}
+
+
+ 忘记凭证
+
+ }
+ >
+
+ handleAppKeyChange(e.target.value)}
+ style={{ width: 320 }}
+ allowClear
+ size="middle"
+ />
+ handleSecretChange(e.target.value)}
+ style={{ width: 400 }}
+ allowClear
+ size="middle"
+ />
+
+
+
+
}
+ loading={loading}
+ onClick={handleSend}
+ disabled={!appKey.trim() || !secret.trim()}
+ size="middle"
+ >
+ 发送请求
+
+ }
+ >
+
setSelectedKey(e.target.value)}
+ style={{ width: '100%', display: 'block' }}
+ >
+ {endpoints.map((ep) => (
+ setSelectedKey(ep.key)}
+ >
+
+
+ {ep.method}
+
+ {ep.path}
+ {ep.summary}
+
+ ))}
+
+
+
+ {endpoint && (
+
+ {`{${p.name}}`}} help={p.desc}>
+ setPathValues((prev) => ({ ...prev, [p.name]: e.target.value }))}
+ style={{ maxWidth: 480 }}
+ />
+
+ ))}
+
+ {endpoint.queryParams?.map((p) => (
+ {p.name}} help={p.desc}>
+ setQueryValues((prev) => ({ ...prev, [p.name]: e.target.value }))}
+ style={{ maxWidth: 240 }}
+ />
+
+ ))}
+
+ {endpoint.method !== 'GET' && (
+
+ Request Body (JSON)
+ } onClick={() => setBodyText('')}>清空
+ {endpoint.requestExample && (
+
+ )}
+
+ }
+ >
+
+ )}
+
+ {isCreateOrder && (
+ Idempotency-Key} help="须与 client_order_no 一致">
+ setIdempotencyKey(e.target.value)}
+ style={{ maxWidth: 480 }}
+ placeholder="会从 Request Body 自动取 client_order_no"
+ />
+
+ )}
+
+
+
+ {endpoint.method}
+ {readyPath + readyQuery}
+
+ }
+ />
+
+ )}
+
+ {signInfo && (
+
+
+ {signInfo.timestamp}
+ {signInfo.nonce}
+ {appKey.trim()}
+
+
+ {signInfo.signString}
+
+
+
+ {signInfo.signature}
+
+
+
+ )}
+
+ {response && (
+
+ = 200 && response.status < 300 ? 'green' : 'red'}>
+ {response.status || 'ERR'}
+
+ {response.elapsed}ms
+
+ }
+ >
+
+ Response Headers
+
+ {Object.entries(response.headers)
+ .map(([k, v]) => `${k}: ${v}`)
+ .join('\n') || '(无)'}
+
+
+ Response Body
+
+ {formatJSON(response.body)}
+
+
+
+ )}
+
+ )
+}