精华内容
下载资源
问答
  • 现如今QR码(二维码)支付已经普遍存在于越南。2019年3月8日,胡志明市正式在部分公交路线试行二维码扫码支付。...如若此次试验成功,胡志明市将把QR码支付的试验扩展到更多公交线路。QR码支付方法将有机会在此测...

      现如今QR码(二维码)支付已经普遍存在于越南。2019年3月8日,胡志明市正式在部分公交路线试行二维码扫码支付。此后乘客可以不购买纸质车票而通过手机钱包应用ZaloPay的付款二维码进行扫码支付。如若此次试验成功,胡志明市将把QR码支付的试验扩展到更多公交线路。QR码支付方法将有机会在此测试后更深入到人们的生活中。

      在越南,QR码支付方式已广泛应用于电子商务网站和线下商店如Tiki.vn、thegioididong.com、各便利店连锁店、奶茶店、路边咖啡馆,等等。

      越南在线服务股份公司(VietUnion,Payoo平台的所有者)总经理Ngo Trung Linh表示,QR码支付服务在其他国家非常成功,这一种付款方式将受到越南的关注和发展。

      “在越南,国家银行正在制定相关支付标准规定,目前许多单位也准备接受这种新的支付方式,“Ngo Trung Linh表示。

      ZaloPay表示,较2018年相比,ZaloPay的QR码接受点增长了20%。今年ZaloPay将扩大QR码支付接受点的部署,目标占系统总收入的50%。

      与此同时,截至今日,与2018年第二季度相比,Payoo的QR支付接受点也增加了25%。

      除了数字钱包开发金融科技创企如MoMo、Payoo、ZaloPay等对QR码支付技术感兴趣,许多越南银行也通过这种付款方式开发自己的应用程序。目前大约有18家越南银行如BIDV、Vietcombank、VietinBank、Agribank、TPBank、VPBank、Maritime Bank、SCB、SHB等应用QR码支付服务。据相关数据,目前约有800用户使用银行的QR码支付服务。不过虽然大多企业积极部署接受点,但业务覆盖范围不广。

      QR是越南国家支付系统正在大力推广的服务。通过QR码支付,银行及各类型中间支付服务供应商可以更广泛的推广业务。因此,各银行组织遵循同样的支付标准有利于确保整个信息网络中支付系统以及相关数据的统一性。郑州人流医院

      目前Sacombank、TPBank和NAPAS以及一些相关中间支付服务供应商正在根据统一标准提供QR码支付服务试验,并计划于今年正式投入使用。

    转载于:https://my.oschina.net/u/4098549/blog/3023423

    展开全文
  • 对接微信二维码支付(native方式

    万次阅读 2019-07-11 16:34:12
    微信对接分多中方式,而native是调用微信支付服务在网页生成二维码,客户扫描二维码支付。 2.准备工作 (1)申请服务号,需要审核认证,300块钱。 (2)服务号申请通过后,在微信公众平台开通微信支付 开通...

    1.微信支付的官网对接手册:

    地址:https://pay.weixin.qq.com/wiki/doc/api/index.html

    微信对接分多中方式,而native是调用微信支付服务在网页生成二维码,客户扫描二维码支付。

    2.准备工作

    (1)申请服务号,需要审核认证,300块钱。

    (2)服务号申请通过后,在微信公众平台开通微信支付

    开通参考地址:https://jingyan.baidu.com/album/e8cdb32b0bb7de37042bad7b.html?picindex=3

    简单说下开通流程,需要几个重要信息,身份证正反面照片,一个对公的银行账户和卡号,申请提交后等待3-5个工作日进行审核。开通的时候回填一个邮箱,开通成功后回把一些信息发到邮箱上面。

     

    (3)开通微信支付的邮箱接收到的商品平台信息

    开通之后,APPID是知道了,商户号也知道了。 

    (4)登录微信商用平台

    地址:https://pay.weixin.qq.com/ 

    去设置API密匙,下载证书,密匙设置好后不会显示,所以记得保存。

    注意:证书是退款是用到的,不光退款,是你的钱往外出的时候用到证书,可以不用管,下面会讲到退款怎么处理。

    设置回调接口,就是微信支付成功之后,微信会回调,填写一个回调地址。

    此时,API密匙有了,签名加密方式就用MD5就行,证书也有了。

    (5)另外需要的参数

    还剩一个开发者密码:

    这个应该是申请服务号之后设置的,设置之后不会显示,所以提前需要保存。(我是用公司的服务号,都是开通好的,但是不知道开发者密码,只能选择重置)

     重置:

    (6)参数已经全了,说一些题外的。

    微信分公众平台,开放平台,商户平台总共三个平台。了解一下三个平台的区别。

    微信三个平台区分(开放,公众,商户平台):https://blog.csdn.net/atongmu2017/article/details/94728996

    ps:微信开放平台中可以在查看移动应用中去开通微信支付功能,但是这个是对接微信支付的另一种方式,好像是app拉起微信支付,类似于外卖下单支付的时候跳到微信手机客户端的支付界面。(注意这个区分)

    查看界面:

    3.下载 SDK

    地址:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1

    下载的压缩包解压出来有几个类:

    扔到项目下:

    我项目用的是jdk1.8,WXPayXmlUtil这个类会报错,提示XMLConstants.FEATURE_SECURE_PROCESSING找不到。

     解决办法:把下面这个jar包从libraries中移除,报错消失。消失之后,再次加入libraries中,也不再报错。

    4.生成订单二维码

    页面请求生成二维码有关的类:

     CommonUtil.java

    有两个方法,一个是发送http请求,用于发送xml参数给微信服务器,另一个是获取ip,xml参数中有个参数是ip

    package com.jeeplus.modules.wxpay;
    
    import java.io.BufferedReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.net.URL;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Set;
    import java.util.SortedMap;
    
    import javax.net.ssl.HttpsURLConnection;
    import javax.servlet.http.HttpServletRequest;
    import org.apache.commons.lang.StringUtils;
    import third.wxpay.WXPayUtil;
    
    public class CommonUtil {
    		
    	public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
    		try {
    			URL url = new URL(requestUrl);
    			HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
    			conn.setDoOutput(true);
    			conn.setDoInput(true);
    			conn.setUseCaches(false);
    			// 设置请求方式(GET/POST)
    			conn.setRequestMethod(requestMethod);
    			conn.setRequestProperty("content-type", "application/x-www-form-urlencoded"); 
    			// 当outputStr不为null时向输出流写数据
    			if (null != outputStr) {
    				OutputStream outputStream = conn.getOutputStream();
    				// 注意编码格式
    				outputStream.write(outputStr.getBytes("UTF-8"));
    				outputStream.close();
    			}
    			// 从输入流读取返回内容
    			InputStream inputStream = conn.getInputStream();
    			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
    			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
    			String str = null;
    			StringBuffer buffer = new StringBuffer();
    			while ((str = bufferedReader.readLine()) != null) {
    				buffer.append(str);
    			}
    			// 释放资源
    			bufferedReader.close();
    			inputStreamReader.close();
    			inputStream.close();
    			inputStream = null;
    			conn.disconnect();
    			return buffer.toString();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return null;
    	}
    	
    	
    	/**
    	 * 获取ip
    	 * @param request
    	 * @return
    	 */
    	public static String getIp(HttpServletRequest request) {
    		if (request == null)
    			return "";
    		String ip = request.getHeader("X-Requested-For");
    		if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
    			ip = request.getHeader("X-Forwarded-For");
    		}
    		if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
    			ip = request.getHeader("Proxy-Client-IP");
    		}
    		if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
    			ip = request.getHeader("WL-Proxy-Client-IP");
    		}
    		if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
    			ip = request.getHeader("HTTP_CLIENT_IP");
    		}
    		if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
    			ip = request.getHeader("HTTP_X_FORWARDED_FOR");
    		}
    		if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
    			ip = request.getRemoteAddr();
    		}
    		return ip;
    	}
    	
    }
    

    ConfigUtil.java

    存放一些支付参数和回调接口信息

    package com.jeeplus.modules.wxpay;
    
    public class ConfigUtil {
    	/**
    	 * 服务号相关信息
    	 */
    	public final static String APPID = "";//服务号的应用号
    	public final static String MCH_ID = "";//商户号
    	public final static String APP_SECRECT = "";//服务号的应用密码
    	public final static String API_KEY = "";//API密钥
    	public final static String SIGN_TYPE = "MD5";//签名加密方式
    	public final static String CERT_PATH = "D:/project/cert/apiclient_cert.p12";//微信支付证书存放路径地址
    	
    	 public final static String TOKEN = "";//服务号的配置token
    	 //微信支付统一接口的回调action
             //填写自己网站的接口
    	 public final static String NOTIFY_URL = "http://www.baidu.com";
    
    }
    

    MatrixToImageWriter.java

    地址变成二维码图片的类,用到 com.google.zxing.common.BitMatrix这个类,用到zxing这个jar包

    package com.jeeplus.modules.wxpay;
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.EncodeHintType;
    import com.google.zxing.MultiFormatWriter;
    import com.google.zxing.common.BitMatrix;
     
    
    
    
    
     import javax.imageio.ImageIO;
    
    import java.io.File;
    import java.io.OutputStream;
    import java.io.IOException;
    import java.util.Hashtable;
    import java.awt.image.BufferedImage;
     
     
     public final class MatrixToImageWriter {
     
       private static final int BLACK = 0xFF000000;
       private static final int WHITE = 0xFFFFFFFF;
     
       private MatrixToImageWriter() {}
     
       
       public static BufferedImage toBufferedImage(BitMatrix matrix) {
         int width = matrix.getWidth();
         int height = matrix.getHeight();
         BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
         for (int x = 0; x < width; x++) {
           for (int y = 0; y < height; y++) {
             image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
           }
         }
         return image;
       }
     
       
       public static void writeToFile(BitMatrix matrix, String format, File file)
           throws IOException {
         BufferedImage image = toBufferedImage(matrix);
         if (!ImageIO.write(image, format, file)) {
           throw new IOException("Could not write an image of format " + format + " to " + file);
         }
       }
     
       
       public static void writeToStream(BitMatrix matrix, String format, OutputStream stream)
           throws IOException {
         BufferedImage image = toBufferedImage(matrix);
         if (!ImageIO.write(image, format, stream)) {
           throw new IOException("Could not write an image of format " + format);
         }
       }
     
       public static void main(String[] args) throws Exception { 
           String text = "www.baidu.com"; 
           int width = 300; 
           int height = 300; 
           String format = "gif"; 
           Hashtable hints = new Hashtable(); 
           hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); 
           BitMatrix bitMatrix = new MultiFormatWriter().encode(text, 
                   BarcodeFormat.QR_CODE, width, height, hints); 
           File outputFile = new File("d:"+File.separator+"new.gif"); 
           MatrixToImageWriter.writeToFile(bitMatrix, format, outputFile); 
       }  
     }

    创建订单的方法:

    private void doWx(HttpServletRequest request,HttpServletResponse response) throws Exception {
    		String number=request.getParameter("number")==null?"":request.getParameter("number");
    		Productorder p = productorderService.findUniqueByProperty("number", number);
    		Date date=new Date();
    		SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
    		String timeStart=sdf.format(date);
    		Calendar cal=Calendar.getInstance();
    		cal.add(Calendar.DAY_OF_MONTH, 1);
    		Date date1=cal.getTime();
    		String timeExpire=sdf.format(date1); 
    		SortedMap<String,String> parameters = new TreeMap<String,String>();
            parameters.put("appid", ConfigUtil.APPID);                   
            parameters.put("body", p.getPname());
            parameters.put("mch_id", ConfigUtil.MCH_ID);          
            parameters.put("out_trade_no", number);
            parameters.put("spbill_create_ip",CommonUtil.getIp(request));
            DecimalFormat df = new DecimalFormat("#");
            parameters.put("total_fee",  df.format(Double.parseDouble(p.getOrdermoney())*100));                            
            parameters.put("trade_type", "NATIVE");
            parameters.put("time_expire", CommonUtil.getOrderExpireTime(startData,5*60*1000L));//二维码过期时间5分钟
            parameters.put("nonce_str", WXPayUtil.generateNonceStr());
            parameters.put("notify_url", ConfigUtil.NOTIFY_URL);//支付成功后回调的action,与JSAPI相同
            String generateSignature = WXPayUtil.generateSignature(parameters, ConfigUtil.API_KEY, SignType.MD5);
            parameters.put("sign", generateSignature);
            String generateSignedXml = WXPayUtil.generateSignedXml(parameters, ConfigUtil.API_KEY);
            System.out.println("微信支付预下单请求xml格式::"+generateSignedXml);
            String result =CommonUtil.httpsRequest(ConfigUtil.UNIFIED_ORDER_URL, "POST", generateSignedXml);
            System.out.println(result);
            Map<String, String> map;
    		try {
    			
    			map = WXPayUtil.xmlToMap(result);
    			 String returnCode = map.get("return_code");
    		        String resultCode = map.get("result_code");
    		        if(returnCode.equalsIgnoreCase("SUCCESS")&&resultCode.equalsIgnoreCase("SUCCESS")){
    		           String codeUrl = map.get("code_url");
    		           //TODO 拿到codeUrl,写代码生成二维码
    		           System.out.println("codeUrl="+codeUrl);
    		           int width = 300; 
    		           int height = 300; 
    		           //二维码的图片格式 
    		           String format = "JPEG"; 
    		           Hashtable hints = new Hashtable(); 
    		           //内容所使用编码 
    		           hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); 
    		           BitMatrix bitMatrix = new MultiFormatWriter().encode(codeUrl, 
    		                   BarcodeFormat.QR_CODE, width, height, hints); 
    		          // response.setContentType("image/JPEG");
    		           MatrixToImageWriter.writeToStream(bitMatrix, format, response.getOutputStream());
    		          
    		        }
    		} catch (Exception e) {
    			e.printStackTrace();
    		} 

    可以把生成二维码的方法写成一个接口,测试调用接口,页面会显示二维码

    扫描二维码:

    5.创建订单生成二维码注意的问题

    (1)签名算法,需要参数拼接起来,加上密匙参数,拼接后MD5加密得到sign这个参数。而其他参数拼接的时候注意要按参数名ASCII码从小到大排序(字典序),所以用到SortedMap

    SortedMap<String,String> parameters = new TreeMap<String,String>();

    (2)测试的时候生成二维码,之后修改订单金额,请求后显示不出来二维码,微信返回信息如下,原因是同一个订单不允许前后两次请求金额不同。

    <err_code><![CDATA[INVALID_REQUEST]]></err_code><err_code_des><![CDATA[201 商户订单号重复]]></err_code_des>

    (3)total_fee这个订单金额参数需要注意,单位是分,所以需要把元转换成分。

    解决办法:字符串金额转换成double类型,乘以100,然后去掉小数点后的一个零

    DecimalFormat df = new DecimalFormat("#");
    parameters.put("total_fee",  df.format(Double.parseDouble(p.getOrdermoney())*100));

    有个特别容易出错的地方,如果金额是12.34,转换成double类型,然后乘100,你以为最后返回的是1234这个数,其实是1234.0,然后传给微信也是不成功的。必须是整数。

    下面是金额不对的时候,微信返回的错误提示信息: 

    <xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[invalid total_fee]]></return_msg>

    6.回调接口

    支付成功之后,微信会回调你在商用平台上设置的微信回调接口,里面处理支付成功后的业务逻辑。下面的提供参考: 

    /**
    	 * 微信回调接口
    	 * http://127.0.0.1:8080/qcloud/a/payInterface/notifyWeiXinPay
    	 * @param request
    	 * @param response
    	 * @return
    	 * @throws Exception
    	 */
    	@RequestMapping(value="/notifyWeiXinPay",produces="text/html;charset=utf-8")
    	@ResponseBody
        public String notifyWeiXinPay(HttpServletRequest request, HttpServletResponse response) throws Exception {
    		Map<String,String> return_data = new HashMap<String,String>();
    		//读取参数  
            InputStream inputStream ;  
            StringBuffer sb = new StringBuffer();  
            inputStream = request.getInputStream();  
            String s ;  
            BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));  
            while ((s = in.readLine()) != null){  
                sb.append(s);  
            }  
            in.close();  
            inputStream.close();  
      
            //解析xml成map  
            Map<String, String> map = WXPayUtil.xmlToMap(sb.toString());
            //判断签名是否正确   
    //        if(true) {
            
            if(WXPayUtil.isSignatureValid(map, ConfigUtil.API_KEY)) {
            	if(!map.get("return_code").toString().equals("SUCCESS")){
    	        	return_data.put("return_code", "FAIL");
    	        	return_data.put("return_msg", "return_code不正确");
    	        }else{
                    if(!map.get("result_code").toString().equals("SUCCESS")){
    	            	return_data.put("return_code", "FAIL");
    	            	return_data.put("return_msg", "result_code不正确");
    	            	return WXPayUtil.mapToXml(return_data);
    	            }
                    
                	String orderno = (String)map.get("out_trade_no");//商户订单号
                    String transaction_id = (String)map.get("transaction_id");//微信支付订单号 
                    String time_end = (String)map.get("time_end");//支付完成时间yyyyMMddHHmmss
                    BigDecimal total_fee = new BigDecimal(map.get("total_fee").toString());
                    //付款完成后,支付宝系统发送该交易状态通知
                    Productorder order = productorderService.findUniqueByProperty("order_no", orderno);
                    if(order==null) {
                    	System.out.println("订单不存在");
                        return_data.put("return_code", "FAIL");
                        return_data.put("return_msg", "订单不存在");
                        return WXPayUtil.mapToXml(return_data);
                    }
                    
                    BigDecimal num = new BigDecimal("100");  
                    BigDecimal ordermoney = new BigDecimal(order.getOrdermoney());
                    ordermoney  = ordermoney.multiply(num);
                    //订单已经支付
                    if(order.getOrderstatus().equals("1")){
                        System.out.println("订单已经支付");
                        return_data.put("return_code", "SUCCESS");
                        return_data.put("return_msg", "OK");
                        return WXPayUtil.mapToXml(return_data);
                    }
                    //如果支付金额不等于订单金额返回错误
                    if(ordermoney.compareTo(total_fee)!=0){
                    	System.out.println("资金异常");
                        return_data.put("return_code", "FAIL");
                        return_data.put("return_msg", "金额异常");
                        return WXPayUtil.mapToXml(return_data);
                    }
                    //更新订单信息
                    try {
                    	System.out.println("更新订单信息");
                    	SimpleDateFormat sdf1=new SimpleDateFormat("yyyyMMddHHmmss");
                		SimpleDateFormat sdf2=new SimpleDateFormat("YYYY-MM-dd hh:mm:ss");
                    	order.setOrderstatus("1");
                    	order.setPaytime(sdf2.format(sdf1.parse(time_end)));
                    	order.setPaymentway("1");
                    	productorderService.update(order);
                    	
                    	System.out.println("插入已经支付的订单表");
                    	//插入已经支付的订单表(product_order_pay)
                    	List<String> goodsIds = productgoodsService.getGoodsIdsByOrderno(orderno);
                    	for (String gid : goodsIds) {
                    		Productorderpay productorderpay = new Productorderpay();
                    		productorderpay.setUserid(order.getUserid());
                    		productorderpay.setPpid(gid);
                    		productorderpay.setEndtime(order.getOrderendtime());
                    		productorderpayService.insert(productorderpay);
    					}
                    	
                    	return_data.put("return_code", "SUCCESS");
                        return_data.put("return_msg", "OK");
                        return WXPayUtil.mapToXml(return_data);
    				} catch (Exception e) {
    					e.printStackTrace();
    					return_data.put("return_code", "FAIL");
                        return_data.put("return_msg", "更新订单失败");
                        return WXPayUtil.mapToXml(return_data);
    				}
    	        }
            } else{  
                System.out.println("通知签名验证失败");
                return_data.put("return_code", "FAIL");
    	        return_data.put("return_msg", "签名错误");
            }  
            return WXPayUtil.mapToXml(return_data);
        }

    7.支付页面

    (1)显示二维码:页面中img标签来显示二维码,img的src指向的是生成二维码的请求。

    (2)查询订单支付状态:同一个页面,去写一个定时异步请求方法,去查询订单是否支付成功,支付成功做下一步处理。

    (3)页面代码参考: 

    <body>
    	<!--nav-->
    	<jsp:include page="/eb_headerhs2017.jsp" />
    	<div class="section">
    		<div class="section_div">
    			<div class="section_div_top clear">
    				<p class="section_div_p">订单提交成功,请尽快付款!订单号:${orderNo}</p>
    				<p class="section_div_p2">
    					应付金额 <span class="section_div_span">${orderMoney}</span> 元
    				</p>
    			</div>
    			<div class="section_div_bottom clear">
    				<p class="section_bottom_p">微信支付</p>
    				<div class="QRcode">
    					<img class="QRcode_img"
    						src="填写生成二维码接口?orderNo=${orderNo}" alt="二维码">
    						<div class="QRcode_div clear">
    							<img class="QRcode_div_img"
    								src="images/hs/weixinzhifuerweima_10.png" alt="">
    								<div class="QRcode_div_div">
    									<p>请使用微信扫一扫</p>
    									<p>扫描二维码支付</p>
    								</div>
    						</div>
    				</div>
    				<img class="phone_saosao" src="images/hs/phone_saosao_03.png" alt="">
    					<p class="section_bottom_p2">选择其他支付方式</p>
    			</div>
    		</div>
    
    	</div>
    	<script type="text/javascript">
    	var wxTM = setInterval(function() {
    		getWxPayStatus();
    	},5000)
    	function getWxPayStatus(){
    		jQuery.ajax({
    			type: 'POST',
    		    url: "填写查询支付状态接口?orderNo=${orderNo}",
    			dataType: 'json',
    			success: function(result){
    				if(result.res==1){
    					clearInterval(wxTM);
    					window.location.href="ebHsPay.jsp?payStatus=1&orderNo=${orderNo}";
    				}
    			}
    		});
    	}
    </script>
    	<div class="con_bot"></div>
    	<!--bottom-->
    	<jsp:include page="/eb_footerhs2017.jsp" />
    </body>

    8.订单支付状态接口

    微信提供了查询订单状态的接口,但是一般不去对接微信。对接微信的只涉及一个生产二维码接口。

    怎么去查询支付状态,在支付回调的接口中已经知道订单支付成功还是失败,把状态更新到数据库对应的订单数据中。查询订单状态是从数据库差的,而不是非得去对接微信的查询订单状态接口。

    9.退款

    上面提到自己的账户往外掏钱(退款、发红包)会用到证书,但是退款一般也不对接微信。

    退款的业务逻辑:可以创建一个退款申请表,记录用户退款申请,项目中有这么一个版块。让使用项目管理员去查看这些数据,联系用户为什么退款,让管理员自己处理,真正退款是在微信商用平台上面去退款。平台上有退款的功能,而不是去写代码对接微信退款。

    原因:一方面不用写这块代码。另一方面,万一你这个网站退款的接口被黑会是个问题。还有就是退款请求不会太多,何必走接口。

    10.其他

    自己也是第一次对接微信,有些细节需要注意的地方,我是向经常做商品支付项目的公司同事询问了解的。

    支付这块考虑详细点,代码的可扩展,复用等。越详细越好。不至于之后客户一提需求就改动这块代码,或者这块代码根本用不了。

    (1)建表:一般是订单表和商品表,订单只存订单的信息,商品去关联订单。比如考虑是否有优惠折扣,创建对应的表。

    订单表字段参考

     

     

    (2)查询用户是否订购过这个订单

    订单表是从一开始数据是不会删除的,里面的数据只会越来越多。里面有支付成功的订单,超时支付失效的订单等等。

    比如,用户订购了一个视频,查询用户是否订购了这个视频,是否能播放。不可能去查询原始的订单表,到后面数据量大了,查询速度特别慢。需要另建一个表,里面只保存支付成功的订单,一些关键信息,如订单编号,订单用户,到期时间。去查询这个表,之后可以把这个表里的过期订单删除。

    (3)订单编号

    一开始我的订单编号是随机生成的十六位数字,但是不要这样做。

    订单号要一眼能看到这个订单的信息,比如BOOK20190511xxxx,VIDEO20180613xxx,当看到这个订单就知道这个订单是订购的什么,订购的时间。在订单编号里面加上用户信息等等,到时候去查询这个订单的时候,看到这个订单编号大致先了解这个订单的信息,而不是一堆随机数据,什么信息也看不出来。

    (4)支付从页面到后台的流程

    我看到一个电商平台的项目代码,里面的流程可以参考下。

    页面用img的src属性去请求一个controller的pay方法,这个方法中什么都没做,只是处理下请求参数,然后然后请求到原来的页面。二维码怎么生成,在请求返回的过程中,拦截器拦截了请求,根据参数生成二维码返回原来页面。

    11.补充

    (1)微信回调

    上面因为我只有一个类型的订单,回调写在回调的方法里,但是这样写不好。

    回调方法处理是个入口,根据不同的订单类型再去跳转不同的回调处理方法。便于之后的扩展,调整修改方便,而不是一改动就去改统一的那个回调方法。

    (2)手机app接微信支付

    因为这种支付方式注意是网站生成二维码,用户扫描支付的。

    手机app接微信支付,最好使接像上面提到的,类似美团的,订外卖支付直接跳转到微信。

    现在这种方式也可以,需要注意一些地方:

    ①微信创建订单接口,会返回一个支付地址,之前是把这个地址生成二维码图片展示,而手机app是直接打开这个地址,手机会跳到微信支付。

    ②支付成功的页面,需要判断是从网站来的还是手机来的,分别显示不同的页面。

    ③支付成功之后的回调,手机app会跳到空白页,苹果的会打开赛风浏览器显示支付成功的页面。再跳回app很多余

    参考下面的文章,手机端可以处理:https://www.jianshu.com/p/90db7dfb075c 

    展开全文
  • 刷卡支付是用户展示微信钱包内的“刷卡条码/二维码”给商户系统扫描后直接完成支付的模式。主要应用线下面对面收银的场景。 2、扫码支付 扫码支付是商户系统按微信支付协议生成支付二维码,用户再用微信“扫一扫...

    一、微信支付方式介绍

    微信提供了各种支付方式,试用于各种不同的支付场景,主要有如下几种:

    1、刷卡支付

    刷卡支付是用户展示微信钱包内的“刷卡条码/二维码”给商户系统扫描后直接完成支付的模式。主要应用线下面对面收银的场景。

    2、扫码支付

    扫码支付是商户系统按微信支付协议生成支付二维码,用户再用微信“扫一扫”完成支付的模式。该模式适用于PC网站支付、实体店单品或订单支付、媒体广告支付等场景。

    3、公众号支付

    公众号支付是用户在微信中打开商户的H5页面,商户在H5页面通过调用微信支付提供的JSAPI接口调起微信支付模块完成支付。应用场景有:

    1. ◆ 用户在微信公众账号内进入商家公众号,打开某个主页面,完成支付
    2. ◆ 用户的好友在朋友圈、聊天窗口等分享商家页面连接,用户点击链接打开商家页面,完成支付
    3. ◆ 将商户页面转换成二维码,用户扫描二维码后在微信浏览器中打开页面后完成支付

    4、APP支付

    APP支付又称移动端支付,是商户通过在移动端应用APP中集成开放SDK调起微信支付模块完成支付的模式。

    5、H5支付

    H5支付用于在手机端微信外浏览器进行支付,笔者的测试本支付方式在微信内不能使用。

    本文主要讲解.net mvc实现扫码支付方法,具体代码如下:

    二、调起支付Controller代码
    /// <summary>
    /// 支付首页
    /// </summary>
    /// <returns></returns>
    public ActionResult Index()
    {
        NativePay nativePay = new NativePay();
        //总金额
        int total_fee = 1;
        //生成订单
        //判断是否有未支付订单
        string productId = "产品ID";
        decimal moeny = Convert.ToDecimal(1);//支付金额
        string orderId = "订单ID";
        //订单描述
        string body = "订单描述";
        //生成扫码支付模式二url
        WxPayData data = new WxPayData();
        data.SetValue("body", "商品描述");//商品描述
        data.SetValue("attach", body);//附加数据
        data.SetValue("out_trade_no", orderId);//随机字符串
        data.SetValue("total_fee", total_fee.ToString());//总金额
        data.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));//交易起始时间
        data.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"));//交易结束时间
        data.SetValue("goods_tag", orderId);//商品标记
        data.SetValue("trade_type", "NATIVE");//交易类型
        data.SetValue("product_id", productId);//商品ID
        data.SetValue("notify_url", "http://www.*****.com.cn/Pay/ResultNotify");//支付成功返回调用
        WxPayData result = WxPayApi.UnifiedOrder(data);//调用统一下单接口
        ViewBag.ImageUrl2 = "/Pay/MakeQRCode?data=" + HttpUtility.UrlEncode(result.GetValue("code_url").ToString());
        return View();
    }
    /// <summary>
    /// 生成支付二维码图片
    /// </summary>
    /// <returns></returns>
    public ActionResult MakeQRCode()
    {
        if (!string.IsNullOrEmpty(Request.QueryString["data"]))
        {
            string str = Request.QueryString["data"];
     
            //初始化二维码生成工具
            QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
            qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE;
            qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;
            qrCodeEncoder.QRCodeVersion = 0;
            qrCodeEncoder.QRCodeScale = 4;
     
            //将字符串生成二维码图片
            Bitmap image = qrCodeEncoder.Encode(str, Encoding.Default);
     
            //保存为PNG到内存流 
            MemoryStream ms = new MemoryStream();
            image.Save(ms, ImageFormat.Png);
     
            //输出二维码图片
            return File(ms.GetBuffer(), @"image/png");
            //Response.BinaryWrite(ms.GetBuffer());
            //Response.End();
        }
        return Content("Error");
    }

     

    三、支付成功后台处理方法
    /// <summary>
    /// 支付成功返回处理订单信息
    /// </summary>
    /// <returns></returns>
    public ActionResult ResultNotify()
    {
        WxPayData notifyData = GetNotifyData();
        //检查支付结果中transaction_id是否存在
        if (!notifyData.IsSet("transaction_id"))
        {
            //若transaction_id不存在,则立即返回结果给微信支付后台
            WxPayData res = new WxPayData();
            res.SetValue("return_code", "FAIL");
            res.SetValue("return_msg", "支付结果中微信订单号不存在");
            Log.Error(this.GetType().ToString(), "The Pay result is error : " + res.ToXml());
            return Content("支付结果中微信订单号不存在");
        }
     
        string transaction_id = notifyData.GetValue("transaction_id").ToString();
        string trade_no = notifyData.GetValue("out_trade_no").ToString();
        //查询订单,判断订单真实性
        if (!QueryOrder(transaction_id))
        {
            //若订单查询失败,则立即返回结果给微信支付后台
            WxPayData res = new WxPayData();
            res.SetValue("return_code", "FAIL");
            res.SetValue("return_msg", "订单查询失败");
            Log.Error(this.GetType().ToString(), "Order query failure : " + res.ToXml());
            return Content("订单查询失败");
        }
        //查询订单成功
        else
        {
            WxPayData res = new WxPayData();
            res.SetValue("return_code", "SUCCESS");
            res.SetValue("return_msg", "OK");
            Log.Info(this.GetType().ToString(), "order query success : " + res.ToXml());
            //更新支付状态
             
            return Content("支付成功" + res.ToXml());
        }
    }

     

    四、源码下载:http://www.kwstu.com/ResourcesView/weixin_201710301127489173

    咨询QQ:806693619

    转载于:https://www.cnblogs.com/kwstu/p/7797384.html

    展开全文
  • 刷脸支付是时代发展产物,是二维码的升级版,支付宝、微博官方会逐渐中止二维码缴纳补贴,尽力推展刷脸支付。对于商家而言早晚都会用之上,早用迟收益,你们最终由于不必便会外流客户因而不得不选取。 于超市、...

    刷脸支付是时代发展的产物,是二维码的升级版,支付宝、微博官方会逐渐中止二维码缴纳的补贴,尽力推展刷脸支付。对于商家而言早晚都会用之上,早用迟收益,你们最终由于不必便会外流客户因而不得不选取。

    于超市、餐厅、药店等场景上线之后,减轻了高峰时段结账等候,3-8秒完工支付流程,结算效率提高50%超过;消费者选取这种全新方式展开结账的少于20%,作为商家节约人力成本与时间成本,提现免手续费,成本降下去后,可予消费者越来越余的优惠。刷脸支付,智慧医疗,智慧校园,智慧银行,餐饮超市酒店,无感停车场,各场景解决方案,软件定制开发,支付设备批发,详细请百度“掌优电子 魏”

    刷脸支付设备使用的是目前安全系数最低的3D人脸识别技术,采用毫米级景深信息检测,透过光感点阵,收集了用户独一无二的生物身份信息,接着和实名证书之后的支付宝账号连接,来达安全性支付的效果,目前支付宝的刷脸设备已经达了99.99%的准确度,即使不法分子拿着我们的照片或是视频,亦难以透过宝刷脸的认证。

    刷脸支付流程怕忘带手机、手机没电、信号少、手机卡、死机等造成的困扰;帮顾客省略了记密码,输密码的困难,构建了人和钱包或是银行卡的“合二作为一” ,消费者获得便于,亦越来越愿意来您家消费。设备可刷脸支付,亦可以微信、支付宝收款码支付,除此之外拥护花呗、信用卡间接支付,合乎现在年轻人的消费习惯。

    在消费者刷脸支付的这个场景下,消费者注意力全部放在屏幕上,在店家与消费者建立连接之后,一系列促销的动作就还可以推出,不论是复购券、熟人券还是生日礼包,都能对消费者进行定向营销。刷脸支付设备是店家跟消费者进行接触的一个媒介。在未来,借助于先进的IoT的面部识别的能力并结合店家自身的营销计划,刷脸支付将会为店家节省更多运营营销开支。

    旧的不去新的不来,随着深化改革的脚步越走越远,生产力水平越来越高,人们的经济文化生活也越来越丰富。人们对生活品质的追求越来越高,从现金交易到刷卡交易到电子交易到扫码支付、刷脸支付。

    展开全文
  • 关于微信支付(一) ...这篇文章先讲 第一种最常用 弹出二维码支付 二维码支付 大概流程如下 用户选择支付->后台程序创建订单->请求微信同意下单接口(除了常规参数还需要一个接口这个URL...
  • 二维码支付是由支付宝正式引入中国市场。2011年7月1日,支付宝正式推出了手机APP二维码支付业务,...随着科技不断发展,移动支付与科技融合在不断刷新人们生活方式,除了二维码支付吗,NFC、虹膜支付、声音...
  • 在平台上填写授权回调地址,以及选择加签方式(RSA2)。 注:如果是正式上线,不能使用沙箱AppID,应该到支付宝开放平台创建一个生活号或者小程序应用获取。 2、配置密钥、公钥。 可以使用官方密钥生成工具来...
  • 二维码支付”安全么? 1引言 随时支付宝和微信的线下不断...先来简单说说二维码:二维码是用一定规则排布的点阵的图像来编码信息的方式。与二维码对应的是传统的“条码”(一维码)。 和“条码”一样,二维...
  • 模拟基于加密的二维码实现电子交易系统,实现交易迅速便捷,可以在web浏览器和移动端同时使用。采用Google.zxing接口实现二维码的生成和解析,采用加密协议传送,产品类似webapp形式呈现。开发利用DAO设计...
  • 在现在这个移动支付市场中,互联网技术的支撑下,刷手机乘公交、刷支付宝买菜购物、缴水电费……日常生活中使用“现金”的场景,逐渐被手机各种支付方式取代,“无现金社会”在便捷支付的推动下将越来越近。...
  • 二维码支付场景学习

    2019-08-02 13:47:43
    现在我们生活中基本都离不开两种支付方式,微信和支付宝支付,现金支付方式越来越少。 前段时间因为项目所需,特意了解学习了一些,记录在此,愿对有缘人有所参考价值。 了解两大主流支付。 1、付款码都是一串18位...
  • 通过二维码(条)互方式实现了个人之间、与商户以及资金收付, 实现了个人之间、与商户以及资金收付, 实现了个人之间、与商户以及资金收付
  • 中金公司研报指出,从支付方式来看,目前数字人民币测试App仍以二维码支付方式二维码无法离线加载, App包含了基于NFC标签“碰一碰”付款功能,但尚未开通。试点银行为测试商户提供了新POS机,目前用来专扫...
  • 模拟基于加密的二维码实现电子交易系统,实现交易迅速便捷,可以在web浏览器和移动端同时使用。采用Google.zxing接口实现二维码的生成和解析,采用加密协议传送,产品类似webapp形式呈现。开发利用DAO设计...
  • 盒子支付近日推出了新的支付方式——QRPOS,通过手机识别带刷卡信息的二维码,直接利用插在手机3.5mm音频孔上盒子刷卡器完成刷卡支付。QRPOS支持线上和线下使用,用户只需要有带银联标志银行卡或者信用卡就可以...
  • 二维码又称二维条码,常见的二维码为QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行一种编码方式,它比传统Bar Code条形码能存更多信息,也能表示更多数据类型。图片 是用某种特定几何...
  • 这是传统的方式通过支付宝的接口,自己拼接字符串.然后根据字符串生成一个二维码对于对于传统方式.支付宝限制了一天二维码的生成数量.在这之间简直是好用得不要不要得.但是突然间支付宝爸爸说.你搞那么多二维码干啥....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 900
精华内容 360
关键字:

二维码支付的方式