微信小程序接入支付宝支付沙箱环境
支付宝开放平台
点击控制台->沙箱,由于是小程序使用,申请网页、移动应用
这里接入的产品是网页支付,在小程序中直接使用web-view打开即可
沙箱支付
这里创建订单的时候调用的接口为手机网站支付接口2.0 alipay.trade.wap.pay
maven项目引入依赖
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.39.132.ALL</version>
</dependency>
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-easysdk</artifactId>
<version>2.2.0</version>
</dependency>
客户端发起支付的时候调用该接口,其中total_amount为金额,需要精确到小数点后两位,out_trade_no为商家订单号,在商家端唯一不能重复,subject为支付的订单标题,会在支付界面展示出来
@Data
@Configuration
@ConfigurationProperties(prefix = "alipay")
public class AliPayConfig {
/**
* 私钥
*/
private String privateKey;
/**
* 公钥
*/
private String publicKey;
/**
* 支付宝网关地址
*/
private String serverUrl;
/**
* 支付宝应用ID
*/
private String appId;
/**
* 支付宝商户ID
*/
private String sellerId;
/**
* 回调地址
*/
private String notifyUrl;
}
public String payment(Integer amount, String subject, String orderNo, String userId) {
if (amount == null || amount <= 0) {
throw new OrderException("金额需要大于0");
}
BigDecimal amountDecimal = new BigDecimal(amount.toString()).divide(BigDecimal.valueOf(100)).setScale(2);
try {
String privateKey = serAlipayConfig.getPrivateKey();
String alipayPublicKey = serAlipayConfig.getPublicKey();
AlipayConfig alipayConfig = new AlipayConfig();
alipayConfig.setServerUrl(serAlipayConfig.getServerUrl());
alipayConfig.setAppId(serAlipayConfig.getAppId());
alipayConfig.setPrivateKey(privateKey);
alipayConfig.setFormat("json");
alipayConfig.setAlipayPublicKey(alipayPublicKey);
alipayConfig.setCharset("UTF-8");
alipayConfig.setSignType("RSA2");
AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
model.setOutTradeNo(orderNo);
model.setTotalAmount(amountDecimal.toPlainString());
model.setSubject(subject);
model.setProductCode("QUICK_WAP_WAY");
model.setSellerId(serAlipayConfig.getSellerId());
model.setBody(userId);
request.setBizModel(model);
request.setNotifyUrl(serAlipayConfig.getNotifyUrl());
// AlipayTradeWapPayResponse response = alipayClient.pageExecute(request, "POST");
// 如果需要返回GET请求,请使用
AlipayTradeWapPayResponse response = alipayClient.pageExecute(request, "get");
String pageRedirectionData = response.getBody();
System.out.println(pageRedirectionData);
if (response.isSuccess()) {
log.info("调用支付成功");
return pageRedirectionData;
}
} catch (Exception e) {
log.error("调用支付失败", e);
}
return null;
}
接口调用成功会返回支付宝支付的地址,最后会返回data下面的地址
如果手机端网站或者小程序只需要跳转这个页面进行正常支付就可以
支付回调
异步通知地址:https://opendocs.alipay.com/open/203/105286?pathHash=022a439c
发起支付的时候参数notifyUrl表示用户支付完成支付宝的回调地址,需要配置外网可以正常访问的地址,
当支付成功会触发该回调,根据创建订单传入的订单号在此接口做业务的处理逻辑,处理成功接口要返回success,如果支付宝收到的应答不是 success ,支付宝会认为通知失败,会通过一定的策略定期重新发起通知。通知的间隔频率为:4m、10m、10m、1h、2h、6h、15h。
正式支付一定要添加回调接口的参数签名,
简易流程图如下:
回调内网穿透
如果是本地测试环境,想让支付宝能够正常回调,需要进行内网穿透,如果是服务器上面的服务,一定要联系运维把网络打通,
内网穿透工具,
netapp:https://natapp.cn/
花生壳:https://hsk.oray.com/
微信小程序端
微信端就比较简单了,直接将支付url透传就行
navigatePay: function(data) {
wx.navigateTo({
url: 'pay',
events: {
// 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
acceptDataFromOpenedPage: function(data) {
console.log(data)
},
someEvent: function(data) {
console.log(data)
}
},
success: function(res) {
// 通过eventChannel向被打开页面传送数据
res.eventChannel.emit('acceptDataFromOpenerPage', { data: data })
}
})
},
pay.wxml
<!--pages/pay/index.wxml-->
<web-view src="{{url}}"></web-view>
<!-- {{url}} -->
pay.js
onLoad(option) {
let that = this;
console.log(option.query)
const eventChannel = this.getOpenerEventChannel()
eventChannel.emit('acceptDataFromOpenedPage', {data: 'data'});
eventChannel.emit('someEvent', {data: 'data'});
// 监听acceptDataFromOpenerPage事件,获取上一页面通过eventChannel传送到当前页面的数据
eventChannel.on('acceptDataFromOpenerPage', function(data) {
that.setData({url: data.data})
})
},