Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c083880cbc | ||
|
|
a9ea9d4862 |
43
README.en.md
43
README.en.md
@@ -94,12 +94,24 @@ See [`.env.example`](./.env.example) for the full template.
|
|||||||
|
|
||||||
> `DATABASE_URL` is automatically injected by Docker Compose when using the bundled database.
|
> `DATABASE_URL` is automatically injected by Docker Compose when using the bundled database.
|
||||||
|
|
||||||
### Payment Methods
|
### Payment Providers & Methods
|
||||||
|
|
||||||
Control which payment methods are enabled via `ENABLED_PAYMENT_TYPES` (comma-separated):
|
**Step 1**: Declare which payment providers to load via `PAYMENT_PROVIDERS` (comma-separated):
|
||||||
|
|
||||||
```env
|
```env
|
||||||
ENABLED_PAYMENT_TYPES=alipay,wxpay,stripe
|
# EasyPay only
|
||||||
|
PAYMENT_PROVIDERS=easypay
|
||||||
|
# Stripe only
|
||||||
|
PAYMENT_PROVIDERS=stripe
|
||||||
|
# Both
|
||||||
|
PAYMENT_PROVIDERS=easypay,stripe
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2**: Control which channels are shown to users via `ENABLED_PAYMENT_TYPES`:
|
||||||
|
|
||||||
|
```env
|
||||||
|
# EasyPay supports: alipay, wxpay | Stripe supports: stripe
|
||||||
|
ENABLED_PAYMENT_TYPES=alipay,wxpay
|
||||||
```
|
```
|
||||||
|
|
||||||
#### EasyPay (Alipay / WeChat Pay)
|
#### EasyPay (Alipay / WeChat Pay)
|
||||||
@@ -137,10 +149,31 @@ ENABLED_PAYMENT_TYPES=alipay,wxpay,stripe
|
|||||||
|
|
||||||
### UI Customization (Optional)
|
### UI Customization (Optional)
|
||||||
|
|
||||||
|
Display a support contact image and description on the right side of the payment page.
|
||||||
|
|
||||||
| Variable | Description |
|
| Variable | Description |
|
||||||
|----------|-------------|
|
|----------|-------------|
|
||||||
| `NEXT_PUBLIC_PAY_HELP_IMAGE_URL` | Help image URL (e.g. customer service QR code) |
|
| `PAY_HELP_IMAGE_URL` | Help image URL — external URL or local path (see below) |
|
||||||
| `NEXT_PUBLIC_PAY_HELP_TEXT` | Help text displayed on payment page |
|
| `PAY_HELP_TEXT` | Help text; use `\n` for line breaks, e.g. `Scan to add WeChat\nMon–Fri 9am–6pm` |
|
||||||
|
|
||||||
|
**Two ways to provide the image:**
|
||||||
|
|
||||||
|
- **External URL** (recommended — no Compose changes needed): any publicly accessible image link (CDN, OSS, image hosting).
|
||||||
|
```env
|
||||||
|
PAY_HELP_IMAGE_URL=https://cdn.example.com/help-qr.jpg
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Local file**: place the image in `./uploads/` and reference it as `/uploads/<filename>`.
|
||||||
|
The directory must be mounted in `docker-compose.app.yml` (included by default):
|
||||||
|
```yaml
|
||||||
|
volumes:
|
||||||
|
- ./uploads:/app/public/uploads:ro
|
||||||
|
```
|
||||||
|
```env
|
||||||
|
PAY_HELP_IMAGE_URL=/uploads/help-qr.jpg
|
||||||
|
```
|
||||||
|
|
||||||
|
> Clicking the help image opens it full-screen in the center of the screen.
|
||||||
|
|
||||||
### Docker Compose Variables
|
### Docker Compose Variables
|
||||||
|
|
||||||
|
|||||||
43
README.md
43
README.md
@@ -94,12 +94,24 @@ docker compose up -d --build
|
|||||||
|
|
||||||
> `DATABASE_URL` 使用自带数据库时由 Compose 自动注入,无需手动填写。
|
> `DATABASE_URL` 使用自带数据库时由 Compose 自动注入,无需手动填写。
|
||||||
|
|
||||||
### 支付方式
|
### 支付服务商与支付方式
|
||||||
|
|
||||||
通过 `ENABLED_PAYMENT_TYPES` 控制开启哪些支付方式(逗号分隔):
|
**第一步**:通过 `PAYMENT_PROVIDERS` 声明启用哪些支付服务商(逗号分隔):
|
||||||
|
|
||||||
```env
|
```env
|
||||||
ENABLED_PAYMENT_TYPES=alipay,wxpay,stripe
|
# 仅易支付
|
||||||
|
PAYMENT_PROVIDERS=easypay
|
||||||
|
# 仅 Stripe
|
||||||
|
PAYMENT_PROVIDERS=stripe
|
||||||
|
# 两者都用
|
||||||
|
PAYMENT_PROVIDERS=easypay,stripe
|
||||||
|
```
|
||||||
|
|
||||||
|
**第二步**:通过 `ENABLED_PAYMENT_TYPES` 控制向用户展示哪些支付渠道:
|
||||||
|
|
||||||
|
```env
|
||||||
|
# 易支付支持: alipay, wxpay;Stripe 支持: stripe
|
||||||
|
ENABLED_PAYMENT_TYPES=alipay,wxpay
|
||||||
```
|
```
|
||||||
|
|
||||||
#### EasyPay(支付宝 / 微信支付)
|
#### EasyPay(支付宝 / 微信支付)
|
||||||
@@ -137,10 +149,31 @@ ENABLED_PAYMENT_TYPES=alipay,wxpay,stripe
|
|||||||
|
|
||||||
### UI 定制(可选)
|
### UI 定制(可选)
|
||||||
|
|
||||||
|
在充值页面右侧可展示客服联系方式、说明图片等帮助内容。
|
||||||
|
|
||||||
| 变量 | 说明 |
|
| 变量 | 说明 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| `NEXT_PUBLIC_PAY_HELP_IMAGE_URL` | 帮助图片 URL(如客服二维码) |
|
| `PAY_HELP_IMAGE_URL` | 帮助图片地址(支持外部 URL 或本地路径,见下方说明) |
|
||||||
| `NEXT_PUBLIC_PAY_HELP_TEXT` | 帮助说明文字 |
|
| `PAY_HELP_TEXT` | 帮助说明文字,用 `\n` 换行,如 `扫码加微信\n工作日 9-18 点在线` |
|
||||||
|
|
||||||
|
**图片地址两种方式:**
|
||||||
|
|
||||||
|
- **外部 URL**(推荐,无需改 Compose 配置):直接填图片的公网地址,如 OSS / CDN / 图床链接。
|
||||||
|
```env
|
||||||
|
PAY_HELP_IMAGE_URL=https://cdn.example.com/help-qr.jpg
|
||||||
|
```
|
||||||
|
|
||||||
|
- **本地文件**:将图片放到 `./uploads/` 目录,通过 `/uploads/文件名` 引用。
|
||||||
|
需在 `docker-compose.app.yml` 中挂载目录(默认已包含):
|
||||||
|
```yaml
|
||||||
|
volumes:
|
||||||
|
- ./uploads:/app/public/uploads:ro
|
||||||
|
```
|
||||||
|
```env
|
||||||
|
PAY_HELP_IMAGE_URL=/uploads/help-qr.jpg
|
||||||
|
```
|
||||||
|
|
||||||
|
> 点击帮助图片可在屏幕中央全屏放大查看。
|
||||||
|
|
||||||
### Docker Compose 专用
|
### Docker Compose 专用
|
||||||
|
|
||||||
|
|||||||
@@ -12,4 +12,7 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- '${APP_PORT:-3001}:3000'
|
- '${APP_PORT:-3001}:3000'
|
||||||
env_file: .env
|
env_file: .env
|
||||||
|
volumes:
|
||||||
|
# 宿主机 uploads 目录挂载到 Next.js public/uploads,可通过 /uploads/* 访问
|
||||||
|
- ./uploads:/app/public/uploads:ro
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ function PayContent() {
|
|||||||
maxDailyAmount: 0,
|
maxDailyAmount: 0,
|
||||||
});
|
});
|
||||||
const [userNotFound, setUserNotFound] = useState(false);
|
const [userNotFound, setUserNotFound] = useState(false);
|
||||||
|
const [helpImageOpen, setHelpImageOpen] = useState(false);
|
||||||
|
|
||||||
const effectiveUserId = resolvedUserId || userId;
|
const effectiveUserId = resolvedUserId || userId;
|
||||||
const isEmbedded = uiMode === 'embedded' && isIframeContext;
|
const isEmbedded = uiMode === 'embedded' && isIframeContext;
|
||||||
@@ -432,13 +433,16 @@ function PayContent() {
|
|||||||
<img
|
<img
|
||||||
src={helpImageUrl}
|
src={helpImageUrl}
|
||||||
alt='help'
|
alt='help'
|
||||||
className='mt-3 max-h-40 w-full rounded-lg object-contain bg-white/70 p-2'
|
onClick={() => setHelpImageOpen(true)}
|
||||||
|
className='mt-3 max-h-40 w-full cursor-zoom-in rounded-lg object-contain bg-white/70 p-2'
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{helpText && (
|
{helpText && (
|
||||||
<p className={['mt-3 text-sm leading-6', isDark ? 'text-slate-300' : 'text-slate-600'].join(' ')}>
|
<div className={['mt-3 space-y-1 text-sm leading-6', isDark ? 'text-slate-300' : 'text-slate-600'].join(' ')}>
|
||||||
{helpText}
|
{helpText.split('\\n').map((line, i) => (
|
||||||
</p>
|
<p key={i}>{line}</p>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -467,6 +471,20 @@ function PayContent() {
|
|||||||
{step === 'result' && (
|
{step === 'result' && (
|
||||||
<OrderStatus status={finalStatus} onBack={handleBack} dark={isDark} />
|
<OrderStatus status={finalStatus} onBack={handleBack} dark={isDark} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{helpImageOpen && helpImageUrl && (
|
||||||
|
<div
|
||||||
|
className="fixed inset-0 z-50 flex items-center justify-center bg-black/75 p-4 backdrop-blur-sm"
|
||||||
|
onClick={() => setHelpImageOpen(false)}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={helpImageUrl}
|
||||||
|
alt='help'
|
||||||
|
className='max-h-[90vh] max-w-full rounded-xl object-contain shadow-2xl'
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</PayPageLayout>
|
</PayPageLayout>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user