• 复制学习支付扫码例子


    前期酝酿准备

    最近项目中要上线支付功能、前段时间刚开发完微信的扫码支付、不得不说微信开发团队的文档真是一个烂。但总算是对照着API把功能交付上线了。

    前几天公司申请下来了企业支付宝,得空所以也把支付宝的扫码支付给集成进去。这里又不得不说,是支付宝的文档写的不咋地还是自己没有仔细阅读,总之翻遍了API最终在沙箱里面运行成功(切记、认真读文档,不然各种BUG等着你)

    什么是扫码支付?

    扫码支付,指用户打开支付宝钱包中的“扫一扫”功能,扫描商家展示在某收银场景下的二维码并进行支付的模式。该模式适用于线下实体店支付、面对面支付等场景。

    业务流程:
    LB1KXhmLXXXXXaIapXXXXXXXXXX.png
    使用步骤:
    LB1UHBDLXXXXXbdXFXXXXXXXXXX.png
    用户登陆支付宝钱包,点击首页“付款-扫码付”,进入扫一扫界面;
    收银员在商家收银系统操作生成支付宝订单,用户确认支付金额,并生成二维码;
    用户使用钱包的“扫码付”,扫收银员提供的二维码,确认支付;
    用户付款后商家收银系统会拿到支付成功或者失败的结果。

    具体产品介绍

    如何快速接入?

    前面的大家可以大体了解一下

    开放平台服务端SDK下载地址(这里选择Java版本)、点击下载、里面有详细的API测试方法。

    如何集成到项目中去?

    下载DEMO解压、仔细阅读里面的readme.txt文件、里面有详细的项目结构。

    参数配置zfbinfo.properties(沙箱环境网关参数不同)

    1. # 支付宝网关名、partnerId和appId
    2. #open_api_domain = https://openapi.alipay.com/gateway.do
    3. #支付宝沙箱环境
    4. open_api_domain = https://openapi.alipaydev.com/gateway.do
    5. mcloud_api_domain = http://mcloudmonitor.com/gateway.do
    6. pid = 此处请填写你的PID
    7. appid = 此处请填写你当面付的APPID
    8. # RSA私钥、公钥和支付宝公钥
    9. private_key = 此处请填写你的商户私钥且转PKCS8格式
    10. public_key = 此处请填写你的商户公钥
    11. alipay_public_key = MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDI6d306Q8fIfCOaTXyiUeJHkrIvYISRcc73s3vF1ZT7XN8RNPwJxo8pWaJMmvyTn9N4HQ632qJBVHf8sxHi/fEsraprwCtzvzQETrNRwVxLO5jVmRGi60j8Ue1efIlzPXV9je9mkjzOmdssymZkh2QhUrCmZYI/FCEa3/cNMW0QIDAQAB
    12. # 当面付最大查询次数和查询间隔(毫秒)
    13. max_query_retry = 5
    14. query_duration = 5000
    15. # 当面付最大撤销次数和撤销间隔(毫秒)
    16. max_cancel_retry = 3
    17. cancel_duration = 2000
    18. # 交易保障线程第一次调度延迟和调度间隔(秒)
    19. heartbeat_delay = 5
    20. heartbeat_duration = 900

    RSA私钥、公钥和支付宝公钥 获取方法。
    生成与配置密钥

    这里我选择的是方式一,使用支付宝提供的一键生成工具(内附使用说明)。

    如果是JAVA程序public_key参数对应rsa_private_key_pkcs8.pem文件里面的内容,
    public_key参数对用rsa_public_key.pem文件里面的内容。然后把公钥复制到沙箱中的RSA(SHA1)密钥中生成支付宝公钥、对应的是alipay_public_key参数。

    如何生成二维码订单?

    然后你就可以运行Main.java 中的额main方法进行测试了,运行结果如下:

    1. [acts_pay]|2016-11-04 15:23:35:530|Configs{支付宝openapi网关: https://openapi.alipaydev.com/gateway.do
    2. , 支付宝mcloudapi网关域名: http://mcloudmonitor.com/gateway.do
    3. , pid: 2088102169116018
    4. , appid: 2016073000123724
    5. , 商户RSA私钥: MIICdw******rLZis=
    6. , 商户RSA公钥: MIGfMA******IDAQAB
    7. , 支付宝RSA公钥: MIGfMA******IDAQAB
    8. , 查询重试次数: 5
    9. , 查询间隔(毫秒): 5000
    10. , 撤销尝试次数: 3
    11. , 撤销重试间隔(毫秒): 2000
    12. , 交易保障调度延迟(秒): 5
    13. , 交易保障调度间隔(秒): 900
    14. }
    15. [acts_pay]|2016-11-04 15:23:35:719|trade.precreate bizContent:{"out_trade_no":"tradeprecreate14782442155652020005","seller_id":"","total_amount":"0.01","undiscountable_amount":"0","subject":"xxx品牌xxx门店当面付扫码消费","body":"购买商品3件共20.00元","goods_detail":[{"goods_id":"goods_id001","goods_name":"xxx小面包","quantity":1,"price":"10"},{"goods_id":"goods_id002","goods_name":"xxx牙刷","quantity":2,"price":"5"}],"operator_id":"test_operator_id","store_id":"test_store_id","extend_params":{"sys_service_provider_id":"2088100200300400500"}}
    16. [acts_pay]|2016-11-04 15:23:37:875|{"alipay_trade_precreate_response":{"code":"10000","msg":"Success","out_trade_no":"tradeprecreate14782442155652020005","qr_code":"https://qr.alipay.com/bax03938xgzra2b5pijd00d2"},"sign":"LA2d5txq43c3t12sCsNEEGvu3plXUrqrd/uyzOy4HIMM5eRkWXaFkL+wqVNcYX/Jfn6no72yqiAUvYAivaWZkXZA3UxTRYlW+0EwZ96HrpnjFCK+QGOSDZuoiA2AyQlFgM/cQwdgTFGI+R2X9QZWxft1z3zYVG1uRGEZXed5RPQ="}
    17. [acts_pay]|2016-11-04 15:23:37:878|支付宝预下单成功: )
    18. [acts_pay]|2016-11-04 15:23:37:878|code:10000, msg:Success
    19. [acts_pay]|2016-11-04 15:23:37:878|body:{"alipay_trade_precreate_response":{"code":"10000","msg":"Success","out_trade_no":"tradeprecreate14782442155652020005","qr_code":"https://qr.alipay.com/bax03938xgzra2b5pijd00d2"},"sign":"LA2d5txq43c3t12sCsNEEGvu3plXUrqrd/uyzOy4HIMM5eRkWXaFkL+wqVNcYX/Jfn6no72yqiAUvYAivaWZkXZA3UxTRYlW+0EwZ96HrpnjFCK+QGOSDZuoiA2AyQlFgM/cQwdgTFGI+R2X9QZWxft1z3zYVG1uRGEZXed5RPQ="}
    20. [acts_pay]|2016-11-04 15:23:37:878|filePath:D:qr.png

    最后下载沙箱钱包就可以完成手机支付了。

    下载地址

    如何实现异步通知?

    相关参数说明

    用户会用手机扫码给支付宝付款,然后支付宝收到之后会发送一条支付成功的消息给我们设置的notify_url

      1. import java.io.BufferedOutputStream;
      2. import java.util.Enumeration;
      3. import java.util.HashMap;
      4. import java.util.Map;
      5. import javax.servlet.http.HttpServletRequest;
      6. import javax.servlet.http.HttpServletResponse;
      7. import org.springframework.beans.factory.annotation.Autowired;
      8. import org.springframework.stereotype.Controller;
      9. import org.springframework.web.bind.annotation.RequestMapping;
      10. import org.springframework.web.bind.annotation.RequestMethod;
      11. import com.acts.web.acc.service.IWeixinPayService;
      12. import com.acts.web.common.utils.LogUtil;
      13. import com.alipay.api.AlipayApiException;
      14. import com.alipay.api.internal.util.AlipaySignature;
      15. import com.alipay.demo.trade.config.Configs;
      16. @Controller
      17. @RequestMapping(value = "alipay")
      18. public class AliPayController {
      19. //初始化参数 不然signVerified会验证失败
      20. static {
      21. Configs.init("zfbinfo.properties");
      22. }
      23. /**
      24. * 支付宝支付回调
      25. * @Author 小柒
      26. * @param request
      27. * @param response
      28. * @throws Exception
      29. * void
      30. * @Date 2016年10月31日 更新日志 2016年10月31日 小柒 首次创建
      31. *
      32. */
      33. @SuppressWarnings("unchecked")
      34. @RequestMapping(value = "pay",method = RequestMethod.POST)
      35. public void alipay_notify(HttpServletRequest request, HttpServletResponse response) throws Exception {
      36. LogUtil.info("支付宝付款异步通知!");
      37. String message = "success";
      38. Map<String, String> params = new HashMap<String, String>();
      39. // 取出所有参数是为了验证签名
      40. Enumeration<String> parameterNames = request.getParameterNames();
      41. while (parameterNames.hasMoreElements()) {
      42. String parameterName = parameterNames.nextElement();
      43. params.put(parameterName, request.getParameter(parameterName));
      44. }
      45. //验证签名
      46. boolean signVerified = false;
      47. try {
      48. signVerified = AlipaySignature.rsaCheckV1(params, Configs.getAlipayPublicKey(), "UTF-8");
      49. } catch (AlipayApiException e) {
      50. e.printStackTrace();
      51. message = "failed";
      52. }
      53. if (signVerified) {
      54. LogUtil.info("验证签名成功!");
      55. // 若参数中的appid和填入的appid不相同,则为异常通知
      56. if (!Configs.getAppid().equals(params.get("app_id"))) {
      57. LogUtil.info("与付款时的appid不同,此为异常通知,应忽略!");
      58. message = "failed";
      59. }else{
      60. String outtradeno = params.get("out_trade_no");
      61. LogUtil.info(outtradeno + "号订单回调通知。");
      62. //在数据库中查找订单号对应的订单,并将其金额与数据库中的金额对比,若对不上,也为异常通知
      63. String status = params.get("trade_status");
      64. if (status.equals("WAIT_BUYER_PAY")) { // 如果状态是正在等待用户付款
      65. } else if (status.equals("TRADE_CLOSED")) { // 如果状态是未付款交易超时关闭,或支付完成后全额退款
      66. } else if (status.equals("TRADE_SUCCESS") || status.equals("TRADE_FINISHED")) { // 如果状态是已经支付成功
      67. //成功 更新状态
      68. } else {
      69. weixinpayBack.updateAccOrder(outtradeno);
      70. }
      71. LogUtil.info(outtradeno + "订单的状态已经修改为" + status);
      72. }
      73. } else { // 如果验证签名没有通过
      74. message = "failed";
      75. LogUtil.info("验证签名失败!");
      76. }
      77. BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
      78. out.write(message.getBytes());
      79. out.flush();
      80. out.close();
      81. }
      82. }
  • 相关阅读:
    Why Choose Jetty?
    Jetty 的工作原理以及与 Tomcat 的比较
    Tomcat设计模式
    Servlet 工作原理解析
    Tomcat 系统架构
    spring boot 打包方式 spring boot 整合mybaits REST services
    wireshark udp 序列号 User Datagram Protocol UDP
    Maven 的聚合(多模块)和 Parent 继承
    缓存策略 半自动化就是mybaitis只支持数据库查出的数据映射到pojo类上,而实体到数据库的映射需要自己编写sql语句实现,相较于hibernate这种完全自动化的框架我更喜欢mybatis
    Mybatis解决sql中like通配符模糊匹配 构造方法覆盖 mybits 增删改
  • 原文地址:https://www.cnblogs.com/hp123/p/7453613.html
Copyright © 2020-2023  润新知