前提条件

这是必要条件!!! 这是必要条件!!! 这是必要条件!!! 注册当面付,个人、企业账号均可!!!


演示

获取订单点击,然后扫码付出

自己个人拥有一个可以支付功能的网站?当然可以了!保姆级演示!

付出成功后就会呼应付出成功

自己个人拥有一个可以支付功能的网站?当然可以了!保姆级演示!

运用恳求注册和装备

接下来介绍运用的创立和装备,必定要细心哦!!!

运用创立

首要进入付出宝敞开渠道,进入控制台,创立一个运用,大概1个工作日内就会审阅

自己个人拥有一个可以支付功能的网站?当然可以了!保姆级演示!

把这几个必填项填写,然后承认创立,留意姓名要清晰,运用图标要有必定的可识别性,否则不给过,运用类型选网页运用

自己个人拥有一个可以支付功能的网站?当然可以了!保姆级演示!

运用装备

创立好后,进入产品概况页面,点击产品绑定,然后去绑定

自己个人拥有一个可以支付功能的网站?当然可以了!保姆级演示!

挑选付出 -> 当面付[勾选] -> 绑定,另外你还能够找到花呗付出,这样用户扫码时就支撑花呗付出了

自己个人拥有一个可以支付功能的网站?当然可以了!保姆级演示!

要承认是注册状况哦,如果没有注册需求注册哦,看上面的 前提条件

自己个人拥有一个可以支付功能的网站?当然可以了!保姆级演示!

然后需求装备密钥,点击下图中侧边栏中的 开发设置,需求装备的是 接口加签方法(证书/密钥)

  • 接口加签方法(证书/密钥):装备付出宝敞开渠道会引导你下载安装密钥生成东西,生成一个运用公钥和运用私钥,私钥必定要保管好,不要泄露,保存到本地,到时候装备在服务器上,然后把运用公钥装备在敞开渠道上,就算装备完结了,付出宝就会给到你一个付出宝公钥,接下来你一共有三个密钥,付出宝公钥、运用公钥、运用私钥,这三个必定要辨明,接下来文章介绍的所需求用到的密钥只要这三个,清必定要辨明!!!

自己个人拥有一个可以支付功能的网站?当然可以了!保姆级演示!


代码开发

接下来你能够结合着官方的开发文档看我的文章,官方文档:opendocs.alipay.com/open/02ekfg…

  • 本文后端以Java的开发方法,仅供参考!
  • Web前端运用原生Html+CSS+JavaScript简略实现,仅供参考!
  • 安卓调用能够参考我这篇文章:myhub.blog.csdn.net/article/det…

后端实例

SDK集成

首要获取相应的SDK,SDK下载页面(官方):opendocs.alipay.com/open/54/103…

我这儿以Maven的方法集成,另外我集成了zxing,用于生成付出二维码运用

 <!--alipay SDK-->
<dependency>
	<groupId>com.alipay.sdk</groupId>
	<artifactId>alipay-sdk-java</artifactId>
	<version>4.35.9.ALL</version>
</dependency>
<!-- zxing -->
<dependency>
	<groupId>com.google.zxing</groupId>
	<artifactId>core</artifactId>
	<version>3.5.1</version>
</dependency>

Controller实例

  • 生成付款二维码,我标明晰详细的注释,能够直接看!
  • 因为涉及到公钥、私钥等信息,这些部分我都用了 **************来表示,
  • 记住替换哦!!!
  • 记住替换哦!!!
  • 记住替换哦!!!
  • 替换成你自己的!!!

以下为简略的Demo演示,必定要结合官方文档,阅览接入留意事项:opendocs.alipay.com/open/194/10…

package com.demo.pay;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;
/**
 * @author ThirdGoddess
 * @version 1.0.0
 * @time 2022/12/22 14:37
 * @desc AliPay当面付Demo
 */
@RestController
@RequestMapping("pay")
public class AliPayController {
    //模仿一个用户的付出状况
    private boolean userPayState = false;
    //==================================================================================================================
    //这儿都是固定的
    //付出宝网关地址
    private static final String SERVER_URL = "https://openapi.alipay.com/gateway.do";
    //charset
    private static final String CHARSET = "GBK";
    //format
    private static final String FORMAT = "json";
    //sign type
    private static final String SIGN_TYPE = "RSA2";
    //==================================================================================================================
    //下面这三个是需求装备的
    //APPID,即创立运用的那个ID,在运用概况中的左上角能够看到
    private static final String APPID = "**************";
    //运用私钥,留意是运用私钥!!!运用私钥!!!运用私钥!!!
    private static final String APP_PRIVATE_KEY = "**************";
    //付出宝公钥,留意是付出宝公钥!!!付出宝公钥!!!付出宝公钥!!!
    private static final String ALIPAY_PUBLIC_KEY = "**************";
    /**
     * 获取二维码
     * 获取的是用户要扫码付出的二维码
     * 创立订单,带入自己的事务逻辑
     */
    @RequestMapping(value = "/getQr", produces = MediaType.IMAGE_JPEG_VALUE)
    @ResponseBody
    public byte[] getQr() {
        userPayState = false;
        AlipayClient alipayClient = new DefaultAlipayClient(SERVER_URL, APPID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        //装备这是一个url,下图我已经装备好了,这个意思是当用户成功后,付出宝那边会调用这个地址url,他会给你传过去一些订单信息,
        //你处理完你的事务逻辑给付出宝呼应success就行,就代表这个订单完结买卖了!
        //* 建议前期开发的时候加上内网穿透调试,否则付出宝是没有办法调到你开发的接口的
        request.setNotifyUrl("http://**************.com/pay/payNotification");
        JSONObject bizContent = new JSONObject();
        //自己生成一个订单号,我这儿直接用时刻戳演示,正常情况下创立完订单需求存储到自己的事务数据库,做记载和付出完结后校验
        String orderNumber = "pay" + System.currentTimeMillis();
        bizContent.put("out_trade_no", orderNumber);//订单号
        bizContent.put("total_amount", 0.01);//订单金额
        bizContent.put("subject", "demo");//付出主题,自己略微界说一下
        request.setBizContent(bizContent.toString());
        try {
            AlipayTradePrecreateResponse response = alipayClient.execute(request);
            if (response.isSuccess()) {
                System.out.println("调用成功");
            } else {
                System.out.println("调用失利");
            }
            //获取生成的二维码,这儿是一个String字符串,即二维码的内容;
            //然后用二维码生成SDK生成一下二维码,弄成图片回来给前端就行,我这儿运用Zxing生成
            //其实也能够直接把这个字符串信息回来,让前端去生成,一样的道理,只需求关心这个二维码的内容就行
            String qrCode = response.getQrCode();
            //生成付出二维码图片
            BufferedImage image = QrCodeUtil.createImage(qrCode);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ImageIO.write(image, "jpeg", out);
            byte[] b = out.toByteArray();
            out.write(b);
            out.close();
            //最终回来图片
            return b;
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("调用失利");
        }
        return null;
    }
    /**
     * 付出完结后付出宝会恳求这个回调
     */
    @PostMapping("payNotification")
    public String payNotification(HttpServletRequest request) {
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (String name : requestParams.keySet()) {
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }
        for (Map.Entry<String, String> entry : params.entrySet()) {
            System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
        }
        //==============================================================================================================
        try {
            //履行验签,保证成果是付出宝回调的,而不是被歹意调用,必定要做这一步
            boolean signVerified = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE);
            if (signVerified) {
                //验签成功,持续履行事务逻辑
                System.out.println("验签成功");
                //再次自动查询订单,不要只依赖付出宝回调的成果
                String orderStatus = searchOrderStatus(params.get("out_trade_no"), params.get("trade_no"));
                switch (orderStatus) {
                    case "TRADE_SUCCESS"://买卖付出成功;
                    case "TRADE_FINISHED": //买卖完毕,不行退款;
                        //TODO 在这儿持续履行用户付出成功后的事务逻辑
                        userPayState = true;
                        break;
                }
                return "success";
            } else {
                //验签失利(很可能接口被非法调用)
                System.out.println("验签失利");
                return "fail";
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return "fail";
        }
    }
    /**
     * 封装一个订单查询
     *
     * @param outTradeNo 商户订单号
     * @param tradeNo    付出宝买卖号。付出宝买卖凭证号
     * @return 订单状况:String
     * @throws AlipayApiException AlipayApiException
     * @desc "WAIT_BUYER_PAY":买卖创立,等候买家付款;"TRADE_CLOSED":未付款买卖超时封闭,或付出完结后全额退款; "TRADE_SUCCESS":买卖付出成功;"TRADE_FINISHED":买卖完毕,不行退款;
     */
    private String searchOrderStatus(String outTradeNo, String tradeNo) throws AlipayApiException {
        AlipayClient alipayClient = new DefaultAlipayClient(SERVER_URL, APPID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE); //取得初始化的AlipayClient
        AlipayTradeQueryRequest aliRequest = new AlipayTradeQueryRequest();//创立API对应的request类
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", outTradeNo);
        bizContent.put("trade_no", tradeNo);
        aliRequest.setBizContent(bizContent.toString()); //设置事务参数
        AlipayTradeQueryResponse response = alipayClient.execute(aliRequest);//通过alipayClient调用API,取得对应的response类
        JSONObject responseObject = JSONObject.parseObject(response.getBody());
        JSONObject alipayTradeQueryResponse = responseObject.getJSONObject("alipay_trade_query_response");
        return alipayTradeQueryResponse.getString("trade_status");
    }
    /**
     * 前端轮询查询这个接口,来查询订单的付出状况
     *
     * @return OrderStateEntity
     */
    @CrossOrigin
    @GetMapping("searchOrder")
    public OrderStateEntity searchOrder() {
        //userPayState是一个模仿值
        if (userPayState) {
            //用户付出成功了
            return new OrderStateEntity(200, "付出成功了");
        } else {
            //用户还没有付出
            return new OrderStateEntity(201, "你还没有付出哦");
        }
    }
    /**
     * 呼应给前端的实体
     */
    static class OrderStateEntity {
        private int code;
        private String msg;
        public OrderStateEntity(int code, String msg) {
            this.code = code;
            this.msg = msg;
        }
        public int getCode() {
            return code;
        }
        public void setCode(int code) {
            this.code = code;
        }
        public String getMsg() {
            return msg;
        }
        public void setMsg(String msg) {
            this.msg = msg;
        }
    }
}

用户付出后的回调

当运用setNotifyUrl后,用户成功付出后,会回调其设置的url,如 ==setNotifyUrl(“xxx.com/pay/payNoti… ,那么付出宝会等候用户付出成功后会以POST去恳求 ==xxx.com/pay/payNoti… 这个地址来达到回调,需求呼应success或许fail,只要这两种值哦!

呼应值 描绘 异步是否重试发送
fail 音讯获取失利 重试
success 音讯获取成功 不重试

前端代码实例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <meta charset="UTF-8">
    <title>付出宝当面付Demo演示</title>
    <style>
        * {
            margin: 0 auto;
        }
        .root {
            width: 260px;
        }
        .img_box {
            width: 260px;
            height: 260px;
            background-color: #adadad;
        }
        button {
            width: 260px;
            margin-top: 12px;
        }
    </style>
</head>
<body>
<div class="root">
    <div class="img_box"><img width="260" height="260" id="qr" src="" alt=""></div>
    <button onclick="getOrderQr()">获取订单</button>
    <div class="response" id="response"></div>
    <script>
        /**
         * 获取一个二维码
         */
        function getOrderQr() {
            let qrImg = document.getElementById('qr');
            qrImg.src = "http://**************.com/pay/getQr?time=" + new Date().getTime()
            //开始轮询查询订单
            orderResponse()
        }
        let number = 1;
        const responseView = document.getElementById('response')
        /**
         * 循环查询订单呼应
         */
        function orderResponse() {
            //每2秒查询一次付出状况
            setTimeout(function () {
                //恳求接口查询付出状况
                const xhr = new XMLHttpRequest();
                xhr.open('GET', "http://**************.com/pay/searchOrder", true);
                xhr.send(null);
                xhr.onreadystatechange = function () {
                    if (xhr.status === 200 && xhr.readyState === 4) {
                        const json = JSON.parse(xhr.responseText);
                        if (200 === json.code) {
                            //付出成功
                            responseView.innerText = xhr.responseText
                        } else {
                            //没有付出,持续下一次查询
                            responseView.innerText = '第' + number + '次查询,成果:' + xhr.responseText
                            number++
                            orderResponse()
                        }
                    }
                }
            }, 2000)
        }
    </script>
</div>
</body>
</html>

源码

Github:github.com/ThirdGoddes…