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

news2025/7/9 3:52:57

文章目录

    • 前提条件
    • 演示
    • 应用申请开通和配置
      • 应用创建
      • 应用配置
    • 代码开发
      • 后端实例
      • 前端代码实例
    • 源码


前提条件

这是必要条件!!!
这是必要条件!!!
这是必要条件!!!
开通当面付,个人、企业账号均可,个人账号可以私聊我帮忙代开通,10分钟就OK !!!


演示

获取订单点击,然后扫码支付
在这里插入图片描述
支付成功后就会响应支付成功
在这里插入图片描述

应用申请开通和配置

接下来介绍应用的创建和配置,一定要仔细哦!!!

应用创建

首先进入支付宝开放平台,进入控制台,创建一个应用,大概1个工作日内就会审核
在这里插入图片描述

把这几个必填项填写,然后确认创建,注意名字要清晰,应用图标要有一定的可识别性,不然不给过,应用类型选网页应用

在这里插入图片描述

应用配置

创建好后,进入产品详情页面,点击产品绑定,然后去绑定
在这里插入图片描述

选择支付 -> 当面付[勾选] -> 绑定,另外你还可以找到花呗支付,这样用户扫码时就支持花呗支付了
在这里插入图片描述

要确认是开通状态哦,如果没有开通需要开通哦,看上面的 前提条件
在这里插入图片描述

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

  • 接口加签方式(证书/密钥):配置支付宝开放平台会引导你下载安装密钥生成工具,生成一个应用公钥和应用私钥,私钥一定要保管好,不要泄露,保存到本地,到时候配置在服务器上,然后把应用公钥配置在开放平台上,就算配置完成了,支付宝就会给到你一个支付宝公钥,接下来你一共有三个密钥,支付宝公钥、应用公钥、应用私钥,这三个一定要分清,接下来文章介绍的所需要用到的密钥只有这三个,清一定要分清!!!

在这里插入图片描述


代码开发

接下来你可以结合着官方的开发文档看我的文章,官方文档:https://opendocs.alipay.com/open/02ekfg?ref=api&scene=19

  • 本文后端以Java的开发方式,仅供参考!
  • Web前端使用原生Html+CSS+JavaScript简单实现,仅供参考!
  • 安卓调用可以参考我这篇文章:https://myhub.blog.csdn.net/article/details/128399771

后端实例

SDK集成

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

我这里以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演示,一定要结合官方文档,阅读接入注意事项:https://opendocs.alipay.com/open/194/105322

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(“http://xxx.com/pay/payNotification”) ,那么支付宝会等待用户支付成功后会以POST去请求 http://xxx.com/pay/payNotification 这个地址来达成回调,需要响应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://39.107.80.105:8080/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:https://github.com/ThirdGoddess/aliPay

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/109320.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

人脸检测和对齐算法MTCNN

1. 概述 人脸识别在实际的生活中有着广泛的应用&#xff0c;得益于深度学习的发展&#xff0c;使得人脸识别的准确率得到大幅度提升。然而&#xff0c;为了做好人脸识别&#xff0c;第一步需要做的是对人脸检测&#xff0c;主要是通过对图片分析&#xff0c;定位出图片中的人脸…

Java项目:springboot网上点餐系统

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 功能介绍 SpringBoot在线订餐系统项目。主要功能说明&#xff1a; 分为两个角色&#xff0c;餐厅老板、普通用户 餐厅老板可以登录&#xff0c;注册&…

质量不错的蓝牙耳机有哪些?2023年值得选购的四款蓝牙耳机

现如今&#xff0c;蓝牙耳机越多人使用&#xff0c;不同于有线耳机&#xff0c;蓝牙耳机更为方便&#xff0c;没有线束的困扰&#xff0c;走到哪也不用带上手机一起&#xff0c;特别便利。然而&#xff0c;随着蓝牙耳机市场的旷大&#xff0c;各种类型各种样式的耳机五花八门&a…

C++ 实现并查集结构

前言 并查集一般用于多元素&#xff0c;多集合的查找问题&#xff1b; 听说很有用&#xff0c;但是平时好像确实没有怎么见过。。 leetcode典型例题&#xff1a;岛屿数量 一、原理 其实并查集的每个小集合就是一张有向图&#xff0c;只不过是所有子节点指向父节点的图结构。…

认证鉴权对于 API 网关的重要性

认证鉴权作为 API 网关不可或缺的能力&#xff0c;已然成为用户在选型 API 网关时考量的重要因素之一。 作者钱勇&#xff0c;API7.ai 开发工程师&#xff0c;Apache APISIX Committer 在当下云原生越发成熟的环境下&#xff0c;API 网关最核心的功能可以概括为&#xff1a;连接…

高品质蓝牙耳机排行榜,值得入手的四款蓝牙耳机分享

2023年即将到来&#xff0c;还有哪些蓝牙耳机值得大家购买呢&#xff1f;蓝牙耳机在我们日常生活中发挥着很大作用。无论是听歌还是通话&#xff0c;又或者是运动健身、玩游戏等&#xff0c;都常见大家使用。同样也伴随着蓝牙耳机市场的壮大&#xff0c;五花八门的耳机层出不穷…

【C语言进阶】进来抄作业,完善你的通讯录(软工期末大作业可用)

目录 &#x1f970;前言&#x1f970;&#xff1a; 一、输入合法性检测&#x1f920;&#xff1a; ①.对“ 联系方式 ”的合法性检测&#xff1a; ②.对“年龄”进行合法性检测&#xff1a; 二、字典排序&#x1f911;&#xff1a; 三、反馈优化&#x1f92f;&#xff1a; …

Python 圣诞树代码

一、前言 1.本章将会讲解Python编程 实现圣诞树效果&#xff01; 2.圣诞节介绍 基督教纪念耶稣诞生的重要节日。亦称耶稣圣诞节、主降生节&#xff0c;天主教亦称耶稣圣诞瞻礼。耶稣诞生的日期&#xff0c;《圣经》并无记载。公元336年罗马教会开始在12月25日过此节。12月25日…

现在转行计算机如49年入国军?

阿里&#xff0c;腾讯等互联网大厂最近不太安宁&#xff0c;裁员消息频出&#xff0c;无风不起浪&#xff0c;裁员年年有&#xff0c;今年特别多。于是不少打算入行或者已经入行计算机的同学开始担忧&#xff0c;如今入行计算机&#xff0c;怎么有点49年入国军的赶脚&#xff1…

Android面试题及答案整理(2023最新版)持续更新中......

倒霉的时候总会想起福祸相依&#xff0c;但你会发现倒霉起来没完没了&#xff0c;就是看不到传说中的“福” 年初被裁了&#xff0c;我会安慰自己&#xff0c;此处不留爷自有留爷处&#xff0c;然后踏入找工作的行列&#xff1b;没有面试邀请&#xff0c;我会告诉自己&#xf…

倒在转“码”路上的文科生,文科生也能转行做IT吗?

近期&#xff0c;一篇《倒在转“码”路上的文科生》火了。 这也让关于“文科转码”的话题引起了一番热度&#xff0c;由于大环境不佳&#xff0c;使得毕业生就业成为了一个难度&#xff0c;其中文科生相较而言&#xff0c;选择更少&#xff0c;因此&#xff0c;让不少学子有了…

Java项目:springboot酒店宾馆管理系统

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 功能介绍 springboot酒店宾馆管理系统。该系统为后管系统&#xff0c;无前台。主要分三种角色&#xff1a;管理者/工作人员/前台人员。 主要功能有&…

网络安全方向好吗?

我就在这个行业&#xff0c;今年刚毕业&#xff0c;民办二本&#xff0c;目前武汉&#xff0c;薪资就没必要说了&#xff0c;高就对了。 这个行业优势就是工资高&#xff0c;缺点就需要一直学&#xff0c;卷得要死&#xff0c;不是跟别人卷&#xff0c;而是自己卷&#xff0c;…

数据库实验3 完整性语言实验

实验3 完整性语言实验 实验3.1实体完整性实验 1.实验目的 掌握实体完整性的定义和维护方法。 2.实验内容和要求 定义实体完整性,删除实体完整性。能够写出两种方式定义实体完整性的SQL 语句:创建表时定义实体完整性﹑创建表后定义实体完整性。设计SQL语句验证完整性约束是…

LeetCode 96. 不同的二叉搜索树

LeetCode 96. 不同的二叉搜索树 给你一个整数 n &#xff0c;求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种&#xff1f;返回满足题意的二叉搜索树的种数。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;5示例 2&#xff1a; 输入&#x…

我,30多岁的土木工程人,终于转行了

行外人可能没法想象&#xff0c;十年前最火爆、高校录取分数最高的土木工程专业&#xff0c;现在在贴吧知乎等社交网站上&#xff0c;竟然成了一个“劝退率”最高的专业。 土木出身的工程人&#xff0c;一边吐槽“土木毁我青春”&#xff0c;一边苦口婆心的劝退还在上学的学弟学…

一本通 1276:【例9.20】编辑距离

看完题目后&#xff0c;整个人都懵了&#xff0c;这题咋整&#xff1f; 哎呀&#xff0c;知道知道&#xff0c;用动态规划做 不要慌&#xff0c;我们慢慢分析.... 目录 做题前须知 状态转移 如果 a[i] b[j] 如果 a[i] ! b[j] 做删除操作 做插入操作 做替换操作 初始…

跑步热来袭!缤跃关注运动健康生活,跨界推出差异化酒店产品!

近期&#xff0c;人民数据研究院发布《2022全民跑步运动健康报告》&#xff0c;报告中显示参与跑步人群的年龄跨度随着社会对跑步运动不断攀升的热情而增加。现代生活节奏加快、竞争压力大使得部分中青年通过运动寻求解压&#xff0c;2022年18-40岁的跑者开始成为中坚力量&…

非零基础自学Golang 第15章 Go命令行工具 15.1 编译相关指令 15.1.3 install 15.1.4 交叉编译

非零基础自学Golang 文章目录非零基础自学Golang第15章 Go命令行工具15.1 编译相关指令15.1.3 install15.1.4 交叉编译第15章 Go命令行工具 15.1 编译相关指令 15.1.3 install go install命令的作用是编译后安装&#xff0c;该命令依赖于GOPATH&#xff0c;因此不能在独立的…

网上到处转行编程成功的,现实中真的容易吗?

首先&#xff0c;我先回答&#xff0c;转行编程真的这么简单么&#xff1f;答案是极其简单&#xff0c;但是也非常艰难。 这是一句正确的废话&#xff01; 其实&#xff0c;网上到处都是转行成功的案例。而我们现在也是在互联网上咨询&#xff0c;所以得到的答案会是什么答案…