百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

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

ztj100 2025-03-13 22:12 21 浏览 0 评论

前提条件

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


演示

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

支付成功后就会响应支付成功

应用申请开通和配置

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

应用创建

首先进入支付宝开放平台,进入控制台,创建一个应用,大概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,用于生成支付二维码使用

 

	com.alipay.sdk
	alipay-sdk-java
	4.35.9.ALL




	com.google.zxing
	core
	3.5.1

复制代码

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 params = new HashMap<>();
        Map 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 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

消息获取成功

不重试

前端代码实例




    
    
    支付宝当面付Demo演示
    


<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>
复制代码

源码

Github:github.com/ThirdGoddes…

作者:第三女神程忆难
链接:
https://juejin.cn/post/7180312322085224508

相关推荐

使用 Pinia ORM 管理 Vue 中的状态

转载说明:原创不易,未经授权,谢绝任何形式的转载状态管理是构建任何Web应用程序的重要组成部分。虽然Vue提供了管理简单状态的技术,但随着应用程序复杂性的增加,处理状态可能变得更具挑战性。这就是为什么...

Vue3开发企业级音乐Web App 明星讲师带你学习大厂高质量代码

Vue3开发企业级音乐WebApp明星讲师带你学习大厂高质量代码下栽课》jzit.top/392/...

一篇文章说清 webpack、vite、vue-cli、create-vue 的区别

webpack、vite、vue-cli、create-vue这些都是什么?看着有点晕,不要怕,我们一起来分辨一下。...

超赞 vue2/3 可视化打印设计VuePluginPrint

今天来给大家推荐一款非常不错的Vue可拖拽打印设计器Hiprint。引入使用//main.js中引入安装import{hiPrintPlugin}from'vue-plugin-...

搭建Trae+Vue3的AI开发环境(vue3 ts开发)

从2024年2025年,不断的有各种AI工具会在自媒体中火起来,号称各种效率王炸,而在AI是否会替代打工人的话题中,程序员又首当其冲。...

如何在现有的Vue项目中嵌入 Blazor项目?

...

Vue中mixin怎么理解?(vue的mixins有什么用)

作者:qdmryt转发链接:https://mp.weixin.qq.com/s/JHF3oIGSTnRegpvE6GSZhg前言...

Vue脚手架安装,初始化项目,打包并用Tomcat和Nginx部署

1.创建Vue脚手架#1.在本地文件目录创建my-first-vue文件夹,安装vue-cli脚手架:npminstall-gvue-cli安装过程如下图所示:创建my-first-vue...

新手如何搭建个人网站(小白如何搭建个人网站)

ElementUl是饿了么前端团队推出的桌面端UI框架,具有是简洁、直观、强悍和低学习成本等优势,非常适合初学者使用。因此,本次项目使用ElementUI框架来完成个人博客的主体开发,欢迎大家讨论...

零基础入门vue开发(vue快速入门与实战开发)

上面一节我们已经成功的安装了nodejs,并且配置了npm的全局环境变量,那么这一节我们就来正式的安装vue-cli,然后在webstorm开发者工具里运行我们的vue项目。这一节有两种创建vue项目...

.net core集成vue(.net core集成vue3)

react、angular、vue你更熟悉哪个?下边这个是vue的。要求需要你的计算机安装有o.netcore2.0以上版本onode、webpack、vue-cli、vue(npm...

使用 Vue 脚手架,为什么要学 webpack?(一)

先问大家一个很简单的问题:vueinitwebpackprjectName与vuecreateprojectName有什么区别呢?它们是Vue-cli2和Vue-cli3创建...

vue 构建和部署(vue项目部署服务器)

普通的搭建方式(安装指令)安装Node.js检查node是否已安装,终端输入node-v会使用命令行(安装)npminstallvue-cli-首先安装vue-clivueinitwe...

Vue.js 环境配置(vue的环境搭建)

说明:node.js和vue.js的关系:Node.js是一个基于ChromeV8引擎的JavaScript运行时环境;类比:Java的jvm(虚拟机)...

vue项目完整搭建步骤(vuecli项目搭建)

简介为了让一些不太清楚搭建前端项目的小白,更快上手。今天我将一步一步带领你们进行前端项目的搭建。前端开发中需要用到框架,那vue作为三大框架主流之一,在工作中很常用。所以就以vue为例。...

取消回复欢迎 发表评论: