精华内容
下载资源
问答
  • 防伪二维码

    千次阅读 2020-04-25 01:14:01
    防伪二维码 一.虚拟一个场景: 在购买贵重物品时可以使用手机扫一扫物品上的二维码, 手机上就会显示出该二维码关联物品的信息 1.出产地,物品的一些参数信息; 2.物品中间经过哪些供应商, 3.当前物品所处的柜台...

    防伪二维码

    一.虚拟一个场景:

    在购买贵重物品时可以使用手机扫一扫物品上的二维码,
    手机上就会显示出该二维码关联物品的信息

    1.出产地,物品的一些参数信息;
    2.物品中间经过哪些供应商,
    3.当前物品所处的柜台地址,是否售卖状态。
    这样通过1出产地,和3当前柜台地址,就能知道该二维码的真伪

    例如,你去深圳XX商城购买茅台酒。 扫一扫二维码就会看到如下信息
    在这里插入图片描述
    在你购买后,售货人员扫码出库,状态就会变成 已售卖
    在这里插入图片描述

    二.二维码的生成

    手机/电脑通过一个权威机构申请一个唯一的二维码,然后你在补充该二维码的基本信息,以及作用,然后提交。

    三.二维码的使用

    1.商品生产完成,打或贴二维码时需要把商品的基本信息,生产日期,生产地等提交。

    2.出厂时扫码出库状态自动改为已售卖,以及买方商家信息(为了买方商家能有权限添加自己的信息和更改状态),售卖日期。

    3.买家商家收到商品后扫码验码,确认后可以更改商品状态为售卖中,以及自己的柜台信息。

    4.个人消费者购买该商品,商家扫码出库,状态自动改为已售卖。若消费者有自己的个人认证信息,也可以继续添加买方为XXX ,这样消费者也就当作下级商家处理了,有权限进行自己信息的添加和状态更改。

    **四.解惑
    1.权威机构时指谁呢?
    指大家能信赖的大公司,阿里,腾讯等,或者未来成为权威机构的你,不会去随意更改二维码的信息;当然,要是能用区块链来记录最好不过了。

    2.为何可以实现防伪?
    1) 假设盗版商从真品上复制了大量的二维码,贴在了自己商品上,那么消费者或者下级商家,通过扫码就可以知道当前售卖地与二维码显示的地点不符
    2) 商家自己在自己的柜台上复制二维码售卖假货,这样售卖地址信息是相符合的。但商家在卖出一件商品后,二维码状态会改为已售卖,以及更新当前用户信息。这样商家就只能卖出一件相同二维码的商品,商家这样造假的意义就没有了。

    3.大批商品售卖一个个去填写/修改信息吗?
    这就需要APP实现批量添加和批量修改的功能了。

    我这也就是一个灵感,没有详细的做细节的构想,想去实现的,仅供可以参考。
    我实现不了,写出来,看看以后会不会有人把它实现,也验证下我的这个想法是有价值的。**

    展开全文
  • 二维码识别的原理?

    千次阅读 2020-07-07 08:40:25
    点击上方“3D视觉工坊”,选择“星标”干货第一时间送达整理:公众号@图像处理与计算机视觉本文仅做学术分享,如有侵权,请联系删除。二维码的特征定位和信息识别背景介绍视觉的方法可以用来估计位...

    点击上方“3D视觉工坊”,选择“星标”

    干货第一时间送达

    整理:公众号@图像处理与计算机视觉

    本文仅做学术分享,如有侵权,请联系删除。

    二维码的特征定位和信息识别

    背景介绍

    视觉的方法可以用来估计位置和姿态。最容易想到的是在目标上布置多个容易识别的特征,这样使用opencv相机标定和、相机畸变矫正、轮廓提取、solvepnp来获取目标相对于相机的位姿。在实际使用中只要相机和目标一方是估计的,那就可以得到全局坐标。如果相机和靶标都在移动,那只能获取到相对坐标。但是受限于相机视角和景深,这样多个特征的识别虽然精度可以很高,但是范围却很小。

    对于如何扩大范围,使用二维码是一个很好的思路。首先,二维码本身具有多个特征,单个二维码可以用来实现上述方法的功能。其次,二维码本身带有信息,如果二维码的布置事先已知,那么位置和姿态估计的范围将只受限于二维码的数量。

    本文主要是二维码的特征识别和信息识别。

    二维码的的生成

    二维码是在一个网站上生成的,经过手机的测试,生成的二维码没有问题。http://www.liantu.com/,该网站是免费的,生成的图片及二维码各种参数可以自定义。 
    本文的测试图片有20张,是数字1到5,每个数字隔90度旋转各一张。

    二维码的特征识别

    二维码特征识别的思路是:第一步,寻找二维码的三个角的定位角点,需要对图片进行平滑滤波,二值化,寻找轮廓,筛选轮廓中有两个子轮廓的特征,从筛选后的轮廓中找到面积最接近的3个即是二维码的定位角点。第二步:判断3个角点处于什么位置,主要用来对图片进行透视校正(相机拍到的图片)或者仿射校正(对网站上生成的图片进行缩放拉伸旋转等操作后得到的图片)。需要判断三个角点围成的三角形的最大的角就是二维码左上角的点。然后根据这个角的两个边的角度差确定另外两个角点的左下和右上位置。第三步,根据这些特征识别二维码的范围。 
    具体的代码:

            Mat src = imread( "pic\\456.jpg", 1 );        if(src.empty())  
            {  
                fprintf(stderr, "Can not load image!\n");  
                return 0;  
            }  
    
            Mat src_all=src.clone();  
    
            //彩色图转灰度图  
            Mat src_gray;
            cvtColor( src, src_gray, CV_BGR2GRAY );  
    
            //对图像进行平滑处理  
            blur( src_gray, src_gray, Size(3,3) );  
    
            //使灰度图象直方图均衡化  
            equalizeHist( src_gray, src_gray );  
    
            namedWindow("src_gray");  
            imshow("src_gray",src_gray);         //灰度图
    
            //指定112阀值进行二值化
            Mat threshold_output;
            threshold( src_gray, threshold_output, 112, 255, THRESH_BINARY );
    
    #ifdef DEBUG
            namedWindow("二值化后输出");  
            imshow("二值化后输出",threshold_output);   //二值化后输出#endif
    
            //需要的变量定义
            Scalar color = Scalar(1,1,255 );  
            vector<vector<Point>> contours,contours2;  
            vector<Vec4i> hierarchy;  
            Mat drawing = Mat::zeros( src.size(), CV_8UC3 );  
            //Mat drawing2 = Mat::zeros( src.size(), CV_8UC3 );  
            Mat drawingAllContours = Mat::zeros( src.size(), CV_8UC3 );
    
            //利用二值化输出寻找轮廓
            findContours(threshold_output, contours, hierarchy,  CV_RETR_TREE, CHAIN_APPROX_NONE, Point(0, 0) );  
    
            //寻找轮廓的方法
            int tempindex1 = 0;        int tempindex2 = 0;        for(int i = 0;i<contours.size();i++)
            {            if(hierarchy[i][2] == -1)                continue;            else
                    tempindex1 = hierarchy[i][2];                //第一个子轮廓的索引
    
                if(hierarchy[tempindex1][2] == -1)                continue;            else
                {
                    tempindex2 = hierarchy[tempindex1][2];        //第二个子轮廓的索引
                    //记录搜索到的有两个子轮廓的轮廓并把他们的编号存储
                    in.a1 = i;
                    in.a2 = tempindex1;
                    in.a3 = tempindex2;
                    vin.push_back(in);
                }
            }        //按面积比例搜索
            vector<index>::iterator it;        for(it = vin.begin();it != vin.end();)
            {            vector<Point> out1Contours = contours[it->a1];            vector<Point> out2Contours = contours[it->a2];            double lenth1 = arcLength(out1Contours,1);            double lenth2 = arcLength(out2Contours,1);            if(abs(lenth1/lenth2-2)>1)
                {
                    it = vin.erase(it);
                }            else
                {
                    drawContours( drawing, contours, it->a1,  CV_RGB(255,255,255) , CV_FILLED, 8);
                    it++;
                }
            }        //获取三个定位角的中心坐标  
            Point point[3];        int i = 0;        vector<Point> pointthree;        for(it = vin.begin(),i = 0;it != vin.end();i++,it++)
            {
                point[i] = Center_cal( contours, it->a1 );
                pointthree.push_back(point[i]);
            }        if(pointthree.size() <3)
            {            cout << "找到的定位角点不足3个"<<endl;            return 0;  
            }        //计算轮廓的面积,计算定位角的面积,从而计算出边长
            double area = contourArea(contours[vin[0].a1]);        int area_side = cvRound (sqrt (double(area)));  
            for(int i=0; i<3; i++)  
            {  
                //画出三个定位角的中心连线  
                line(drawing,point[i%3],point[(i+1)%3],color,area_side/10,8);  
            }  
    
            //清除找到的3个点,以便处理下一幅图片使用
            vin.clear();        //由3个定位角校正图片
            //=========================================
            //找到角度最大的点
            double ca[2];        double cb[2];
    
            ca[0] =  pointthree[1].x - pointthree[0].x;
            ca[1] =  pointthree[1].y - pointthree[0].y;
            cb[0] =  pointthree[2].x - pointthree[0].x;
            cb[1] =  pointthree[2].y - pointthree[0].y;        double angle1 = 180/3.1415*acos((ca[0]*cb[0]+ca[1]*cb[1])/(sqrt(ca[0]*ca[0]+ca[1]*ca[1])*sqrt(cb[0]*cb[0]+cb[1]*cb[1])));        double ccw1;        if(ca[0]*cb[1] - ca[1]*cb[0] > 0) ccw1 = 0;        else ccw1 = 1;
    
            ca[0] =  pointthree[0].x - pointthree[1].x;
            ca[1] =  pointthree[0].y - pointthree[1].y;
            cb[0] =  pointthree[2].x - pointthree[1].x;
            cb[1] =  pointthree[2].y - pointthree[1].y;        double angle2 = 180/3.1415*acos((ca[0]*cb[0]+ca[1]*cb[1])/(sqrt(ca[0]*ca[0]+ca[1]*ca[1])*sqrt(cb[0]*cb[0]+cb[1]*cb[1])));        double ccw2;        if(ca[0]*cb[1] - ca[1]*cb[0] > 0) ccw2 = 0;        else ccw2 = 1;
    
            ca[0] =  pointthree[1].x - pointthree[2].x;
            ca[1] =  pointthree[1].y - pointthree[2].y;
            cb[0] =  pointthree[0].x - pointthree[2].x;
            cb[1] =  pointthree[0].y - pointthree[2].y;        double angle3 = 180/3.1415*acos((ca[0]*cb[0]+ca[1]*cb[1])/(sqrt(ca[0]*ca[0]+ca[1]*ca[1])*sqrt(cb[0]*cb[0]+cb[1]*cb[1])));        double ccw3;        if(ca[0]*cb[1] - ca[1]*cb[0] > 0) ccw3 = 0;        else ccw3 = 1;
    
            CvPoint2D32f poly[4];        if(angle3>angle2 && angle3>angle1)
            {            if(ccw3)
                {
                    poly[1] = pointthree[1];
                    poly[3] = pointthree[0];
                }            else
                {
                    poly[1] = pointthree[0];
                    poly[3] = pointthree[1];
                }
                poly[0] = pointthree[2];
                Point temp(pointthree[0].x + pointthree[1].x - pointthree[2].x , pointthree[0].y + pointthree[1].y - pointthree[2].y );
                poly[2] = temp;
            }        else if(angle2>angle1 && angle2>angle3)
            {            if(ccw2)
                {
                    poly[1] = pointthree[0];
                    poly[3] = pointthree[2];
                }            else
                {
                    poly[1] = pointthree[2];
                    poly[3] = pointthree[0];
                }
                poly[0] = pointthree[1];
                Point temp(pointthree[0].x + pointthree[2].x - pointthree[1].x , pointthree[0].y + pointthree[2].y - pointthree[1].y );
                poly[2] = temp;
            }        else if(angle1>angle2 && angle1 > angle3)
            {            if(ccw1)
                {
                    poly[1] = pointthree[1];
                    poly[3] = pointthree[2];
                }            else
                {
                    poly[1] = pointthree[2];
                    poly[3] = pointthree[1];
                }
                poly[0] = pointthree[0];
                Point temp(pointthree[1].x + pointthree[2].x - pointthree[0].x , pointthree[1].y + pointthree[2].y - pointthree[0].y );
                poly[2] = temp;
            }
    
            CvPoint2D32f trans[4];        int temp = 50;
            trans[0] = Point2f(0+temp,0+temp);  
            trans[1] = Point2f(0+temp,100+temp);  
            trans[2] = Point2f(100+temp,100+temp);  
            trans[3] = Point2f(100+temp,0+temp);        //获取透视投影变换矩阵
            CvMat *warp_mat = cvCreateMat(3, 3, CV_32FC1);
            cvGetPerspectiveTransform(poly, trans, warp_mat);        //计算变换结果
            IplImage ipl_img(src_all);
            IplImage *dst = cvCreateImage(cvSize(1000, 1000), 8, 3);
            cvWarpPerspective(&ipl_img,dst,warp_mat);        //=========================================#ifdef DEBUG
            namedWindow("透视变换后的图");  
            cvShowImage("透视变换后的图",dst);         //透视变换后的图
    
            drawContours( drawingAllContours, contours, -1,  CV_RGB(255,255,255) , 1, 8);
            namedWindow("DrawingAllContours");  
            imshow( "DrawingAllContours", drawingAllContours );  
    
            namedWindow(pathtemp);  
            imshow(pathtemp , drawing );    //3个角点填充#endif
    
            //接下来要框出这整个二维码  
            Mat gray_all,threshold_output_all;  
            vector<vector<Point> > contours_all;  
            vector<Vec4i> hierarchy_all;  
            cvtColor( drawing, gray_all, CV_BGR2GRAY );  
    
            threshold( gray_all, threshold_output_all, 45, 255, THRESH_BINARY );
    
            findContours( threshold_output_all, contours_all, hierarchy_all,  RETR_EXTERNAL, CHAIN_APPROX_NONE, Point(0, 0) );//RETR_EXTERNAL表示只寻找最外层轮廓  
    
            Point2f fourPoint2f[4];  
            //求最小包围矩形  
            RotatedRect rectPoint = minAreaRect(contours_all[0]);  
    
            //将rectPoint变量中存储的坐标值放到 fourPoint的数组中  
            rectPoint.points(fourPoint2f);  
            for (int i = 0; i < 4; i++)  
            {  
                line(src_all, fourPoint2f[i%4], fourPoint2f[(i + 1)%4],
                    Scalar(20,21,237), 3);  
            }  
    
            namedWindow(pathtemp);  
            imshow(pathtemp , src_all );
    
            //截取二维码区域
            CvSize size= cvSize(200,200);//区域大小
            cvSetImageROI(dst,cvRect(0,0,size.width, size.height));//设置源图像ROI
            IplImage* pDest = cvCreateImage(size,dst->depth,dst->nChannels);//创建目标图像
            cvCopy(dst,pDest); //复制图像
            cvSaveImage("Roi.jpg",pDest);//保存目标图像
    

    二维码的信息识别

    二维码的信息识别使用的是zbar,一个开源的二维码识别库,经过测试,对图像进行平滑,灰度等处理后识别效率还是很高的。zbar的算法流程简介:http://blog.csdn.net/u013738531/article/details/54574262。

            //对截取后的区域进行解码
            Mat imageSource = cv::Mat(pDest);
            cvResetImageROI(pDest);//源图像用完后,清空ROI
            cvtColor( imageSource, imageSource, CV_BGR2GRAY );  //zbar需要输入灰度图像才能很好的识别
    
            //Zbar二维码识别
            ImageScanner scanner;
            scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);  
            int width1 = imageSource.cols;        
            int height1 = imageSource.rows;        
            uchar *raw = (uchar *)imageSource.data;    
    
            Image imageZbar(width1, height1, "Y800", raw, width1 * height1);          
            scanner.scan(imageZbar); //扫描条码      
            Image::SymbolIterator symbol = imageZbar.symbol_begin();    
            if(imageZbar.symbol_begin()==imageZbar.symbol_end())    
            {    
                cout<<"查询条码失败,请检查图片!"<<endl;    
            }    
    
            for(;symbol != imageZbar.symbol_end();++symbol)      
            {        
                cout<<"类型:"<<endl<<symbol->get_type_name()<<endl;      
                cout<<"条码:"<<endl<<symbol->get_data()<<endl;        
            }
    
            imageZbar.set_data(NULL,0);    
    

    程序运行结果

    运行结果1:网站上生成的二维码,依次是原图,二值化,角点定位,旋转矫正,识别结果。

    运行结果2:相机拍摄的名片上二维码,依次是灰度图,二值化,角点定位,透视矫正,识别结果。

    推荐阅读:

    重磅!3DCVer-学术论文写作投稿 交流群已成立

    扫码添加小助手微信,可申请加入3D视觉工坊-学术论文写作与投稿 微信交流群,旨在交流顶会、顶刊、SCI、EI等写作与投稿事宜。

    同时也可申请加入我们的细分方向交流群,目前主要有3D视觉CV&深度学习SLAM三维重建点云后处理自动驾驶、CV入门、三维测量、VR/AR、3D人脸识别、医疗影像、缺陷检测、行人重识别、目标跟踪、视觉产品落地、视觉竞赛、车牌识别、硬件选型、学术交流、求职交流等微信群,请扫描下面微信号加群,备注:”研究方向+学校/公司+昵称“,例如:”3D视觉 + 上海交大 + 静静“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进去相关微信群。原创投稿也请联系。

    ▲长按加微信群或投稿

    ▲长按关注公众号

    3D视觉从入门到精通知识星球:针对3D视觉领域的知识点汇总、入门进阶学习路线、最新paper分享、疑问解答四个方面进行深耕,更有各类大厂的算法工程人员进行技术指导。与此同时,星球将联合知名企业发布3D视觉相关算法开发岗位以及项目对接信息,打造成集技术与就业为一体的铁杆粉丝聚集区,近1000+星球成员为创造更好的AI世界共同进步,知识星球入口:

    学习3D视觉核心技术,扫描查看介绍,3天内无条件退款

     圈里有高质量教程资料、可答疑解惑、助你高效解决问题

    展开全文
  • 银联二维码支付java 实现

    千次阅读 2017-12-13 18:28:26
    //交易子类 07:申请消费二维码 contentData.put("bizType", "000000"); //填写000000 contentData.put("channelType", "08"); //渠道类型 08手机 /***商户接入参数***/ contentData.put(...

    1. 准备工作

        首先在银联开放平台注册一个测试账号,地址https://open.unionpay.com/ajweb/index

       注册完成后可以根据自己所用的编程语言选择对应的demo下载,我下载了java通用版。

     

      2.创建springmvc项目,将demo中的sdk包copy进项目,编写controller。

    import java.io.IOException;
    import java.util.Enumeration;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Map.Entry;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import com.ccdproject.bean.UnionpayBean;
    import com.ccdproject.unionpay.DemoBase;
    import com.ccdproject.util.DateUtil;
    import com.ccdproject.util.ZxingQrcode;
    import com.unionpay.acp.sdk.AcpService;
    import com.unionpay.acp.sdk.LogUtil;
    import com.unionpay.acp.sdk.SDKConfig;
    import com.unionpay.acp.sdk.SDKConstants;
    
    /**
     * 银联扫码支付
     * 1.获取二维码值
     * 主扫申请二维码交易
     * @author Austin
     *
     */
    @Controller
    @RequestMapping("/unionpay")
    public class Unionpay extends HttpServlet {
    	
    	/**
    	 * 序列化
    	 */
    	private static final long serialVersionUID = 1L;
    	
    	@RequestMapping("/unionpayqrcode")
    	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
    			throws ServletException, IOException {
    		SDKConfig.getConfig().loadPropertiesFromSrc();// 从classpath加载acp_sdk.properties文件
    		String merId = UnionpayBean.merId;
    		String txnAmt = req.getParameter("txnAmt");
    		// 生成商户订单号  orderId
            String  orderId = DateUtil.OrderId();
            orderId += String.valueOf(4);
    	    String txnTime = DateUtil.ordertxnTime(); //订单时间
    		Map<String, String> contentData = new HashMap<String, String>();
    		
    		/***银联全渠道系统,产品参数,除了encoding自行选择外其他不需修改***/
    		contentData.put("version", DemoBase.version);            //版本号 全渠道默认值
    		contentData.put("encoding", DemoBase.encoding);     //字符集编码 可以使用UTF-8,GBK两种方式
    		contentData.put("signMethod", SDKConfig.getConfig().getSignMethod()); //签名方法  默认01
    		contentData.put("txnType", "01");              		 	//交易类型 01:消费
    		contentData.put("txnSubType", "07");           		 	//交易子类 07:申请消费二维码
    		contentData.put("bizType", "000000");          		 	//填写000000
    		contentData.put("channelType", "08");          		 	//渠道类型 08手机
    
    		/***商户接入参数***/
    		contentData.put("merId", merId);   		 				//商户号码,请改成自己申请的商户号或者open上注册得来的777商户号测试
    		contentData.put("accessType", "0");            		 	//接入类型,商户接入填0 ,不需修改(0:直连商户, 1: 收单机构 2:平台商户)
    		contentData.put("orderId", orderId);        	 	    //商户订单号,8-40位数字字母,不能含“-”或“_”,可以自行定制规则	
    		contentData.put("txnTime", txnTime);		 		    //订单发送时间,取系统时间,格式为YYYYMMDDhhmmss,必须取当前时间,否则会报txnTime无效
    		contentData.put("txnAmt", txnAmt);						//交易金额 单位为分,不能带小数点
    		contentData.put("currencyCode", "156");                 //交易币种 境内商户固定 156 人民币
    
    		// 请求方保留域,
            // 透传字段,查询、通知、对账文件中均会原样出现,如有需要请启用并修改自己希望透传的数据。
            // 出现部分特殊字符时可能影响解析,请按下面建议的方式填写:
            // 1. 如果能确定内容不会出现&={}[]"'等符号时,可以直接填写数据,建议的方法如下。
    //		contentData.put("reqReserved", "透传信息1|透传信息2|透传信息3");
            // 2. 内容可能出现&={}[]"'符号时:
            // 1) 如果需要对账文件里能显示,可将字符替换成全角&={}【】“‘字符(自己写代码,此处不演示);
            // 2) 如果对账文件没有显示要求,可做一下base64(如下)。
            //    注意控制数据长度,实际传输的数据长度不能超过1024位。
            //    查询、通知等接口解析时使用new String(Base64.decodeBase64(reqReserved), DemoBase.encoding);解base64后再对数据做后续解析。
    //		contentData.put("reqReserved", Base64.encodeBase64String("任意格式的信息都可以".toString().getBytes(DemoBase.encoding)));
    					
    		//后台通知地址(需设置为外网能访问 http https均可),支付成功后银联会自动将异步通知报文post到商户上送的该地址,【支付失败的交易银联不会发送后台通知】
    		//后台通知参数详见open.unionpay.com帮助中心 下载  产品接口规范  网关支付产品接口规范 消费交易 商户通知
    		//注意:1.需设置为外网能访问,否则收不到通知    2.http https均可  3.收单后台通知后需要10秒内返回http200或302状态码 
    		//    4.如果银联通知服务器发送通知后10秒内未收到返回状态码或者应答码非http200或302,那么银联会间隔一段时间再次发送。总共发送5次,银联后续间隔1、2、4、5 分钟后会再次通知。
    		//    5.后台通知地址如果上送了带有?的参数,例如:http://abc/web?a=b&c=d 在后台通知处理程序验证签名之前需要编写逻辑将这些字段去掉再验签,否则将会验签失败
    		contentData.put("backUrl", DemoBase.backUrl);
    		System.out.println(SDKConfig.getConfig().getBackUrl()+"=SDKConfig.getConfig().getBackUrl()");
    		
    		/**对请求参数进行签名并发送http post请求,接收同步应答报文**/
    		Map<String, String> reqData = AcpService.sign(contentData,DemoBase.encoding);			 //报文中certId,signature的值是在signData方法中获取并自动赋值的,只要证书配置正确即可。
    		String requestAppUrl = SDKConfig.getConfig().getBackRequestUrl();								 //交易请求url从配置文件读取对应属性文件acp_sdk.properties中的 acpsdk.backTransUrl
    		Map<String, String> rspData = AcpService.post(reqData,requestAppUrl,DemoBase.encoding);  //发送请求报文并接受同步应答(默认连接超时时间30秒,读取返回结果超时时间30秒);这里调用signData之后,调用submitUrl之前不能对submitFromData中的键值对做任何修改,如果修改会导致验签不通过
    		System.out.println("rspData="+rspData);
    		/**对应答码的处理,请根据您的业务逻辑来编写程序,以下应答码处理逻辑仅供参考------------->**/
    		//应答码规范参考open.unionpay.com帮助中心 下载  产品接口规范  《平台接入接口规范-第5部分-附录》
    		if(!rspData.isEmpty()){
    			if(AcpService.validate(rspData, DemoBase.encoding)){
    				LogUtil.writeLog("验证签名成功");
    				String respCode = rspData.get("respCode");
    				if(("00").equals(respCode)){
    					//成功,获取tn(银联订单号)
    					String orderId2 = rspData.get("orderId");
    					System.out.println(orderId2);
    					String qrCode = rspData.get("qrCode");
    					System.out.println(qrCode);
    					ZxingQrcode.zxingqrcode(qrCode, resp);
    				}else{
    					//其他应答码为失败请排查原因或做失败处理
    					//TODO
    				}
    			}else{
    				LogUtil.writeErrorLog("验证签名失败");
    				System.out.println("验证签名失败");
    				//TODO 检查验证签名失败的原因
    			}
    		}else{
    			//未返回正确的http状态
    			LogUtil.writeErrorLog("未获取到返回报文或返回http状态码非200");
    			System.out.println("未获取到返回报文或返回http状态码非200");
    		}
    		String reqMessage = DemoBase.genHtmlResult(reqData);
    		String rspMessage = DemoBase.genHtmlResult(rspData);
    		resp.getWriter().write("请求报文:<br/>"+reqMessage+"<br/>" + "应答报文:</br>"+rspMessage+"");
    	}
    	
    	/***
    	 * unionpay 异步通知支付结果
    	 * @param req
    	 * @param resp
    	 * @throws IOException
    	 */
    	@RequestMapping("/Notify")
    	public void Notifyunionpay(HttpServletRequest req,HttpServletResponse resp) throws IOException{
    		// 获取银联post过来的信息
    		System.out.println("BackRcvResponse接收后台通知开始");
    		String encoding = req.getParameter(SDKConstants.param_encoding);
    		Map<String, String> reqParam = getAllRequestParam(req);
    		LogUtil.printRequestLog(reqParam);
    
    		Map<String, String> valideData = null;
    		if (null != reqParam && !reqParam.isEmpty()) {
    			Iterator<Entry<String, String>> it = reqParam.entrySet().iterator();
    			valideData = new HashMap<String, String>(reqParam.size());
    			while (it.hasNext()) {
    				Entry<String, String> e = it.next();
    				String key = (String) e.getKey();
    				String value = (String) e.getValue();
    				
    				valideData.put(key, value);
    			}
    		}
    
    		//重要!验证签名前不要修改reqParam中的键值对的内容,否则会验签不过
    		if (!AcpService.validate(valideData, encoding)) {
    			LogUtil.writeLog("验证签名结果[失败].");
    			System.out.println("验证签名结果[失败].");
    			//验签失败,需解决验签问题
    			
    		} else {
    			LogUtil.writeLog("验证签名结果[成功].");
    			System.out.println("验证签名结果[成功].");
    			//【注:为了安全验签成功才应该写商户的成功处理逻辑】交易成功,更新商户订单状态
    			
    			String orderId =valideData.get("orderId"); //获取后台通知的数据,其他字段也可用类似方式获取
    
    			String respCode = valideData.get("respCode");
    			//判断respCode=00、A6后,对涉及资金类的交易,请再发起查询接口查询,确定交易成功后更新数据库。
    		}
    		LogUtil.writeLog("BackRcvResponse接收后台通知结束");
    		//返回给银联服务器http 200  状态码
    		resp.getWriter().print("ok");
    	}
    	/**
    	 * 获取请求参数中所有的信息
    	 * 
    	 * @param request
    	 * @return
    	 */
    	public static Map<String, String> getAllRequestParam(final HttpServletRequest request) {
    		Map<String, String> res = new HashMap<String, String>();
    		Enumeration<?> temp = request.getParameterNames();
    		if (null != temp) {
    			while (temp.hasMoreElements()) {
    				String en = (String) temp.nextElement();
    				String value = request.getParameter(en);
    				res.put(en, value);
    				//在报文上送时,如果字段的值为空,则不上送<下面的处理为在获取所有参数数据时,判断若值为空,则删除这个字段>
    				//System.out.println("ServletUtil类247行  temp数据的键=="+en+"     值==="+value);
    				if (null == res.get(en) || "".equals(res.get(en))) {
    					res.remove(en);
    				}
    			}
    		}
    		return res;
    	}
    
    	
    }
    访问  /unionpay/unionpayqrcode?txnAmt=100出现 二维码  由于是测试账号,无法使用手机扫码支付,然后可以自己在学一个支付程序
    3.其中txmtime,orderid的生成自己设定,其中一些参数也在官方Demo上也有,具体可以参考官网。

    展开全文
  • 你觉得App最佳推广的...电商、打车、旅游、外卖、教培等App产品都绕不开线下推广,线下推广的高效之处在于:产品体验更加真实可信,受众用户往往受限于信息差,并不了解还有什么同类产品。因此App通过线下推广获客,

    你觉得App最佳推广的方案是什么呢?

    我认为是地推。

    因为通过地推,可以非常精准的找到你的目标用户群。

    比如二次元手游可以选择各大漫展和高校社团;地产类应用可以和各大二手房交易公司、售楼处合作;旅游类App可以选择在各大机场、火车站、汽车站;餐饮类App则可以跟各大商圈走;健康类应用则可以结合之前大热的扫码体重秤和体测仪。
    在这里插入图片描述

    电商、打车、旅游、外卖、教培等App产品都绕不开线下推广,线下推广的高效之处在于:产品体验更加真实可信,受众用户往往受限于信息差,并不了解还有什么同类产品。因此App通过线下推广获客,是比较有效的途径。

    在APP地推中,二维码扮演者无可替代的角色。用户只需要扫描宣传册上面的二维码,就可以进入APP下载界面。整个过程非常便捷。

    那么,App如何生成下载二维码?扫码即可下载App。

    一、App如何生成下载二维码?

    “二维彩虹二维码在线生成器”就可以生成App下载二维码,不管是安卓手机还是苹果手机都是可以的。利用二维彩虹的“应用商店”功能制作二维码即可,安卓手机扫描跳到相应的应用市场(比如应用宝)下载页面,苹果手机扫描跳到AppStore下载页面。

    二,二维彩虹二维码制作App下载二维码步骤:

    1、注册并登录二维彩虹二维码生成器官网

    2、选择“应用商店”功能, 分别在对应栏目输入App的iOS下载地址和安卓下载地址,然后点击生成动态二维码。
    在这里插入图片描述

    3、美化二维码。根据自己的需求和审美对二维码进行一些列的美化处理。比如设置渐变色,更改二维码样式、图眼、边框等。当然还可以上传自己的头像或者logo。

    4、扫描测试,然后点击“编辑/下载”按钮,就可以应用二维码啦。

    这样一个苹果和安卓手机都通用的App下载二维码就生成了。若是苹果手机,直接跳转到AppStore的下载页面;若是安卓手机,进入安卓应用市场的下载页面。当然,如果您的APP未能上传至应用商店,也可以先将APP上传到类似于蒲公英这样的平台上,获取下载链接。

    三,二维彩虹App二维码的优势有哪些呢?

    App地推统计只需要二维彩虹二维码就可以搞定了,这是因为二维彩虹具备数据追踪的功能,通过这一个二维码还可以检测IOS和安卓渠道下载情况。

    1、追踪用户来源:通过这个不同的推广渠道二维码,了解各个渠道的粉丝引流情况等。

    2、监测推广效果:监控各种渠道广告带来的粉丝关注量,优化分析投放效果,再选择优质的推广渠道,节省推广成本。

    四,关于二维彩虹
    二维彩虹作为一家拥有全球十万+用户的二维码生成器公司,是国内首家专注于为世界120余个国家地区提供二维码美化与数据追踪服务的大数据解决方案供应商,深受全球用户的信任。

    在二维彩虹,你可以轻松制作多种类型的二维码:文件二维码、pdf二维码、网页链接二维码、多链接二维码、视频二维码、音频二维码、电子名片二维码、图片二维码。它们被广泛应用于各种场合:展览、活动宣传、会议、产品电子说明书、售后服务、店铺引流、APP下载、地推、宣传海报、作品集展示、线上售票等。

    原文阅读:
    App如何生成下载二维码?扫码即可下载App
    相关阅读:
    二维码制作:网页二维码如何生成?

    展开全文
  • 简单说一下使用方法,这个程序首先爬取了一个优惠券网站的优惠信息(就不用自己再去寻找了),然后再去阿里巴巴淘宝联盟,通过自己的pid来申请佣金,最终生成二维码,添加商品图片以及文字介绍,最终生成带有二维码...
  • images: 图片缓存区,缓存存二维码还有用户头像上传七牛云 impl: 接口功能实现 key: 各种加密文件,微信支付,ssl证书等 log: 日志文件,目前天级别生成最新的一份 model: 数据模型, 第一版已废弃 pjt_data: ...
  • 数据准确性高,安全性高:二、二维码技术特点:1. 存贮密度大,数据格式多样2. 拥有纠错能力3. 版本众多,可应用于不同场景,自由度高4. 经济便宜,易于制作三、基于RFID或二维码的实际应用:1. 基于 RFID 技术的...
  • 微信群-街边二维码别乱扫-这些传销陷阱要当心骗局 强哥整理网络骗局内容,不是强哥原创的啊,大家注意看,是各大媒体报道的,强哥整理出来的。 您通常使用的密码安全吗? “单击鼠标,您就是有钱人”? 日前,2019...
  • 微信小程序只是一个促销和流失工具,它是一个简化的应用...它是做更多的小程序(每个企业实体可以申请50个小程序)以形成一个霸气的屏幕,使用当前可以想到的一些关键字,并使用实际的在线效果来构建自己的关键字大数据。
  • 人工智能、视频结构化、云平台等概念也相继提出,视频监控系统、门禁系统与防盗报警系统成为民用安防的三大支柱,支撑大部分民用安防市场份额,其各类型产品在各行各业得到了广泛应用。 随着人们的生活水平在不断...
  • 支持二维码的生成与识别。...注意,该示例代码仅适用于 www.apishop.net网站下API 使用该产品前,您需要通过 https://www.apishop.net/#/api/detail/?productID=128申请API服务 1、二维码生成 <?php $metho...
  • 每个二维码扫描器开发可能不同,我主要以微光的产品进行分享,你买回来二维码扫描器你需要进行配置,这个到时候买的那个问淘宝就可以。还要说,这个二维码扫描器需要网络,本地测试在本地就可以,但是部署在网络一定...
  • 最近在做银联二维码支付Android端相关项目,因为中国银联网站上并未提供Android端demo,只提供了Java相关demo,只能是根据自己的业务需求去更改,开始看银联的开发文档觉得一脸懵逼,看不懂,后来经过深入分析,才...
  • JAVA实现的支付宝扫描二维码支付

    万次阅读 2016-12-05 17:34:04
    支付项目采用springMvc+Dubbo架构实现,只对外...前几天公司申请下来了企业支付宝,得空所以也把支付宝的扫码支付给集成进去。这里又不得不说,是支付宝的文档写的不咋地还是自己没有仔细阅读,总之翻遍了API最终在沙箱
  • 然后对于编程爱好者而言,想学习这一点就有点难,因为要想使用支付宝接口,必须前提是使用软件应用程序,软件应用程序需要向支付宝申请,提交一系列资料,这一点是实现不了的。这就对开发者增加了一定的难度,因为...
  • 我与产品经理的“恩怨情仇”,在最近一次需求中,需要给用户提供微信快捷登录。 先科普一下,微信开放平台提供了两种二维码的展示方式,一种是跳转页面,还有一种是内嵌在自己的网站中,可以直接在网站内就能完成...
  • 在现在的一些开发中有些硬件不支持传图片,所以在一些支付的应用中,可以通过传一个支付的二维码,然后通过硬件解析,进而完成支付的功能。通过在支付宝官网的教程,修改了一下,做成了一个小案例。 运行结果: ...
  • 二维码支付”安全么? 1 引言 随时支付宝和微信的线下不断推广,目前使用手机进行二维码支付已经逐渐成为一种时尚了。 但是大家有没有思考过:这种便捷的支付方式到底安不安全呢?今天我们就针对这个话题来...
  • 背景:公司开发的小程序要实现将产品免费给用户试用的功能,用户登录小程序后在产品页可以将产品二维码海报的方式分享给微信好友,好友扫码后跳转公众号,关注后公众号推送小程序,点击小程序后跳转到小程序中的...
  • 概述现在的各种市场推广方式,不论是平面的还是多媒体的,都能看到二维码的身影了,可以说是二维码满天飞。扫一扫的方式几乎已经深入人心,这一方面微信可谓功不可没,现在也是树敌无数(如果这一句你不懂,请继续看...
  • 申请“扫码”专利后,还申请了数字货币“统一码发行”专利,目前覆盖全球100个国家和地区。  近日,中国央行数字货币DCEP测试公告与徐蔚码链技术研究成果密切相关,“包括使用扫描离线数字货币钱包”专利技术,...
  • 二维码现在是无处不在,无孔不入了。大到一辆汽车,小到一包纸巾,身上都印有二维码,明码标价。败家娘们可能会说:没想过要买的,真心的!就是看着漂亮嘛,想拍个照片,谁知道一拍就弹出个支付界面,想按退出但是手...
  • 扫一扫二维码隐私权政策    2018年10月5日   “扫一扫二维码”深知个人信息对您的重要性,并会尽全力保护您的个人信息安全可靠。我们致力于维持您对我们的信任,恪守以下原则,保护您的个人信息:权责一致...
  • 二维码编解码 支持二维码的生成与识别。...注意,该示例代码仅适用于 www.apishop.net网站下API 使用该产品前,您需要通过 https://www.apishop.net/#/api/detail/?productID=128申请API服务 1、二维码...
  • 产品要求用户通过其他用户的推荐二维码进入小程序,并且绑定二维码所带的参数 微信小程序的二维码生成分为A接口和B接口: 这是微信的官方文档介绍(文档链接如下...
  • 怎么申请微信公众平台账号,微信二维码如何生成 本文摘要:最近腾讯微信这款产品已经是越来越深入人心了,尤其是近期微信公众平台的开放,更是吸引了众多“大师们”纷纷去开通这个账号。今天就来讲一下如何申请微信...
  • 刷脸支付有什么优势,相比其他支方式,刷脸支付最显著的特点就是没有支付介质,不需要现金、手机、二维码等介质,支付只需面向刷脸支付设备就可完成支付,更加方便快捷,没有媒介就不用担心没带钱、手机没电、不方便...
  • 二维码云平台是一个开放的平台,只要申请注册就可以使用,不需要用户支付费用,永久使用。 其次,平台内置工单功能,维护人员只要扫描二维码,就实现一键报修,让管理人员能够实时掌控资产的报修情况和工单的完成...
  • 因为公司已经支持了支付宝支付和微信支付,所以需要加上一个银联的云闪付,主要是二维码支付。 银联商务的官方文档其实已经很清楚了,但是因为之前对接支付宝和微信,有一个保存商户信息的表,表结构已经确定了,再...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,344
精华内容 3,337
关键字:

如何申请产品二维码