评论

Donut多端-云开发API_V2微信支付案例

Donut多端-云开发API_V2微信支付案例

Donut多端-云开发API_V2微信支付案例



使用的是小程序原生-多端支付
使用条件
1.微信开放平台
2.微信支付(app支付)
3.多端SDK(含支付)

云开发回调这个不知道怎么解决
只能在微信确认支付返回app后确认
有解决方法的可以分享一下


前端js

// 调用云开发
//自定义支付信息
const payData = {price,body,attach}
cloud('Ger_pay',{
  type2:'pay_token',
  payData
}).then(res =>{
  console.log('获取sign信息',res)
  const {timestamp,prepayid,partnerid,appId,noncestr,sign} = res.result;
  wx.miniapp.requestPayment({
       timeStamp: timestamp,
     mchId: partnerid,
     prepayId: prepayid,
     package'Sign=WXPay',
    nonceStr: noncestr,
    sign: sign,
    success(res) => {
      console.warn('wx.miniapp.requestPayment success:', res)
      wx.showLoading({
          title'支付中...',
          masktrue
      })
      // 支付成功返回
      cloud('Ger_pay',{
         type2:'app_vip',
         prepayid,
         payData
      }).then(res =>{
         console.log(res)
         wx.reLaunch({
           url'../index/index'
         })
      })
    },
    fail(res) => {
      console.error('取消支付', res)
      wx.showToast({
        title'取消支付',
      })
    }
  })
})


云开发index.js

// 云函数入口文件
const cloud = require('wx-server-sdk')
const pay_token = require('./pay_token.js') 
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境


const USER_LIST = 'UserList' 
// 修改付款记录
async function getpre_order(db,prepayid){
   try {
      await db.collection('pre_order').where({
         prepayid:prepayid
       }).update({
         data: {
           payTimenew Date().getTime(),
           payStatus1 // 0:未支付, 1:已支付
         },
      })
   } catch (error) {
      console.error(error);
   }
}

exports.main = async (event,context) => {
   try {
      const wxContext = cloud.getWXContext()
      const db = cloud.database()
      const unionid = wxContext.UNIONID
      const time = Date.parse(new Date());
      const timestamp = time / 1000;
      var e = event;



      if (e.type2 === 'pay_token') {
         return await pay_token.main(event,context);
      }
      if (e.type2 === 'app_vip') {
         const {prepayid,payData} = e
         await getpre_order(db,prepayid)
      }

   }catch (error) {
      console.error(error);
      return { code-1message'服务器错误' + error};
   } 
   
}


//云开发代码pay_token.js
//以下全部照抄即可
const key = "253050DD68FF61CC99D56232E002489" //换成你的商户key,32位
const mch_id = "160755748" //换成你的商户号

const cloud = require('wx-server-sdk')
const rp = require('request-promise')
const crypto = require('crypto')


cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境
const db = cloud.database()


// 签名接口 
function getSign(args{
   let arr = new Array();
   let num = 0;
   for (let i in args) {
      arr[num] = i;
      num++;
   }
   let sortArr = arr.sort();
   let sortObj = {};
   for (let i in sortArr) {
      sortObj[sortArr[i]] = args[sortArr[i]];
   }
   // 对传入的对象进行拼接
   let sortStr = ''
   sortArr.forEach(key => {
      sortStr += key + "=" + sortObj[key] + "&"
   });
   // 拼接密钥
   sortStr += "key=" + key
   // 使用MD5进行加密, 并将加密结果的英文字母全部转换成大写
   const sign = crypto.createHash('md5').update(sortStr, 'utf8').digest('hex').toUpperCase();
   return sign;
}


//  转换成xml
function getXml(args{
   let sa = []
   for (let k in args) sa.push('<' + k + '>' + args[k] + '</' + k + '>')
   sa.push('<sign>' + getSign(args) + '</sign>')
   return '<xml>' + sa.join('') + '</xml>'
}
exports.main = async (event, context) => {
       //前端传入payData
      const {total_fee,body,attach} = event.payData    //total_fee金额   body商品描述  attach附加数据

      const wxContext = cloud.getWXContext()
    const openid = wxContext.OPENID
    const unionid = wxContext. unionid
   const appId = appid = 'wx8c699bc1e33333fa9'
   const attach = attach || 'app支付'    //attach 附加数据
   const notify_url = "https://api.XXX.com/notify"
   const spbill_create_ip = "127.0.0.1"
   const noncestr = nonceStr = nonce_str = Math.random().toString(36).substr(215)
   const timestamp = timeStamp = parseInt(Date.now() / 1000) + ''
   const out_trade_no = "otn" + nonce_str + timeStamp
   const trade_type = "APP"  //trade_type支付类型 
   const sign_type = 'MD5'


   //   统一下单数据
   const xmlArgs = {
      appid,
      attach,
      body: body,
      mch_id,
      nonce_str,
      notify_url,
      out_trade_no,
      spbill_create_ip,
      total_fee,
      fee_type:'CNY',
      trade_type,
      sign_type
   }


   //   统一下单
   let xml = (await rp({
      url"https://api.mch.weixin.qq.com/pay/unifiedorder",
      method'POST',
      body: getXml(xmlArgs)
   }))
   // 下单完成,返回XML
   if (xml.indexOf('prepay_id') < 0return xml


   // 取出 预支付交易会话标识
   let prepay_id = xml.split("<prepay_id><![CDATA[")[1].split("]]></prepay_id>")[0]


   // 第二次签名 数据
   let payArgs = {
      appid,
      noncestr,
      partnerid: mch_id,
      prepayid:prepay_id,
      package'Sign=WXPay',
      timestamp,
   }

      //保存支付信息到云开发数据库
    await db.collection("pre_order").add({
        data: {
          ...payArgs,  // 保存支付信息
        body,
        trade_type,
        openid: openid, // 用户openid
        unionid:unionid,
        orderTimenew Date().getTime(),
        payStatus0 ,// 0:未支付, 1:已支付, -1:失效
        totalFee:total_fee
      }
   })
   return { 
      ...payArgs,
      // 返回数据  把payArgs里面的sign替换成第二次签名sign
      sign: getSign(payArgs)
   }
}


最后一次编辑于  2023-07-24  
点赞 0
收藏
评论

1 个评论

  • Dyn
    Dyn
    发表于移动端
    2023-07-24
    用户支付成功后,notify_url 会被触发,可以在里面处理订单状态和具体业务逻辑。前端直接 watch 订单状态,不依赖用户点击确定。
    2023-07-24
    赞同 2
    回复 1
    • Ray
      Ray
      2023-07-25
      好的,我试试呢
      2023-07-25
      回复
登录 后发表内容