测试地址
项目背景
为什么想做这个 一是工作中也接触到了支付宝,微信支付方面,二是自己也想弄个收费服务,比如之后做的程序想收费可以直接让用户扫码支付,而不用微信交流了。
了解什么支付适合个人支付
微信支付:需要营业执照,个人不好弄,所以放弃。
支付宝手机支付:大多也需要营业执照,个人不好弄,所以放弃。
爬虫和监听收款手机信息:操作太复杂,爬虫好像说也容易被封,放弃。
支付宝当面付,暂时可以支持个人不需要营业执照,只需要店面图片即可,所以了解到这,直接开搞。
开通支付宝当面付流程
开通 当面付(点击下方链接开通)
开通 当面付
- 填写相关资料
- 经营类目 选择 “百货零售 / 其他零售 / 杂货店”,或者其他…问题不大
- 营业执照 可不上传
- 店铺招牌 可以拍一下身份的百货店,或者百度找一张类似的图
- 等待审核(工作日的话大概30分钟,非工作日就不好说了)
创建应用并且添加支付能力
可以参考官方文档:(或者按照我的步骤下面步骤)
创建应用
创建应用(点击链接进入)
open.alipay.com/platform/de…
填写相关应用资料
- 应用名称
- 应用图标
应用 添加能力


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

- 上传刚才生成的应用公钥

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

- 设置应用网关等

应用 提交审核
审核一般一天左右,运气好半天就可以

开始写代码
当面付,我总结流程就分两步,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", "07846"); //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", "99128"); //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 ""; } }
讯享网
如果在本地測試的話,可以使用钉钉给的免费的内网穿透工具,这里我是使用自己的服务,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"; } }
這里是支付宝提供的代码,验签失败和成功可以添加自己的逻辑代码,这里我是将结果放在队列里,为了后续将数据保存到数据库,将支付结果通知给我的其他服务等等。
测试截图


测试地址

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/34561.html