springMVC实现的沙箱环境下的支付宝支付的功能,是沙箱环境下的,这里只演示电脑上的扫码支付。没事就玩玩嘛
本文参考了支付宝官方文档:https://docs.open.alipay.com/catalog
首先先进入支付宝的开放平台,点击“开放平台-开发者中心-沙箱环境”。进入沙箱环境页面。
第一次使用需要先进行申请,然后获取到APPID,有这个才能调用支付宝开放产品的接口。
申请的话。我这里就不说了。这个不会的话就评论找我吧。
一:准备环境
首先你需要下载支付宝的SDK,我这里推荐使用maven来下载(官方也推荐)
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.0.0</version>
</dependency>
这里废话一句,推荐使用maven的时候配置一下阿里的镜像。下载jar包的时候会快一些。
然后你可以阅读一下下面的流程,请参考下面链接生成RSA密钥
https://docs.open.alipay.com/291/105971
然后配置好公钥后会在页面会自动的给你生成好下面的图片上的代码,这个非常有用。红色那块东西写着是要你去复制上一步中生成的密钥中的商户应用私钥。
这里注意一下:如果你配置公钥后再重新生成了一次公钥,请重新配置,不然在你跑接口的时候会报错的。
上面图片这个地方找不到就打开下面这个链接吧:
https://openhome.alipay.com/platform/appDaily.htm
在刚才的开发平台页面下面去下载沙箱环境的支付宝APP(安卓版的)
二:具体实现
当你做完上面的工作后,可以直接进行开发了。你可以进行分层的开发,我这边就全部写在Controller层上了。
在测试的时候你直接在浏览器发起get请求来访问这个方法,支付个1000W尝试一下支付的快感吧!!!
不要直接粘贴下面的代码直接运行
记得替换下面我标注的地方!
记得替换下面我标注的地方!
记得替换下面我标注的地方!
重要的事情要多讲
@RequestMapping("/ailpay")
public void 方法名(HttpServletRequest request, HttpServletResponse response)
throws IOException {
AlipayClient alipayClient = new
DefaultAlipayClient("https://openapi.alipaydev.com/gateway.do",
"你的APPID",
"生成的密钥中的商户应用私钥",
"json","utf-8",
"公钥",
"RSA2" );
//上面这个方法是不是很眼熟?就是刚才配置完公钥后生成的那段,你可以直接复制然后加上你的私钥就好
String out_trade_no = "订单号";
out_trade_no = URLDecoder.decode(out_trade_no,"UTF-8");
String total_amount = "总金额";
total_amount = URLDecoder.decode(total_amount,"UTF-8");
String subject = "商品名称";
subject = URLDecoder.decode(subject,"UTF-8");
String body = "商品描述";
body = URLDecoder.decode(body,"UTF-8");
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();//创建API对应的request
alipayRequest.setReturnUrl("回调接口");
alipayRequest.setBizContent("{" +
" \"out_trade_no\":\""+ out_trade_no +"\"," +
" \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," +
" \"total_amount\":"+ total_amount +"," +
" \"subject\":\""+ subject +"\"," +
" \"body\":\""+ body +"\"" +
" }"+
" }");//填充业务参数
String form="";
try {
form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单
} catch (AlipayApiException e) {
e.printStackTrace();
}
response.setContentType("text/html;charset=utf-8");
response.getWriter().println(form);//直接将完整的表单html输出到页面
response.getWriter().close();
}
这边我没有把全部的参数都加上,你们可以参考一下下面的参数(我复制了支付宝官方给出的公共的请求参数):
公共参数
请求地址
环境 | HTTPS请求地址 |
---|---|
正式环境 | https://openapi.alipay.com/gateway.do |
公共请求参数
参数 | 类型 | 是否必填 | 最大长度 | 描述 | 示例值 |
---|---|---|---|---|---|
app_id | String | 是 | 32 | 支付宝分配给开发者的应用ID | 2014072300007148 |
method | String | 是 | 128 | 接口名称 | alipay.trade.pay |
format | String | 否 | 40 | 仅支持JSON | JSON |
charset | String | 是 | 10 | 请求使用的编码格式,如utf-8,gbk,gb2312等 | utf-8 |
sign_type | String | 是 | 10 | 商户生成签名字符串所使用的签名算法类型,目前支持RSA2和RSA,推荐使用RSA2 | RSA2 |
sign | String | 是 | 344 | 商户请求参数的签名串,详见签名 | 详见示例 |
timestamp | String | 是 | 19 | 发送请求的时间,格式"yyyy-MM-dd HH:mm:ss" | 2014-07-24 03:07:50 |
version | String | 是 | 3 | 调用的接口版本,固定为:1.0 | 1.0 |
notify_url | String | 否 | 256 | 支付宝服务器主动通知商户服务器里指定的页面http/https路径。 | http://api.test.alipay.net/atinterface/receive_notify.htm |
app_auth_token | String | 否 | 40 | 详见应用授权概述 | |
biz_content | String | 是 | 请求参数的集合,最大长度不限,除公共参数外所有请求参数都必须放在这个参数中传递,具体参照各产品快速接入文档 |
请求参数
参数 | 类型 | 是否必填 | 最大长度 | 描述 | 示例值 |
---|---|---|---|---|---|
out_trade_no | String | 必选 | 64 | 商户订单号,64个字符以内、可包含字母、数字、下划线;需保证在商户端不重复 | 20150320010101001 |
scene | String | 必选 | 32 | 支付场景 条码支付,取值:bar_code 声波支付,取值:wave_code | bar_code |
auth_code | String | 必选 | 32 | 支付授权码,25~30开头的长度为16~24位的数字,实际字符串长度以开发者获取的付款码长度为准 | 28763443825664394 |
product_code | String | 可选 | 32 | 销售产品码 | FACE_TO_FACE_PAYMENT |
subject | String | 必选 | 256 | 订单标题 | Iphone6 16G |
buyer_id | String | 可选 | 28 | 买家的支付宝用户id,如果为空,会从传入了码值信息中获取买家ID | 2088202954065786 |
seller_id | String | 可选 | 28 | 如果该值为空,则默认为商户签约账号对应的支付宝用户ID | 2088102146225135 |
total_amount | Price | 可选 | 11 | 订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000] 如果同时传入【可打折金额】和【不可打折金额】,该参数可以不用传入; 如果同时传入了【可打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【可打折金额】+【不可打折金额】 | 88.88 |
trans_currency | String | 可选 | 8 | 标价币种, total_amount 对应的币种单位。支持英镑:GBP、港币:HKD、美元:USD、新加坡元:SGD、日元:JPY、加拿大元:CAD、澳元:AUD、欧元:EUR、新西兰元:NZD、韩元:KRW、泰铢:THB、瑞士法郎:CHF、瑞典克朗:SEK、丹麦克朗:DKK、挪威克朗:NOK、马来西亚林吉特:MYR、印尼卢比:IDR、菲律宾比索:PHP、毛里求斯卢比:MUR、以色列新谢克尔:ILS、斯里兰卡卢比:LKR、俄罗斯卢布:RUB、阿联酋迪拉姆:AED、捷克克朗:CZK、南非兰特:ZAR、人民币:CNY | USD |
settle_currency | String | 可选 | 8 | 商户指定的结算币种,支持英镑:GBP、港币:HKD、美元:USD、新加坡元:SGD、日元:JPY、加拿大元:CAD、澳元:AUD、欧元:EUR、新西兰元:NZD、韩元:KRW、泰铢:THB、瑞士法郎:CHF、瑞典克朗:SEK、丹麦克朗:DKK、挪威克朗:NOK、马来西亚林吉特:MYR、印尼卢比:IDR、菲律宾比索:PHP、毛里求斯卢比:MUR、以色列新谢克尔:ILS、斯里兰卡卢比:LKR、俄罗斯卢布:RUB、阿联酋迪拉姆:AED、捷克克朗:CZK、南非兰特:ZAR、人民币:CNY | USD |
discountable_amount | Price | 可选 | 11 | 参与优惠计算的金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000]。 如果该值未传入,但传入了【订单总金额】和【不可打折金额】,则该值默认为【订单总金额】-【不可打折金额】 | 8.88 |
body | String | 可选 | 128 | 订单描述 | Iphone6 16G |
goods_detail | GoodsDetail[] | 可选 | 订单包含的商品列表信息,json格式,其它说明详见商品明细说明 | ||
operator_id | String | 可选 | 28 | 商户操作员编号 | yx_001 |
store_id | String | 可选 | 32 | 商户门店编号 | NJ_001 |
terminal_id | String | 可选 | 32 | 商户机具终端编号 | NJ_T_001 |
extend_params | ExtendParams | 可选 | 业务扩展参数 | ||
timeout_express | String | 可选 | 6 | 该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。 该参数数值不接受小数点, 如 1.5h,可转换为 90m | 90m |
auth_confirm_mode | String | 可选 | 32 | 预授权确认模式,授权转交易请求中传入,适用于预授权转交易业务使用,目前只支持PRE_AUTH(预授权产品码) COMPLETE:转交易支付完成结束预授权,解冻剩余金额; NOT_COMPLETE:转交易支付完成不结束预授权,不解冻剩余金额 | COMPLETE:转交易支付完成结束预授权;NOT_COMPLETE:转交易支付完成不结束预授权 |
terminal_params | String | 可选 | 2048 | 商户传入终端设备相关信息,具体值要和支付宝约定 | {"key":"value"} |
你可以按照业务的需求来对请求参数进行设置,下面展示一下回调的响应参数
公共响应参数
参数 | 类型 | 是否必填 | 最大长度 | 描述 | 示例值 |
---|---|---|---|---|---|
code | String | 是 | - | 网关返回码,详见文档 | 40004 |
msg | String | 是 | - | 网关返回码描述,详见文档 | Business Failed |
sub_code | String | 否 | - | 业务返回码,参见具体的API接口文档 | ACQ.TRADE_HAS_SUCCESS |
sub_msg | String | 否 | - | 业务返回码描述,参见具体的API接口文档 | 交易已被支付 |
sign | String | 是 | - | 签名,详见文档 | DZXh8eeTuAHoYE3w1J+POiPhfDxOYBfUNn1lkeT/V7P4zJdyojWEa6IZs6Hz0yDW5Cp/viufUb5I0/V5WENS3OYR8zRedqo6D+fUTdLHdc+EFyCkiQhBxIzgngPdPdfp1PIS7BdhhzrsZHbRqb7o4k3Dxc+AAnFauu4V6Zdwczo= |
响应参数
参数 | 类型 | 是否必填 | 最大长度 | 描述 | 示例值 |
---|---|---|---|---|---|
trade_no | String | 必填 | 64 | 支付宝交易号 | 2013112011001004330000121536 |
out_trade_no | String | 必填 | 64 | 商户订单号 | 6823789339978248 |
buyer_logon_id | String | 必填 | 100 | 买家支付宝账号 | 159****5620 |
total_amount | Price | 必填 | 11 | 交易金额 | 120.88 |
trans_currency | String | 选填 | 5 | 标价币种, total_amount对应的币种单位。目前支持英镑:GBP、港币:HKD、美元:USD、新加坡元:SGD、日元:JPY、加拿大元:CAD、澳元:AUD、欧元:EUR、新西兰元:NZD、韩元:KRW、泰铢:THB、瑞士法郎:CHF、瑞典克朗:SEK、丹麦克朗:DKK、挪威克朗:NOK、马来西亚林吉特:MYR、印尼卢比:IDR、菲律宾比索:PHP、毛里求斯卢比:MUR、以色列新谢克尔:ILS、斯里兰卡卢比:LKR、俄罗斯卢布:RUB、阿联酋迪拉姆:AED、捷克克朗:CZK、南非兰特:ZAR、人民币:CNY | USD |
settle_currency | String | 选填 | 8 | 商户指定的结算币种,目前支持英镑:GBP、港币:HKD、美元:USD、新加坡元:SGD、日元:JPY、加拿大元:CAD、澳元:AUD、欧元:EUR、新西兰元:NZD、韩元:KRW、泰铢:THB、瑞士法郎:CHF、瑞典克朗:SEK、丹麦克朗:DKK、挪威克朗:NOK、马来西亚林吉特:MYR、印尼卢比:IDR、菲律宾比索:PHP、毛里求斯卢比:MUR、以色列新谢克尔:ILS、斯里兰卡卢比:LKR、俄罗斯卢布:RUB、阿联酋迪拉姆:AED、捷克克朗:CZK、南非兰特:ZAR、人民币:CNY | USD |
settle_amount | String | 选填 | 11 | 结算币种订单金额 | 88.88 |
pay_currency | String | 选填 | 8 | 支付币种 | CNY |
pay_amount | String | 选填 | 11 | 支付币种订单金额 | 580.04 |
settle_trans_rate | String | 选填 | 32 | 结算币种兑换标价币种汇率 | 1 |
trans_pay_rate | String | 选填 | 32 | 标价币种兑换支付币种汇率 | 6.5261 |
receipt_amount | String | 必填 | 11 | 实收金额 | 88.88 |
buyer_pay_amount | Price | 选填 | 11 | 买家付款的金额 | 8.88 |
point_amount | Price | 选填 | 11 | 使用集分宝付款的金额 | 8.12 |
invoice_amount | Price | 选填 | 11 | 交易中可给用户开具发票的金额 | 12.50 |
gmt_payment | Date | 必填 | 32 | 交易支付时间 | 2014-11-27 15:45:57 |
fund_bill_list | TradeFundBill | 必填 | 交易支付使用的资金渠道 | ||
card_balance | Price | 选填 | 11 | 支付宝卡余额 | 98.23 |
store_name | String | 选填 | 512 | 发生支付交易的商户门店名称 | 证大五道口店 |
buyer_user_id | String | 必填 | 28 | 买家在支付宝的用户id | 2088101117955611 |
discount_goods_detail | String | 选填 | 1024 | 本次交易支付所使用的单品券优惠的商品优惠信息 | [{"goods_id":"STANDARD1026181538","goods_name":"雪碧","discount_amount":"100.00","voucher_id":"2015102600073002039000002D5O"}] |
voucher_detail_list | VoucherDetail | 选填 | 本交易支付时使用的所有优惠券信息 | ||
auth_trade_pay_mode | String | 选填 | 64 | 预授权支付模式,该参数仅在信用预授权支付场景下返回。信用预授权支付:CREDIT_PREAUTH_PAY | CREDIT_PREAUTH_PAY |
business_params | String | 选填 | 512 | 商户传入业务信息,具体值要和支付宝约定 将商户传入信息分发给相应系统,应用于安全,营销等参数直传场景 格式为json格式 | {"data":"123"} |
buyer_user_type | String | 选填 | 18 | 买家用户类型。CORPORATE:企业用户;PRIVATE:个人用户。 | PRIVATE |
mdiscount_amount | String | 选填 | 11 | 商家优惠金额 | 88.88 |
discount_amount | String | 选填 | 11 | 平台优惠金额 | 88.88 |
可以参考一下我写的回调接口:
@RequestMapping("success")
public ModelAndView success(String out_trade_no,Double total_amount){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("success");
modelAndView.addObject("money",total_amount);
modelAndView.addObject("no",out_trade_no);
return modelAndView;
}
好了,本文就到这了。赶紧玩起来吧~~~