开通支付宝沙箱环境
https://sandbox.alipaydev.com/user/accountDetails.html
开通完毕后各种公钥、私钥、appid等内容都在里面了,而后就是进行配置
注意:公钥使用的是支付宝公钥,不是应用公钥,应用公钥只是在验签的时候和私钥匹配的!
回调内容可以选择异步回调和同步回调,一般项目下使用异步回调,然后前端进行轮询查找订单状态,或者后台使用socket进行查询。
异步通知回调:url中不能有参数,必须是公网可访问,使用post请求。写法和同步回调差不多。
我这里使用的是springboot
直接上代码
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.springboot.entity.OrderItem;
import com.springboot.service.OrderItemService;
import com.springboot.service.OrderService;
/**
* 支付宝支付Controller
*
*/
@RestController
@RequestMapping("/alipay")
public class AlipayController {
// 获取配置文件的信息
// 用户APPid
@Value("${alipay.appId}")
String app_id;
// 私钥
@Value("${alipay.merchantPrivateKey}")
String private_key;
// 同步返回地址
@Value("${alipay.notifyUrl}")
String notify_url;
// 异步返回地址
@Value("${alipay.returnUrl}")
String return_url;
// 支付网端
@Value("${alipay.gatewayUrl}")
String url;
// 编码格式
@Value("${alipay.charset}")
String charset;
// 传输格式
@Value("${alipay.format}")
String format;
// 公钥
@Value("${alipay.alipayPublicKey}")
String public_key;
// 签名方式
@Value("${alipay.signType}")
String signtype;
// 支付成功地址
@Value("${pay_s_url}")
String pay_success;
// 支付失败地址
@Value("${pay_f_url}")
String pay_failure;
@Autowired
private OrderService orderService;
@Autowired
private OrderItemService orderItemService;
/**
* 支付请求
*
* @param request
* @param response
* @throws Exception
*/
@RequestMapping(value = "/pay", method = RequestMethod.GET)
public void pay(HttpServletRequest request, HttpServletResponse response) throws Exception {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
String orderNo = request.getParameter("orderId"); // 获取订单号
String totalAmount = request.getParameter("payment"); // 支付总金额
String subject = request.getParameter("subject"); // 订单名称
String body = "reading"; // 商品描述
// 获得初始化的AlipayClient
AlipayClient alipayClient = new DefaultAlipayClient(url, app_id, private_key, format, charset, public_key,
signtype);
// 设置请求参数
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
alipayRequest.setReturnUrl(return_url);
alipayRequest.setNotifyUrl(notify_url);
alipayRequest.setBizContent("{\"out_trade_no\":\"" + orderNo + "\"," + "\"total_amount\":\"" + totalAmount
+ "\"," + "\"subject\":\"" + subject + "\"," + "\"body\":\"" + body + "\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
// 请求
String result = alipayClient.pageExecute(alipayRequest).getBody();
// 输出
response.getWriter().println(result);
}
/**
* 支付宝服务器异步通知
*
* @param request
* @throws Exception
*/
@RequestMapping("/notifyUrl")
public void notifyUrl(HttpServletRequest request,HttpServletResponse response) throws Exception {
// 获取支付宝GET过来反馈信息
Map<String, String> params = new HashMap<String, String>();
Map<String, String[]> requestParams = request.getParameterMap();
Map<String, Object> map = new HashMap<>();
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);
params.put(name, valueStr);
}
boolean signVerified = AlipaySignature.rsaCheckV1(params, public_key, charset, signtype); // 调用SDK验证签名
if (signVerified) { // 验证成功 更新订单信息
System.out.println("异步通知成功");
// 商户订单号
String out_trade_no = request.getParameter("out_trade_no");
// 修改数据库
map.put("status", "1"); // 未发货状态
orderService.update(map);
Map<String, Object> orderMap = new HashMap<>();
orderMap.put("orderId", out_trade_no);
List<OrderItem> orderItemList = orderItemService.findList(orderMap);
// 支付成功时修改订单状态
for (OrderItem orderItem : orderItemList) {
orderItem.setStatus("1");
// 更新订单详情状态
orderItemService.update(orderItem);
}
} else {
System.out.println("异步通知失败");
}
}
}