springboot实现支付宝沙箱支付功能

写在前面
  你们好,我是小庄。很高兴能和你们一起学习SpringBoot的支付功能。如果您对Java感兴趣的话可关注我的动态.
  写博文是一种习惯,在这过程中能够梳理和巩固知识点。

一、支付宝测试开发环境前期准备

1.Java支付的demo
下载地址:https://docs.open.alipay.com/270/106291/
下载位置
2.解压并打开内容。大致的内容如下:

import java.io.FileWriter;
import java.io.IOException;

public class AlipayConfig {
// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号,开发时使用沙箱提供的APPID,生产环境改成自己的APPID
    public static String APP_ID = "";

    // 商户私钥,您的PKCS8格式RSA2私钥
    public static String APP_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://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问(其实就是支付成功后返回的页面)
    public static String return_url = "";

    // 签名方式
    public static String SIGN_TYPE = "RSA2";

    // 字符编码格式
    public static String CHARSET = "utf-8";

    // 支付宝网关,这是沙箱的网关
    public static String GATEWAYURL = "https://openapi.alipaydev.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();
                }
            }
        }
    }
}

3.免费注册蚂蚁金服开发者账号
点击进入注册
或者复制:https://open.alipay.com 访问

4.进入沙箱环境进行配置
沙箱环境
在这里插入图片描述
在沙箱账号里面进行充值虚拟金额
在这里插入图片描述
5.下载工具生成密钥
下载链接网页
选择电脑版本下载
下载安装后进入工具
点击生成密钥
打开密钥文件路径
公钥私钥
设置加密配置
在这里插入图片描述

在这里插入图片描述
搞定完前期准备后,下面代码配置

二.实现支付宝支付接口

1.在pom.xml文件添加依赖

<!--支付宝支付-->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>3.0.0</version>
        </dependency>

2.配置config类
这里就是上面的demo,我再复制一遍,将开发环境的内容一一对应填入

import java.io.FileWriter;
import java.io.IOException;

public class AlipayConfig {
// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号,开发时使用沙箱提供的APPID,生产环境改成自己的APPID
    public static String APP_ID = "";

    // 商户私钥,您的PKCS8格式RSA2私钥
    public static String APP_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://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问(其实就是支付成功后返回的页面)
    public static String return_url = "";

    // 签名方式
    public static String SIGN_TYPE = "RSA2";

    // 字符编码格式
    public static String CHARSET = "utf-8";

    // 支付宝网关,这是沙箱的网关
    public static String GATEWAYURL = "https://openapi.alipaydev.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();
                }
            }
        }
    }
}

3.配置支付接口

import com.alipay.api.AlipayApiException;

/**
 * 支付接口
 * @author zwz
 *
 */
public interface AlipayService {

    /**
     * web端订单支付
     * @param outTradeNo    订单编号(唯一)
     * @param totalAmount   订单价格
     * @param subject       商品名称
     */
    String webPagePay(String outTradeNo,Integer totalAmount,String subject) throws Exception;

    /**
     * app端订单支付
     * @param outTradeNo    订单编号
     * @param totalAmount   订单价格
     * @param subject       商品名称
     */
    String appPagePay(String outTradeNo,Integer totalAmount,String subject) throws Exception;

    /**
     * 退款
     * @param outTradeNo    订单编号
     * @param refundReason  退款原因
     * @param refundAmount  退款金额
     * @param outRequestNo  标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传
     */
    String refund(String outTradeNo,String refundReason,Integer refundAmount,String outRequestNo) throws AlipayApiException;

    /**
     * 交易查询
     * @param outTradeNo 订单编号(唯一)
     */
    String query(String outTradeNo) throws AlipayApiException;

    /**
     * 交易关闭
     * @param outTradeNo 订单编号(唯一)
     */
    String close(String outTradeNo) throws AlipayApiException;

    /**
     * 退款查询
     * @param outTradeNo 订单编号(唯一)
     * @param outRequestNo 标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传
     */
    String refundQuery(String outTradeNo,String outRequestNo) throws AlipayApiException;
}

4.配置支付接口实现类


import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.*;
import com.zwz.config.AlipayConfig;
import org.springframework.stereotype.Service;

@Service("alipayService")
public class AlipayServiceImpI implements AlipayService{
    /** 调取支付宝接口 web端支付*/
    DefaultAlipayClient alipayClient = new DefaultAlipayClient(
            AlipayConfig.GATEWAYURL, AlipayConfig.APP_ID, AlipayConfig.APP_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGN_TYPE);

    /** 调取支付宝接口app端支付*/
    AlipayClient alipayClients = new DefaultAlipayClient(
            AlipayConfig.GATEWAYURL, AlipayConfig.APP_ID, AlipayConfig.APP_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGN_TYPE);


    /**
     * web端订单支付
     *
     * @param outTradeNo  订单编号(唯一)
     * @param totalAmount 订单价格
     * @param subject     商品名称
     */
    @Override
    public String webPagePay(String outTradeNo, Integer totalAmount, String subject) throws Exception {
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        /** 同步通知,支付完成后,支付成功页面*/
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        /** 异步通知,支付完成后,需要进行的异步处理*/
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
        alipayRequest.setBizContent("{" +
                "    \"out_trade_no\":\""+outTradeNo+"\"," +
                "    \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," +
                "    \"total_amount\":"+totalAmount+"," +
                "    \"subject\":\""+subject+"\"," +
                "    \"body\":\""+"商品介绍"+"\"," +
                "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        /**转换格式*/
        String result = alipayClient.pageExecute(alipayRequest).getBody().replace('\"','\'').replace('\n',' ');
        return result;
    }

    /**
     * app端订单支付
     *
     * @param outTradeNo  订单编号
     * @param totalAmount 订单价格
     * @param subject     商品名称
     */
    @Override
    public String appPagePay(String outTradeNo, Integer totalAmount, String subject) throws Exception {
        AlipayTradeWapPayRequest alipayRequest=new AlipayTradeWapPayRequest();

        /** 同步通知,支付完成后,支付成功页面*/
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        /** 异步通知,支付完成后,需要进行的异步处理*/
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

        /**销售产品码(固定)*/
        String productCode="QUICK_WAP_WAY";

        /** 进行赋值 */
        AlipayTradeWapPayModel wapPayModel=new AlipayTradeWapPayModel();
        wapPayModel.setOutTradeNo(outTradeNo);
        wapPayModel.setSubject(subject);
        wapPayModel.setTotalAmount(totalAmount.toString());
        wapPayModel.setBody("商品名称");
        wapPayModel.setTimeoutExpress("200000m");
        wapPayModel.setProductCode(productCode);
        alipayRequest.setBizModel(wapPayModel);

        /** 格式转换*/
        String result = alipayClients.pageExecute(alipayRequest).getBody().replace('\"','\'').replace('\n',' ');
        return result;
    }

    /**
     * 退款
     *
     * @param outTradeNo   订单编号
     * @param refundReason 退款原因
     * @param refundAmount 退款金额
     * @param outRequestNo 标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传
     */
    @Override
    public String refund(String outTradeNo, String refundReason, Integer refundAmount, String outRequestNo) throws AlipayApiException {
        AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();

        /** 调取接口*/
        alipayRequest.setBizContent("{\"out_trade_no\":\""+ outTradeNo +"\","
                + "\"refund_amount\":\""+ refundAmount +"\","
                + "\"refund_reason\":\""+ refundReason +"\","
                + "\"out_request_no\":\""+ outRequestNo +"\"}");
        String result = alipayClient.execute(alipayRequest).getBody();
        return result;
    }

    /**
     * 交易查询
     *
     * @param outTradeNo 订单编号(唯一)
     */
    @Override
    public String query(String outTradeNo) throws AlipayApiException {
        AlipayTradeQueryRequest alipayRequest = new AlipayTradeQueryRequest();
        /**请求接口*/
        alipayRequest.setBizContent("{\"out_trade_no\":\""+ outTradeNo +"\","+"\"trade_no\":\""+ "" +"\"}");
        /**转换格式*/
        String result = alipayClient.execute(alipayRequest).getBody();
        return result;
    }

    /**
     * 交易关闭
     *
     * @param outTradeNo 订单编号(唯一)
     */
    @Override
    public String close(String outTradeNo) throws AlipayApiException {
        AlipayTradeCloseRequest alipayRequest = new AlipayTradeCloseRequest();

        alipayRequest.setBizContent("{\"out_trade_no\":\""+ outTradeNo +"\"," +"\"trade_no\":\""+ "" +"\"}");

        String result = alipayClient.execute(alipayRequest).getBody();

        return result;
    }

    /**
     * 退款查询
     *
     * @param outTradeNo   订单编号(唯一)
     * @param outRequestNo 标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传
     */
    @Override
    public String refundQuery(String outTradeNo, String outRequestNo) throws AlipayApiException {
        AlipayTradeFastpayRefundQueryRequest alipayRequest = new AlipayTradeFastpayRefundQueryRequest();

        /** 请求接口*/
        alipayRequest.setBizContent("{\"out_trade_no\":\""+ outTradeNo +"\","
                +"\"out_request_no\":\""+ outRequestNo +"\"}");

        /** 格式转换*/
        String result = alipayClient.execute(alipayRequest).getBody();

        return result;
    }
}

5.配置Contorller

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class PayController {
    @Autowired
    @Qualifier("alipayService")
    private AlipayService alipayService;

    @RequestMapping("/pay")
    public String payController(@RequestParam("WIDout_trade_no") String id,@RequestParam("WIDsubject") String name,@RequestParam("WIDtotal_amount") String amount ) throws Exception {
        Integer pay=Integer.valueOf(amount);
        String pays = alipayService.webPagePay(id, pay, name);
        return pays;
    }

}

然后配置一个html页面,用来模拟数据库实现支付接口
这里我就配置一个简单的页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/pay" method="post">
    订单号:<input type="text" name="WIDout_trade_no" required><br/>
    订单名称:<input type="text" name="WIDsubject" required><br/>
    付款金额:<input type="text" name="WIDtotal_amount" required><br/>
    <input type="submit" value="下单"> <input type="reset" value="重置">
</form>
</body>
</html>
以上的内容就是实现支付功能的内容,这个是沙箱测试,如果需要运营的,需要把沙箱环境变成正常的支付环境。喜欢的小伙伴记得关注哦!
  • 10
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值