fix: remove dead zpay/client, fix zpay notify route type imports
This commit is contained in:
10
.idea/.gitignore
generated
vendored
Normal file
10
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Ignored default folder with query files
|
||||
/queries/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/sub2apipay.iml" filepath="$PROJECT_DIR$/.idea/sub2apipay.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
8
.idea/sub2apipay.iml
generated
Normal file
8
.idea/sub2apipay.iml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
7
.idea/vcs.xml
generated
Normal file
7
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/third-party/sub2api" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -1,90 +0,0 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
|
||||
// Mock config
|
||||
vi.mock('@/lib/config', () => ({
|
||||
getEnv: () => ({
|
||||
ZPAY_PID: 'test_pid',
|
||||
ZPAY_PKEY: 'test_pkey',
|
||||
ZPAY_API_BASE: 'https://test.zpay.com',
|
||||
ZPAY_NOTIFY_URL: 'https://test.com/api/zpay/notify',
|
||||
ZPAY_RETURN_URL: 'https://test.com/pay/result',
|
||||
}),
|
||||
}));
|
||||
|
||||
import { createPayment, queryOrder, refund } from '@/lib/zpay/client';
|
||||
|
||||
describe('ZPAY Client', () => {
|
||||
beforeEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it('createPayment should post to mapi.php and return result', async () => {
|
||||
const mockResponse = {
|
||||
code: 1,
|
||||
trade_no: 'zpay_123',
|
||||
payurl: 'https://pay.example.com',
|
||||
qrcode: 'https://qr.example.com',
|
||||
img: 'https://img.example.com/qr.jpg',
|
||||
};
|
||||
|
||||
global.fetch = vi.fn().mockResolvedValue({
|
||||
json: () => Promise.resolve(mockResponse),
|
||||
});
|
||||
|
||||
const result = await createPayment({
|
||||
outTradeNo: 'test_order_1',
|
||||
amount: '10.00',
|
||||
paymentType: 'alipay',
|
||||
clientIp: '127.0.0.1',
|
||||
productName: 'Test Product',
|
||||
});
|
||||
|
||||
expect(result.trade_no).toBe('zpay_123');
|
||||
expect(result.payurl).toBe('https://pay.example.com');
|
||||
expect(fetch).toHaveBeenCalledWith(
|
||||
'https://test.zpay.com/mapi.php',
|
||||
expect.objectContaining({ method: 'POST' }),
|
||||
);
|
||||
});
|
||||
|
||||
it('createPayment should throw on error response', async () => {
|
||||
global.fetch = vi.fn().mockResolvedValue({
|
||||
json: () => Promise.resolve({ code: 0, msg: 'insufficient balance' }),
|
||||
});
|
||||
|
||||
await expect(
|
||||
createPayment({
|
||||
outTradeNo: 'test_order_2',
|
||||
amount: '10.00',
|
||||
paymentType: 'alipay',
|
||||
clientIp: '127.0.0.1',
|
||||
productName: 'Test Product',
|
||||
}),
|
||||
).rejects.toThrow('ZPAY create payment failed');
|
||||
});
|
||||
|
||||
it('queryOrder should fetch order status', async () => {
|
||||
global.fetch = vi.fn().mockResolvedValue({
|
||||
json: () => Promise.resolve({
|
||||
code: 1,
|
||||
trade_no: 'zpay_123',
|
||||
out_trade_no: 'test_order_1',
|
||||
status: 1,
|
||||
money: '10.00',
|
||||
}),
|
||||
});
|
||||
|
||||
const result = await queryOrder('test_order_1');
|
||||
expect(result.status).toBe(1);
|
||||
expect(result.money).toBe('10.00');
|
||||
});
|
||||
|
||||
it('refund should post refund request', async () => {
|
||||
global.fetch = vi.fn().mockResolvedValue({
|
||||
json: () => Promise.resolve({ code: 1, msg: '退款成功' }),
|
||||
});
|
||||
|
||||
const result = await refund('zpay_123', 'test_order_1', '10.00');
|
||||
expect(result.code).toBe(1);
|
||||
});
|
||||
});
|
||||
@@ -1,12 +1,12 @@
|
||||
import { NextRequest } from 'next/server';
|
||||
import { handlePaymentNotify } from '@/lib/order/service';
|
||||
import type { ZPayNotifyParams } from '@/lib/zpay/types';
|
||||
import type { EasyPayNotifyParams } from '@/lib/easy-pay/types';
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
const searchParams = request.nextUrl.searchParams;
|
||||
|
||||
const params: ZPayNotifyParams = {
|
||||
const params: EasyPayNotifyParams = {
|
||||
pid: searchParams.get('pid') || '',
|
||||
name: searchParams.get('name') || '',
|
||||
money: searchParams.get('money') || '',
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
import { getEnv } from '@/lib/config';
|
||||
import { generateSign } from './sign';
|
||||
import type { ZPayCreateResponse, ZPayQueryResponse, ZPayRefundResponse } from './types';
|
||||
|
||||
export interface CreatePaymentOptions {
|
||||
outTradeNo: string;
|
||||
amount: string; // 金额字符串,如 "10.00"
|
||||
paymentType: 'alipay' | 'wxpay';
|
||||
clientIp: string;
|
||||
productName: string;
|
||||
}
|
||||
|
||||
export async function createPayment(opts: CreatePaymentOptions): Promise<ZPayCreateResponse> {
|
||||
const env = getEnv();
|
||||
const params: Record<string, string> = {
|
||||
pid: env.ZPAY_PID,
|
||||
type: opts.paymentType,
|
||||
out_trade_no: opts.outTradeNo,
|
||||
notify_url: env.ZPAY_NOTIFY_URL,
|
||||
return_url: env.ZPAY_RETURN_URL,
|
||||
name: opts.productName,
|
||||
money: opts.amount,
|
||||
clientip: opts.clientIp,
|
||||
};
|
||||
|
||||
const sign = generateSign(params, env.ZPAY_PKEY);
|
||||
params.sign = sign;
|
||||
params.sign_type = 'MD5';
|
||||
|
||||
const formData = new URLSearchParams(params);
|
||||
const response = await fetch(`${env.ZPAY_API_BASE}/mapi.php`, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
});
|
||||
|
||||
const data = await response.json() as ZPayCreateResponse;
|
||||
if (data.code !== 1) {
|
||||
throw new Error(`ZPAY create payment failed: ${data.msg || 'unknown error'}`);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function queryOrder(outTradeNo: string): Promise<ZPayQueryResponse> {
|
||||
const env = getEnv();
|
||||
const url = `${env.ZPAY_API_BASE}/api.php?act=order&pid=${env.ZPAY_PID}&key=${env.ZPAY_PKEY}&out_trade_no=${outTradeNo}`;
|
||||
const response = await fetch(url);
|
||||
const data = await response.json() as ZPayQueryResponse;
|
||||
if (data.code !== 1) {
|
||||
throw new Error(`ZPAY query order failed: ${data.msg || 'unknown error'}`);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function refund(tradeNo: string, outTradeNo: string, money: string): Promise<ZPayRefundResponse> {
|
||||
const env = getEnv();
|
||||
const params = new URLSearchParams({
|
||||
pid: env.ZPAY_PID,
|
||||
key: env.ZPAY_PKEY,
|
||||
trade_no: tradeNo,
|
||||
out_trade_no: outTradeNo,
|
||||
money,
|
||||
});
|
||||
const response = await fetch(`${env.ZPAY_API_BASE}/api.php?act=refund`, {
|
||||
method: 'POST',
|
||||
body: params,
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
});
|
||||
const data = await response.json() as ZPayRefundResponse;
|
||||
if (data.code !== 1) {
|
||||
throw new Error(`ZPAY refund failed: ${data.msg || 'unknown error'}`);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
Reference in New Issue
Block a user