支付宝支付
支付宝(中国)网络技术有限公司 [1] 是国内的第三方支付平台,致力于提供“简单、安全、快速”的支付解决方案 [2] 。支付宝公司从2004年建立开始,始终以“信任”作为产品和服务的核心。旗下有“支付宝”与“支付宝钱包”两个独立品牌。自2014年第二季度开始成为当前全球最大的移动支付厂商。
1、产品介绍
(1)产品特色
选择手机网站支付:https://open.alipay.com/api/detail?code=I1080300001000041949
![image-20230709160020998](D:\Program Files\feiq\Recv Files\课件\images\image-20230709160020998.png)
手机网站支付是指商家在移动端网页展示商品或服务,用户在商家页面确认使用支付宝支付后,浏览器自动跳转支付宝 App 或支付宝网页完成付款的支付产品。该产品在签约完成后,需要技术集成方可使用。
(2)使用示例
(3)申请条件
签约申请提交材料要求:
- 提供网站地址,网站能正常访问且页面显示完整,网站需要明确经营内容且有完整的商品信息。
- 网站必须通过 ICP 备案,且备案主体需与支付宝账号主体一致。若网站备案主体与当前账号主体不同时需上传授权函。
- 个人账号申请,需提供营业执照,且支付宝账号名称需与营业执照主体一致。
注意:需按照要求提交材料,若部分材料不合格,收款额度将受到限制(单笔收款 ≤ 2000 元,单日收款 ≤ 20000 元)。若签约时未能提供相关材料(如营业执照),请在合约生效后的 30 天内补全,否则会影响正常收款。
(4)费率
收费模式 | 费率 |
---|---|
单笔收费 | 0.6%-1.0% |
特殊行业费率为 1.0%,非特殊行业费率为 0.6%。特殊行业包含:休闲游戏、网络游戏点卡、游戏渠道代理、游戏系统商、网游周边服务、交易平台、网游运营商(含网页游戏)等。
2、接入准备
(开发测试阶段不用接入)
官方文档:https://opendocs.alipay.com/open/203/107084?pathHash=a33de091
整体流程:
3、手机网站支付快速接入
官方文档:https://opendocs.alipay.com/open/203/105285?pathHash=ada1de5b
系统交互流程图:
作为我们的项目来讲只需要将支付宝的收银台展示给用户即可,后续支付的动作和我们的系统就没有关系了。支付成功以后,支付宝开放平台会请求我们系统的接口通知支付结果,我们的系统也可以调用支付宝交易查询接口获取支付结果。
4、官方demo研究
步骤:
-
官方demo下载地址:https://opendocs.alipay.com/open/203/105910?pathHash=1a2e3a94
-
将访问demo的eclipse项目更改为idea的maven项目(jdk8)
-
在AlipayConfig类中填写参数信息
-
启动项目进行测试
支付功能实现(沙箱环境)
1、前置工作
进入沙箱工作台
获取支付宝的公共密钥和应用私钥
【获取应用公钥】
工具下载地址:https://opendocs.alipay.com/common/02kipk
【通过应用公钥得到支付宝公钥】
2、编写java代码
参考地址
https://opendocs.alipay.com/open/203/105285?pathHash=ada1de5b#支付流程
1、引入依赖
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
</dependency>
2、创建一个配置文件放支付宝支付的《必需参数》
alipay:
# alipay_url: https://openapi.alipay.com/gateway.do # 真实支付的url
alipay_url: https://openapi-sandbox.dl.alipaydev.com/gateway.do # 沙箱的url
app_id: # APPID
app_private_key: # 应用私钥
alipay_public_key: # 支付宝公钥
format: json # 数据格式
charset: utf-8 # 编码格式
sign_type: RSA2 # 加密方式
return_payment_url: # 通知地址,支付成功后点击完成后,会调用该路径接口。
notify_payment_url: # 异步通知地址,用于接收支付宝推送给商户的支付/退款成功的消息。
return_order_url: # 重定向地址,支付成功后点击完成后,会《重定向自动跳转回》商家页面地址。
3、创建一个类调用支付宝支付API,并获取配置文件值
package com.spzx.payment.configure;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AlipayConfig {
// 支付宝网关地址
@Value("${alipay.alipay_url}")
private String alipay_url;
// 应用的私钥
@Value("${alipay.app_private_key}")
private String app_private_key;
// 支付宝的appId
@Value("${alipay.app_id}")
private String app_id;
public final static String format="json";
public final static String charset="utf-8";
public final static String sign_type="RSA2";
public static String return_payment_url;
public static String notify_payment_url;
public static String return_order_url;
public static String alipay_public_key;
@Value("${alipay.alipay_public_key}")
public void setAlipay_public_key(String alipay_public_key) {
AlipayConfig.alipay_public_key = alipay_public_key;
}
@Value("${alipay.return_payment_url}")
public void setReturn_url(String return_payment_url) {
AlipayConfig.return_payment_url = return_payment_url;
}
@Value("${alipay.notify_payment_url}")
public void setNotify_url(String notify_payment_url) {
AlipayConfig.notify_payment_url = notify_payment_url;
}
@Value("${alipay.return_order_url}")
public void setReturn_order_url(String return_order_url) {
AlipayConfig.return_order_url = return_order_url;
}
// 创建一个client对象
@Bean
public AlipayClient alipayClient(){
AlipayClient alipayClient=new DefaultAlipayClient(alipay_url,app_id,app_private_key,format,charset, alipay_public_key,sign_type );
return alipayClient;
}
}
4、使用支付宝支付
参考地址:https://opendocs.alipay.com/open/29ae8cb6_alipay.trade.wap.pay?pathHash=1ef587fd&scene=21
@Autowired
private AlipayConfig alipauConfig
public String submitAlipay(String orderNo) {
//创建支付记录
PaymentInfo paymentInfo = this.createPaymentInfo(orderNo);
//调用支付宝api进行支付操作
//不同支付宝端的不同接口,对应不同的request对象
AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
//用于封装参数
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
// 设置商户订单号
model.setOutTradeNo(paymentInfo.getOrderNo());
// 设置订单总金额
model.setTotalAmount(paymentInfo.getAmount() + "");
// 设置订单标题
model.setSubject(paymentInfo.getContent());
// 设置产品码
model.setProductCode("QUICK_WAP_WAY");
// 设置针对用户授权接口
// model.setAuthToken("appopenBb64d181d0146481ab6a762c00714cC27");
// 设置用户付款中途退出返回商户网站的地址
// model.setQuitUrl("http://www.taobao.com/product/113714.html");
request.setBizModel(model);
try {
AlipayTradeWapPayResponse response = alipayClient.pageExecute(request, "POST");
// 如果需要返回GET请求,请使用
// AlipayTradeWapPayResponse response = alipayClient.pageExecute(request, "GET");
String form = response.getBody();
if (response.isSuccess()) {
System.out.println("调用成功");
return form;
} else {
System.out.println("调用失败");
// sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
// String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
// System.out.println(diagnosisUrl);
throw new ServiceException("支付失败!请重新支付");
}
} catch (AlipayApiException e) {
throw new RuntimeException(e);
}
}
5、支付宝同步回调
支付成功后点击完成会自动跳转回商家页面地址
request.setReturnUrl(url);
点击完成后,会调用指定url接口,而该接口里的内容是重定向到本地的支付成功界面
@Autowired
private AlipayConfig alipauConfig
@Override
public String submitAlipay(String orderNo) {
//创建支付记录
PaymentInfo paymentInfo = this.createPaymentInfo(orderNo);
//调用支付宝api进行支付操作
//不同支付宝端的不同接口,对应不同的request对象
AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
//用于封装参数
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
// 设置商户订单号
model.setOutTradeNo(paymentInfo.getOrderNo());
// 设置订单总金额
model.setTotalAmount(paymentInfo.getAmount() + "");
// 设置订单标题
model.setSubject(paymentInfo.getContent());
// 设置产品码
model.setProductCode("QUICK_WAP_WAY");
// 设置针对用户授权接口
// model.setAuthToken("appopenBb64d181d0146481ab6a762c00714cC27");
// 设置用户付款中途退出返回商户网站的地址
// model.setQuitUrl("http://www.taobao.com/product/113714.html");
// 点击完成后,会调用指定url接口,而该接口里的内容是重定向到本地的支付成功界面
request.setReturnUrl(AlipayConfig.return_payment_url);
request.setBizModel(model);
try {
AlipayTradeWapPayResponse response = alipayClient.pageExecute(request, "POST");
// 如果需要返回GET请求,请使用
// AlipayTradeWapPayResponse response = alipayClient.pageExecute(request, "GET");
String form = response.getBody();
if (response.isSuccess()) {
System.out.println("调用成功");
return form;
} else {
System.out.println("调用失败");
// sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
// String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
// System.out.println(diagnosisUrl);
throw new ServiceException("支付失败!请重新支付");
}
} catch (AlipayApiException e) {
throw new RuntimeException(e);
}
6、支付宝异步回调
参考地址:https://opendocs.alipay.com/open/203/105285?pathHash=ada1de5b#支付流程
该接口是,支付宝内部调用的,所以该接口需要暴露在公网上
当用户支付成功以后,支付宝系统会调用我们系统的接口通知支付结果
异步调用,支付成功后支付宝自动调用该接口
request.setNotifyUrl(url);
/**
* 支付宝支付成功或会自动调用该接口,传入一个map参数
*/
@PostMapping("callback/notify")
public String notifyUrl(@RequestParam Map<String, String> paramsMap, HttpServletRequest request) {
boolean signVerified = false;
// 签名校验
try {
signVerified = AlipaySignature.rsaCheckV1(paramsMap, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);
if (signVerified) {
return "succuess";
//判断是否支付成功
if("TRADE_SUCCESS".equals(paramsMap.get("trade_status"))){
//成功后的业务代码
}
} else {
return "failure";
}
} catch (AlipayApiException e) {
throw new RuntimeException(e);
}
}
}
内网穿透介绍
当支付成功以后支付宝无法调用本地接口,因为本地接口是位于一个私有IP地址范围内,并且被路由器或防火墙等设备保护起来。这个私有的网络设备无法直接从公共网络访问,该问题的解决可以使用内网穿透技术。
内网穿透:内网穿透(Intranet Port Forwarding)是一种将本地网络中的服务暴露给公共网络访问的技术。
内网穿透通过在公共网络上建立一个中转服务器,使得公共网络上的设备可以通过该中转服务器访问内网中的设备和服务。具体而言,内网穿透技术允
许您在公共网络上使用一个公网IP地址和端口号来映射到内网中的某个设备或服务的私有IP地址和端口号。
常见的内网穿透工具包括natapp、Ngrok、frp、花生壳等。
官网地址:https://natapp.cn/
官网地址:cpolar - secure introspectable tunnels to localhost
试用步骤:
1、注册用户
2、购买隧道
3、购买二级域名,绑定隧道
4、下载客户端
5、客户端使用教程:https://natapp.cn/article/nohup
natapp.exe -authtoken=1bd364e142d4277
authtoken信息获取:
标签:alipay,支付宝,功能,String,url,支付,public From: https://www.cnblogs.com/21CHS/p/18528873