栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot集成支付宝

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot集成支付宝

1.沙箱环境简介&基础开发配置

1.进入支付宝官网,扫码进入,网址:https://open.alipay.com/platform/home.htm

2.找到开发服务进入下面的研发服务

3.在手机上面下载支付宝沙箱

 4.沙箱账号里面有一个商家信息,一个是买家信息

账号余额可以自动更改不过不能太多有上限,可惜这都是假的

5.找到自己的开发信息

6.这是自己的:应用私钥和支付宝公钥

7.支付流程

2.创建Spring Boot项目

创建SpringBoot的流程就不写了

1.1  这里只粘贴一下我的pom.xml依赖:
 
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
            
                
                    org.junit.vintage
                    junit-vintage-engine
                
            
        
        
            com.alipay.sdk
            alipay-easysdk
            2.0.2
        
    

这个里面只有基本的web、lombok、支付宝的sdk依赖。

1.2   下面就是我的项目结构

结构介绍:

1.PaymentBO是接收controller层的入参,如商品id、购买数量等等,结合具体的业务而定
2.PayController是控制器,负责分发请求,主要是处理用户的支付请求,以及支付宝的回调
3.ProjectInit是项目初始化时执行的一些操作,适合在整个过程中只需要执行一次的业务
4.PayService是真正的服务层,主要的业务代码在这里
5.OrderUtil是一个订单工具类,主要是生成随机订单号
6.index.html是模拟下单支付的页面
7.return.html是支付完成之后的页面

3.编写支付页面和回调页面

在index.html里面的代码:




    
    确认订单


    
      您的订单信息如下,请确认无误后支付:
这个里面就是您的订单详细信息,在这里我就不多写了,想写的话可以自己设置一些样式

 在return.html里面的代码:




    
    支付成功


    
        您已成功购买此商品,感谢您的支持
    


回调地址肯定要外网可以访问,要不然支付宝怎么会调用得到呢?但是我们作为开发者可能没有自己到服务器和域名,所以我们使用内网穿透工具natapp获取临时域名,在这里我就不说怎么搭建内网穿透了

映射完成之后,启动项目,用临时域名测试一下下面的页面:

3.配置Spring Boot项目&初始化支付宝SDK

1.新版本的SDK 把大部分操作都封装到了Factory类中,但是Factory类在使用之前需要我们配置一下参数,且全局配置一次即可,所以我们把这部分代码拿到ProjectInit类中,在项目启动时执行一次:

alipay:
  appId: 换成自己的APPID
  privateKey: 换成自己的私钥
  publicKey: 换成自己的公钥
  #支付网关配置,这一项是写死的,正式环境是openapi.alipay.com
  gateway: openapi.alipaydev.com
  #支付成功之后的回调页面,只是一个友好页面。主要换成你自己映射的临时域名
  returnUrl: http://frnqxw.natappfree.cc/return.html
  #支付成功的接口回调
  notifyUrl: 

2. 新版本的SDK 把大部分操作都封装到了Factory类中,但是Factory类在使用之前需要我们配置一下参数,且全局配置一次即可,所以我们把这部分代码拿到ProjectInit类中,在项目启动时执行一次:

import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
 

@Component
public class ProjectInit implements ApplicationRunner {
 
    //应用id
    @Value("${alipay.appId}")
    private String appId;
 
    //私钥
    @Value("${alipay.privateKey}")
    private String privateKey;
 
    //公钥
    @Value("${alipay.publicKey}")
    private String publicKey;
 
    //支付宝网关
    @Value("${alipay.gateway}")
    private String gateway;
 
    //支付成功后的接口回调地址,不是回调的友好页面,不要弄混了
    @Value("${alipay.notifyUrl}")
    private String notifyUrl;
 
    
    @Override
    public void run(ApplicationArguments args) throws Exception {
        //初始化支付宝SDK
        Factory.setOptions(getOptions());
        System.out.println("**********支付宝SDK初始化完成**********");
    }
 
    private Config getOptions() {
        //这里省略了一些不必要的配置,可参考文档的说明
        
        Config config = new Config();
        config.protocol = "https";
        config.gatewayHost = this.gateway;
        config.signType = "RSA2";
 
        config.appId = this.appId;
 
        // 为避免私钥随源码泄露,推荐从文件中读取私钥字符串而不是写入源码中
        config.merchantPrivateKey = this.privateKey;
 
        //注:如果采用非证书模式,则无需赋值上面的三个证书路径,改为赋值如下的支付宝公钥字符串即可
        config.alipayPublicKey = this.publicKey;
 
        //可设置异步通知接收服务地址(可选)
        config.notifyUrl = notifyUrl;
 
        return config;
    }
}
3.1 编写下单支付接口

既然要下单,肯定少不了传参,所以我们这里简单的声明一个PaymentBO类

import lombok.Data;
 
import java.math.BigDecimal;
 


@Data
public class PaymentBO {
    //省略其他的业务参数,如商品id、购买数量等
 
    //商品名称
    private String subject;
 
    //总金额
    private BigDecimal total = BigDecimal.ZERO;
}

然后在OrderUtil编写如下代码:

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;




    public static String getOrderNo () {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
        LocalDateTime localDateTime = Instant.ofEpochMilli(System.currentTimeMillis()).atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
        return df.format(localDateTime);
    }
}

 接下来我们只需要Factory.Payment.Page.pay就可以发起一个支付请求,所以我们在PayService编写以下代码:

​

mport com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.payment.facetoface.models.AlipayTradePayResponse;
import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
import com.course.java.alipay.bo.PaymentBO;
import com.course.java.alipay.util.OrderUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
 
import java.math.BigDecimal;
 

@Service
public class PayService {
 
    //支付成功后要跳转的页面
    @Value("${alipay.returnUrl}")
    private String returnUrl;
 
    
    public Object pay (PaymentBO bo) throws Exception {
 
        //从存储介质(如MySQL、Redis)查询商品信息、总金额等敏感信息
 
        //…………省略相关代码,这里直接赋值…………
 
        bo.setSubject("游戏充值")
        bo.setTotal(new BigDecimal(648.00));
 
        //调用sdk,发起支付
        AlipayTradePagePayResponse response = Factory.Payment
                //选择网页支付平台
                .Page()
                //调用支付方法,设置订单名称、我们自己系统中的订单号、金额、回调页面
                .pay(bo.getSubject() , OrderUtil.getOrderNo(), bo.getTotal().toString() , returnUrl);
 
        //这里的response.body,就是一个可以直接加载的html片段,
        // 这里为了简单我直接返回这个片段,前端直接
        return response.body;
    }
}

[点击并拖拽以移动]
​

 再往下,编写PayController:

import com.course.java.alipay.bo.PaymentBO;
import com.course.java.alipay.service.PayService;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
 
import java.util.Map;
 

@RestController
@RequestMapping(value = "/payController")
@AllArgsConstructor
public class PayController {
 
    private PayService payService;
 
    
    @GetMapping(value = "//confirm/i" , produces = {"text/html;charset=UTF-8"})
    public Object pay (@RequestParam(required = false) PaymentBO bo) throws Exception {
        //这个接口其实应该是post方式的,但是我这里图方便,直接以get方式访问,
        //且返回格式是text/html,这样前端页面就能直接显示支付宝返回的html片段
        //真实场景下由post方式请求,返回code、msg、data那种格式的标准结构,让前端拿到data里的        
        //html片段之后自行加载
 
        //由于我这里并没有真正的传参数,所以象征性的new一下,避免空指针
        bo = new PaymentBO();
        return payService.pay(bo);
    }
}
4. 支付测试

在手机上打开沙箱版支付宝,登录买家帐号,扫码支付:

 

 

到这里支付宝支付流程就完了

         

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/591580.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号