此项目已开源欢迎Start、PR、发起Issues一起讨论交流共同进步
https://github.com/Javen205/IJPay
http://git.oschina.net/javen205/IJPay
此文章来介绍下支付宝Wap支付(也叫作手机网站支付)
目录
1、创建应用并获取APPID
2、配置应用环境
3、配置沙箱环境
4、服务端实现(Maven添加本地Jar包、集成并配置SDK)
先上官方文档入口,支付宝文档入口模仿微信最最近做了更新,变得更简洁明了。
1、创建应用并获取APPID
这个比较简单可以参考《开放平台应用创建指南》
2、配置应用环境
开发者调用接口前需要先生成RSA密钥,RSA密钥包含应用私钥(APP_PRIVATE_KEY)、应用公钥(APP_PUBLIC_KEY)。生成密钥后在开放平台管理中心进行密钥配置,配置完成后可以获取支付宝公钥(ALIPAY_PUBLIC_KEY)。详细步骤请参考《配置应用环境》。
为了方便开发者生成一对RSA密钥支付宝提供一键生成工具,具体如何生成与配置密钥详见签名专区。 WINDOWS MAC_OSX
下载该工具后,解压打开文件夹,运行“RSA签名验签工具.bat”(WINDOWS)或“RSA签名验签工具.command”(MAC_OSX)。
以下演示截图
Window 配置应用环境生成相关Key截图参考上篇文档支付宝APP支付
以下是Mac电脑生成RSA密钥工具截图
工具生成一对RSA密钥之后将公钥配置到应用环境。
生成的私钥需妥善保管,避免遗失,不要泄露。应用私钥需填写到代码中供签名时使用。应用公钥需提供给支付宝账号管理者上传到支付宝开放平台。
3、配置沙箱环境
注意:沙箱环境的密钥最好与正式上线的应用进行区分避免一些不必要的麻烦。WAP支付支持沙箱环境而app支付不支持沙箱环境
上传对应的公钥,沙箱账号待会在测试的时候回使用到
4、服务端实现(集成并配置SDK)
【官方资源下载地址】
服务端SDK下载与简介
Maven项目中使用本地JAR包
1、首先我在项目根目录中创建一个lib文件夹,将jar包拷贝到lib文件夹下
2、然后我们在maven的pom.xml中配置
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>20161129201425</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/alipay-sdk-java20161129201425.jar</systemPath>
</dependency>
3、这里的groupId和artifactId以及version都是可以随便填写的 ,scope必须填写为system,而systemPath我们现在我们jar包的地址就可以了
4、最后我们必须在maven打包的过程中加入我们这个jar包。因为项目运行的时候需要这个Jar,并且我们得拷贝在WEB-INF/lib目录下
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webResources>
<resource>
<directory>${project.basedir}/lib</directory>
<targetPath>WEB-INF/lib</targetPath>
<filtering>false</filtering>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
</webResources>
</configuration>
<version>2.1.1</version>
集成
在使用SDK调用具体API前,需要先配置通用接入参数
1、
APP_ID
使用沙箱模式中的APP_ID
.
2、APP_PRIVATE_KEY
ALIPAY_PUBLIC_KEY
使用文章2、配置应用环境
中生成的测试密钥.
3、CHARSET
默认使用UTF-8
然后,使用上述接入参数初始化AlipayClient:
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",APP_ID,APP_PRIVATE_KEY,"json",CHARSET,ALIPAY_PUBLIC_KEY);
接下来,就可以用alipayClient来调用具体的API了。alipayClient只需要初始化一次,后续调用不同的API都可以使用同一个alipayClient对象。
手机网站支付不支持第三方授权,不能代商家发起请求。
调用接口
手机网站支付产品包含两类API:
页面跳转类:需要从前端页面以Form表单的形式发起请求,浏览器会自动跳转至支付宝的相关页面(一般是收银台或签约页面),用户在该页面完成相关业务操作后再回跳到商户指定页面。例如本产品中的手机网站支付接口alipay.trade.wap.pay。系统调用类:直接从服务端发起HTTP请求,支付宝会同步返回请求结果。例如本产品中的交易查询等配套API。
调用流程图
使用SDK快速接入
手机网站支付alipay.trade.wap.pay:
对于页面跳转类API,SDK不会也无法像系统调用类API一样自动请求支付宝并获得结果,而是在接受request请求对象后,为开发者生成前台页面请求需要的完整form表单的html(包含自动提交脚本),商户直接将这个表单的String输出到http response中即可。
public void doPost(HttpServletRequest httpRequest,
HttpServletResponse httpResponse) throws ServletException, IOException {
AlipayClient alipayClient = ... //获得初始化的AlipayClient
AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();//创建API对应的request
alipayRequest.setReturnUrl("http://domain.com/CallBack/return_url.jsp");
alipayRequest.setNotifyUrl("http://domain.com/CallBack/notify_url.jsp");//在公共参数中设置回跳和通知地址
alipayRequest.setBizContent("{" +
" \"out_trade_no\":\"20150320010101002\"," +
" \"total_amount\":88.88," +
" \"subject\":\"Iphone6 16G\"," +
" \"seller_id\":\"2088123456789012\"," +
" \"product_code\":\"QUICK_WAP_PAY\"" +
" }");//填充业务参数
String form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单
httpResponse.setContentType("text/html;charset=" + AlipayServiceEnvConstants.CHARSET);
httpResponse.getWriter().write(form);//直接将完整的表单html输出到页面
httpResponse.getWriter().flush();
}
异步通知验签
Map paramsMap = ... //将异步通知中收到的所有参数都存放到map中
boolean signVerified = AlipaySignature.rsaCheckV1(paramsMap, ALIPAY_PUBLIC_KEY, CHARSET) //调用SDK验证签名
if(signVerfied){
// TODO 验签成功后,按照支付结果异步通知中的描述,对支付结果中的业务内容进行二次校验,校验成功后在response中返回success并继续商户自身业务处理,校验失败返回failure
}else{
// TODO 验签失败则记录异常日志,并在response中返回failure.
}
服务端具体封装
将参数独立配置在一个属性文件中方便管理,当然也可以从数据库
加载接入参数并初始化
AlipayClient
使用SDK快速接入代码封装
public void wapPay(){
String body="我是测试数据";
String subject="Iphone6 16G";
String total_amount="0.01";
String passback_params="1";
BizContent content = new BizContent();
content.setBody(body);
content.setOut_trade_no(OrderInfoUtil2_0.getOutTradeNo());;
content.setPassback_params(passback_params);
content.setSubject(subject);
content.setTotal_amount(total_amount);
content.setProduct_code("QUICK_WAP_PAY");
try {
AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();//创建API对应的request
alipayRequest.setReturnUrl("http://javen.tunnel.qydev.com/alipay/return_url");
alipayRequest.setNotifyUrl("http://javen.tunnel.qydev.com/alipay/notify_url");//在公共参数中设置回跳和通知地址
//参数参考 https://doc.open.alipay.com/doc2/detail.htm?treeId=203&articleId=105463&docType=1#s0
System.out.println(JsonKit.toJson(content));
alipayRequest.setBizContent(JsonKit.toJson(content));//填充业务参数
String form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单
HttpServletResponse httpResponse = getResponse();
httpResponse.setContentType("text/html;charset=" + charset);
httpResponse.getWriter().write(form);//直接将完整的表单html输出到页面
httpResponse.getWriter().flush();
} catch (Exception e) {
e.printStackTrace();
}
renderNull();
}
public void return_url() {
try {
// 获取支付宝GET过来反馈信息
Map<String, String> map = AliPayApi.toMap(getRequest());
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
boolean verify_result = AlipaySignature.rsaCheckV1(map, AliPayApi.ALIPAY_PUBLIC_KEY, AliPayApi.CHARSET,
AliPayApi.SIGN_TYPE);
if (verify_result) {
// 验证成功
// TODO 请在这里加上商户的业务逻辑程序代码
System.out.println("return_url 验证成功");
renderText("success");
return;
} else {
System.out.println("return_url 验证失败");
// TODO
renderText("failure");
return;
}
} catch (AlipayApiException e) {
e.printStackTrace();
renderText("failure");
}
}
public void notify_url() {
try {
// 获取支付宝POST过来反馈信息
Map params = AliPayApi.toMap(getRequest());
for (Map.Entry entry : params.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
boolean verify_result = AlipaySignature.rsaCheckV1(params, AliPayApi.ALIPAY_PUBLIC_KEY, AliPayApi.CHARSET,
AliPayApi.SIGN_TYPE);
if (verify_result) {
// 验证成功
// TODO 请在这里加上商户的业务逻辑程序代码
System.out.println("notify_url 验证成功succcess");
renderText("success");
return;
} else {
System.out.println("notify_url 验证失败");
// TODO
renderText("failure");
return;
}
} catch (AlipayApiException e) {
e.printStackTrace();
renderText("failure");
}
}
/**
* 将异步通知的参数转化为Map
* @param request
* @return
*/
public static Map toMap(HttpServletRequest request) {
Map params = new HashMap();
Map requestParams = request.getParameterMap();
for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String[] values = (String[]) requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
}
// 乱码解决,这段代码在出现乱码时使用。
// valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
}
return params;
}
此项目源码【下载地址】
测试
下载部署如果没有做任何修改默认的分别为:
测试地址:http://域名或者IP/alipay/wapPay
回跳地址:http://域名或者IP/alipay/return_url
通知地址:http://域名或者IP/alipay/notify_url
测试截图
推荐阅读
Android版-微信APP支付
极速开发微信公众号之微信买单
极速开发微信公众号之公众号支付
极速开发微信公众号之扫码支付
极速开发微信公众号之刷卡支付
极速开发微信公众号之现金红包
Android版-支付宝APP支付
记录学习的点滴,以此勉励不断奋斗的自己️️️ 如果对你有帮助记得点喜欢