最近公司需要做一个在微信公众号中实现支付宝支付的项目
网上找了很多资料和问了好久的支付宝客服
终于整理出一份跑的通的项目
注意:微信支付和支付宝支付需要公司资质
微信公众号中使用微信支付是JSAPI进行支付,使用支付宝支付是跳转到浏览器在使用支付宝网站进行支付
第一次写博客可能不是很会写,有需要源码的朋友加微信:15733171104
百度网盘地址:
链接:https://pan.baidu.com/s/1oXUM0wBJtu5QYnri26vmZQ
提取码:i72h
话不多说,上代码:
先看下项目结构:

pom导入依赖:
<dependencies>
<!--支付-->
<dependency>
<groupId>cn.springboot</groupId>
<artifactId>best-pay-sdk</artifactId>
<version>1.3.3</version>
</dependency>
<!--微信授权-->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>3.7.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies> |
application.yml:
############微信公众号支付配置############
wechat:
#公众号APPID
appId: wx890e1ee5ee081dfe
#公众号秘钥
appSecret: 810135b716ab24e22b121c7916972cb5
#商户号Id
mchId: 1518762741
#商户号秘钥
mchKey: abcdefghijklmnopqrstuvwxyz123456
#微信支付回调地址
notifyUrl: http://nanhongshun.com/pay/notify
# 证书所在位置,退款使用
keyPath: C:/weixin_cert/h5.p12
#微信授权回调地址
callback: http://nanhongshun.com/wxAuth/callBack
ali:
#支付宝APPID
appId: 2019061065499889
#支付宝商户私钥
privateKey: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCaSyaQ6zcEQrd6fSs9US08VcwgQO005Z2NOGSFRGmRIe/UhIBe0m6psU8HpLyLqxICUpPP+zq4jY5Hpphy0w+5wJxUnm++i97bhCknveEfKaZVyFWmgJ6ropQgEtKTvz/ZSYiJ/egkW9nATIU3S54lfkBHeeHkRfGrvfHQD1u4G30zul6Qb0KJDiAtq8SMvQnkspBkC824JaxLAxIpO8Qv1uQZ79lNxohFzU3zya0Vu1y6AmYrAv07OQavPpNnnsHkvGDLwVLyk4P1oQ+BnCz+MA20yQf9sAODClIuqjxSiUrJqlGV176xRpPxfQc5iMyOxJSlAw6bMeOl/9EFmrofAgMBAAECggEAWZJTG0JRuBl7JpLPrVMY7bPpQrgufMzn//nC8VLb7jNDZZ5eX63OLJkQhiFui66OT+bchJsWZdlXxeTDD7XTpURZ/Q3VVUsh31IEClxC+rJVK+uXPYfhlUZWs5/5u2gFiwETUPij8aeY6/gARi+R6bY3Xsc1Ci5ItCka3mxsFJ6HacVWkJs0zfiJ/CzQbZY4c9zT8hMYMQEEacNwG82NvUW+ubD/lOD4wdQ5l/UutYDbnWw+by3W1+1Ob9ZBBVI/yV1KW02x+kUojWSzRhTNDw7bnjdF+kpLl9bfLy1ozzwVP0YOrc1vzgIGygJTt8ekcMgSqS1E/6D0M64vDmOv0QKBgQDmonkn6hxSWAXrteMAeCzM0hbPeec8SPsOqAV/ewBJvhv0DaMNYA3KufYTd9jimWD/0FDWkX9RTUwfkcplLYGn6IqIrLz8uXJvbqp5GkinI8j71+gbSvkNUOhw7/bnGnai55YJ6bf06zrCZgx0objFP6n6n5XV/ATccz1ZiNGWHQKBgQCrQ0p/L3hF5MzikyonLYk2qpne7pcaKSO3TuH/5+m6S0XALxNkakeQ8WyKyH6WR6ggLYGgbN/T4s7/ff4WD3VqOIDlE55A/NUbj8vbFbvL6cxmPzSun0DjJxgaWCT7DNd6+umslx3Mk5UC5Iib/7+VBqVWcXaLxNteqsUjysQsawKBgGCF9vbBgADmXfP8N3jm0rkV4/4JIsGUOZ40q7hingg+zCwj2O2sGZmSom4bZmXPk0z8vhhO5F3+X7GGrpIRrYW8SN5SjPWoF0CTrDzqxyVMUL016yohAoKULfO2OjsWVDhxe9XCPv79w6XAV84oMNA8iMMfLvJTeyVYBYEHRc/xAoGBAJWqy9rUaD5kkmzbgTYVxFkCxE+foGtbUnwqsrSKPqbwizdFrKPPgVV4toueZYn9ez8LpcHGA+FOz+lVeQxcXBcE5BfNijpu+eoJQ3TlzGWKn3cne2mzgOhCTP0Q1NiUw2cVCcsrkP4sZ0fM4lm6KfoZgbpGk/vXgIJ9qKT72W6bAoGBAIqoN0yR3/7typaSCc5jSDF81deiOh5P01GV6QsqF8SQrxlq6hiqPFqvXIoaiGTOfQ8EApyKZVxVar4c/wPUEYsZ1tyyyi2b4C9dwqFwzc9Vkrx6oj98z1o0v/g544RsyZkdDX8QaCG9xPHdFN0U1VeLmLnND/BeU1ADtlDRQsas
#支付宝公钥
publicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi9C30CEJzUNbarqHy3Kpd8kK7cQWWCH0/Wv4gzCBG9sD5l4Y9huivJvhJ5IJ4T5v2DF8wx5k/rJQJezo4rS/bVB3JZSxBBgiDGZNn2QFh92ojj1nsedZQDoTcbWoMpM6ZqbB89HCLyOUzLQ/9ftPzquJF18H/jhCA57NCVDQ/opAgEFQ7b9+UoEV/hRriHoQDVu8+AZwnaHjbV+wUyqILI65zQTf0OGQS3zviljqjeIvdm7nspzt+UFYq1Hi5ayHfurcR5wPyp3sy7oWk8CVZdJYI5Kx4Eg5MjVutM4twokRyYPMCsnZyMOXfwSPBfelaq392px9H9uRFPkekDE3YQIDAQAB
#支付宝支付回调地址
notifyUrl: http://nanhongshun.com/ali/notify
returnUrl: http://nanhongshun.com/system/success
|
www
微信配置:
package com.nan.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 微信参数配置
*/
@Data
@Component
@ConfigurationProperties(prefix = "wechat")
public class WechatAccountConfig {
//公众号APPID
private String appId;
//公众号秘钥
private String appSecret;
//微信授权回调地址
private String callback;
//商户号id
private String mchId;
//商户号密钥
private String mchKey;
//商户证书路径
private String keyPath;
//微信支付异步回调地址
private String notifyUrl;
} |
package com.nan.config;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
/**
* 微信授权配置
*/
@Component
public class WechatMpConfig {
@Autowired
private WechatAccountConfig wechatAccountConfig;
@Bean
public WxMpService wxMpService(){
WxMpService wxMpService = new WxMpServiceImpl();
wxMpService.setWxMpConfigStorage(wxMpConfigStorage());
return wxMpService;
}
@Bean
public WxMpConfigStorage wxMpConfigStorage(){
WxMpDefaultConfigImpl wxMpConfigStorage = new WxMpDefaultConfigImpl();
wxMpConfigStorage.setAppId(wechatAccountConfig.getAppId());
wxMpConfigStorage.setSecret(wechatAccountConfig.getAppSecret());
return wxMpConfigStorage;
}
} |
支付宝配置:
package com.nan.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 微信参数配置
*/
@Data
@Component
@ConfigurationProperties(prefix = "ali")
public class AliZhiFuBaoAccountConfig {
//支付宝APPID
private String appId;
//支付宝商户私钥
private String privateKey;
//支付宝公钥
private String publicKey;
private String notifyUrl;
private String returnUrl;
} |
package com.nan.config;
import com.lly835.bestpay.config.AliPayConfig;
import com.lly835.bestpay.model.RefundRequest;
import com.lly835.bestpay.model.RefundResponse;
import com.lly835.bestpay.service.impl.BestPayServiceImpl;
import com.lly835.bestpay.service.impl.alipay.AliPayServiceImpl;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AliRefund extends BestPayServiceImpl {
private AliPayConfig aliPayConfig;
@Override
public RefundResponse refund(RefundRequest request) {
AliPayServiceImpl aliPayService = new AliPayServiceImpl();
aliPayService.setAliPayConfig(this.aliPayConfig);
return aliPayService.refund(request);
}
} |
支付相关配置:
package com.nan.config;
import com.lly835.bestpay.config.AliPayConfig;
import com.lly835.bestpay.config.WxPayConfig;
import com.lly835.bestpay.service.impl.BestPayServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
/**
* 支付配置
*/
@Component
public class PayConfig {
@Autowired
private WechatAccountConfig accountConfig;
@Autowired
private AliZhiFuBaoAccountConfig aliZhiFuBaoAccountConfig;
@Bean
public BestPayServiceImpl bestPayService() {
BestPayServiceImpl bestPayService = new BestPayServiceImpl();
bestPayService.setWxPayConfig(wxPayConfig());
bestPayService.setAliPayConfig(aliPayConfig());
return bestPayService;
}
/**
* 微信
* @return
*/
@Bean
public WxPayConfig wxPayConfig() {
WxPayConfig wxPayConfig = new WxPayConfig();
wxPayConfig.setAppId(accountConfig.getAppId());
wxPayConfig.setAppSecret(accountConfig.getAppSecret());
wxPayConfig.setMchId(accountConfig.getMchId());
wxPayConfig.setMchKey(accountConfig.getMchKey());
wxPayConfig.setKeyPath(accountConfig.getKeyPath());
wxPayConfig.setNotifyUrl(accountConfig.getNotifyUrl());
return wxPayConfig;
}
/**
* 支付宝
* @return
*/
@Bean
public AliPayConfig aliPayConfig() {
AliPayConfig aliPayConfig = new AliPayConfig();
aliPayConfig.setAppId(aliZhiFuBaoAccountConfig.getAppId());
aliPayConfig.setPrivateKey(aliZhiFuBaoAccountConfig.getPrivateKey());
aliPayConfig.setAliPayPublicKey(aliZhiFuBaoAccountConfig.getPublicKey());
aliPayConfig.setNotifyUrl(aliZhiFuBaoAccountConfig.getNotifyUrl());
aliPayConfig.setReturnUrl(aliZhiFuBaoAccountConfig.getReturnUrl());
return aliPayConfig;
}
}
|
service:
package com.nan.service;
import com.lly835.bestpay.enums.BestPayTypeEnum;
import com.lly835.bestpay.model.PayRequest;
import com.lly835.bestpay.model.PayResponse;
import com.lly835.bestpay.model.RefundRequest;
import com.lly835.bestpay.model.RefundResponse;
import com.lly835.bestpay.service.impl.BestPayServiceImpl;
import com.nan.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Random;
/**
* 支付相关service
*/
@Slf4j
@Service
public class PayService{
private static final String ORDER_MONEY = "0.01";
private static final String ORDER_NAME = "南南支付";
@Autowired
private BestPayServiceImpl bestPayService;
//生成订单id
public String orderId(){
//生成订单id
Random random = new Random();
Integer number = random.nextInt(900000)+100000;
String orderId = System.currentTimeMillis()+String.valueOf(number);
return orderId;
}
/**
* 微信支付下订单
* @param openid
* @return
*/
public PayResponse create(String openid){
PayRequest payRequest = new PayRequest();
payRequest.setOpenid(openid);
payRequest.setOrderAmount(Double.valueOf(ORDER_MONEY));
payRequest.setOrderId(orderId());
payRequest.setOrderName(ORDER_NAME);
payRequest.setPayTypeEnum(BestPayTypeEnum.WXPAY_MP);
log.info("【微信支付】发起支付,request={}", JsonUtil.toJson(payRequest));
PayResponse payResponse = bestPayService.pay(payRequest);
log.info("【微信支付】发起支付,response={}",JsonUtil.toJson(payResponse));
return payResponse;
}
/**
* 微信支付回调
* @return
*/
public PayResponse notify(String notifyData){
PayResponse payResponse = bestPayService.asyncNotify(notifyData);
return payResponse;
}
//微信退款
public RefundResponse reFund(){
RefundRequest refundRequest = new RefundRequest();
refundRequest.setOrderId(orderId());
refundRequest.setOrderAmount(Double.valueOf(ORDER_MONEY));
refundRequest.setPayTypeEnum(BestPayTypeEnum.WXPAY_NATIVE);
log.info("【微信退款】request={}",JsonUtil.toJson(refundRequest));
RefundResponse refundResponse = bestPayService.refund(refundRequest);
log.info("【微信退款】response={}",JsonUtil.toJson(refundResponse));
return refundResponse;
}
}
|
package com.nan.service;
import com.lly835.bestpay.enums.BestPayPlatformEnum;
import com.lly835.bestpay.enums.BestPayTypeEnum;
import com.lly835.bestpay.model.PayRequest;
import com.lly835.bestpay.model.PayResponse;
import com.lly835.bestpay.model.RefundRequest;
import com.lly835.bestpay.model.RefundResponse;
import com.lly835.bestpay.service.impl.BestPayServiceImpl;
import com.lly835.bestpay.service.impl.alipay.AliPayServiceImpl;
import com.nan.config.AliRefund;
import com.nan.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Random;
@Slf4j
@Service
public class AliService{
private static final String ORDER_MONEY = "0.01";
private static final String ORDER_NAME = "南南支付";
@Autowired
private BestPayServiceImpl bestPayService;
@Autowired
private AliRefund aliRefund;
//生成订单id
public String orderId(){
//生成订单id
Random random = new Random();
Integer number = random.nextInt(900000)+100000;
String orderId = System.currentTimeMillis()+String.valueOf(number);
return orderId;
}
/**
* 支付宝支付下订单
* @return
*/
public PayResponse create(){
PayRequest payRequest = new PayRequest();
payRequest.setOrderAmount(Double.valueOf(ORDER_MONEY));
payRequest.setOrderId(orderId());
payRequest.setOrderName(ORDER_NAME);
payRequest.setPayTypeEnum(BestPayTypeEnum.ALIPAY_WAP);
log.info("【支付宝支付】发起支付,request={}", JsonUtil.toJson(payRequest));
PayResponse payResponse = bestPayService.pay(payRequest);
System.out.println("====="+payResponse.getBody());
log.info("【支付宝支付】发起支付,response={}",JsonUtil.toJson(payResponse));
log.info("【支付宝支付返回】{}",payResponse);
return payResponse;
}
/**
* 支付宝支付回调
* @return
*/
public String notify(String notifyData){
PayResponse payResponse = bestPayService.asyncNotify(notifyData);
if(payResponse.getPayPlatformEnum() == BestPayPlatformEnum.ALIPAY){
return "success";
}
return null;
}
//支付宝退款
public RefundResponse reFund(){
RefundRequest refundRequest = new RefundRequest();
refundRequest.setOrderId(orderId());
refundRequest.setOrderAmount(Double.valueOf(ORDER_MONEY));
refundRequest.setPayTypeEnum(BestPayTypeEnum.WXPAY_NATIVE);
log.info("【支付宝退款】request={}",JsonUtil.toJson(refundRequest));
RefundResponse refundResponse = aliRefund.refund(refundRequest);
log.info("【支付宝退款】response={}",JsonUtil.toJson(refundResponse));
return refundResponse;
}
}
|
controller:
controller:
package com.nan.controller;
import com.nan.config.WechatAccountConfig;
import com.nan.service.PushMessageService;
import com.nan.service.UserService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
/**
* 微信授权登录
*/
@Slf4j
@Controller
@RequestMapping("/wxAuth")
public class WxLoginController {
@Autowired
private WechatAccountConfig wechatAccountConfig;
@Autowired
private UserService userService;
@Autowired
private WxMpService wxMpService;
@Autowired
private PushMessageService messageService;
/**
* 微信授权获取code
*
*/
@RequestMapping("/login")
public String wxLogin(){
String redirectUrl = wxMpService.oauth2buildAuthorizationUrl(wechatAccountConfig.getCallback(), WxConsts.OAuth2Scope.SNSAPI_USERINFO, null);
log.info("【微信网页授权】获取code,result={}",redirectUrl);
return "redirect:"+ redirectUrl;
}
/**
* 微信授权回调
*
*/
@RequestMapping("/callBack")
public ModelAndView wxCallBack(@RequestParam("code")String code, ModelAndView model, HttpServletRequest request){
WxMpOAuth2AccessToken wxMpOAuth2AccessToken = new WxMpOAuth2AccessToken();
try {
wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code);
}catch(WxErrorException e){
log.error("【微信网页授权】{}",e.getMessage());
e.printStackTrace();
}
WxMpUser wxMpUser = new WxMpUser();
try{
wxMpUser = wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken, null);
}catch(Exception e){
log.error("【微信授权】{}",e.getMessage());
e.printStackTrace();
}
model.setViewName("wechat/login");
model.addObject("nickname",wxMpUser.getNickname());
model.addObject("headimgurl",wxMpUser.getHeadImgUrl());
model.addObject("openid",wxMpUser.getOpenId());
//模板消息
messageService.loginTemplate(wxMpUser.getNickname(),wxMpUser.getOpenId());
return model;
}
}
|
package com.nan.controller;
import com.lly835.bestpay.model.PayResponse;
import com.nan.service.PayService;
import com.nan.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
/**
* 微信支付
*/
@Slf4j
@Controller
@RequestMapping("/pay")
public class PayController {
@Autowired
private PayService payService;
@GetMapping("/create")
public ModelAndView create(String openid, Map<String,Object> map, HttpServletResponse response){
//1.查询订单
//2.发起支付
// log.info("【微信支付】下订单");
PayResponse payResponse = payService.create(openid);
String returnUrl = "http://nanhongshun.com/pay/success";
map.put("payResponse",payResponse);
map.put("returnUrl",returnUrl);
return new ModelAndView("pay/create",map);
}
@PostMapping("/notify")
public ModelAndView notify(@RequestBody String notifyData) {
log.info("【异步回调】request={}", notifyData);
PayResponse response = payService.notify(notifyData);
log.info("【异步回调】response={}", JsonUtil.toJson(response));
return new ModelAndView("pay/success");
}
//跳转支付成功界面
@RequestMapping("/success")
public ModelAndView success(){
return new ModelAndView("success");
}
}
|
package com.nan.controller;
import com.lly835.bestpay.model.PayResponse;
import com.nan.service.AliService;
import com.nan.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
/**
* 支付宝支付
*/
@Slf4j
@Controller
@RequestMapping("/ali")
public class AliPayController {
@Autowired
private AliService aliService;
//支付宝支付
@GetMapping("/create")
public ModelAndView create(Map<String,Object> map){
PayResponse payResponse = aliService.create();
map.put("payResponse",payResponse);
map.put("body",payResponse.getBody());
return new ModelAndView("ali/create",map);
}
@PostMapping("/notify")
public ModelAndView notify(@RequestBody String notifyData) {
log.info("【异步回调】request={}", notifyData);
String response = aliService.notify(notifyData);
log.info("【异步回调】response={}", JsonUtil.toJson(response));
return new ModelAndView("pay/success");
}
}
|