zoukankan      html  css  js  c++  java
  • 复制学习支付扫码例子

    前期酝酿准备

    最近项目中要上线支付功能、前段时间刚开发完微信的扫码支付、不得不说微信开发团队的文档真是一个烂。但总算是对照着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. }
  • 相关阅读:
    学习:恢复被孤立的数据库dbo (转)
    学习:SharePoint编程提升权限的方法(转)
    SQL行列互换
    前台用js、jquery出现错误很多是由于IE缓存
    关于dialog首次加载的时候隐藏的一个问题
    要取某个对象的值,先要判断对象是否为空的简便写法(记)
    写js或者jquery的时候最重要的调试,再也不用alert弹出对象
    嵌入式软件测试的十大秘诀
    SIMULINK sfunction的设计
    关于java解压zip与rar的问题
  • 原文地址:https://www.cnblogs.com/hp123/p/7453613.html
Copyright © 2011-2022 走看看