cb/server/laf-cloud/functions/wx/iosgetPayInfo.ts
2026-07-02 11:22:24 +08:00

157 lines
5.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import cloud from '@lafjs/cloud'
import crypto from 'crypto';
const mchid = "1719895437";//商户id
const serialNo = "2A97ED6ED441E55600EBC8830B9EC889ED41496E";//证书序列号
const db = cloud.database();
const ThinkingData = require('thinkingdata-node');
export default async function (ctx: FunctionContext) {
let outTradeNo = ctx.body.outTradeNo;
if(!outTradeNo){
return { code: 0, data: null, msg: "未获取到充值订单" };
}
const uid = ctx.body.uid;
let res = await getOrder(outTradeNo);
let ret = await db.collection("order").where({"outTradeNo":outTradeNo}).getOne();
let iosOrder = cloud.shared.get("iosOrder"); // 获取 wsMap
if(!ret.data){
console.error("ios找不到充值订单"+outTradeNo);
return {code:0,data:null,msg:"未获取到充值信息"};
}
if(ret.data.state==2){
console.error("ios已经获取奖励");
return {code:0,data:null,msg:"已经获取到奖励"};
}
let payment_name = ret.data?.itemid;
if(res){
if (uid) {
let res1 = await db.collection("users").where({ _id: uid }).getOne();
if(!iosOrder){
iosOrder={};
}else{
//console.log(iosOrder);
}
if(!iosOrder[outTradeNo]){
sead(ret.data, res1.data, getClientIp(ctx));
iosOrder[outTradeNo]=2;
}else{
}
cloud.shared.set("iosOrder",iosOrder); // 设置 wsMap
switch (payment_name) {
case "month_Card":
let monthCardTime = res1.data.monthCardTime;
if (!monthCardTime || monthCardTime < Date.now()) {
monthCardTime = Date.now();
}
monthCardTime = monthCardTime + 2592000000;
let ret = await db.collection("users").where({ _id: uid }).update({ monthCardTime: monthCardTime, monthCardReward: 0, pay_user: true });
break;
case "reborn_Gift":
db.collection("users").where({ _id: uid }).update({ rebornGiftTime: Date.now(), rebornGiftCount: 1, pay_user: true });
break;
case "starter_pack":
db.collection("users").where({ _id: uid }).update({ starter_packState:1, pay_user: true });
break;
default:
db.collection("users").where({ _id: uid }).update({pay_user: true });
break;
}
}
await db.collection("order").where({ outTradeNo: outTradeNo }).update({ state: 2 });
return { code: 1, data: { goodsPrice: ret.data?.goodsPrice,payment_name:payment_name}, msg: "充值成功" };
}else{
console.log("充值不成功:"+outTradeNo);
return { code: 0, data: { goodsPrice: ret.data?.goodsPrice, payment_name: payment_name }, msg: "充值失败" };
}
}
const getClientIp = (req) => {
return (
req.headers['x-forwarded-for']?.split(',')[0]?.trim() || // 代理链中的第一个 IP
req.headers['x-real-ip'] || // Nginx 配置的 real-ip
req.socket.remoteAddress // 原始 IP可能是代理
);
};
/**获取订单*/
async function getOrder(outTradeNo) {
const url = `https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/${outTradeNo}?mchid=1719895437`;
const nonceStr = crypto.randomBytes(16).toString('hex');
const timestamp = Math.floor(Date.now() / 1000).toString();
let au=await sign(outTradeNo,nonceStr,timestamp);
let res=await fetch(url,{
method: 'GET', // 默认是 GET可省略
headers: {
'Authorization': au, // 认证令牌
'Content-Type': 'application/json', // 声明请求体类型GET 请求通常不需要)
'Accept': 'application/json', // 声明期望的响应类型
}
})
const data = await res.json();
if (data.trade_state == 'SUCCESS'){
return true;
}else{
return false;
}
}
async function sign(outTradeNo,nonceStr, timestamp) {
const data = `GET\n/v3/pay/transactions/out-trade-no/${outTradeNo}?mchid=1719895437\n${timestamp}\n${nonceStr}\n\n`
// 创建签名对象
const sign = crypto.createSign('RSA-SHA256');
// 更新签名内容
sign.update(data);
// 获取存储桶
const bucket = cloud.storage.bucket('j3k323ol-colorblock-oss');
// 获取文件列表
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 sead(order,userInfo,ip){
if(!userInfo.distinctId){
return;
}
let id = '87d18958cea145f29d3265470ecd3486';
if (userInfo.isDebug != "true"){
id = '121591378fc1423893deb12041413eb3';
}
let teSDK = ThinkingData.initWithBatchMode(id, 'https://data.nika4fun.com/sync_data', {
dryRun: false, // report data to TE or not
deviceId: "123456789",//设备唯一标识
});
let trackEvent = {
accountId: order.openid,
distinctId: userInfo.distinctId,//访客id
event: 'payment',
time: new Date(Date.now() + 8 * 3600000),
ip:ip,
properties: {
order_id: order.outTradeNo,
pay_amount:order.goodsPrice,
payment_name: order.itemid,
payment_num: order.itemCount,
payment_type: "ios",
current_level: userInfo.levelAmount, //当前关卡等级 number
current_health: userInfo.healthAmount, //当前体力值
tmp_coin: userInfo.coinAmount,//当前金币
version: "1.6",
user_id: userInfo._id, //用户id
pay_user: userInfo.pay_user,
register_time: userInfo.register_time
},
callback(e) {
if(e){
console.log(e);
}
}
};
teSDK.track(trackEvent);
teSDK.close();
return;
}