1.首先是创建应用,我创建的是网页移动应用
2.设置接口加签方式
3.点击设置,可能会获取验证码,输入验证码,然后弹出框看得到有个支付宝密钥生成器字样点击下载,然后安装,生成私钥和公钥
4.复制公钥到这里来,粘贴,保存设置
4.提交审核
5.等待审核通过。。。。。。。
6.下载alipay的sdk,我这里直接maven方式导入
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.8.73.ALL</version>
</dependency>
7.支付配置类
public class AlipayConfig {
//↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
public static String app_id = "20191107690....";
// 商户私钥,您的PKCS8格式RSA2私钥
public static String merchant_private_key = "MIIEvQIBADANBgkqhkiG9w0......";
// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
public static String alipay_public_key = "MIIBIjANBgkqhkiG9w0......";
// 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String notify_url = "http://127.0.0.1:8080/returnUrl";
// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String return_url = "http://127.0.0.1:8080/returnUrl";
// 签名方式
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:\\";
//↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
}
注意:配置类里的merchant_private_key(对应第4步上面那栏秘钥字符串)和alipay_public_key(对应第4步下面那栏秘钥字符串),
8.手机wap页面(浏览器应用,套壳安卓app都可以)唤起支付宝代码如下,直接返回,会跳转到支付宝的支付页,页面不用自己写,然后询问是否打开支付宝
@RequestMapping("/test")
@ResponseBody
public String test(Integer id, HttpServletRequest request) throws Exception{
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id,
AlipayConfig.merchant_private_key,
"json", AlipayConfig.charset,
AlipayConfig.alipay_public_key,
AlipayConfig.sign_type); //获得初始化的AlipayClient
String authOrderid = new SimpleDateFormat("yyyyMMdd").format(new Date()) + System.currentTimeMillis();
AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();//创建API对应的request
//alipayRequest.setReturnUrl("http://domain.com/CallBack/return_url.jsp");
alipayRequest.setReturnUrl(request.getScheme() + "://" + request.getLocalAddr() + ":" + request.getServerPort() + "/alipay/payResult");//返回地址,如:通知支付成功
alipayRequest.setNotifyUrl("http://2y819821x1.zicp.vip/payResult");//在公共参数中设置回跳和通知地址
alipayRequest.setBizContent("{" +
" \"out_trade_no\":\"" + authOrderid + "\"," + //订单号
" \"total_amount\":\"0.01\"," + // 支付价格
" \"subject\":\"" + URLEncoder.encode("配送员押金","utf-8") + "\"," + // 商品信息
" \"product_code\":\"QUICK_WAP_PAY\"" +
" }");//填充业务参数
String result="";
try {
result = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单
// AlipayTradeWapPayResponse pageExecute = alipayClient.pageExecute(alipayRequest);
// AlipayTradeWapPayResponse execute = alipayClient.execute(alipayRequest);
// result = alipayClient.sdkExecute(alipayRequest).getBody();
} catch (AlipayApiException e) {
e.printStackTrace();
}
return result;
}
9.app唤起支付宝,这里返回的是一串get形式的参数不带host,意思是只有一个url问号?后面的参数,但是这不足以唤起支付宝需要与前端配合,具体怎么唤起看支付宝文档
@RequestMapping("/toAlipay")
@ResponseBody
public AjaxResult toAlipay(HttpServletRequest request) throws Exception {
// 获得初始化的AlipayClient
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id,
AlipayConfig.merchant_private_key, "json", AlipayConfig.charset,
AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
String authOrderid = new SimpleDateFormat("yyyyMMdd").format(new Date()) + System.currentTimeMillis();
AlipayTradeAppPayRequest alipayRequest = new AlipayTradeAppPayRequest();// 创建API对应的request
// 参数设置
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setBody("body");
model.setSubject("阿甘配送员押金");
// 请保证OutTradeNo值每次保证唯一
model.setOutTradeNo(authOrderid);
model.setTimeoutExpress("30m");
model.setTotalAmount("0.01");
model.setProductCode("QUICK_MSECURITY_PAY");
alipayRequest.setBizModel(model);
alipayRequest.setNotifyUrl("http://www.moxikilox.com:8081/api/payResult");
String result = "";
Map<String, Object> map = new HashMap<>();
map.put("orderid", authOrderid);
try {
AlipayTradeAppPayResponse sdkExecute = alipayClient.sdkExecute(alipayRequest);
result = sdkExecute.getBody();
map.put("orderinfo", result);
} catch (AlipayApiException e) {
e.printStackTrace();
}
return AjaxResult.success("操作成功", map);
}
10.异步回调操作,验证支付状态,以及支付金额,一定注意,异步回调地址(NotifyUrl)必须公网,我代码里是用花生壳做了内网映射请求到我电脑的,返回地址(ReturnUrl)支付宝标明必须公网,但是可以是局域网地址,只要返回的页面和你手机网络在同一局域网内就行!
/**
* 异步 交易验证
*/
@RequestMapping("/payResult")
public String payResult(HttpServletRequest request, HttpServletResponse response) {
// 1.从支付宝回调的request域中取值
// 获取支付宝返回的参数集合
Map<String, String[]> aliParams = request.getParameterMap();
// 用以存放转化后的参数集合
Map<String, String> conversionParams = new HashMap<String, String>();
for (Iterator<String> iter = aliParams.keySet().iterator(); iter.hasNext();) {
String key = iter.next();
String[] values = aliParams.get(key);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
}
// 乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
// valueStr = new String(valueStr.getBytes("ISO-8859-1"), "uft-8");
conversionParams.put(key, valueStr);
}
// 这一段是我自己的业务代码,可根据需求变更
AjaxResult ajaxResult = xpenseTrackerService.updatePayStatus(conversionParams);
if(ajaxResult.getStatus() == 200){
return "success";
}
return "fail";
}
注意:异步验证从request中取出了支付宝的请求参数,然后封装为map,支付宝回每隔一段时间就请求一次这个接口,直到返回success字符串才停止请求。