支付宝Wap支付你了解多少?

简介: 此项目已开源欢迎Start、PR、发起Issues一起讨论交流共同进步 https://github.

此项目已开源欢迎Start、PR、发起Issues一起讨论交流共同进步
https://github.com/Javen205/IJPay
http://git.oschina.net/javen205/IJPay

上几篇文章详细介绍了支付宝APP支付微信APP支付

此文章来介绍下支付宝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密钥工具截图

Mac 生成RSA密钥工具.png

生成密钥.png

工具生成一对RSA密钥之后将公钥配置到应用环境。
生成的私钥需妥善保管,避免遗失,不要泄露。应用私钥需填写到代码中供签名时使用。应用公钥需提供给支付宝账号管理者上传到支付宝开放平台。

上传支付宝公钥.png

3、配置沙箱环境

注意:沙箱环境的密钥最好与正式上线的应用进行区分避免一些不必要的麻烦。WAP支付支持沙箱环境而app支付不支持沙箱环境

官方介绍质料-箱环境使用说明

上传对应的公钥,沙箱账号待会在测试的时候回使用到

沙箱环境配置.png

沙箱工具.png

4、服务端实现(集成并配置SDK)

官方资源下载地址

服务端SDK下载与简介

服务端SDK下载

服务端SDK

SDK包说明

Maven项目中使用本地JAR包

1、首先我在项目根目录中创建一个lib文件夹,将jar包拷贝到lib文件夹下

添加jar包

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

加载接入参数并初始化<code>AlipayClient</code>

使用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

测试截图

wap支付页面

输入支付账号以及密码

确认付款

输入支付密码

支付成功

回跳页面

推荐阅读
Android版-微信APP支付
极速开发微信公众号之微信买单
极速开发微信公众号之公众号支付
极速开发微信公众号之扫码支付
极速开发微信公众号之刷卡支付
极速开发微信公众号之现金红包
Android版-支付宝APP支付

记录学习的点滴,以此勉励不断奋斗的自己️️️ 如果对你有帮助记得点喜欢

源码下载地址

目录
相关文章
|
XML 移动开发 API
微信支付开发(7) H5支付
关键字:微信支付 微信支付v3 H5支付 wap支付 prepay_id 作者:方倍工作室原文: http://www.cnblogs.com/txw1958/p/wxpayv3_h5.html    本文介绍微信支付下的H5支付实现流程。
3402 1
|
XML 移动开发 小程序
抖音小程序开发 唤起收银台支付(可以选择支付宝APP支付或微信H5支付)
字节跳动也开放了小程序给商家接入,可以在旗下APP如抖音、今日头条、今日头条极速版等应用中即点即用,基于庞大的数亿用户量为其引流,帮助商家获取用户流量,销售商品,其模式和微信小程序差不多。
1917 0
抖音小程序开发 唤起收银台支付(可以选择支付宝APP支付或微信H5支付)
|
6月前
|
消息中间件 Java 测试技术
支付宝支付
支付宝支付
163 1
|
移动开发 安全 前端开发
〔支付接入〕微信的 h5 支付和 jsapi 支付
学会微信支付,打开你的财富之门
305 2
〔支付接入〕微信的 h5 支付和 jsapi 支付
|
XML 存储 安全
微信支付宝支付真的安全吗?为什么没人攻击
微信支付宝支付真的安全吗?为什么没人攻击
|
Java 数据安全/隐私保护
支付宝支付功能使用
支付宝支付功能使用
|
测试技术 开发工具
支付宝支付-PC电脑网站支付
支付产品全面升级(更新时间:2017/05/05 ),若您使用的是老接口,请移步老版本即时到账文档。
3064 0
|
机器学习/深度学习
关于支付宝/微信免签实现个人支付
最近一直在了解关于个人支付的问题。由于之前一直想实现个人支付,但是目前微信和支付宝的支付接口都需要企业或个体户资质,导致没办法实现,无奈只能走向这个道路。 说是免签,实际上就是拿到收款金额来做些事情。
关于支付宝/微信免签实现个人支付
如何在微信中使用支付宝手机网站支付
目前微信已经拦截了所有在微信内调用支付宝支付的途径,故无法直接唤起支付宝。 但您可以借助点击右上角的通过浏览器打开的方式,来试着打开支付宝。  更多详见“快速接入”部分的微信公众平台无法使用支付宝收付款的解决方案。
832 12