import * as StarterPackModule from "@/limitedTimeEvent"; const StarterPack: any = StarterPackModule as any; import cloud from '@lafjs/cloud' import { passOrderFields, PASS_PRICES } from '@/passCheckUpgrade'; // const token = "nika123"; // const EncodingAESKey = "XcdOFaZOQjmyBqYHxWAITtrmq11YaZQ63DeEZAAgYJt"; const mchid = process.env.WX_MCH_ID;//商户id const serialNo = process.env.WX_MCH_CERT_SERIAL_NO;//证书序列号 const appid = process.env.WX_MINIGAME_APP_ID; import crypto from 'crypto'; const db = cloud.database(); export default async function (ctx: FunctionContext) { console.log(ctx.body); //console.log(ctx.query);; try { let openid = ctx.body.FromUserName; //console.log(openid); const data = JSON.parse(ctx.body.SessionFrom); //console.log(data); console.log(data); if (data.tpye == "ios") { await PostMsg(openid, "点击下方页面进行充值"); await PostImg(openid, data.outTradeNo, data.propName, data.count, data.price, data); } } catch (e) { console.error("ios客服充值参数错误:" + ctx.body.SessionFrom); console.log(ctx.body); } //return ctx.query.echostr; return { data: "scuess" }; } /**获取订单*/ async function getOrder(openid, toatal, outTradeNo, timestamp, nonceStr) { const url = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi"; // 生成随机字符串和时间戳 const body = { "appid": appid, "mchid": mchid, "description": "消消王者道具购买", "out_trade_no": outTradeNo, "notify_url": process.env.WX_PAY_NOTIFY_URL, "amount": { "total": Number(toatal), "currency": "CNY" }, "payer": { "openid": openid } } let ret = await sign(nonceStr, timestamp, body); const res = await fetch(url, { method: 'POST', headers: { 'Authorization': ret, 'Accept': 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify(body) }) if (res.ok) { const data = await res.json().catch(async () => { //如果不是JSON,尝试读取文本 return await res.text().catch(() => 'Empty response'); }); return data.prepay_id; } return null; } async function sign(nonceStr, timestamp, body) { const data = `POST\n/v3/pay/transactions/jsapi\n${timestamp}\n${nonceStr}\n${JSON.stringify(body)}\n`; // 创建签名对象 const sign = crypto.createSign('RSA-SHA256'); // 更新签名内容 sign.update(data); // 获取存储桶 const bucket = cloud.storage.bucket(process.env.WX_PAY_PRIVATE_KEY_BUCKET); // 获取文件列表 const res = await bucket.readFile('apiclient_key.pem'); const privateKeyPem = await res.Body.transformToString(); // 使用私钥签名(PKCS1 填充) const signature = sign.sign({ key: privateKeyPem, padding: crypto.constants.RSA_PKCS1_PADDING }, 'base64'); // 构建Authorization头 const authorization = `WECHATPAY2-SHA256-RSA2048 mchid="${mchid}",nonce_str="${nonceStr}",signature="${signature}",timestamp="${timestamp}",serial_no="${serialNo}"`; return authorization; } /**前端签名*/ async function frontsign(data) { // 创建签名对象 const sign = crypto.createSign('RSA-SHA256'); // 更新签名内容 sign.update(data); // 获取存储桶 const bucket = cloud.storage.bucket(process.env.WX_PAY_PRIVATE_KEY_BUCKET); // 获取文件列表 const res = await bucket.readFile('apiclient_key.pem'); const privateKeyPem = await res.Body.transformToString(); //console.error(privateKeyPem); // 使用私钥签名(PKCS1 填充) const signature = sign.sign({ key: privateKeyPem, padding: crypto.constants.RSA_PKCS1_PADDING }, 'base64'); // 构建Authorization头 return signature } const propName = { reborn_Gift: "复活礼包6元", reborn_Gift_2: "复活礼包8元", reborn_Gift_3: "复活礼包10元", reborn_Gift_4: "复活礼包12元", reborn_Gift_5: "复活礼包15元", battlepass: '基础战令', battlepass_30: '高级战令', battlepass_12: '战令升级', gold_1: "金币包1", gold_2: "金币包2", gold_3: "金币包3", gold_4: "金币包4", gold_5: "金币包5", gold_6: "金币包6", unlimited_health_bundle_1: "无限体力组合包1", unlimited_health_bundle_2: "无限体力组合包2", unlimited_health_bundle_3: "无限体力组合包3", freeze_in_game: "局内购买冻结", hammer_in_game: "局内购买锤子", wand_in_gamerefill: "局内购买魔棒", health: "补满体力", jungle_treasure_1: "宝藏1", jungle_treasure_2: "宝藏2", jungle_treasure_3: "宝藏3", jungle_treasure_4: "宝藏4", jungle_treasure_5: "宝藏5", jungle_treasure_6: "宝藏6", jungle_treasure_7: "宝藏7", jungle_treasure_8: "宝藏8" }; async function PostMsg(OpenId, msg) { let token = cloud.shared.get('wxaccess_token'); if (!token) { return { code: 0, data: null, msg: "token获取失败" }; } const url = `https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=${token}`; const data = { "touser": OpenId, "msgtype": "text", "text": { "content": msg } } const res = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json;charset=utf-8' }, body: JSON.stringify(data) }) return "ok" } async function PostImg(OpenId, outTradeNo, name, count, price, passInput: any = {}) { const rebornPrice = { reborn_Gift: 600, reborn_Gift_2: 800, reborn_Gift_3: 1000, reborn_Gift_4: 1200, reborn_Gift_5: 1500 }; if (/^reborn_Gift(?:_[2-5])?$/.test(name)) { count = 1; price = rebornPrice[name]; } let passFields: any = {}; if (Object.prototype.hasOwnProperty.call(PASS_PRICES, name)) { const owner = await db.collection('users').where({ openid: OpenId }).getOne(); try { passFields = passOrderFields(owner.data, { ...passInput, itemid: name }); } catch (error) { await PostMsg(OpenId, error.message); return; } if (passFields.passVersion) { price = PASS_PRICES[name]; count = 1; } } let token = cloud.shared.get('wxaccess_token'); if (!token) { return { code: 0, data: null, msg: "token获取失败" }; } const giftUser = name === "starter_pack" ? (await db.collection("users").where({ openid: OpenId }).getOne()).data : null; const giftSnapshot = StarterPack.starterPackOrderSnapshot(giftUser, name); const url = `https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=${token}`; const nonceStr = crypto.randomBytes(16).toString('hex'); const timestamp = Math.floor(Date.now() / 1000).toString(); const total = count * price; let prepay_id = await getOrder(OpenId, total, outTradeNo, timestamp, nonceStr); let frontBody = { "appId": appid, //公众号ID,由商户传入 "timeStamp": timestamp, //时间戳,自1970年以来的秒数 "nonceStr": nonceStr, //随机串 "package": "prepay_id=" + prepay_id } const data1 = `${frontBody.appId}\n${frontBody.timeStamp}\n${frontBody.nonceStr}\n${frontBody.package}\n`; let paySign = await frontsign(data1); let user = await db.collection("users").where({ openid: OpenId }).update({ iosTime: frontBody.timeStamp }); let param = { name: propName[name], openid: OpenId, outTradeNo: outTradeNo, time: timestamp, quantity: count, price: price, body: { "appId": frontBody.appId, //公众号ID,由商户传入 "timeStamp": frontBody.timeStamp, //时间戳,自1970年以来的秒数 "nonceStr": frontBody.nonceStr, //随机串 "package": frontBody.package, "signType": "RSA", //微信签名方式: "paySign": paySign //微信签名 } } await db.collection("iosOrder").add({ ...passFields, ...giftSnapshot, openid: OpenId, outTradeNo: outTradeNo, itemid: name, itemCount: count, goodsPrice: Number(price), time: Date.now(), orderTime: new Date(Date.now() + 8 * 3600000), chargeTime: 0, getTime: 0, type: "ios", state: 0, }); const data = { "touser": OpenId, "msgtype": "link", "link": { "title": "点我支付", "description": "金额:" + (total / 100).toFixed(2) + "元", "url": `https://pay.nika4games.com/order3.html#data=${encodeURIComponent(JSON.stringify(param))}`, "thumb_url": "https://static-host-j3k323ol-colorblock-oss.sealoshzh.site/icon.jpg" } } //console.log(data); const res = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json;charset=utf-8' }, body: JSON.stringify(data) }) const data11 = await res.json(); console.log(data11); if (data11.errcode == 40001) { console.error("未获取到正确token,重新发送请求"); let res = await getWxToken(); await PostMsg(OpenId, "点击下方页面进行充值"); await PostImg(OpenId, outTradeNo, name, count, price, passInput); } return "ok" } /**获取微信Token*/ async function getWxToken() { const api_url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${appsecret}`; const ret = await cloud.fetch({ url: api_url, method: "get", }); if (ret?.data?.access_token) { cloud.shared.set('wxaccess_token', ret.data.access_token); return ret.data.access_token; } else { //access_token = nul l; return null; } }