1、支付宝
1.1 集成阿里SDK
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.13.50.ALL</version>
</dependency>
1.2 封装工具类
application.yml
alipay:
app_id: 2016092100563791
merchant_private_key: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCqJHUhOmlseTto0KJN6WtSEeTFUNzuzUN3GGI7/IYdd61XeuWGfk+ppi6Pc3S83VEuBbtI8EkJzc+4MVOMpk+bxwNdeG6bp1y1/p8BOhVImzv21ON02nnZRtOgSEFcysJqnjA+lNf6RA/cOsfFiteOZVpyMmIcjWr3vp2aDbXv3yzOKXbz5pRB/bWCaHN83r7pNlGgEXKB4P+BeVBHiU4Kp1nYdebWX+no+fXxIzpBKGvwBAtsyOfbABBxOmYwFZhoI7HGxeBKmZHzyq7hrhr8AeKpaPlx0VrfUKdFyomB/0kXmkmnwBeTFrMyHdoK4ojIdG5H2goPKejGveYw2xplAgMBAAECggEBAIVDsQqpudFg04uxfq8P2SObKFj0kVfqJqGt06Owk0uZZYhTllvVq4fxxh5ODG2x29f0XVEwA8VOExjuacaMrWYSZyxbHCeG2zMhkGFhoTIRhNI8xTvNtArfUvsEHU4U8lqYNKmP4+r+TH3u/HJZ4aSC9mjj1b0Pd209PCxh+NM77BUU1bxWEdejsLjwFdeFE+B8zl1xiXDmD1eHZ3qjc+7oQdWxK4BbGTcrgXWcn5fIrsDdBD6vO602py+g/R04tlp8p4I49NOra2RpT+OZoZAAAv3s2O58dipDky/wwR4mNxNh4jXFqLpBQu45xisereIEzPKqSPiT3eMEEEhYtbECgYEA8ylRrdxUTiwGbokiBmdusVfE+GotplathTN8FGV7ueuDqjD5pHPPbYQSF1Ag3P8gbDwKOyPo/SXwjTrHrvPjwB64Q2+FvI+ttVPYOCVyu+ny37h5LOVTJZSAmicrsEkgLgIpg9Nca/aBwHxGKksenw3shEirCHr0T5KPDKRyIrcCgYEAsyAuKzF8TK4lW0xWQFxrjDGgWmBSKJko+82G0vu2VKdJlbEBfWe88YVWqS5f1lf+RW9+WKyuEtJVXtXGxnwZzxgxCBcNwRTUDENIUio9nqiQEFZBnSJmSV3qLTgikEuvs66uPw8PCTsQNFLfyJ7YjgWGLwWC2hEF/SbY/qF9n8MCgYA/u0+uKvZpur5A0G57kTaBAskcdu/aDhPSuqjFy8d+9kx/GfEEeloekSQQui6y3aeI1r+zunjBiOUgjwxxPXkvDJ4tBpjd0CauRPiB1sbYm7vNiVMxQjXlvqNqQ+P+g1wM0wJAi/BIV8awRaI6SZAQDh00mrtBMMDB7l7R6HQFxwKBgECdlin8ouMiWtVxVxfGfwFGkZqoblq4zUDwJfeL13z4D6JRBMGRH2ZcfCNxWB8BBPdVPdWNDQo7F5KrORY2hDThfCZ38n05HzkBOGBzXmESW02ZX/foBc/ncec3/bfhpZMCq1aR/xGMXc8SKim7q1CoC3yA13AEfg2Q6uwHo0JzAoGBAO5gr6+skCSQrVto1z6LXIVxu9yCcUhz37svyzKIkvtvuUKw9aUx56KYhlPQY++RuVvDjp91IIuN2u7JoVYPjTarS+CFvPagdqU0g+Hk/RfVsxQV+8Vxm0CABxGhHzm5402Fj1aMyXpfNoeW5GeJA/+hf0IG4nJb8QMwS0Smm1+g
alipay_public_key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqiR1ITppbHk7aNCiTelrUhHkxVDc7s1DdxhiO/yGHXetV3rlhn5PqaYuj3N0vN1RLgW7SPBJCc3PuDFTjKZPm8cDXXhum6dctf6fAToVSJs79tTjdNp52UbToEhBXMrCap4wPpTX+kQP3DrHxYrXjmVacjJiHI1q976dmg21798szil28+aUQf21gmhzfN6+6TZRoBFygeD/gXlQR4lOCqdZ2HXm1l/p6Pn18SM6QShr8AQLbMjn2wAQcTpmMBWYaCOxxsXgSpmR88qu4a4a/AHiqWj5cdFa31CnRcqJgf9JF5pJp8AXkxazMh3aCuKIyHRuR9oKDynoxr3mMNsaZQIDAQAB
notify_url: http://t8wfpevaon.52http.tech/order/pay/success
return_url: http://localhost:90/idea/member/order/list.html
sign_type: RSA2
charset: utf-8
format: json
gateway_url: https://openapi.alipaydev.com/gateway.do
order_ttl: 30m
AlipayProperties
@Data
@Component
@ConfigurationProperties(prefix = "alipay")
public class AlipayProperties {
//在支付宝创建的应用的id
private String app_id;
// 商户私钥,您的PKCS8格式RSA2私钥
private String merchant_private_key;
// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
private String alipay_public_key;
// 服务器[异步通知]页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
// 支付宝会悄悄的给我们发送一个请求,告诉我们支付成功的信息
private String notify_url;
// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
// 同步通知,支付成功,一般跳转到成功页
private String return_url;
// 签名方式
private String sign_type;
// 字符编码格式
private String charset;
private String format;
// 支付宝网关
private String gateway_url;
// 订单存活时间
private String order_ttl;
}
AlipayTemplate
@Slf4j
@Component
public class AlipayTemplate {
@Autowired
AlipayProperties properties;
public String pay(PayVO vo) throws AlipayApiException {
//1、根据支付宝的配置生成一个支付客户端
AlipayClient alipayClient = new DefaultAlipayClient(properties.getGateway_url(),
properties.getApp_id(),
properties.getMerchant_private_key(),
properties.getFormat(),
properties.getCharset(),
properties.getAlipay_public_key(),
properties.getSign_type());
//2、创建一个支付请求 //设置请求参数
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
alipayRequest.setReturnUrl(properties.getReturn_url());
alipayRequest.setNotifyUrl(properties.getNotify_url());
//商户订单号,商户网站订单系统中唯一订单号,必填
String out_trade_no = vo.getOutTradeNo();
//付款金额,必填
String total_amount = vo.getTotalAmount();
//订单名称,必填
String subject = vo.getSubject();
//商品描述,可空
String body = vo.getBody();
alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
+ "\"total_amount\":\""+ total_amount +"\","
+ "\"subject\":\""+ subject +"\","
+ "\"body\":\""+ body +"\","
+ "\"timeout_express\":\""+ properties.getOrder_ttl() +"\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
String result = alipayClient.pageExecute(alipayRequest).getBody();
//会收到支付宝的响应,响应的是一个页面,只要浏览器显示这个页面,就会自动来到支付宝的收银台页面
log.info("支付宝的响应:{}", result);
return result;
}
}
1.3 处理支付请求
@ResponseBody
@GetMapping(value = "/payOrder", produces = "text/html")
public String payOrder(@RequestParam("orderSn") String orderSn) throws Exception {
// 获取支付信息
PayVO payVO = orderService.getPayVO(orderSn);
// 返回一个页面,直接交给浏览器
return alipayTemplate.pay(payVO);
}
1.4 处理支付结果(支付宝最大努力通知方案)
PayAsyncVO
@ToString
@Data
public class PayAsyncVo {
private String gmt_create;
private String charset;
private String gmt_payment;
private Date notify_time;
private String subject;
private String sign;
private String buyer_id;//支付者的id
private String body;//订单的信息
private String invoice_amount;//支付金额
private String version;
private String notify_id;//通知id
private String fund_bill_list;
private String notify_type;//通知类型; trade_status_sync
private String out_trade_no;//订单号
private String total_amount;//支付的总额
private String trade_status;//交易状态 TRADE_SUCCESS
private String trade_no;//流水号
private String auth_app_id;//
private String receipt_amount;//商家收到的款
private String point_amount;//
private String app_id;//应用id
private String buyer_pay_amount;//最终支付的金额
private String sign_type;//签名类型
private String seller_id;//商家的id
}
@RestController
public class OrderPayedListener {
@Autowired
AlipayProperties properties;
@Autowired
OrderService orderService;
@RequestMapping("/order/pay/success")
public String handlePaySuccess(PayAsyncVo vo, HttpServletRequest request) throws Exception {
// 验签
Map<String,String> params = new HashMap<>();
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);
}
//调用SDK验证签名
boolean signVerified = AlipaySignature.rsaCheckV1(params, properties.getAlipay_public_key(), properties.getCharset(), properties.getSign_type());
if (signVerified) {
// 处理支付宝支付结果
orderService.handlePayResult(vo);
} else {
return "error";
}
return "success";
}
}
1.5 收单
1、订单在支付页不支付,一直刷新,订单过期了才支付,订单状态改为已支付,但是库存解锁了。
使用支付宝自动收单功能。只要一段时间不支付,就不能支付了。
2、由于时延等问题。订单解锁完成,正在解锁库存的时候,异步通知才到。
订单解锁,手动调用收单
3、网络阻塞问题,订单支付成功的异步通知一直不到达
查询订单列表时,ajax获取当前未支付的订单状态,查询订单状态时,再获取一下支付宝订单状态
4、其它各种问题
每天晚上闲时下载支付宝账单,一一进行对账。