Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2590145a2c | ||
|
|
e2018cbcf9 | ||
|
|
a1d3f3b639 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -42,3 +42,6 @@ next-env.d.ts
|
|||||||
|
|
||||||
# third-party source code (local reference only)
|
# third-party source code (local reference only)
|
||||||
/third-party
|
/third-party
|
||||||
|
|
||||||
|
# Claude Code project instructions (contains sensitive deployment info)
|
||||||
|
CLAUDE.md
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ describe('Payment Flow - PC/Mobile, QR/Redirect', () => {
|
|||||||
).toBe(true);
|
).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('EasyPay does not use isMobile flag itself (delegates to frontend)', async () => {
|
it('EasyPay forwards isMobile to client for device=jump on mobile', async () => {
|
||||||
mockEasyPayCreatePayment.mockResolvedValue({
|
mockEasyPayCreatePayment.mockResolvedValue({
|
||||||
code: 1,
|
code: 1,
|
||||||
trade_no: 'EP-003',
|
trade_no: 'EP-003',
|
||||||
@@ -212,16 +212,14 @@ describe('Payment Flow - PC/Mobile, QR/Redirect', () => {
|
|||||||
|
|
||||||
await provider.createPayment(request);
|
await provider.createPayment(request);
|
||||||
|
|
||||||
// EasyPay client is called the same way regardless of isMobile
|
// EasyPay client receives isMobile so it can set device=jump
|
||||||
expect(mockEasyPayCreatePayment).toHaveBeenCalledWith(
|
expect(mockEasyPayCreatePayment).toHaveBeenCalledWith(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
outTradeNo: 'order-ep-003',
|
outTradeNo: 'order-ep-003',
|
||||||
paymentType: 'alipay',
|
paymentType: 'alipay',
|
||||||
|
isMobile: true,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
// No isMobile parameter forwarded to the underlying client
|
|
||||||
const callArgs = mockEasyPayCreatePayment.mock.calls[0][0];
|
|
||||||
expect(callArgs).not.toHaveProperty('isMobile');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,19 +3,17 @@ import { z } from 'zod';
|
|||||||
import { verifyAdminToken, unauthorizedResponse } from '@/lib/admin-auth';
|
import { verifyAdminToken, unauthorizedResponse } from '@/lib/admin-auth';
|
||||||
import { prisma } from '@/lib/db';
|
import { prisma } from '@/lib/db';
|
||||||
|
|
||||||
const updateChannelSchema = z
|
const updateChannelSchema = z.object({
|
||||||
.object({
|
group_id: z.number().int().positive().optional(),
|
||||||
group_id: z.number().int().positive().optional(),
|
name: z.string().min(1).max(100).optional(),
|
||||||
name: z.string().min(1).max(100).optional(),
|
platform: z.string().min(1).max(50).optional(),
|
||||||
platform: z.string().min(1).max(50).optional(),
|
rate_multiplier: z.number().positive().optional(),
|
||||||
rate_multiplier: z.number().positive().optional(),
|
description: z.string().max(500).nullable().optional(),
|
||||||
description: z.string().max(500).nullable().optional(),
|
models: z.union([z.array(z.string()), z.string()]).nullable().optional(),
|
||||||
models: z.array(z.string()).nullable().optional(),
|
features: z.union([z.record(z.string(), z.unknown()), z.string()]).nullable().optional(),
|
||||||
features: z.record(z.string(), z.unknown()).nullable().optional(),
|
sort_order: z.number().int().min(0).optional(),
|
||||||
sort_order: z.number().int().min(0).optional(),
|
enabled: z.boolean().optional(),
|
||||||
enabled: z.boolean().optional(),
|
});
|
||||||
})
|
|
||||||
.strict();
|
|
||||||
|
|
||||||
export async function PUT(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
|
export async function PUT(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
|
||||||
if (!(await verifyAdminToken(request))) return unauthorizedResponse(request);
|
if (!(await verifyAdminToken(request))) return unauthorizedResponse(request);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ export interface CreatePaymentOptions {
|
|||||||
clientIp: string;
|
clientIp: string;
|
||||||
productName: string;
|
productName: string;
|
||||||
returnUrl?: string;
|
returnUrl?: string;
|
||||||
|
isMobile?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeCidList(cid?: string): string | undefined {
|
function normalizeCidList(cid?: string): string | undefined {
|
||||||
@@ -68,6 +69,10 @@ export async function createPayment(opts: CreatePaymentOptions): Promise<EasyPay
|
|||||||
params.cid = cid;
|
params.cid = cid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opts.isMobile) {
|
||||||
|
params.device = 'jump';
|
||||||
|
}
|
||||||
|
|
||||||
const sign = generateSign(params, env.EASY_PAY_PKEY);
|
const sign = generateSign(params, env.EASY_PAY_PKEY);
|
||||||
params.sign = sign;
|
params.sign = sign;
|
||||||
params.sign_type = 'MD5';
|
params.sign_type = 'MD5';
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ export class EasyPayProvider implements PaymentProvider {
|
|||||||
clientIp: request.clientIp || '127.0.0.1',
|
clientIp: request.clientIp || '127.0.0.1',
|
||||||
productName: request.subject,
|
productName: request.subject,
|
||||||
returnUrl: request.returnUrl,
|
returnUrl: request.returnUrl,
|
||||||
|
isMobile: request.isMobile,
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user