• 针对支付宝-当面付实现的个人支付


    测试地址

    项目背景

    为什么想做这个 一是工作中也接触到了支付宝,微信支付方面,二是自己也想弄个收费服务,比如之后做的程序想收费可以直接让用户扫码支付,而不用微信交流了。

    了解什么支付适合个人支付

    微信支付:需要营业执照,个人不好弄,所以放弃。

    支付宝手机支付:大多也需要营业执照,个人不好弄,所以放弃。

    爬虫和监听收款手机信息:操作太复杂,爬虫好像说也容易被封,放弃。

    支付宝当面付,暂时可以支持个人不需要营业执照,只需要店面图片即可,所以了解到这,直接开搞。

    开通支付宝当面付流程

    开通 当面付(点击下方链接开通)

    开通 当面付

    • 填写相关资料
    1. 经营类目 选择 “百货零售 / 其他零售 / 杂货店”,或者其他…问题不大
    2. 营业执照 可不上传
    3. 店铺招牌 可以拍一下身份的百货店,或者百度找一张类似的图
    • 等待审核(工作日的话大概30分钟,非工作日就不好说了)

    创建应用并且添加支付能力

    可以参考官方文档:(或者按照我的步骤下面步骤)

    创建应用

    创建应用(点击链接进入)

    open.alipay.com/platform/de…

    创建应用

    填写相关应用资料

    • 应用名称
    • 应用图标

    应用 添加能力

    添加能力

    应用 开发设置

    1. 设置 接口加签方式,手机收到验证码填写
    2. 下载 支付宝开放平台开发助手即密钥生成工具 opendocs.alipay.com/open/291/in…

    支付宝开放平台开发助手即密钥生成工具

    1. 上传刚才生成的应用公钥

    上传刚才生成的应用公钥

    1. 点击保存上传的应用公钥之后,会弹窗给出支付宝的公钥

    支付宝的公钥

    1. 设置应用网关等

    设设置应

    应用 提交审核

    审核一般一天左右,运气好半天就可以

    提交审核

    开始写代码

    当面付,我总结流程就分两步,1. 获取支付二维码,2. 支付回调。

    获取支付二维码

    public String preCreateOrder(AliPayInfo aliPayInfo) throws AlipayApiException {
            AlipayClient alipayClient = aliPayBusinessConfig.getAlipayClient();
            AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
            request.setNotifyUrl("https://ggball.top/notify/ali/pay/face/notify");
            JSONObject bizContent = new JSONObject();
            bizContent.put("out_trade_no", aliPayInfo.getOutTradeNo());
            bizContent.put("total_amount", aliPayInfo.getTotalAmount());
            bizContent.put("subject", aliPayInfo.getSubject());
    
     商品明细信息,按需传入
    //JSONArray goodsDetail = new JSONArray();
    //JSONObject goods1 = new JSONObject();
    //goods1.put("goods_id", "goodsNo1");
    //goods1.put("goods_name", "子商品1");
    //goods1.put("quantity", 1);
    //goods1.put("price", 0.01);
    //goodsDetail.add(goods1);
    //bizContent.put("goods_detail", goodsDetail);
    
     扩展信息,按需传入
    //JSONObject extendParams = new JSONObject();
    //extendParams.put("sys_service_provider_id", "2088511833207846");
    //bizContent.put("extend_params", extendParams);
    
     结算信息,按需传入
    //JSONObject settleInfo = new JSONObject();
    //JSONArray settleDetailInfos = new JSONArray();
    //JSONObject settleDetail = new JSONObject();
    //settleDetail.put("trans_in_type", "defaultSettle");
    //settleDetail.put("amount", 0.01);
    //settleDetailInfos.add(settleDetail);
    //settleInfo.put("settle_detail_infos", settleDetailInfos);
    //bizContent.put("settle_info", settleInfo);
    
     二级商户信息,按需传入
    //JSONObject subMerchant = new JSONObject();
    //subMerchant.put("merchant_id", "2088000603999128");
    //bizContent.put("sub_merchant", subMerchant);
    
     业务参数信息,按需传入
    //JSONObject businessParams = new JSONObject();
    //businessParams.put("busi_params_key", "busiParamsValue");
    //bizContent.put("business_params", businessParams);
    
     营销信息,按需传入
    //JSONObject promoParams = new JSONObject();
    //promoParams.put("promo_params_key", "promoParamsValue");
    //bizContent.put("promo_params", promoParams);
    
            request.setBizContent(bizContent.toString());
            AlipayTradePrecreateResponse response = alipayClient.execute(request);
            if(response.isSuccess()){
                System.out.println("调用成功");
                log.info("res:{}",response.getBody());
    
                JSONObject jsonObject = JSONObject.parseObject(response.getBody());
                return jsonObject.getJSONObject("alipay_trade_precreate_response").getString("qr_code");
    
            } else {
                log.error("res:{}",response.getBody());
                System.out.println("调用失败");
                return "";
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    如果在本地測試的話,可以使用钉钉给的免费的内网穿透工具,这里我是使用自己的服务,frp内网穿透到本地的。回调地址一定是公网能够访问到的域名,要不然回调会失败。

    支付回调

    @PostMapping ("/notify")
        public String preOrderNotify(HttpServletRequest request) throws AlipayApiException {
            //获取支付宝POST过来反馈信息,将异步通知中收到的待验证所有参数都存放到map中
            Map<String, String> params = new HashMap<String, String>();
            Map requestParams = request.getParameterMap();
            for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
                String name = (String) iter.next();
                String[] values = (String[]) requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
                }
                //乱码解决,这段代码在出现乱码时使用。
                //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
                params.put(name, valueStr);
            }
            log.info("params:{}",params);
    
    
    
            //调用SDK验证签名
            //公钥验签示例代码
            boolean signVerified = AlipaySignature.rsaCheckV1(params, aliPayBusinessConfig.getPublicKey(), aliPayBusinessConfig.getCharset(), aliPayBusinessConfig.getSignType());
            //公钥证书验签示例代码
            //   boolean flag = AlipaySignature.rsaCertCheckV1(params,alipayPublicCertPath,"UTF-8","RSA2");
    
            PayBill oldPayBill = payBillService.getPayBillByNotifyId(params.get("notify_id"));
            if (null != oldPayBill) {
                return "success";
            } else if (signVerified) {
                // TODO 验签成功后
                PayBill payBill = new PayBill();
                payBill.setOrderNum(params.get("out_trade_no"));
                payBill.setIsPay(true);
                payBill.setNotifyId(params.get("notify_id"));
                payBill.setPayerId(params.get("buyer_id"));
                payBill.setSellerEmail(params.get("seller_email"));
                payBill.setSellerId(params.get("seller_id"));
                payBill.setTradeNo(params.get("trade_no"));
                payBill.setBuyerLogonId(params.get("buyer_logon_id"));
                PayBill newPayBill = payBillService.updatePayBill(payBill);
    
                // push queue
                try {
                    QueueCore<PayBill> billQueueCore = new QueueCore<>("NOTIFY_JOB");
                    billQueueCore.get("NOTIFY_JOB").push(newPayBill);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
    
                return "success";
                //按照支付结果异步通知中的描述,对支付结果中的业务内容进行1\2\3\4二次校验,校验成功后在response中返回success
            } else {
                // TODO 验签失败则记录异常日志,并在response中返回fail.
                return "fail";
            }
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    這里是支付宝提供的代码,验签失败和成功可以添加自己的逻辑代码,这里我是将结果放在队列里,为了后续将数据保存到数据库,将支付结果通知给我的其他服务等等。

    测试截图

    image-20221128231305902

    image-20221128231336632

    测试地址

  • 相关阅读:
    极坐标和直角坐标的积分转换
    Python大数据之linux学习总结——day08_hive04
    架构师进阶,微服务设计与治理的 16 条常用原则
    nodejs+vue考研信息查询系统-计算机毕业设计
    知乎小说推文渠道怎么找?一级代理机构是哪家?
    学了个学教育游戏与源码
    tauri vs electron
    NC61 两数之和
    Java调用com组件之jacob
    【Spring Cloud】如何确定微服务项目的Spring Boot、Spring Cloud、Spring Cloud Alibaba的版本
  • 原文地址:https://blog.csdn.net/ZHUXIUQINGIT/article/details/128089539