- 微信小程序使用Canvas实现签字绘制功能
微信小程序使用Canvas实现签字绘制功能 1、效果图 [图片][图片] 2、代码仓库 https://gitee.com/synctimes/canvas-sign/tree/master 3、部分代码演示 Page({ data: { context1: null, hasDraw: false, //默认没有画 src: null }, onLoad: function () { var self = this; var context1 = wx.createCanvasContext('handWriting1'); context1.setStrokeStyle("#000000") context1.setLineWidth(3); this.setData({ context1: context1, }) }, touchstart1: function (e) { var context1 = this.data.context1; context1.moveTo(e.touches[0].x, e.touches[0].y); this.setData({ context1: context1, hasDraw: true, //要签字了 }); }, touchmove1: function (e) { var x = e.touches[0].x; var y = e.touches[0].y; var context1 = this.data.context1; context1.setLineWidth(3); context1.lineTo(x, y); context1.stroke(); context1.setLineCap('round'); context1.draw(true); context1.moveTo(x, y); }, reSign1: function () { //重新画 var self = this; var context1 = self.data.context1; context1.draw(); //清空画布 self.setData({ hasDraw: false, //没有画 src: null }); self.ajaxLoading = false; }, sign1ok: function () { var self = this; if (!self.data.hasDraw) { console.log("签字是空白的 没有签字") return } var context1 = self.data.context1; context1.draw(true, wx.canvasToTempFilePath({ canvasId: 'handWriting1', success(res) { console.log(res.tempFilePath) //得到了图片下面自己写上传吧 self.setData({ src: res.tempFilePath }) const fs = wx.getFileSystemManager(); fs.getFileInfo({ filePath: res.tempFilePath, success(result) { console.log("getFileInfo result=>", result) res.size = result.size; }, fail(err) { } }) } })) }, }); <view class="g-doc"> <view class="g-bd"> <view class="paper"> <canvas class="handWriting" disable-scroll="true" bindtouchstart="touchstart1" bindtouchmove="touchmove1" canvas-id="handWriting1"> </canvas> </view> </view> <view class="g-ft"> <view class="weui-flex"> <view class="weui-flex__item" bindtap="reSign1"> <view class="f-ins2"> 重新签字 </view> </view> <view class="weui-flex__item" bindtap="sign1ok"> <view class="f-ins1"> 提交 </view> </view> </view> <view class="iphonex-env-constant"></view> </view> </view> 4、相关参考文献 https://developers.weixin.qq.com/miniprogram/dev/component/canvas.html https://juejin.cn/post/6991670574200127495 5、使用问题描述 签字三 在真机安卓手机下,存在无法绘制问题。 [图片] 签字二,实际使用场景中,因为我是在 列表页-列表详情页-表单页-签字页。存在页面较多层级的状态下,会出现卡顿,iPhone越画往后会感觉卡顿明显。而页面栈只有一层时,则很流畅。 [图片]
2023-03-23 - 微信小程序base64图片 canvas 画布 drawImage 实现分享海报
在微信小程序中 canvas drawImage API 传入的第一个参数是图片资源路径,这个参数通常由wx.chooseImage 或 wx.getImageInfo 获取图片信息来获得。 而 base64 格式图片数据,无法被 getImageInfo 直接调用,以下是解决方案: 首先使用 wx.base64ToArrayBuffer 将 base64 数据转换为 ArrayBuffer 数据 使用 FileSystemManager.writeFile 将 ArrayBuffer 数据写为本地用户路径的二进制图片文件 此时的图片文件路径在 wx.env.USER_DATA_PATH 中, wx.getImageInfo 接口能正确获取到这个图片资源并 drawImage 至 canvas 上 以下是具体的转换代码: getImgCode(url) { //自己接口获取base64图片 let res = await this.$http.post(’/WeixinMin/getEqr’, { pages: url }) if (res.code == 1) { const fsm = wx.getFileSystemManager(); const FILE_BASE_NAME = ‘tmp_base64src’; const filePath = [代码]${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}[代码]; //base64 数据转换为 ArrayBuffer 数据 const buffer = wx.base64ToArrayBuffer(res.data.image); fsm.writeFile({ filePath: filePath, data: buffer, encoding: ‘binary’, success: () => { console.log('写入成功, 路径: ', filePath); }, fail: err => { console.log(“失败******”, err); }, }); } }
2020-06-08 - canvas 2D 背景图片覆盖文字的问题?
我希望背景图片置于文字下方,但是一旦写了文字和图片,图片就会覆盖掉文字,不知道有没有什么方法可以安排一下图片和文字的优先级顺序? js: wx.createSelectorQuery() .select('#canvas') .fields({ node: true, size: true }) .exec(async (res) => { const canvas = res[0].node; // Canvas 绘制上下文 const ctx = canvas.getContext('2d'); //画布大小根据屏幕分辨率进行缩放,防止模糊 const renderWidth = res[0].width const renderHeight = res[0].height // 初始化画布大熊啊 const dpr = wx.getSystemInfoSync().pixelRatio canvas.width = renderWidth*dpr canvas.height = renderHeight*dpr ctx.scale(dpr, dpr) //画布背景色 //ctx.fillStyle = "pink"; //ctx.fillRect(0, 0, canvas.width, canvas.height) //画图片 const image = canvas.createImage() image.src = "图片地址" image.onload = ()=>{ ctx.drawImage(image,100,10,414,650) } // 标题 ctx.font= 'normal bold 15px sans-serif' ctx.textAligh = "center" ctx.textBaseline = "middle" ctx.fillText('这是一个测试',100,100) ctx.font= 'normal bold 15px sans-serif' ctx.fillText('这是二个测试',200,100) })
2022-09-15 - 微信小程序测试号功能如何申请使用
为方便开发者开发和体验小程序、小游戏的各种能力,开发者可以申请小程序或小游戏的测试号,并使用此帐号在开发者工具创建项目进行开发测试,以及真机预览体验。 申请测试号申请测试号的过程非常简单。只需访问 申请地址 ,并使用微信扫描二维码,即可获得为自己分配好的小程序和小游戏测试账号。 [图片]登录测试号申请成功后,进入 微信公众平台首页,扫描登录二维码,选择已有的小程序测试号或小游戏测试号登录即可。 [图片] 创建测试号项目在得到了测试号的帐号信息之后,可以在开发者工具中使用此帐号信息创建项目进行开发。 [图片] 如图所示,打开工具并新建一个小程序项目,填入测试帐号的 appid,即可创建测试项目。 [图片] 如果需要跳过网络请求域名的校验,可勾选项目设置里的 “不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书” 选项。 点击工具栏上的预览按钮即可在真机上预览体验。在真机上如需跳过网络请求域名的校验,需要点击右上角选项,选择 “打开调试” 即可。 [图片]
2022-12-01 - 境外小程序支付攻略(云开发篇),看这一篇就够了。
一、前言 境外微信支付的实现方式,与国内支付的方式大不同,即不是V2,也不是V3,而是经由海外支付服务商,通过间连的方式来实现的。(香港地区融合钱包除外)。 以下专门介绍具体的实现攻略: 二、开通 首先,你需要先了解当地有哪些第三方支付服务商,然后选择其中一家,接入他们提供的支付服务,从而实现微信支付的开通。 1、全球第三方支付服务商: https://pay.weixin.qq.com/index.php/public/wechatpay_en/partner_search#/ 找到当地服务商的联系方式,与他们联系,他们会告诉你所需提供哪些资料,并帮你开通商户号,接入微信支付; 资料信息包括: 营业执照 翻译认证 公司银行账户 法人及联系人信息 其他信息等。 2、香港融合钱包 融合钱包以下不做介绍,技术方面和v3支付完全一样。 技术方案可以参考: https://pay.weixin.qq.com/wiki/doc/api/wxpay/en/pages/MiniProgramPay_fw.shtml 三、第三方服务商提供的支付服务 每个第三方服务商所提供的支付服务各不相同,以下分别举例: Yaband Pay (Europe PayPro B.V.): 微信支付, 支付宝, PayPal, SOFORT, IDEAL, 银联支付, List 2paynow (Europe Sepay B.V.): 微信支付, 支付宝 VR Payment (Europe CardProcess GmbH): 微信支付, 支付宝 Supay (Australia): 微信支付, 信用卡支付 其他地区第三方支付服务商,提供哪些服务,需要向他们咨询。 注: 1、境外小程序对除微信支付之外的支付方式,卡得并不象国内这样严,一般情况下,PayPal, 信用卡等方式,都支持并审核通过,支付宝会稍难点; 2、小程序里实现其他支付方式的唯一方案:生成支付链接,复制到剪贴板,在手机浏览器或微信浏览器中打开,完成支付流程。 四、第三方支付账号和接入文档 第三方帮你接入微信支付后,会回复邮件给你,并提供相关支付信息: 1. 一个属于第三方的支付账号 比如Yaband pay,支付账号类似如下: ID: yourname@yoursite.com Key: f4f70db6107xxxxxxxb75efa1f1490b4 2paynow,支付账号类似如下: ID: 541102252 Key: osVx_0POxxxxF9h3JSCls 2. 该第三方支付服务商支付接入文档 比如Yaband pay 支付文档: https://www.yabandmedia.com/api/cn-api.html 比如2paynow支付文档,是由技术支持人员发送给你的PDF文档,具体内容暂不介绍。 3. 第三方支付服务商的商家管理后台 你可以登录该后台进行配置,并查看详细的订单数据。 [图片] 五、云开发实现境外支付 因为商家可以自主选择第三方支付服务商,所以我们在实现支付功能时,需要同时支付多个第三方支付服务商。 用云开发来实现,一般会有两种方式: (1)、每个第三方的支付功能,分别用一个云函数实现; (2)、一个云函数集成所有第三方支付功能;(我们采用的是该方式) 1、云函数pay.js: 按支付接口、支付服务商、支付方式分流: const cloud = require('wx-server-sdk') const rp = require('request-promise') const CryptoJS = require('crypto-js') cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) const db = cloud.database() exports.main = async (event, context) => { switch (event.action) {//根据小程序端传入的支付相关接口分流 case 'unifiedorder': return await unifiedorder(event)//统一下单 case 'queryorder': return await queryorder(event)//订单查询 case 'refund': return await refund(event)//退款 default: return 'wrong action' } } async function unifiedorder(event) { let res = await db.collection('config').doc('payment').get().catch() if (res && res.data) { } else return 'wrong action'//注意:res?.data在云函数中不支持 let config = res.data//云数据库中保存了支付配置信息 switch (config.pay_sp) {//根据支付服务商pay_sp来分流 case '2paynow': return await unifiedorder_2paynow(event, config) case 'yaband': return await unifiedorder_yaband(event, config) case 'cloudpay': return await unifiedorder_cloudpay(event, config) case 'supay': return await unifiedorder_supay(event, config) case 'vr': return await unifiedorder_vr(event, config) case 'v2': return await unifiedorder_v2(event, config) case 'v3': return await unifiedorder_v3(event, config) case 'v2sp': return await unifiedorder_v2(event, config)//v2服务商模式 case 'v3sp': return await unifiedorder_v3(event, config)//v3服务商模式 default: return 'wrong action' } } async function queryorder(event) { let res = await db.collection('config').doc('payment').get().catch() if (res && res.data) { } else return 'wrong action' let config = res.data switch (config.pay_sp) { case '2paynow': return await queryorder_2paynow(event, config) case 'supay': return await queryorder_supay(event, config) case 'vr': return await queryorder_vr(event, config) default: return 'wrong action' } } async function refund(event) { let res = await db.collection('config').doc('payment').get() if (res && res.data) { } else return 'wrong action' let config = res.data switch (res.data.pay_sp) { case '2paynow': return await refund_2paynow(event, config) case 'yaband': return await refund_yaband(event, config) case 'cloudpay': return await refund_cloudpay(event, config) case 'supay': return await refund_supay(event, config) case 'vr': return await refund_vr(event, config) default: return 'wrong action' } } 2、统一下单(Yaband pay为例) 接口文档:https://www.yabandmedia.com/api/cn-api.html // -------------------yaband----------------------------------------------------------- async function unifiedorder_yaband(event, config) { let notify_url = config.notify_url let user = config.mchid let key = config.key let timeStamp = parseInt(Date.now() / 1000) let payMethod = event.pay_method if (payMethod == 'wechat') {//微信支付 const wxContext = cloud.getWXContext() let param = { "user": user, "method": "v3.CreatePaymentsWechatMiniPay", "time": timeStamp, } let data = { "pay_method": "online", "sub_pay_method": "WeChat Pay", "order_id": event.out_trade_no, "amount": event.total_fee || "0.1", "currency": event.fee_type || config.currency, "description": event.body || "YabandPay pay", "demo": event.demo || "order", "timeout": "0", "notify_url": notify_url, "sub_app_id": wxContext.FROM_APPID || wxContext.APPID, "sub_open_id": wxContext.FROM_OPENID || wxContext.OPENID } let sign = getSign_yaband({ ...param, ...data }, key) let body = { ...param, sign, data } let res = await rp({ url: "https://mapi.yabandpay.com/Payments", method: 'POST', body, json: true }) let payment = res.data.parameters return { payment, sp_trade_no: res.data.trade_id } } if (payMethod == 'sofort') {//省略 } if (payMethod == 'alipay') {//省略 } if (payMethod == 'paypal') {//Paypal支付 let param = { "user": user, "method": "v3.CreatePayments", "time": timeStamp, } let data = { "pay_method": "online", "sub_pay_method": "PAYPAL/RECURRING", "order_id": event.out_trade_no, "amount": event.total_fee || "0.1", "currency": event.fee_type || config.currency, "description": event.body || "YabandPay pay", "demo": event.demo || "order", "post_email": "xin.liu@elbsino.com", "timeout": "0", "redirect_url": "https://www.klarna.com/de/", "notify_url": notify_url } let sign = getSign_yaband({ ...param, ...data }, key) let body = { ...param, sign, data } let res = await rp({ url: "https://mapi.yabandpay.com/Payments", method: 'POST', body, json: true }) let url = res.data.url return { url }//除微信支付外,都必须返回一个url:支付链接 } } async function refund_yaband(event, config) { console.log('refund_yaband') let notify_url = config.notify_url let user = config.mchid let key = config.key let timeStamp = parseInt(Date.now() / 1000) let param = { "user": user, "method": "v3.CreateRefund", "time": timeStamp, } let data = { "trade_id": event.trade_id, "refund_amount": event.refund_amount || "0.1", "refund_currency": config.refund_currency, "refund_description": event.refund_description || "test", "notify_url": notify_url } let sign = getSign_yaband({ ...param, ...data }, key) let body = { ...param, sign, data } console.log(body) return await rp({ url: "https://mapi.yabandpay.com/Payments", method: 'POST', body, json: true }) } function getSign_yaband(args, key, sa = []) {//每个支付服务商的签名方式都不一样 for (let k in args) sa.push(k + '=' + args[k]) sa = sa.sort() let signStr = sa.join('&') let hash = CryptoJS.HmacSHA256(signStr, key) return CryptoJS.enc.Hex.stringify(hash) } function getSign_2paynow(args, key) {//2paynow的签名算法。 let signStr = args.function + args.mid + args.timestamp + key let hash = CryptoJS.MD5(signStr, key) return CryptoJS.enc.Hex.stringify(hash) } 踩坑实录: 1、每次统一下单,都会产生三种订单号: 商家订单号 支付服务商的支付订单号 微信支付订单号 记住:一定要保存支付服务商的支付订单号,因为有些支付服务商在订单查询和退款接口中,只认该订单号。 2、每个服务商的签名方案是不同的,有的甚至不需要签名,这个需要分别对待。 六、支付成功异步通知 多个服务商的异步通知,用一个云函数来实现。 云函数:notify.js const cloud = require('wx-server-sdk') cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) const db = cloud.database() const _ = db.command exports.main = async (event, context) => { let res = await db.collection('config').doc('payment').get() switch (res.data.pay_sp) { case '2paynow': return await notify_2paynow(event) case 'yaband': return await notify_yaband(event) case 'cloudpay': return await notify_cloudpay(event) case 'vr': return await notify_vr(event)//vr暂时不支持回调通知 case 'supay': return await notify_supay(event) case 'v2': return await notify_v2(event) case 'v3': return await notify_v3(event) default: return 'wrong action' } } async function notify_2paynow(event) { console.log('notify_2paynow') let qs = event.queryStringParameters if (qs.merchant_trade_no) { } else return 'success' await db.collection('payment').add({ data: qs }).then(res => console.log(res)) if (qs.merchant_trade_no && qs.trade_status == 'TRADE_SUCCESS') { await onPaymentSuccess(qs.merchant_trade_no, qs.trade_no, qs.original_trade_no) } return 'success' } async function notify_yaband(event) { console.log('notify_yaband') if (event.body) { } else return { statusCode: 200, body: 'ok' } let body = JSON.parse(event.body) let pay = body.data await db.collection('payment').add({ data: pay }).then(res => console.log(res)) if (pay.transaction_id && pay.state == 'paid') { await onPaymentSuccess(event.outTradeNo) } return { statusCode: 200, body: 'ok' } } async function notify_cloudpay(event) {//云支付pay_cb console.log('notify_cloudpay') if (event.outTradeNo) { await db.collection('payment').add({ data: event }).then(res => console.log(res)) if (event.returnCode == 'SUCCESS' && event.resultCode == 'SUCCESS') { await onPaymentSuccess(event.outTradeNo) } } return { "errcode": 0, "errmsg": 'SUCCESS' } } 踩坑实录: 1、有些国外支付服务商,并不提供异步通知功能,比如VR Payment,这就很尴尬了,因为我们业务的流程里,是非常依赖这个功能的,因此,后期造成了大量的代码修改工作,建议大家从一开始就考虑这种情况。 七、币种选择 统一下单时,支持两种币种: 1、CNY 2、当地币种,比如EUR 境外退款,一般只能使用当地币退款,不支持RMB。 八、境外小程序云开发禁用后的选择 目前境外小程序的云开发功能已经被禁用,可以通过环境共享的模式支持以上云开发境外支付方案; 1、共享在禁用令之前的同主体小程序的云环境; 2、我们是采用开放平台第三方服务商批量云开发模式; 九、境外小程序相关文章 1、https://developers.weixin.qq.com/community/develop/article/doc/000aec921e4fd8a320ec0f9795bc13 2、https://developers.weixin.qq.com/community/develop/article/doc/0000e805af0900b37f6c900c356c13 3、https://developers.weixin.qq.com/community/develop/article/doc/000a68f1a24a687242eb2427556013 4、https://developers.weixin.qq.com/community/develop/article/doc/000860b434cd180a749b9268f51c13
2022-05-31 - 商家付款到零钱,V3接口对接详细教程
出个教程吧,官方文档看着一头雾水 上架付款到零钱与之前的企业付款基本一个性质,不同点是这个是批量,那个一次一个。 接入前准备无需多言。直接入正题。 一、获取平台证书 这个平台证书就是微信的证书,不是我们商户后台设置的证书。这个证书的作用是加密后续请求以及设置后续请求的serial_no。官网文章:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_0.shtml 1:请求url:https://api.mch.weixin.qq.com/v3/certificates 2:这里header构造参数的时候要注意以下几点: a)Authorization内的signature用到的签名私钥,就是我们后台申请的私钥apiclient_cert.p12里面的私钥信息。 b)Authorization内的serial_no,就是apiclient_cert.p12的证书编号。 c)注意请求和返回都是JSON字符串即可。 3:当你正确的拿到返回结果之后,需要对结果内容进行解密拿到证书信息。 a)解密用到的密钥(就是我们再商户平台设置的那个APIV3密钥) b)解密逻辑,仿照官网即可:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_2.shtml 4:完成上述步骤之后,也就得到了服务器上的证书信息。这个证书的作用就是用来加密我们后续的请求用的。 二、开始请求商家付款到零钱 1:文档位置:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter4_3_1.shtml 2:请求参数,json格式参数没啥说的,主要是加密,稍后我们说真实姓名加密如何操作 3:构造header的时候 a)Authorization内的signature用到的签名私钥,就是我们后台申请的私钥apiclient_cert.p12里面的私钥信息。这里跟上面是一致的 b)Authorization内的serial_no,就是apiclient_cert.p12的证书编号。 c)Wechatpay-Serial用的是【第一步】获取到的证书的serialNo【这里是重点】。 4:实名认证的时候 实名认证的时候需要用第一步拿到的证书来进行加密,第一步的证书就是X509。然后根据https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_3.shtml进行加密即可 这里也就说明了,为什么Wechatpay-Serial的证书编号是第一步获取的证书编号的原因了。 5:完成以上操作,即可调起! 三、不对地方还请扶正
2022-12-08 - 云开发短信跳小程序(自定义开发版)教程
写在前面如果你想要自主开发,但没有云开发相关经验,可以采用演示视频来学习本教程: [视频] 一、能力介绍境内非个人主体的认证的小程序,开通静态网站后,可以免鉴权下发支持跳转到相应小程序的短信。短信中会包含支持在微信内或微信外打开的静态网站链接,用户打开页面后可一键跳转至你的小程序。 这个链接的网页在外部浏览器是通过 URL Scheme 的方式来拉起微信打开主体小程序的。 总之,短信跳转能力的实现分为两个步骤,「配置拉起网页」和「发送短信」。本教程将介绍如何执行操作完成短信跳转小程序的能力。 如果你想要无需写代码就能完成短信跳转小程序的能力,可以参照无代码版教程进行逐步实现。 二、操作指引1、网页创建首先我们需要构建一个基础的网页应用,在任何代码编辑器创建一个 html 文件,在教程这里命名为 index.html 在这个 html 文件中输入如下代码,并根据注释提示更换自己的信息: window.onload = function(){ window.web2weapp.init({ appId: 'wx999999', //替换为自己小程序的AppID gh_ID: 'gh_999999',//替换为自己小程序的原始ID env_ID: 'tcb-env',//替换小程序底下云开发环境ID function: { name:'openMini',//提供UrlScheme服务的云函数名称 data:{} //向这个云函数中传入的自定义参数 }, path: 'pages/index/index.html' //打开小程序时的路径 }) } 以上引入的 web2weapp.js 文件是教程封装的有关拉起微信小程序的极简应用,我们直接引用即可轻松使用。 如果你想进一步学习和修改其中的一些WEB展示信息,可以前往 github 获取源码并做修改。 有关于网页拉起小程序的更多信息可以访问官方文档 如果你只想体验短信跳转功能,在执行完上述文件创建操作后,继续以下步骤。 2、创建服务云函数在上面创建网页的过程中,需要填写一个UrlScheme服务云函数。这个云函数主要用来调用微信服务端能力,获取对应的Scheme信息返回给调用前端。 我们在示例中填写的是 openMini 这个命名的云函数。 我们前往微信开发者工具,定位对应的云开发环境,创建一个云函数,名称叫做 openMini 。 在云函数目录中 index.js 文件替换输入以下代码: const cloud = require('wx-server-sdk') cloud.init() exports.main = async (event, context) => { return cloud.openapi.urlscheme.generate({ jumpWxa: { path: '', // 打开小程序时访问路径,为空则会进入主页 query: '',// 可以使用 event 传入的数据制作特定参数,无需求则为空 }, isExpire: true, //是否到期失效,如果为true需要填写到期时间,默认false expire_time: Math.round(new Date().getTime()/1000) + 3600 //我们设置为当前时间3600秒后,也就是1小时后失效 //无需求可以去掉这两个参数(isExpire,expire_time) }) } 保存代码后,在 index.js 右键,选择增量更新文件即可更新成功。 接下来,我们需要开启云函数的未登录访问权限。进入小程序云开发控制台,转到设置-权限设置,找到下方未登录,选择上几步我们统一操作的那个云开发环境(注意:第一步配置的云开发环境和云函数所在的环境,还有此步操作的环境要一致),勾选打开未登录 [图片] 接下来,前往云函数控制台,点击云函数权限,安全规则最后的修改,在弹出框中按如下配置: [图片] 3、本地测试我们在本地浏览器打开第一步创建的 index.html ;唤出控制台,如果效果如下图则证明成功! 需要注意,此处本地打开需要时HTTP协议,建议使用live server等扩展打开。不要直接在资源管理器打开到浏览器,会有跨域的问题! [图片] 4、上传本地创建好的 index.html 至静态网站托管将本地创建好的 index.html 上传至静态网站托管,在这里静态托管需要是小程序本身的云开发环境里的静态托管。 如果你上传至其他静态托管或者是服务器,你仍然可以使用外部浏览器拉起小程序的能力,但会丧失在微信浏览器用开放标签拉起小程序的功能,也不会享受到云开发短信发送跳转链接的能力。 如果你的目标小程序底下有多个云开发环境,则不需要保证云函数和静态托管在一个环境中,无所谓。 比如你有A、B两个环境,A部署了上述的云函数,但是把 index.html 部署到B的环境静态托管中了,这个是没问题的,符合各项能力要求。只需要保证第一步 index.html 网页中的云开发环境配置是云函数所在环境即可。 部署成功后,你便可以访问静态托管的所在地址了,可以通过手机外部浏览器以及微信内部浏览器测试打开小程序的能力了。 5、短信发送云函数的配置在上面创建 openMini 云函数的环境中再来一个云函数,名字叫 sendsms 。 在此云函数 index.js 中配置如下代码: const cloud = require('wx-server-sdk') cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV, }) exports.main = async (event, context) => { try { const config = { env: event.env, content: event.content ? event.content : '发布了短信跳转小程序的新能力', path: event.path, phoneNumberList: event.number } const result = await cloud.openapi.cloudbase.sendSms(config) return result } catch (err) { return err } } 保存代码后,在 index.js 右键,选择增量更新文件即可更新成功。 6、测试短信发送能力在小程序代码中,在 app.js 初始化云开发后,调用云函数,示例代码如下: App({ onLaunch: function () { wx.cloud.init({ env:"tcb-env", //短信云函数所在环境ID traceUser: true }) wx.cloud.callFunction({ name:'sendsms', data:{ "env": "tcb-env",//网页上传的静态托管的环境ID "path":"/index.html",//上传的网页相对根目录的地址,如果是根目录则为/index.html "number":[ "+8616599997777" //你要发送短信的目标手机,前面需要添加「+86」 ] },success(res){ console.log(res) } }) } }) 重新编译运行后,在控制台中看到如下输出,即为测试成功: [图片] 你会在发送的目标手机中收到短信,因为短信中包含「退订回复T」字段,可能会触发手机的自动拦截机制,需要手动在拦截短信中查看。 需要注意:你可以把短信云函数和URLScheme云函数分别放置在不同云开发环境中,但必须保证所放置的云开发环境属于你操作的小程序 另外,出于防止滥用考虑,短信发送的云调用能力需要真实小程序用户访问才可以生效,你不能使用云端测试、云开发JS-SDK以及其他非wx.cloud调用方式(微信侧WEB-SDK除外),会提示如下错误: [图片] 如果你想在其他处使用此能力,可以使用服务端API来做正常HTTP调用,具体访问官方文档 7、查看短信监控图表进入 云开发控制台 > 运营分析 > 监控图表 > 短信监控,即可查看短信监控曲线图、短信发送记录。 [图片] 三、总结短信跳转小程序核心是静态网站中配置的可跳转网页,外部浏览器通过URL Scheme 来实现的,这个方式不适用于微信浏览器,需要使用开放标签才可以URL Scheme的生成是云调用能力,需要是目标小程序的云开发环境的云函数中使用才可以。并且生成的URL Scheme只能是自己小程序的打开链接,不能是任意小程序(和开放标签的任意不一致)短信发送能力的体验是每个有免费配额的环境首月100条,如有超过额度的需求可前往开发者工具-云开发控制台-对应按量付费环境-资源包-短信资源包,进行购买。如当前资源包无法满足需求也可通过云开发 工单 提交申请[图片]短信发送也是云调用能力,需要真实小程序用户调用才可以正常触发,其他方式均报错返回参数错误,出于防止滥用考虑云函数和网页的放置可以不在同一个环境中,只需要保证所属小程序一致即可。(需要保证对应环境ID都能接通)如果你不需要短信能力,可以忽略最后两个步骤CMS配置渠道投放、数据统计可参考官方文档
2021-04-07 - 微信开放平台 平台型服务商只能添加30个开发小程序?
就是我目前的义务是,我有要为很多客户提供小程序服务,一个客户就有一个小程序,类似凡科的服务,每次我升级版本,或者修改bug,都需要一个一个小程序的去打包上传,所以我想通过微信开放平台,弄一个开放服务,让客户的小程序授权平台,然后就可以统一管理代码上线下线等,但是现在遇到一个问题,就是平台型服务商最多只能添加30个开发小程序,但是我的小程序不止30个,我这种情况有没有其他的解决方案,望平台关注,万分感谢,十万火急。
2021-02-12 - 小程序中可以开发支付宝支付嘛?
客户需求,想要支付宝的支付方式。知道微信公众号可以对接支付宝支付,但是小程序的没有见过。 告诉我是否支持即可,不管什么方式。
2021-01-15 - 用户信息接口不返回用户昵称和头像了,那以后从哪里获取用户昵称和头像呀?
收到通知说:2021.12.27后,公众号用户信息获取接口,https://developers.weixin.qq.com/doc/offiaccount/User_Management/Get_users_basic_information_UnionID.html#UinonId 不再返回用户昵称和头像信息,如需获取请通过相关业务用户授权获取。 这个“通过相关业务用户授权”的是哪个接口呀?怎么获取呀? [图片]
2021-12-07 - 关于小程序安全测试的通知
为进一步提升小程序的安全性和用户体验,目前平台正在对提审的小程序进行安全测试,以便能及时帮助开发者发现小程序可能存在的安全漏洞。 一、背景介绍 小程序在开发过程中若存在安全漏洞的情况,如敏感数据篡改、拖库信息泄露、WEB攻击等,容易造成小程序的安全隐患,可能带来代码易被反编译,核心业务逻辑被破译,算法易被二次打包等风险。因此,平台将对提审的小程序进行安全测试,以协助开发者提升小程序服务的安全性。 二、测试过程 安全测试过程中,平台会模拟真实业务场景,向提审小程序的后台发送服务请求,服务器会收到来自平台(显示为:Tencent Security Team,请求IP为106.55.202.118;113.96.223.69;125.39.132.125)的测试请求。测试均以较低速率进行,正常情况下不会影响小程序的正常服务。特殊情况下如有必要,开发者可基于自身业务情况,对相应请求加以限频,如有其他疑问,欢迎随时通过官方社区进行反馈。 三、测试结果 安全测试的结果是小程序审核的重要参考。若小程序在安全测试中被检测到存在安全漏洞,该小程序的审核将不予通过。开发者可根据修改指引,对安全漏洞进行相应修复后,再重新进行提审。
2021-11-01 - 今天调用file.api.weixin.qq.com取图报43003错误,以前都不会的,怎么办?
用微信api上传图片后再调用http://file.api.weixin.qq.com取图,结果报43003错误,引导说明网页显示不再支持HTTP方式调用。但是如果直接改用 https://file.api.weixin.qq.com,又会报错: No subject alternative DNS name matching file.api.weixin.qq.com found. 以前一直都还好,就今天开始报错了。该怎么办啊?
2020-09-18