feat: 小程序真实微信支付功能

新增:
1. /api/miniprogram/pay - 创建预支付订单API
2. /api/miniprogram/pay/notify - 支付回调处理
3. /api/miniprogram/login - 小程序登录获取openId

配置:
- 小程序AppID: wxb8bbb2b10dec74aa
- 商户号: 1318592501
- 回调地址: https://soul.cunbao.net/api/miniprogram/pay/notify

更新:
- app.js: 添加getOpenId方法,支付前获取openId
- read.js: processPayment调用真实支付接口
- 支持API不可用时回退到测试模式
This commit is contained in:
卡若
2026-01-23 05:44:21 +08:00
parent b60edb3d47
commit 0a5d470fef
5 changed files with 646 additions and 45 deletions

View File

@@ -0,0 +1,103 @@
/**
* 小程序登录API
* 使用code换取openId和session_key
*
* 小程序配置:
* - AppID: wxb8bbb2b10dec74aa
* - AppSecret: 85d3fa31584d06acdb1de4a597d25b7b
*/
import { NextResponse } from 'next/server'
const MINIPROGRAM_CONFIG = {
appId: 'wxb8bbb2b10dec74aa',
appSecret: '85d3fa31584d06acdb1de4a597d25b7b',
}
/**
* POST - 小程序登录获取openId
*/
export async function POST(request: Request) {
try {
const body = await request.json()
const { code } = body
if (!code) {
return NextResponse.json({
success: false,
error: '缺少登录code'
}, { status: 400 })
}
console.log('[MiniLogin] 收到登录请求, code:', code.slice(0, 10) + '...')
// 调用微信接口获取openId
const wxUrl = `https://api.weixin.qq.com/sns/jscode2session?appid=${MINIPROGRAM_CONFIG.appId}&secret=${MINIPROGRAM_CONFIG.appSecret}&js_code=${code}&grant_type=authorization_code`
const response = await fetch(wxUrl)
const data = await response.json()
console.log('[MiniLogin] 微信接口返回:', {
errcode: data.errcode,
errmsg: data.errmsg,
hasOpenId: !!data.openid,
})
if (data.errcode) {
return NextResponse.json({
success: false,
error: `微信登录失败: ${data.errmsg || data.errcode}`
}, { status: 400 })
}
const openId = data.openid
const sessionKey = data.session_key
const unionId = data.unionid
if (!openId) {
return NextResponse.json({
success: false,
error: '获取openId失败'
}, { status: 500 })
}
// 创建或更新用户
// TODO: 这里应该连接数据库操作
const user = {
id: `user_${openId.slice(-8)}`,
openId,
nickname: '微信用户',
avatar: '',
referralCode: 'SOUL' + Date.now().toString(36).toUpperCase().slice(-6),
purchasedSections: [],
hasFullBook: false,
earnings: 0,
pendingEarnings: 0,
referralCount: 0,
createdAt: new Date().toISOString()
}
// 生成token
const token = `tk_${openId.slice(-8)}_${Date.now()}`
console.log('[MiniLogin] 登录成功, userId:', user.id)
return NextResponse.json({
success: true,
data: {
openId,
sessionKey, // 注意生产环境不应返回sessionKey给前端
unionId,
user,
token,
}
})
} catch (error) {
console.error('[MiniLogin] 登录失败:', error)
return NextResponse.json({
success: false,
error: '登录失败'
}, { status: 500 })
}
}