真实环境支付宝第三方支付demo,整合进SpringBoot项目全过程(电脑网站支付)

真实环境支付宝第三方支付demo,整合进SpringBoot项目全过程(电脑网站支付)

一、准备阶段

 我是小白,第一次做第三方支付,出了很多问题,网上文档都看得有点懵,所以做完后自己做了一个全过程第三方支付。
 这是真实环境下的第三方支付,需要公司或商家的账号,营业执照等。不是真实环境需要沙箱。
 该步骤可根据官方文档来写(文档跳转有点多,第一次做的话可能要绕晕,慢慢来就好)
 网址:[电脑网站支付准备工作链接](https://opendocs.alipay.com/open/01didh)  根据文档把准备工作做完即可,做第三方支付之前最好把流程搞清楚。

这是流程图:
第三方支付流程图

二、下载demo测试第三方支付

下载demo地址:[电脑网站支付demo](https://opendocs.alipay.com/open/270/106291)
我下的java版本,因为用的时idea,所以下载过来转换了一下(Eclipse直接跳过)。自己先创建一个web项目

创建maven添加webapp
创建好后,用idea把Eclipse版本的打开,然后复制到新创建的项目中。结果如下:
idea demo
pom如下

    <dependency>
      <groupId>com.alipay.sdk</groupId>
      <artifactId>alipay-sdk-java</artifactId>
      <version>4.10.159.ALL</version>
    </dependency>
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1.1</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.1</version>
    </dependency>

配置AlipayConfig:

public class AlipayConfig {
	
//↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

	// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
	public static String app_id = "";
	
	// 商户私钥,您的PKCS8格式RSA2私钥
    public static String merchant_private_key = "";
	
	// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
    public static String alipay_public_key = "";

	// 服务器异步通知页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
	public static String notify_url = "http://工程公网访问地址/alipay.trade.page.pay-JAVA-UTF-8/notify_url.jsp";

	// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
	public static String return_url = "http://工程公网访问地址/alipay.trade.page.pay-JAVA-UTF-8/return_url.jsp";

	// 签名方式
	public static String sign_type = "RSA2";
	
	// 字符编码格式
	public static String charset = "utf-8";
	
	// 支付宝网关(这是真实环境网关,沙箱请百度搜索)
	public static String gatewayUrl = "https://openapi.alipay.com/gateway.do";
	
	// 支付宝网关
	public static String log_path = "C:\\";


//↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

    /** 
     * 写日志,方便测试(看网站需求,也可以改成把记录存入数据库)
     * @param sWord 要写入日志里的文本内容
     */
    public static void logResult(String sWord) {
        FileWriter writer = null;
        try {
            writer = new FileWriter(log_path + "alipay_log_" + System.currentTimeMillis()+".txt");
            writer.write(sWord);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

现在还运行不了,需要配置tomcat服务器:
在这里插入图片描述
现在可以运行了,但是会出现一个bug,当时没截图,找不到了。出问题了可以用这个解决办法,要是不行就百度吧。方法如下:
在这里插入图片描述
换成GBK,点击Convert键;再换回UTF-8,点击Convert键。开启服务器,成功:
在这里插入图片描述
如果点击支付后显示什么权限不足,可能是没有添加能力电脑网站支付并且要生效。demo测试完成,接下来完成整合进SpringBoot项目。

三、整合第三方支付进SpringBoot项目

直接在web下创建applicaliton.yml配置文件,并添加如下:
alipay:
    appid: 202100133239687044
    gatewayUrl: https://openapi.alipay.com/gateway.do
    format: JSON
    charset: utf-8
    signType: RSA2
    notifyUrl: http://地址/notify
    returnUrl: 自己想支付完成后返回的地址
    app-private-key:
    alipay-public-key:

根据自己之前配置的配置就行,returnUrl可以写自己想返回的页面地址。
pom依赖:

<dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.10.159.ALL</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>

如果有多的或者少的,见谅。
工具层:

package com.md.common;

import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

@Configuration
public class AlipayConfig {
	
    @Resource
    private AlipayProperties alipayProperties;

    @Bean
    public AlipayClient initAlipayClient(){
        return new DefaultAlipayClient(alipayProperties.getGatewayUrl(),
                alipayProperties.getAppId(),alipayProperties.getAppPrivateKey(),
                alipayProperties.getFormat(),alipayProperties.getCharset(),
                alipayProperties.getAlipayPublicKey(),alipayProperties.getSignType());
    }

}
package com.md.common;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties("alipay")
public class AlipayProperties {

    private String appId;
    private String gatewayUrl;
    private String format;
    private String charset;
    private String signType;
    private String appPrivateKey;
    private String alipayPublicKey;

    private String returnUrl;
    private String notifyUrl;
}

这两个类我是写在common下的在这里插入图片描述
Controller层:(因能力有限,这层代码只能去别人那搬过来的,见谅。我小改了一下)

package com.md.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.*;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.*;
import com.alipay.api.response.AlipayDataDataserviceBillDownloadurlQueryResponse;
import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.md.common.AlipayProperties;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

@RestController
public class AlipayController {

    @Resource
    private AlipayClient alipayClient;

    @Resource
    private AlipayProperties alipayProperties;

    @RequestMapping("/pay")
    public String pagePay() throws AlipayApiException {
        AlipayTradePagePayModel model=new AlipayTradePagePayModel();
        Random random = new Random();
        Integer i = random.nextInt(1000000000);
        model.setOutTradeNo(i.toString());       //商户订单号(订单号是唯一的,所以推荐使用不会与下一次重复的字符串)
        model.setProductCode("FAST_INSTANT_TRADE_PAY");  //电脑网站支付销售产品码,不同的支付方式productCode不同
        model.setSubject("测试");         //订单标题
        model.setTotalAmount("0.01");        //订单总金额
        model.setTimeoutExpress("1h");     //支付超市时间,1h后关闭

        AlipayTradePagePayRequest request=new AlipayTradePagePayRequest();
        request.setBizModel(model);
        request.setReturnUrl(alipayProperties.getReturnUrl());   //支付成功后同步返回的url地址
        request.setNotifyUrl(alipayProperties.getNotifyUrl());   //trade_success、trade_closed触发

        AlipayTradePagePayResponse response= alipayClient.pageExecute(request);

        return response.getBody();
    }

    @RequestMapping("/query")
    public String query() throws Exception{
        AlipayTradeQueryModel model=new AlipayTradeQueryModel();
        model.setOutTradeNo("3000");

        AlipayTradeQueryRequest request=new AlipayTradeQueryRequest();
        request.setBizModel(model);

        return alipayClient.execute(request).getTradeStatus();
    }

    @RequestMapping("/close")
    public String close() throws Exception{
        AlipayTradeCloseModel model=new AlipayTradeCloseModel();
        model.setOutTradeNo("3000");

        AlipayTradeCloseRequest request=new AlipayTradeCloseRequest();
        request.setBizModel(model);

        return alipayClient.execute(request).getBody();
    }

    @RequestMapping("/refund")
    public String refund() throws Exception{
        AlipayTradeRefundModel model=new AlipayTradeRefundModel();
        model.setOutTradeNo("3000");
        model.setRefundAmount("20");
        model.setOutRequestNo("100");  //分批次退款时,对应的每一次退款请求号,同一订单该值不能相同

        AlipayTradeRefundRequest refundRequest=new AlipayTradeRefundRequest();
        refundRequest.setBizModel(model);

        AlipayTradeRefundResponse refundResponse=alipayClient.execute(refundRequest);

        return "退款总金额:"+refundResponse.getRefundFee();
    }

    @RequestMapping("/refundQuery")
    public String refundQuery() throws Exception{
        AlipayTradeFastpayRefundQueryModel model=new AlipayTradeFastpayRefundQueryModel();
        model.setOutTradeNo("3000");     //商户订单号
        model.setOutRequestNo("100");    //退款请求号

        AlipayTradeFastpayRefundQueryRequest refundQueryRequest=new AlipayTradeFastpayRefundQueryRequest();
        refundQueryRequest.setBizModel(model);

        AlipayTradeFastpayRefundQueryResponse refundQueryResponse=alipayClient.execute(refundQueryRequest);

        return "本次退款金额为:"+refundQueryResponse.getRefundAmount()+
                "\n订单总金额为:"+refundQueryResponse.getTotalAmount();
    }

    @RequestMapping("/queryDownload")
    public String downloadUrl() throws Exception{    //对账单下载地址
        AlipayDataDataserviceBillDownloadurlQueryModel model=new AlipayDataDataserviceBillDownloadurlQueryModel();
        model.setBillType("trade");
        model.setBillDate("2020-04-06");

        AlipayDataDataserviceBillDownloadurlQueryRequest request=new AlipayDataDataserviceBillDownloadurlQueryRequest();
        request.setBizModel(model);

        AlipayDataDataserviceBillDownloadurlQueryResponse response=alipayClient.execute(request);

        return response.getBillDownloadUrl();
    }

    @RequestMapping("/notify")
    public void notify(HttpServletRequest request) throws Exception{  //异步通知接口
        if (check(request.getParameterMap())){
            System.out.println("异步通知");
        }else {
            System.out.println("验签失败");
        }
    }

    @RequestMapping("/return")
    public String returnUrl(HttpServletRequest request) throws Exception{ //同步跳转接口
        if (check(request.getParameterMap())){
            return "success";
        }else {
            return "false";
        }
    }

    private boolean check(Map<String,String[]> requestParams) throws Exception{
        Map<String,String> params = new HashMap<>();

        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);
        }

        return AlipaySignature.rsaCheckV1(params, alipayProperties.getAlipayPublicKey(),
                alipayProperties.getCharset(), alipayProperties.getSignType()); //调用SDK验证签名
    }
}

配置完毕,不用在idea写任何前端代码。只需要在前端页面写个支付链接跳转到"/pay"下即可。至此大功告成。感谢观看!

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值