一、首先就是你需要申请网页版支付的功能,申请完网站之后,就可以申请支付功能了,app支付也差不多,没什么区别
1、登陆你的商家支付宝账号,进入,支付宝商家中心,选择接入电脑网站支付
![](https://img-blog.csdnimg.cn/20190303160436472.png)
2、然后点击立即接入
![](https://img-blog.csdnimg.cn/20190303160533456.png)
3、这一步是需要提交申请的,需要注意的是,网站上最少需要五个左右的明码标价的商品或者功能,如果没有是不可能通过审核的,之后就可以开始开发了
![](https://img-blog.csdnimg.cn/20190303160126182.png)
二、java开发
1、下载支付宝的 demo 支付宝网页支付demo
2、解压之后,先取出page.pay.jsp,这是最主要的一个页面,然后放到你的项目中,作为跳转页面存放
![](https://img-blog.csdnimg.cn/20190303161151342.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01yTGlfSVQ=,size_16,color_FFFFFF,t_70)
3、Controller层代码,主要是为了形成签名
/**
* 支付宝支付
*/
@ResponseBody
@RequestMapping("/order_alipay.do")
//memberSettled是我自己的对象,查出来支付宝所需的属性
public String alipayOrder(HttpServletRequest request, HttpServletResponse response, MemberSettled memberSettled, Model model){
String form = null;
try {
Map<String,Object> settledMap = goodsService.selectMemberSettledInfoBySetId(memberSettled);
Integer userId = getCurrentLoginId();
String order_code = userService.insertMemberSettledOrderInfo(memberSettled.getPayMode(),(Double) settledMap.get("pay_number"),
(String) settledMap.get("pay_detail"),userId);
//自己封装的方法
form = PayUtil.alipayH5PayResponse(order_code,(Double) settledMap.get("pay_number"),(String) settledMap.get("pay_detail"),
(String) settledMap.get("settled_time"),request,response);
response.setContentType("text/html;charset=" + Alipay.getCHARSET());
response.getWriter().write(form);//直接将完整的表单html输出到页面
response.getWriter().flush();
response.getWriter().close();
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return form.toString();
} |
4、进入支付宝网页支付API ,查看需要的请求或者参数
5、PayUtil.alipayH5PayResponse的内容
AlipayClient alipayClient = new DefaultAlipayClient(Alipay.getURL(), Alipay.getAppId(), Alipay.getAppPrivateKey(), "json",
Alipay.getCHARSET(), Alipay.getAlipayPublicKey(), Alipay.getSignType()); //获得初始化的AlipayClient
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();//创建API对应的request
alipayRequest.setReturnUrl("xxxx");
// alipayRequest.setReturnUrl("http://domain.com/CallBack/return_url.jsp");
alipayRequest.setNotifyUrl("xxxx");//在公共参数中设置回跳和通知地址
// alipayRequest.setNotifyUrl("http://domain.com/CallBack/notify_url.jsp");
//只是为了测试
// alipayRequest.setBizContent("{" +
// " \"out_trade_no\":" + out_trade_no +"," + //商户订单号,64个字符以内、可包含字母、数字、下划线;需保证在商户端不重复
// " \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," + //销售产品码,与支付宝签约的产品码名称。 注:目前仅支持FAST_INSTANT_TRADE_PAY
// " \"total_amount\":" + total_amount + "," + //订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000]
// " \"subject\":" + subject + "" + //订单标题
// " }");//填充业务参数
//正式代码,需要什么就添加什么
alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
+ "\"total_amount\":\""+ total_amount +"\","
+ "\"subject\":\""+ subject +"\","
+ "\"body\":\""+ body +"\","
+ "\"timeout_express\":\"10m\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
String form="";
try {
form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单
} catch (AlipayApiException e) {
e.printStackTrace();
}
return form; |
6、我自己的Alipay中的内容
/**
* 回调地址,必须是外网可以访问的到
*/
private static final String RESULT_URL = "xxxx";
/**
* 商家产品码(不知道啥玩意)一串数字
*/
private static final String SELL_ID = "xxxxx";
/**
* 支付宝网关(固定)
*/
private static final String URL = "https://openapi.alipay.com/gateway.do";
/**
* APPID即创建应用后生成,点击你的应用,复制APPID
*/
private static final String APP_ID = "xxxx";
/**
* 开发者应用私钥,由开发者自己生成
*/
private static final String APP_PRIVATE_KEY = "xxxxxxx";
/**
* 求和签名使用的字符编码格式,支持GBK和UTF-8 开发者根据实际工程编码配置
*/
private static final String CHARSET = "UTF-8";
/**
* 支付宝公钥,由支付宝生成
*/
private static final String ALIPAY_PUBLIC_KEY = "xxxxx";
/**
* 商户生成签名字符串所使用的签名算法类型,目前支持RSA2和RSA,推荐使用RSA2 RSA2
*/
private static final String SIGN_TYPE = "RSA2";
/**
* 参数返回格式,只支持json json(固定)
*/
private Map<String,Object> FORMAT;
private static final String RETURN_URL = "";
private static final String NOTIFY_URL = "";
public static String getSellId() {
return SELL_ID;
}
public static String getURL() {
return URL;
}
public static String getAppId() {
return APP_ID;
}
public static String getAppPrivateKey() {
return APP_PRIVATE_KEY;
}
public static String getCHARSET() {
return CHARSET;
}
public static String getAlipayPublicKey() {
return ALIPAY_PUBLIC_KEY;
}
public static String getSignType() {
return SIGN_TYPE;
}
public Map<String, Object> getFORMAT() {
return FORMAT;
}
public void setFORMAT(Map<String, Object> FORMAT) {
this.FORMAT = FORMAT;
}
public static String getResultUrl() {
return RESULT_URL;
}
public static String getReturnUrl() {
return RETURN_URL;
}
public static String getNotifyUrl() {
return NOTIFY_URL;
} |
7、到此为止,支付是已经没问题了,秘钥什么的我其他的博客中也有写过其实这些都不是特别的难,多看看demo以及api就行了
三、开始写回调
1、因为我的项目并不会需要特别复杂的回调页面,所以就简单的写一下,还记得上面有个notify.jsp,这个就是回调的意思
/**
* 后台管理系统支付宝支付成功通知接口
*/
@RequestMapping("/notify_url")
public String notifyAlipayInterface(HttpServletResponse response, AliReturnPayBean returnPay, HttpServletRequest request)
throws AlipayApiException, IOException {
//获取支付宝POST过来反馈信息
Map<String,String> params = new HashMap<String,String>();
Map<String,String[]> requestParams = request.getParameterMap();
for (Iterator<String> 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);
}
//这的AlipayConfig其实就是我上面的Alipay
boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.getAlipayPublicKey(), AlipayConfig.getCHARSET(), AlipayConfig.getSignType()); //调用SDK验证签名
if(signVerified){
// TODO 验签成功后,按照支付结果异步通知中的描述,对支付结果中的业务内容进行二次校验,
// TODO 校验成功后在response中返回success并继续商户自身业务处理,校验失败返回failure
// TODO 其中seller_id 是卖家支付宝用户号
//因为params中没有status这个参数,所以我就用自己封装的AliReturnPayBean来接收的部分参数,其实没有什么用,可以直接删除的
if(returnPay.getTrade_status() == null || "TRADE_SUCCESS".equals(returnPay.getTrade_status())
|| "TRADE_FINISHED".equals(returnPay.getTrade_status())){
//查找出来信息之后可以二次判断,我并没有做判断,你们可以判断价格以及数量,时间等等的信息,判断订单是否正确
// Map<String,Object> payOrderMap = cmsService.selectSettledPayOrderInfo(returnPay.getOut_trade_no());
int result = cmsService.updateSettledPayOrderStatusByTradeNo(returnPay.getOut_trade_no(),1,(String) params.get("trade_no"));
}else if("TRADE_FINISHED".equals(returnPay.getTrade_status())){
int result = cmsService.updateSettledPayOrderStatusByTradeNo(returnPay.getOut_trade_no(),2,null);
}
// response.getWriter().write("success");
}else{
// TODO 验签失败则记录异常日志,并在response中返回failure.
// response.getWriter().write("failure");
}
//这是我自己测试跳转用的页面
return "share";
} |
8、第一阶段结束 over over over