精华内容
下载资源
问答
  • 二维码扫码开门在垃圾分类中的应用
    2019-09-17 10:54:21

    一种垃圾投放口二维码开门系统。背景技术:随着人口的增长、经济的发展和人们生活水平的不断提高,垃圾的产量不断增加,垃圾的成分也发生了很大的变化。许多国家都把垃圾视为环境破坏的祸首。垃圾,既是人类文明的副产品,又是人类生存的“污染物”,垃圾已成为当今世界一大公害。根据联合国人口统计资料,20 世纪末世界人口有 70 %~ 80 %聚集到城市,城市化发展,致使人口密集,人们消费水平不断提高,垃圾量猛增,许多城市形成了“垃圾围城”的严重污染局面,这既侵占了大量土地,污染土壤、空气和水体,破坏生态环境,又易滋生蚊蝇传染疾病。垃圾对人类的危害越来越大,严重地威胁着人们的生活和健康。

    因此,城市生活垃圾的消纳处理和综合治理,已成为影响和制约城市整体功能正常发挥和城市居民生活及劳动环境的突出因素。解决生活垃圾的处理问题,不再仅是垃圾的最终出路问题,而是生活垃圾源头的减量化、过程资源化和末端无害化的综合管理问题。而生活垃圾源头的减量化是减少城市成活垃圾的根本。

    技术特征:

    1.一种垃圾投放口二维码扫码开门系统,其特征在于,包括:二维码扫码器,其设置在垃圾箱投放口位置,其具有用于扫描二维码的扫描摄像头,用于扫描居民提供的二维码;用户信息采集器,其通过网线传输方式与所述二维码扫码器连接,接收二维码扫码器发送的二维码信息和身份验证信息;投放口开关控制器,其与所述用户信息采集器连接,接收所述用户信息采集器发送的开启信号,将垃圾投放口开启。

    2.垃圾投放口二维码扫码开门系统,其特征在于,还包括荧光灯,其设置在所述扫描摄像头一侧。

    3.垃圾投放口二维码扫码开门系统,其特征在于,还包括大数据管理器,其与所述用户信息采集器连接。

    4.垃圾投放口二维码扫码开门系统,其特征在于,所述垃圾投放口上还设置有拍摄摄像头,用于采集用户图像。

    5.垃圾投放口二维码扫码开门系统,其特征在于,还包括称重传感器,其与所述用户信息采集器连接,将垃圾重量信息传递给用户信息采集器。技术总结公开了一种垃圾投放口二维码扫码开门系统,包括:二维码扫码器,其设置在垃圾箱投放口位置,其具有用于扫描二维码的扫描摄像头,用于扫描居民提供的二维码;用户信息采集器,其通过网线传输方式与二维码扫码器连接,接收二维码扫码器发送的二维码信息和身份验证信息;投放口开关控制器,其与所述用户信息采集器连接,接收所述用户信息采集器发送的开启信号,将垃圾投放口开启,通过用户提供二维码经二维码扫描器扫描后将垃圾投放口开启,大大方便了垃圾的投放。

    转载于:https://my.oschina.net/u/4163596/blog/3079359

    更多相关内容
  • Honeywell霍尼韦尔1400G二维码扫码器用户手册(中文),手册详解详实,包含设置扫描器的开关参数。
  • uniapp中应用H5自定义二维码扫码界面

    千次阅读 热门讨论 2020-09-10 15:48:17
    uniapp中应用H5自定义二维码扫码界面最终效果pages配置组件代码 最终效果 pages配置 { "path": "components/barcode/scan-page", "style": { "navigationBarTitleText": "扫一扫" } } 组件代码 <template&...

    uniapp中应用H5自定义二维码扫码界面

    最终效果

    效果图

    pages配置

    {
    	"path": "components/barcode/scan-page",
    	"style": {
    		"navigationBarTitleText": "扫一扫"
    	}
    }
    

    组件代码

    <template>
    
    	<view>
    		<!-- 扫码页面 -->
    		<!-- #ifndef APP-PLUS -->
    		<view class="wrap">
    			<view class="u-tips-color">
    				请在app中打开
    			</view>
    		</view>
    		<!-- #endif -->
    	</view>
    </template>
    
    <script>
    	export default {
    		data() {
    			return {
    				barcode: null,
    				flash: false,
    				tip: '将二维码放入框中,即可自动扫描',
    			}
    		},
    		onShow() {
    			// 页面展示时,重新启动扫描检测
    			if (this.barcode) {
    				this.barcode.start()
    			}
    		},
    		onLoad(params) {
    			const {
    				tip
    			} = params
    			if (tip) {
    				this.tip = tip
    			}
    			// #ifdef APP-PLUS
    			plus.navigator.setFullscreen(true); //全屏
    			let currentWebview = this.$scope.$getAppWebview();
    			this.createBarcode(currentWebview)
    			this.createTipInfoView(currentWebview)
    			this.createFlashBarView(currentWebview)
    			// #endif
    		},
    		mounted() {
    
    		},
    		methods: {
    			/**
    			 * 创建二维码
    			 * @param {Object} currentWebview
    			 */
    			createBarcode(currentWebview) {
    				if (!this.barcode) {
    					this.barcode = plus.barcode.create('barcode', [plus.barcode.QR], {
    						top: `0px`,
    						left: '0px',
    						height: `100%`,
    						width: '100%',
    						position: 'absolute',
    						background: '#FFCC00',
    						frameColor: '#FFCC33',
    						scanbarColor: '#FFCC33',
    					});
    					this.barcode.onmarked = this.onmarked;
    					this.barcode.setFlash(this.flash);
    					//此处未演示扫码成功回调的地址设置,实际请参考HTML5Plus API自行处理  
    					//注意扫码区域需为正方形,否则影响扫码识别率  
    					currentWebview.append(this.barcode);
    				}
    				this.barcode.start()
    			},
    
    			/**
    			 * 创建提示信息
    			 * @param {Object} currentWebview
    			 */
    			createTipInfoView(currentWebview) {
    				const content = new plus.nativeObj.View('content', {
    						top: '0px',
    						left: '0px',
    						height: '100%',
    						width: '100%'
    					},
    					[{
    						tag: 'font',
    						id: 'scanTips',
    						text: this.tip,
    						textStyles: {
    							size: '14px',
    							color: '#ffffff',
    							whiteSpace: 'normal'
    						},
    						position: {
    							top: '90px',
    							left: '10%',
    							width: '80%',
    							height: 'wrap_content'
    						}
    					}]);
    				currentWebview.append(content);
    
    			},
    			// 创建 开关灯按钮
    			createFlashBarView(currentWebview) {
    
    				const openImg = this.crtFlashImg('static/yellow-scanBar.png')
    				const closeImg = this.crtFlashImg('static/scanBar.png')
    				const scanBarVew = new plus.nativeObj.View('scanBarVew', {
    						top: '65%',
    						left: '40%',
    						height: '10%',
    						width: '20%',
    					},
    					closeImg);
    				scanBarVew.interceptTouchEvent(true);
    
    				currentWebview.append(scanBarVew);
    
    				scanBarVew.addEventListener("click", (e) => { //点亮手电筒
    					this.flash = !this.flash;
    					if (this.flash) {
    						scanBarVew.draw(openImg);
    					} else {
    						scanBarVew.draw(closeImg)
    					}
    					if (this.barcode) {
    						this.barcode.setFlash(this.flash);
    					}
    				}, false)
    			},
    			crtFlashImg(imgsrc) {
    				return [{
    					tag: 'img',
    					id: 'scanBar',
    					src: imgsrc,
    					position: {
    						width: '28%',
    						left: '36%',
    						height: '30%'
    					}
    				}, {
    					tag: 'font',
    					id: 'font',
    					text: '轻触照亮',
    					textStyles: {
    						size: '10px',
    						color: '#ffffff'
    					},
    					position: {
    						width: '80%',
    						left: '10%'
    					}
    				}]
    			},
    			// 扫码成功回调
    			onmarked(type, result) {
    				console.log('条码类型:' + type);
    				console.log('条码内容:' + result);
    				// 业务代码
    				// 核对扫描结果
    				// 判断是否是正确的格式
    				// 不正确则跳转到 错误页面
    					
    			}
    
    		}
    	}
    </script>
    
    <style scoped>
    	.wrap {
    		height: calc(100vh);
    		/* #ifdef H5 */
    		height: calc(100vh - var(--window-top));
    		/* #endif */
    		display: flex;
    		flex-direction: column;
    		justify-content: center;
    		align-items: center;
    	}
    </style>
    
    

    参考资料
    h5 barcode

    展开全文
  • 快速集成zxing二维码扫描,生成二维码,可配置相册,闪光灯,相机可以调整焦距放大缩小,自定义扫描线颜色,自定义背景颜色,自定义遮罩层,自定义Activity,多个二维码扫码(zxing:core:3.3.3/3.4.0) 1:生成...

    现在很多App都有扫码识别二维码的场景,最新的扫码已经支持全屏扫码、从相册选取二维码识别,以下使用基于Zxing封装的一个库:https://github.com/maning0303/MNZXingCode

    MNZXingCode 快速集成zxing二维码扫描
    快速集成zxing二维码扫描,生成二维码,可配置相册,闪光灯,相机可以调整焦距放大缩小,自定义扫描线颜色,自定义背景颜色,自定义遮罩层,自定义Activity,多个二维码扫码(zxing:core:3.3.3/3.4.0)

    1:生成二维码,支持修改颜色和边距,支持带Logo
    2:二维码扫描,手势缩放,无拉伸,样式自定义
    3:相册中选取图片识别
    4:闪光灯开关
    5: 相机可以调整焦距放大缩小
    6: 完全自定义遮罩层
    7: 自定义Activity
    8: 支持微信,支付宝类似多个二维码扫码

    gradle集成方式:

        //扫一扫支持全屏、从相册选择:需要支持7.0以下
        implementation 'com.google.zxing:core:3.3.3'
        implementation 'com.github.maning0303:MNZXingCode:V2.1.8'

    具体使用:

    //(1)默认扫描使用:
    
            MNScanManager.startScan(this, new MNScanCallback() {
                @Override
                public void onActivityResult(int resultCode, Intent data) {
                    switch (resultCode) {
                        case MNScanManager.RESULT_SUCCESS:
                            String resultSuccess = data.getStringExtra(MNScanManager.INTENT_KEY_RESULT_SUCCESS);
                            break;
                        case MNScanManager.RESULT_FAIL:
                            String resultError = data.getStringExtra(MNScanManager.INTENT_KEY_RESULT_ERROR);
                            break;
                        case MNScanManager.RESULT_CANCLE:
                            showToast("取消扫码");
                            break;
                    }
                }
            });
    // (2)自定义扫描布局和参数
            MNScanConfig scanConfig = new MNScanConfig.Builder()
                    //设置完成震动
                    .isShowVibrate(true)
                    //扫描完成声音
                    .isShowBeep(true)
                    //显示相册功能
                    .isShowPhotoAlbum(true)
                    //显示闪光灯
                    .isShowLightController(false)
                    //打开扫描页面的动画
                    .setActivityOpenAnime(R.anim.activate_in)
                    //退出扫描页面动画
                    .setActivityExitAnime(R.anim.activate_out)
                    //自定义文案--不展示
                    .setScanHintText("")
                    //自定义文案颜色
                    .setScanHintTextColor("#FFFFFF")
                    //自定义文案大小(单位sp)
                    .setScanHintTextSize(15)
                    //是否显示缩放控制器
                    .isShowZoomController(false)
                    //显示缩放控制器位置
                    .setZoomControllerLocation(MNScanConfig.ZoomControllerLocation.Bottom)
                    //背景颜色
                    .setBgColor("#33FF0000")
                    //扫描线样式
                    .setLaserStyle(MNScanConfig.LaserStyle.Line)
                    //扫描线的颜色
                    .setScanColor("#E61F55")
                    //网格扫描线的列数
                    .setGridScanLineColumn(30)
                    //网格高度
                    .setGridScanLineHeight(1)
                    //高度偏移值(单位px)+向上偏移,-向下偏移
                    .setScanFrameHeightOffsets(150)
                    //是否全屏范围扫描
                    .setFullScreenScan(true)
                    //二维码标记点
                    .isShowResultPoint(true)
                    // 设置标记点的大小、色值
                    .setResultPointConfigs(36, 20, 2, "#FFFFFFFF", "#E61F55")
                    //状态栏设置:颜色,是否黑色字体
                    .setStatusBarConfigs("#00000000", true)
                    //是否支持多二维码同时扫出,默认false,多二维码状态不支持条形码
                    .setSupportMultiQRCode(true)
                    //自定义遮罩
                    .setCustomShadeViewLayoutID(R.layout.layout_custom_view, new MNCustomViewBindCallback() {
                        @Override
                        public void onBindView(View customView) {
                            //TODO:通过findviewById 获取View
                            // 返回按钮,点击关闭扫描
                            ImageView ivBack = customView.findViewById(R.id.ivBack);
                            //TODO 打开相册,选择二维码
                            ImageView ivPhoto = customView.findViewById(R.id.ivPhoto);
                            tvTips = customView.findViewById(R.id.tvTips);
                            scanLine = customView.findViewById(R.id.scanLine);
                            ivBack.setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View v) {
                                    //关闭扫描页面
                                    MNScanManager.closeScanPage();
                                }
                            });
                            ivPhoto.setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View v) {
                                    //打开相册扫描
                                    RxPermissions.getInstance(activity).request(
                                            Manifest.permission.WRITE_EXTERNAL_STORAGE,
                                            Manifest.permission.READ_EXTERNAL_STORAGE,
                                            Manifest.permission.CAMERA)
                                            .subscribe(new Observer<Boolean>() {
                                                @Override
                                                public void onCompleted() {
                                                }
    
                                                @Override
                                                public void onError(Throwable e) {
                                                }
    
                                                @Override
                                                public void onNext(Boolean aBoolean) {
                                                    if (aBoolean) {
                                                        MNScanManager.openAlbumPage();
                                                    } else {
                                                        Toast.makeText(activity, R.string.permission_request_denied, Toast.LENGTH_LONG)
                                                                .show();
                                                    }
                                                }
                                            });
                                }
                            });
                            startScanAnimation();
                        }
                    })
                    .builder();
    // 开启扫描
            MNScanManager.startScan(activity, scanConfig, new MNScanCallback() {
                public void onActivityResult(int resultCode, Intent data) {
                    switch (resultCode) {
                        case MNScanManager.RESULT_SUCCESS:
                            String resultSuccess = data.getStringExtra(MNScanManager.INTENT_KEY_RESULT_SUCCESS);
                            if (callback != null) {
                                callback.onResult(resultSuccess);
                            } else {
                                handleDecode(activity, from, resultSuccess, barcode);
                            }
                            break;
                        case MNScanManager.RESULT_FAIL:
                            // 错误提示:比如:初始化相机失败等
                            String resultError = data.getStringExtra(MNScanManager.INTENT_KEY_RESULT_ERROR);
                           
                            break;
                        case MNScanManager.RESULT_CANCLE:
                            ZZSSLog.e("取消扫码");
                            break;
                    }
                }
            });
    Activity中调用以上方法:
    
    // (1)授权相机、读写权限
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                activity.requestPermissions(
                        new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE},
                        REQUEST_CODE_OF_SCAN_PAGE);
            }
    
    
    // (2)在onRequestPermissionsResult,获取授权请求结果后,启动扫码
        @Override
        public void onRequestPermissionsResult(final int requestCode, @NonNull String[] permissions,
                                               @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            if (requestCode == REQUEST_CODE_OF_SCAN_PAGE) {
                // 将最上面的扫描代码写在startScan()方法中,进行调用,也可以将扫描结果回调出来,随时使用。
                startScan(this);
            }
        }
    展开全文
  • 饭店,商铺存在共享的wifi的地方,只需要贴出二维码,用户扫描后自动连接 小程序 缺点:android6版本 ios11版本 图片演示 (此图片来源于网络,如有侵权,请联系删除! ) 实现代码(IOS没看懂文档说明 只简单的带过 希望能...
  • 本demo实现了一维码二维码扫描功能,加入了相册图片识别,加入了开关灯按钮。可快速接入项目中。 [注:本内容来自网络,在此分享仅为帮助有需要的网友,如果侵犯了您的权利,麻烦联系我,我会第一时间删除,谢谢您。...
  • python实现微信扫码支付完整流程

    千次阅读 2021-03-04 13:54:35
    生成支付二维码2.签名加密方式,将Key 和参数进行混合加密3.out_trade_no为微信平台那边需要的订单号4.nonce_str 为我们商户提供的32位以内的随机字符串三、前端回调提示用户支付成功四、 云服务平台微信通知 微信...

    微信官方开发文档:
    https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1

    一、支付前要做的准备

    我们需要准备的东西:

    1. 微信开放平台申请应用的appid , 商户号mch_id, 秘钥API_KEY, 这些信息会作为收款的凭据。

    2. 安装依赖:
      python的版本是: 3.7, django的版本是: 2.0.13

    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple lxml
    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple django-qrcode==0.3
    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple django-wechat==0.1a1
    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple html5lib==1.0.1
    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple idna==2.7
    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple image==1.5.25
    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple optionaldict==0.1.1
    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pytz==2018.5
    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple qrcode==6.0
    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple six==1.10.0
    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple urllib3==1.23
    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple webencodings==0.5.1
    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple wechatpy==1.7.5
    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple xmltodict==0.11.0
    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple bs4
    
    1. 统一支付接口: https://api.mch.weixin.qq.com/pay/unifiedorder
      ,此接口必须采用post方式调用,必须需要传的参数解释如下:
    字段名变量名类型示例值描述
    公众账号IDappidString(32)wxd678efh567hg6787微信支付分配的公众账号ID(企业号corpid即为此appId)
    商户号mch_idString(32)1230000109微信支付分配的商户号
    随机字符串nonce_strString(32)5K8264ILTKCH16CQ2502SI8ZNMTM67VS随机字符串,长度要求在32位以内。推荐随机数生成算法
    签名signString(32)C380BEC2BFD727A4B6845133519F3AD6通过签名算法计算得出的签名值,详见签名生成算法
    商品描述bodyString(128)腾讯充值中心-QQ会员充值商品简单描述,该字段请按照规范传递,具体请见参数规定
    商户订单号out_trade_noString(32)20150806125346商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-
    标价金额total_feeInt88订单总金额,单位为分,详见支付金额
    终端IPspbill_create_ipString(64)123.12.12.123支持IPV4和IPV6两种格式的IP地址。用户的客户端IP
    通知地址notify_urlString(256)http://www.weixin.qq.com/wxpay/pay.php异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。
    交易类型trade_typeString(16)JSAPIJSAPI -JSAPI支付NATIVE -Native支付APP -APP支付
    注: 我们是扫码模式的支付,因此要设置trade_type='NATIVE ’
    1. 支付接口参数样例:
    <xml>
       <appid>wx2421b1c4370ec43b</appid>
       <attach>支付测试</attach>
       <body>JSAPI支付测试</body>
       <mch_id>10000100</mch_id>
       <detail><![CDATA[{ "goods_detail":[ { "goods_id":"iphone6s_16G", "wxpay_goods_id":"1001", "goods_name":"iPhone6s 16G", "quantity":1, "price":528800, "goods_category":"123456", "body":"苹果手机" }, { "goods_id":"iphone6s_32G", "wxpay_goods_id":"1002", "goods_name":"iPhone6s 32G", "quantity":1, "price":608800, "goods_category":"123789", "body":"苹果手机" } ] }]]></detail>
       <nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str><notify_url>http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php</notify_url>
       <openid>oUpF8uMuAJO_M2pxb1Q9zNjWeS6o</openid>
       <out_trade_no>1415659990</out_trade_no>
       <spbill_create_ip>14.23.150.211</spbill_create_ip>
       <total_fee>1</total_fee>
       <trade_type>NATIVE</trade_type>
       <sign>0CB01533B8C1EF103065174F50BCA001</sign>
    </xml>
    
    1. 在python中用字典进行处理需要的参数,在发起支付时,给参数转换为XML格式的,调用成功后,再将返回的XML格式的结果转换为字典处理即可,可用如下代码进行转换。
    # 定义字典转XML的函数
    def trans_dict_to_xml(data_dict):
        data_xml = []
        for k in sorted(data_dict.keys()):  # 遍历字典排序后的key
            v = data_dict.get(k)  # 取出字典中key对应的value
            if k == 'detail' and not v.startswith('<![CDATA['):  # 添加XML标记
                v = '<![CDATA[{}]]>'.format(v)
            data_xml.append('<{key}>{value}</{key}>'.format(key=k, value=v))
        return '<xml version="1.0" encoding="UTF-8" >{}</xml>'.format(''.join(data_xml))  # 返回XML
    
    
    # 定义XML转字典的函数
    def trans_xml_to_dict(data_xml):
        soup = BeautifulSoup(data_xml, features='xml')
        xml = soup.find('xml')  # 解析XML
        if not xml:
            return {}
        data_dict = dict([(item.name, item.text) for item in xml.find_all()])
        return data_dict
    

    二、发起微信支付

       知道我们需要哪些东西后,就可以通过如下的方式来实现返回二维码,生成的二维码通过base64加密,然后返回给前端。

    1.生成支付二维码

       生成二维码的同时,我们应该先在系统内生成订单记录,为后续通过云服务器回调通知做准备。

    from __future__ import unicode_literals
    from random import Random
    import io
    from edu_saas_app.pay.produce_order import UpdateOrder
    from django.shortcuts import render
    from django.http.response import HttpResponse, JsonResponse
    from django.views.decorators.csrf import csrf_exempt  # 解除csrf验证
    from edu_saas_app.models import MetaSettings, StudentBugCourseRecord, LoggerRecord
    from edu_saas_app.BaseView import BaseView
    from bs4 import BeautifulSoup
    import base64
    import random
    import requests
    import hashlib
    import qrcode
    import time
    from HttpResult import Result
    
    def wxpay(request, datas):
        meta = MetaSettings.objects.using(BaseView.get_partner(None, request)).values_list("wechat_appid",
                                                                                           "wechat_merchant_id",
                                                                                           "wechat_secret_key").first()
        r = Result()
        try:
            if "未设置" in meta:
                raise Exception("请维护微信信息!")
            _APP_ID = meta[0]
            _MCH_ID = meta[1]
            _API_KEY = meta[2]
            _CREATE_IP = "192.168.124.8"
            _NOTIFY_URL = request.get_host() + "/app/wechat/notify"
            _PAY_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder"
            order_number = datas["order_number"]
            nonce_str = order_number  # 拼接出随机的字符串即可,我这里是用  时间+随机数字+5个随机字母
            total_fee = int((datas["total_pay"] * 100))  # 付款金额,单位是分,必须是整数
            subject = "购买课程"  # 商品描述
            out_trade_no = order_num()  # 订单编号
            params = {
                "appid": _APP_ID,  # APPID
                "mch_id": _MCH_ID,  # 商户号
                "nonce_str": nonce_str,
                "out_trade_no": out_trade_no,  # 订单编号
                "total_fee": total_fee,  # 订单总金额
                "spbill_create_ip": _CREATE_IP,  # 发送请求服务器的IP地址
                "notify_url": _NOTIFY_URL,  # 支付结果通知地址
                "body": subject,  # 商品描述
                "trade_type": 'NATIVE'  # 扫码支付
            }
    
            sign = get_sign(params, _API_KEY)  # 获取签名
            params['sign'] = sign  # 添加签名到参数字典
            request.session[order_number] = params
            # print(params)
            xml = trans_dict_to_xml(params)  # 转换字典为XML
            data = xml.encode("utf-8")
            response = requests.request('post', _PAY_URL, data=data)  # 以POST方式向微信公众平台服务器发起请求
            content = response.content
            data_dict = trans_xml_to_dict(content)  # 将请求返回的数据转为字典
            # qrcode_name = out_trade_no + '.png'  # 支付二维码图片保存路径
    
            if data_dict.get('return_code') == 'SUCCESS':  # 如果请求成功
                datas["wx_params"] = params
                # 创建订单信息
                UpdateOrder.pay_course(request, datas)
                img = qrcode.make(data_dict.get('code_url'))  # 创建支付二维码
                # img_path = 'edu_saas_app/static/' + qrcode_name
                # img.save(img_path)  #
                buf = io.BytesIO()
                img.save(buf, format='PNG')
                image_stream = buf.getvalue()
                heximage = base64.b64encode(image_stream)
                # return render(request, 'qrcode.html', {'qrcode_img': qrcode_name})  # 为支付页面模板传入二维码图像
                return {'code': 0, 'qrcode_img': str(heximage, "utf-8")}
            else:
                raise Exception("请求失败!", data_dict.get('return_code'))
        except Exception as e:
            r.error(e)
            return r.message
    

    注: 在发送post请求前,需要将xml进行utf-8转码,否则得到的二维码扫出来后的中文是乱码。

    2.签名加密方式,将Key 和参数进行混合加密

    def get_sign(data_dict, key):  # 签名函数,参数为签名的数据和密钥
        params_list = sorted(data_dict.items(), key=lambda e: e[0], reverse=False)  # 参数字典倒排序为列表
        params_str = "&".join(u"{}={}".format(k, v) for k, v in params_list) + '&key=' + key
        # 组织参数字符串并在末尾添加商户交易密钥
        md5 = hashlib.md5()  # 使用MD5加密模式
        md5.update(params_str.encode())  # 将参数字符串传入
        sign = md5.hexdigest().upper()  # 完成加密并转为大写
        return sign
    
    

    3.out_trade_no为微信平台那边需要的订单号

    def order_num(package_id=12345, user_id=56789):
        # 商品id后2位+下单时间的年月日12+用户2后四位+随机数4位
        local_time = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))[2:]
        result = str(package_id)[-2:] + local_time + str(user_id)[-2:] + str(random.randint(1000, 9999))
        return result
    
    

    4.nonce_str 为我们商户提供的32位以内的随机字符串

    import datetime
    
    def generate_number(length):
        start = int("1" + "0" * (length - 1))
        end = int("9" * length)
        return random.randrange(start, end)
    
     def get_order_number():
            now = datetime.datetime.now()
            str_time = now.strftime('%Y%m%d%H%M%S')
            # 在加一个4位的随机数
            rand_str = generate_number(8)
            return str_time + str(rand_str)
    

    发起支付时需要注意点:

    1. 必须的参数一定要传,不传会报错。
    params = {
                "appid": _APP_ID,  # APPID
                "mch_id": _MCH_ID,  # 商户号
                "nonce_str": nonce_str,     
                "out_trade_no": out_trade_no,  # 订单编号
                "total_fee": total_fee,  # 订单总金额
                "spbill_create_ip": _CREATE_IP,  # 发送请求服务器的IP地址
                "notify_url": _NOTIFY_URL,  # 支付结果通知地址
                "body": subject,  # 商品描述
                "trade_type": 'NATIVE'  # 扫码支付
            }
    
    1. total_fee的单位是分,不能为0,否则会报错。

    2. 发起请求的方式为POST, 传给微信的body必须是XML格式的,不能接收其他格式的body参数。

          xml = trans_dict_to_xml(params)  # 转换字典为XML
            data = xml.encode("utf-8")
            response = requests.request('post', _PAY_URL, data=data)  # 以POST方式向微信公众平台服务器发起请求
    

    三、前端回调提示用户支付成功

      用户付钱以后,需要知道的第一件事就是自己有没有支付成功,主要方式有2种:

    1. 前端使用ajax的方式进行定时回调。
    2. 前端调用后端的接口,后端在一定的时间内给予返回。

    在这里介绍第一种回调方式,前端持续间隔时间调用该接口,这个结构并不会影响到用户支付成功,而是给前端一个响应,让用户知道是否成功。
    建议不采用第二种方式进行回调,因为后端会一直循环查询,比较占用资源,也容易出问题,比如出现死循环问题。
    需要的参数格式还是XML格式:

    <xml>
       <appid>wx2421b1c4370ec43b</appid>
       <mch_id>10000100</mch_id>
       <nonce_str>ec2316275641faa3aacf3cc599e8730f</nonce_str>
       <transaction_id>1008450740201411110005820873</transaction_id>
       <sign>FDD167FAA73459FD921B144BAF4F4CA2</sign>
    </xml>
    

    完整代码

    # 查询订单信息
    def check_wxpay(request):
        q_url = "https://api.mch.weixin.qq.com/pay/orderquery"
    
        meta = MetaSettings.objects.using(BaseView.get_partner(None, request)).values_list("wechat_appid",
                                                                                           "wechat_merchant_id",
                                                                                           "wechat_secret_key").first()
    
        _APP_ID = meta[0]
        _MCH_ID = meta[1]
        _API_KEY = meta[2]
        # 从session中拿出订单信息
        order_number = request.GET.get("order_id")
        data_dict = request.session[order_number]
        data_dict = dict(data_dict)
        data_dict.pop("body")
        data_dict.pop("notify_url")
        data_dict.pop("total_fee")
        data_dict.pop("trade_type")
        data_dict.pop("spbill_create_ip")
        data_dict.pop("sign")
        sign = get_sign(data_dict, _API_KEY)  # 获取签名
        data_dict['sign'] = sign  # 添加签名到参数字典
        xml = trans_dict_to_xml(data_dict)  # 转换字典为XML
        response = requests.request('post', q_url, data=xml.encode("utf-8"))  # 以POST方式向微信公众平台服务器发起请求
        content = response.content
        data_dict = trans_xml_to_dict(content)
        trade_state = data_dict["trade_state"]
        # SUCCESS支付成功
        # REFUND 转入退款
        # NOTPAY
        # CLOSED 已关闭
        # REVOKED—已撤销(付款码支付)
        # USERPAYING--用户支付中(付款码支付)
        # PAYERROR--支付失败(其他原因,如银行返回失败)
        if "SUCCESS" == trade_state:
            del request.session[order_number]
            return JsonResponse({"code": 0, "msg": "支付成功!"})
        elif "PAYERROR" == trade_state:
            return JsonResponse({"code": -1, "msg": "支付失败!"})
        elif "NOTPAY" == trade_state:
            return JsonResponse({"code": -2, "msg": "未支付!"})
    
    

    四、 云服务平台微信通知

      前端回调不能保证用户是否支付成功,因此不能使用前端回调来确定用户这单是否支付成功,微信给出的解决方案是: 支付完成后,微信会把相关支付结果及用户信息通过数据流的形式发送给商户,商户需要接收处理,并按文档规范返回应答。
      1. 自己定义通知接口: /notify ,另外微信会给商户传如下的参数:
    支付成功的话,微信给商户返回的return_code为SUCCESS, 另外会带有其他的一些信息参数,如下:
      2. 用户就可以根据return_code来做对应的支付成功或者失败处理逻辑!
      3. 处理完成后,商户需要给微信返回一个xml,来确认商户收到了消息,避免微信重复发送消息。

    <xml>
      <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
      <attach><![CDATA[支付测试]]></attach>
      <bank_type><![CDATA[CFT]]></bank_type>
      <fee_type><![CDATA[CNY]]></fee_type>
      <is_subscribe><![CDATA[Y]]></is_subscribe>
      <mch_id><![CDATA[10000100]]></mch_id>
      <nonce_str><![CDATA[5d2b6c2a8db53831f7eda20af46e531c]]></nonce_str>
      <openid><![CDATA[oUpF8uMEb4qRXf22hE3X68TekukE]]></openid>
      <out_trade_no><![CDATA[1409811653]]></out_trade_no>
      <result_code><![CDATA[SUCCESS]]></result_code>
      <return_code><![CDATA[SUCCESS]]></return_code>
      <sign><![CDATA[B552ED6B279343CB493C5DD0D78AB241]]></sign>
      <time_end><![CDATA[20140903131540]]></time_end>
      <total_fee>1</total_fee>
      <coupon_fee><![CDATA[10]]></coupon_fee>
      <coupon_count><![CDATA[1]]></coupon_count>
      <coupon_type><![CDATA[CASH]]></coupon_type>
      <coupon_id><![CDATA[10000]]></coupon_id>
      <trade_type><![CDATA[JSAPI]]></trade_type>
      <transaction_id><![CDATA[1004400740201409030005092168]]></transaction_id>
    </xml>
    

    完整代码,此连接必须要在外网下可访问,需要csrf_exempt装饰器去掉验证。

    # 云服务平台微信通知
    @csrf_exempt
    def notify_url(request):
        body = request.body
        # XML转换为dict
        dict_data = trans_xml_to_dict(body)
        # 获取订单号
        out_trade_no = dict_data["nonce_str"]
        try:
            if dict_data["result_code"] == "SUCCESS":
                return_msg = {"return_code": "SUCCESS", "return_msg": "OK"}
                # 交易成功
                order = StudentBugCourseRecord.objects.filter(order_number=out_trade_no).first()
                if order is not None and order.pay_status != "Y":
                    # 创建订单
                    order.pay_status = "Y"
                    order.save()
            elif dict_data["result_code"] == "FAIL":
                return_msg = {"return_code": "FAIL", "return_msg": "支付失败!"}
            else:
                return_msg = {"return_code": "OTHER", "return_msg": "出现其他问题!!"}
            # 给微信返回xml,表示收到通知。
            result_xml = trans_dict_to_xml(return_msg)
            return HttpResponse(result_xml)
        except Exception as e:
            logger = LoggerRecord(description="微信支付异常,单号:" + out_trade_no + "状态:" + "fail,信息为:" + e, task_name="成功",
                                  task_type=0)
            logger.save()
    
    

    最后我们只需要在dict_data[“result_code”] == "SUCCESS"里写上支付成功后需要处理的逻辑就行了,同时给微信返回一个xml通知给微信,表示确认收到消息。

    展开全文
  • 以下是教学如何将Zxing开源库集成到自己项目中,并且自定义扫码界面,后期可根据自己的业务需求进行修改,最后补充了一点由此延伸的学习技能点。一. 集成Zing开源库到应用中如上图所示,我使用的集成方法是拷入jar包...
  • 最近在做android项目需要用到二维码条形...右边版本的扫码框和扫描线是图片因为太丑所以最终换成左边样式。 自定义版本我是仿着微信的样式大小来做的。 集成步骤: 以左边图片样式为例 1.首先将源码中com.google...
  • 扫码支付原理

    千次阅读 2019-10-27 22:20:47
    一、主动扫码 1、网页上购物后扫码支付 二维码对应的URL中有商家信息及订单信息,扫码后通过我们的支付宝或微信把钱转给商家账户。 网页端在二维码展示出来的时候,轮询调用后台接口查询支付结果。 2、用自己的手机...
  • Android扫码枪数据读取封装

    千次阅读 2020-09-26 14:56:36
    前言 本文介绍如何从Android端获取扫码枪的二维码数据,扫码枪应用场景多,如:扫码付款,扫码取票,扫码开门等。...通过usb com连接扫码:发送扫码开关指令进行扫码,即基于Usb相关类控制扫码开关,控制不好容易出问
  • FNScanner 模块是一个...只有在 IOS7 以上版本才会调用系统自带扫码功能。 模块文档地址(点击即可跳转) 模块需要注意的地方: 注意:使用本模块前,需在云编译页面勾选添加访问摄像头权限,若要访问相册也需勾选申
  • 扫描二维码是HMS的一项基础服务,虽然谷歌公司也提供了zxing扫码框架,但是zxing框架的集成步骤不够简洁,而且它的识别速度偏慢,识别准确率也不高,远不如HMS的扫码服务来得好用。下面介绍如何在App工程中集成HMS的...
  • 实质就是扫码模块扫码将码的内容通过串口传输给单片机做判断,识别到码的内容再控制继电器的开关,继电器进一步控制电子锁。 单片机判断这一步其实都是串口代码 usart.c #include "config.h" #include "Usart.h...
  • 2、具体解决步骤 2-1、打开谷歌浏览器输入 chrome://flags 2-2 、通过禁用“SameSite by default cookies”和“Cookies without SameSite must be secure”功能开关 修改后点击Relaunch重新启动即可。
  • 二维码/条形码是生活中非常常见的技术,只要通过手机或者扫码枪扫描一下就能读取到里面的信息,给我们的生活带来了很多的便利。在Android开发当中,这也是很常用的技术。本文主要简单的介绍所用到的工具及用法。 1....
  • js 二维码扫描

    万次阅读 2018-03-27 19:04:29
    应用在h5浏览器的扫二维码, 用到getUserMedia   qrcode.js库(解析二维码的库)   _aa={};_aa._ab=function(f,e){var d=qrcode.width;var b=qrcode.height;var c=true;for(var g=0;g&lt;e.length&...
  • H5扫码功能实现

    千次阅读 2020-07-29 14:15:47
    H5扫码功能的实现 功能实现要用到H5+ 1.首先需要下载Hbuilder,然后创建H5+项目。再把自己的项目文件替换到新创建的项目里。项目要引入common.js 2.添加一个扫码按钮,给按钮添加点击事件 $(".Scan-three").on(...
  • iOS 扫描二维码/条形

    千次阅读 2018-12-14 19:01:00
    QiCodeManager 负责扫描功能(二维码/条形码的识别和读取等),QiCodePreviewView 负责扫描界面(扫码框、扫描线、提示语等)。可按照如下方式在项目中使用两个类。 // 初始化扫码界面 _previewView = [...
  • 在 iOS 平台上本模块底层集成了 Zbar 和系统自带的条形/二维码分析库,由于 IOS 系统平台在 IOS7.0 以上才开放了二维码/条码的相关接口,所以在 IOS6 上运行时模块会调用开源库 Zbar 去读取解析二维码/条码。...
  • 微信扫码登录原理?

    2022-03-12 15:12:45
    用户拿着已经登录成功的移动终端(手机)扫码二维码 浏览器中获取到了移动终端已经登录的账号信息(包括头像),并且进行了显示 在手机端点击确定登录,浏览器端登录网页版微信成功,可以进行信息交互 原理: ...
  • 微信小程序自定义扫码

    千次阅读 2020-08-18 10:17:14
    在开发过程中,经常会遇到像下面这种的需求,这种时候如果使用微信自带的扫码功能的话,他们的页面我们是没有办法去编辑的,这种时候我们就需要用到自定义一个扫码界面,用到的是微信小程序的camera组件 在小程序...
  • 本文主要记录一下 H5 app+ 实现扫码功能,并用plus.nativeObj(官方文档:HTML5+ APL/nativeObj)创建原生控件对象的实现。 ... // 扫码控件对象 var textResult = ""; // 扫描成功时的结果 ...
  • 在前两篇文章中,我们讲述了二维码的生成、保存和分享的内容,本次我们对于二维码的扫描的内容进行说明,实现一个简易的Android功能。 系列文章: Android二维码的基础使用(一):利用Zxing生成自定义二维码 ...
  • 因为个人项目是导航栏点击事件跳转到控制器,所以下面的控制器里面会有导航栏 View.h里面 #import <UIKit/UIKit.h> @protocol QRCodeReaderViewDelegate <NSObject> - (void)...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,511
精华内容 604
关键字:

二维码扫码开关