首先需要一个沙箱环境,专门为开发者提供的。里面给你提供了卖家账号,和买家账号。具体的自行百度。
需要下载沙箱版的支付宝,然后登陆提供的买卖家账号即可操作。因为在沙箱环境中支付宝给出的二维码只能在沙箱版的支付宝中扫。
沙箱买卖家:
https://openhome.alipay.com/platform/appDaily.htm?tab=account
沙箱需要的配置文件信息:
https://openhome.alipay.com/platform/appDaily.htm?tab=info
当面付demo
https://docs.open.alipay.com/54/104506/
需要一个sra2秘钥生成器,支付宝有提供下载:
https://openclub.alipay.com/read.php?tid=955&fid=46
支付宝当面付开发者文档
https://docs.open.alipay.com/194

场景:用户下单,然后我们后台会去掉支付宝的接口,当然支付宝接口需要一些参数,比如说,标题了,订单号,总金额,物品明细,等等之类的,这些支付宝官方的demo中都有,直接拿过来改造就行。我们主要的是掉支付宝的接口让他给我们返回一个json串,里面有个网址,生成二维码的。然后我们再用这个一个工具包将这个二维码生成二维码,保存到我们的图片服务器上。然后,我们用刚刚下载好的沙箱支付宝扫码支付。然后,支付成功,支付宝会会回调我们之前设置的本地的回调函数(内网映射)。参数中有支付宝返回的结果,比如订单号,支付状态,支付时间等等,但是这些都时支付宝给我们的一些结果,在这之前,我们必须要验证一下这个回调函数是不是支付宝发起的,支付包的demo里有提供这个方法,返回的是布尔值。然后是true的时候,进行我们下一步的操作,就是验证返回的结果的参数正确性和更该数据库里面的状态。最后如果支付成功,给支付宝返回success,不然,支付宝会隔一段时间还回调,具体看文档。大致流程就是这样的。不会的给我留言。。。。

controller

package com.mmall.controller.protal;import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.demo.trade.config.Configs;
import com.google.common.collect.Maps;
import com.mmall.common.Const;
import com.mmall.common.ServerResponse;
import com.mmall.dao.OrderMapper;
import com.mmall.pojo.Order;
import com.mmall.pojo.User;
import com.mmall.service.IOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;/*** Created by 敲代码的卡卡罗特* on 2018/3/18 14:08.*/
@RequestMapping("/order/")
@Controller
@Slf4j
public class OrderController {@AutowiredIOrderService iOrderService;@RequestMapping("pay.do")@ResponseBodypublic ServerResponse pay(HttpSession httpSession, Long orderNo, HttpServletRequest request){User user = (User)httpSession.getAttribute(Const.CURRENT_USER);if (user==null){return ServerResponse.createByError("请登录账号");}System.out.println("request.getContextPath():----"+request.getContextPath());System.out.println("request.getSession().getServletContext()-----"+request.getSession().getServletContext().getRealPath("upload"));String upload = request.getSession().getServletContext().getRealPath("upload");return  iOrderService.pay(orderNo,user.getId(),upload);}@RequestMapping("alipay_callback.do")@ResponseBodypublic Object alipayCallback(HttpServletRequest httpServlet){HashMap<String, String> map = Maps.newHashMap();Map<String, String[]> parameterMap = httpServlet.getParameterMap();Set<String> set = parameterMap.keySet();for (String s: set){String[] strings = parameterMap.get(s);String str="";for (int i=0;i<strings.length;i++){str=i==strings.length-1?str+strings[i]:str+strings[i]+",";}map.put(s,str);}log.info("支付宝回调:sign:{},trade_status:{},参数:{}",map.get("sign"),map.get("trade_status"),map.toString());//验签是不是支付宝发起的回调map.remove("sign_type");try {Configs.init("zfbinfo.properties");boolean bool = AlipaySignature.rsaCheckV2(map, Configs.getAlipayPublicKey(), "utf-8", Configs.getSignType());if (!bool){return ServerResponse.createByError("非法请求,再请求老子就报警了");}} catch (AlipayApiException e) {log.error("支付宝验证回调异常",e);}ServerResponse alipaycall = iOrderService.alipaycall(map);if (alipaycall.isSuccess()){return Const.AlipayCallback.RESPONSE_SUCCESS;}return Const.AlipayCallback.RESPONSE_FAILED;}@RequestMapping("queryOrderPayStatus.do")@ResponseBodypublic ServerResponse queryOrderPayStatus(HttpSession httpSession, Long orderNo){User user = (User)httpSession.getAttribute(Const.CURRENT_USER);if (user==null){return ServerResponse.createByError("请登录账号");}ServerResponse serverResponse = iOrderService.queryOrderPayStatus(user.getId(), orderNo);if (serverResponse.isSuccess()){return ServerResponse.createBySuccess(true);}return  ServerResponse.createBySuccess(false);}
}

service

package com.mmall.service.impl;import com.alipay.api.AlipayResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.demo.trade.config.Configs;
import com.alipay.demo.trade.model.ExtendParams;
import com.alipay.demo.trade.model.GoodsDetail;
import com.alipay.demo.trade.model.builder.AlipayTradePrecreateRequestBuilder;
import com.alipay.demo.trade.model.result.AlipayF2FPrecreateResult;
import com.alipay.demo.trade.service.AlipayTradeService;
import com.alipay.demo.trade.service.impl.AlipayTradeServiceImpl;
import com.alipay.demo.trade.utils.ZxingUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mmall.common.Const;
import com.mmall.common.ServerResponse;
import com.mmall.dao.OrderItemMapper;
import com.mmall.dao.OrderMapper;
import com.mmall.dao.PayInfoMapper;
import com.mmall.pojo.Order;
import com.mmall.pojo.OrderItem;
import com.mmall.pojo.PayInfo;
import com.mmall.service.IOrderService;
import com.mmall.untis.BigDecimalUtil;
import com.mmall.untis.DateUtils;
import com.mmall.untis.FTPUtil;
import com.mmall.untis.PropertiesUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** Created by 敲代码的卡卡罗特* on 2018/3/18 14:17.*/
@Service
@Slf4j
public class OrderServiceImpl implements IOrderService {@AutowiredOrderMapper orderMapper;@AutowiredOrderItemMapper orderItemMapper;@AutowiredPayInfoMapper payInfoMapper;// 支付宝当面付2.0服务private static AlipayTradeService tradeService;public ServerResponse pay(Long orderNo,Integer userId,String path){HashMap map = Maps.newHashMap();if (orderNo==null){return  ServerResponse.createByError("参数错误");}Order order = orderMapper.selectByUserIdAndOrderNo(userId, orderNo);if (order==null){return  ServerResponse.createByError("没有查到该订单");}map.put("orderNo",order.getOrderNo());// (必填) 商户网站订单系统中唯一订单号,64个字符以内,只能包含字母、数字、下划线,// 需保证商户系统端不能重复,建议通过数据库sequence生成,String outTradeNo = order.getOrderNo().toString();// (必填) 订单标题,粗略描述用户的支付目的。如“xxx品牌xxx门店当面付扫码消费”String subject = new StringBuilder().append("快乐慕商城订单:").append(outTradeNo).append("生成订单成功").toString();// (必填) 订单总金额,单位为元,不能超过1亿元// 如果同时传入了【打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】String totalAmount = order.getPayment().toString();// (可选) 订单不可打折金额,可以配合商家平台配置折扣活动,如果酒水不参与打折,则将对应金额填写至此字段// 如果该值未传入,但传入了【订单总金额】,【打折金额】,则该值默认为【订单总金额】-【打折金额】String undiscountableAmount = "0";// 卖家支付宝账号ID,用于支持一个签约账号下支持打款到不同的收款账号,(打款到sellerId对应的支付宝账号)// 如果该字段为空,则默认为与支付宝签约的商户的PID,也就是appid对应的PIDString sellerId = "";// 订单描述,可以对交易或商品进行一个详细地描述,比如填写"购买商品2件共15.00元"String body = new StringBuilder().append("订单:").append(outTradeNo).append(",购买商品共:").append(totalAmount).toString();// 商户操作员编号,添加此参数可以为商户操作员做销售统计String operatorId = "test_operator_id";// (必填) 商户门店编号,通过门店号和商家后台可以配置精准到门店的折扣信息,详询支付宝技术支持String storeId = "test_store_id";// 业务扩展参数,目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法),详情请咨询支付宝技术支持ExtendParams extendParams = new ExtendParams();extendParams.setSysServiceProviderId("2088100200300400500");// 支付超时,定义为120分钟String timeoutExpress = "120m";// 商品明细列表,需填写购买商品详细信息,List<GoodsDetail> goodsDetailList = new ArrayList<GoodsDetail>();List<OrderItem> orderItems = orderItemMapper.getOrderItemByUserIdAndOrderNo(userId, order.getOrderNo());for (OrderItem orderItem : orderItems){GoodsDetail goods1 = GoodsDetail.newInstance(orderItem.getProductId().toString(),orderItem.getProductName(),BigDecimalUtil.mul(orderItem.getCurrentUnitPrice().doubleValue(),orderItem.getQuantity()).longValue(),orderItem.getQuantity());goodsDetailList.add(goods1);}// 创建扫码支付请求builder,设置请求参数AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder().setSubject(subject).setTotalAmount(totalAmount).setOutTradeNo(outTradeNo).setUndiscountableAmount(undiscountableAmount).setSellerId(sellerId).setBody(body).setOperatorId(operatorId).setStoreId(storeId).setExtendParams(extendParams).setTimeoutExpress(timeoutExpress).setNotifyUrl(PropertiesUtil.getProperty("alipay.callback.url"))//支付宝服务器主动通知商户服务器里指定的页面http路径,根据需要设置.setGoodsDetailList(goodsDetailList);/** 一定要在创建AlipayTradeService之前调用Configs.init()设置默认参数*  Configs会读取classpath下的zfbinfo.properties文件配置信息,如果找不到该文件则确认该文件是否在classpath目录*/Configs.init("zfbinfo.properties");/** 使用Configs提供的默认参数*  AlipayTradeService可以使用单例或者为静态成员对象,不需要反复new*/tradeService = new AlipayTradeServiceImpl.ClientBuilder().build();AlipayF2FPrecreateResult result = tradeService.tradePrecreate(builder);switch (result.getTradeStatus()) {case SUCCESS:log.info("支付宝预下单成功: )");AlipayTradePrecreateResponse response = result.getResponse();dumpResponse(response);File folder = new File(path);if (!folder.exists()){folder.setWritable(true);folder.mkdirs();}// 需要修改为运行机器上的路径String qrPath = String.format(path+"/qr-%s.png",response.getOutTradeNo());String qrFileName = String.format("qr-%s.png",response.getOutTradeNo());ZxingUtils.getQRCodeImge(response.getQrCode(),256,qrPath);File targetFile = new File(path, qrFileName);try {FTPUtil.uploadFile(Lists.newArrayList(targetFile));} catch (IOException e) {log.error("上传到ftp服务器的二维码异常");e.printStackTrace();}log.info("filePath:" + qrPath);String qrurl= PropertiesUtil.getProperty("ftp.server.http.prefix")+targetFile.getName();map.put("qrurl",qrurl);return ServerResponse.createBySuccess(map);case FAILED:log.error("支付宝预下单失败!!!");return ServerResponse.createByError("支付宝预下单失败!!!");case UNKNOWN:log.error("系统异常,预下单状态未知!!!");return ServerResponse.createByError("系统异常,预下单状态未知!!!");default:log.error("不支持的交易状态,交易返回异常!!!");return ServerResponse.createByError("不支持的交易状态,交易返回异常!!!");}}// 简单打印应答private void dumpResponse(AlipayResponse response) {if (response != null) {log.info(String.format("code:%s, msg:%s", response.getCode(), response.getMsg()));if (StringUtils.isNotEmpty(response.getSubCode())) {log.info(String.format("subCode:%s, subMsg:%s", response.getSubCode(),response.getSubMsg()));}log.info("body:" + response.getBody());}}public ServerResponse alipaycall(Map<String,String> map){Long out_trade_no = Long.valueOf(map.get("out_trade_no"));String trade_no = map.get("trade_no");String trade_status = map.get("trade_status");Order order = orderMapper.selectByOrderNo(out_trade_no);if (order==null){return ServerResponse.createByError("非快乐慕商城的订单,请忽略");}if (order.getStatus()>=Const.order.PAID.getCode()){return ServerResponse.createBySuccess("支付宝重复调用");}if (Const.AlipayCallback.TRADE_STATUS_TRADE_SUCCESS.equals(trade_status)){order.setStatus(Const.order.PAID.getCode());order.setPaymentTime(DateUtils.strToDate(map.get("gmt_create")));orderMapper.updateByPrimaryKey(order);}PayInfo payInfo = new PayInfo();payInfo.setUserId(order.getUserId());payInfo.setOrderNo(order.getOrderNo());payInfo.setPayPlatform(Const.PayPlatformEnum.ALI.getCode());payInfo.setPlatformNumber(trade_no);payInfo.setPlatformStatus(trade_status);payInfoMapper.insert(payInfo);return ServerResponse.createBySuccess();}public ServerResponse queryOrderPayStatus(Integer userId,Long orderNo){Order order = orderMapper.selectByUserIdAndOrderNo(userId, orderNo);if (order==null){return ServerResponse.createByError("没有该订单");}if (order.getStatus()>=Const.order.PAID.getCode()){return ServerResponse.createBySuccess(true);}return ServerResponse.createBySuccess(false);}
}

支付宝的当面付扫一扫功能相关推荐

  1. 支付宝支付-当面付之扫码支付「扫码支付」

    前言 支付宝支付-沙箱环境使用 支付宝支付-支付宝PC端扫码支付 支付宝支付-手机浏览器H5支付 支付宝支付-当面付之扫码支付「本文」 当面付包含两种支付方式:商品条形码支付 + 扫码支付 经过前面两 ...

  2. 支付宝支付-当面付和App支付

    公司最近在做个视频桩的项目,需要在桩上用到支付宝支付功能. 去年项目当中有应用过支付宝,当时前端是用react,后台返回qcode到前端后,前端通过react的插件(其实就是支付宝的sdk),拼接qc ...

  3. 对接支付宝服务商当面付手机网页支付

    一.前期准备: SpringBoot对接支付宝当面付和手机网站支付_springboot 支付宝当面付_Biubiubiuexo的博客-CSDN博客 配置成功后获得到我们开发需要的:支付宝公钥.商户私 ...

  4. 支付宝支付——当面付

    开发当面付首先需要成为服务商,然后创建app.配置你.密钥,相应流程参考官网 https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0. ...

  5. 支付宝商家当面付接入java-web

    一.支付宝网站资料准备 1.创建应用 登录支付宝蚂蚁金服开放平台,点击(网页&移动应用列表),查看自己的移动或网页程序. 地址:支付宝蚂蚁金服开放平台 2.开始签约 在(网页&移动应用 ...

  6. Payment:接入支付宝当面付(扫码支付与条码支付)教程

    越写越觉得支付类的文档写这么细,会不会反而让大家觉得很复杂呀?其实都是同样的调用方式 这一篇,将把支付宝剩下的扫码支付与条码支付全部写清楚. Payment 3.0 支付宝的配置设置文档请 点击这里 ...

  7. Payment:接入支付宝当面付(扫码支付与条码支付)教程 1

    越写越觉得支付类的文档写这么细,会不会反而让大家觉得很复杂呀?其实都是同样的调用方式 这一篇,将把支付宝剩下的扫码支付与条码支付全部写清楚. Payment 3.0 支付宝的配置设置文档请 点击这里 ...

  8. ASP.NET Core 2.0 支付宝当面付之扫码支付

    前言 自从微软更换了CEO以后,微软的战略方向有了相当大的变化,不再是那么封闭,开源了许多东西,拥抱开源社区,.NET实现跨平台,收购xamarin并免费提供给开发者等等.我本人是很喜欢.net的,并 ...

  9. 支付宝支付开发——当面付条码支付和扫码支付

    原文: http://www.cnblogs.com/txw1958/p/alipay-f2fpay.html 本文介绍支付宝中当面付下属的条码支付.扫码支付.订单查询.退款申请的集成开发过程. 本文 ...

最新文章

  1. [转载]:合并两个已排序好的int数组,并排序返回c#实现
  2. pdf在线翻译_如何免费快速地翻译pdf英文文档,并保留很好的格式?
  3. resize属性,使textarea在ff(火狐)中禁止拉伸
  4. 【java】测试dubbo业务
  5. 关于集簇因子和柱状图的理解
  6. CKEditor快速介绍与入门示例
  7. 不要在网站上无限滚动!
  8. 使用 matlab 数字图像处理(二)—— 直方图均衡化(极简实现)
  9. 文件操作之fread()和fwrite()函数
  10. 工具分享:xampp-windows-x64-7.3.2-1-VC15-installer.exe 请自行下载(附下载链接)
  11. python科学计算-python科学计算
  12. JAVA win10 JDK环境配置(内含JDK,eclipse安装包)
  13. 如何安全存储密码都不知道,难怪我被面试官吊打呢...学完这个一定打回去!...
  14. 论实体图书馆的馆线制改革
  15. 路飞学城结算中心实现
  16. Vue3中使用Ant Design Vue图标
  17. k8s1.18 StorageClass 使用rbd-provisioner提供ceph rbd持久化存储
  18. Spark开发环境搭建
  19. 再见,仙剑之父!再见,姚壮宪!
  20. go time.after

热门文章

  1. 什么是回程网络(backhual telecommunications )
  2. 南海影视城“腐败”实录
  3. mathtype中的制表位设置、公式编号靠右对齐
  4. JS基础:基本包装类型
  5. opencv图像分割 --- Grabcut图像分割
  6. 供应链可视化_智慧物流_ZETag云标签相比RFID标签有哪些优势?
  7. 「二次开发」2021最新UI云开发新款壁纸小程序源码 支持流量主 用户投稿 后台管理
  8. Jsoup爬虫入门实战
  9. 编程练习题2.14(计算BMI),P65
  10. Helvetic Coding Contest 2018 online mirror (teams allowed, unrated) C2.Encryption (medium)