admin 管理员组文章数量: 1184232
微信支付
一、JDK版本需要1.8u162+以上版本
<!--微信支付 V3--><dependency><groupId>com.github.wechatpay-apiv3</groupId><artifactId>wechatpay-java</artifactId><version>0.2.7</version></dependency><dependency><groupId>com.github.wechatpay-apiv3</groupId><artifactId>wechatpay-apache-httpclient</artifactId><version>0.4.9</version></dependency>
二、前期准备
官网引导:接入前准备-小程序支付 | 微信支付商户平台文档中心
①appid:小程序appid-登录小程序后台获取
②secret:小程序密钥-登录小程序后台获取
登录小程序后台:
③appV3Secret:商户apiV3密钥-登录商户后台获取
④mchid:商户号-登录商户后台获取(商户号要绑定小程序)
⑤certpath:微信平台证书-登录商户后台获取
⑥privateKeyPath:商户私钥证书-登录商户后台获取
⑦merchantSerialNumber:商户证书序列化-登录商户后台获取
登录商户后台:
三、证书存放地
四、配置与加载
# application-dev.ymlwx:miniapp:configs:- appid: wx1fcxxxxxxxxsecret: 1exxxxxxxxxxxxxxxxxxxxxxxxxxxxxtoken: #微信小程序消息服务器配置的tokenaesKey: #微信小程序消息服务器配置的EncodingAESKeymsgDataFormat: JSONappV3Secret: ADxxxAas654xxxxxxxxxxxxxxxxxx # V3密钥mchid: 12345678 # 商户号certpath: D:/workspace/hxj-miniprogram-java/src/main/resources/wxpay/apiclient_cert.pem # 微信平台证书(发布时换成linux地址)privateKeyPath: D:/workspace/hxj-miniprogram-java/src/main/resources/wxpay/apiclient_key.pem # 商户私钥证书(发布时换成linux地址)payCallBackUrl: https://xxxxxxxxxxxxx/wechatPay/payCallback # 支付结束回调地址timeExpire: 1200000 # 交易过期时间(单位毫秒)merchantSerialNumber: 37ABCD098765ADCBF124656099AB # 商户证书序列号
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.List;/*** @author xuhj*/
@Slf4j
@Data
@ConfigurationProperties(prefix = "wx.miniapp")
public class WxMaProperties {private List<Config> configs;@Datapublic static class Config {/*** 设置微信小程序的appid*/private String appid;/*** 设置微信小程序的Secret*/private String secret;/*** 设置微信小程序消息服务器配置的token*/private String token;/*** 设置微信小程序消息服务器配置的EncodingAESKey*/private String aesKey;/*** 消息格式,XML或者JSON*/private String msgDataFormat;/*** appV3Secret V3密钥*/private String appV3Secret;/*** mchid 商户号*/private String mchid;/*** 微信支付平台证书地址,注意 windows地址与linux地址不同*/private String certpath;/*** 商户API证书的路径(一般和上边的certpath在一起下载)*/private String privateKeyPath;/*** 支付回调地址*/private String payCallBackUrl;/*** 交易过期时间(单位毫秒)*/private Long timeExpire;/*** 商户证书序列号*/private String merchantSerialNumber;}
}
五、证书自动更新
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class WxPayConfig {@Autowiredprivate WxMaProperties properties;/*** 初始化商户配置(只能加载一次)* 确保是单例** @return*/@Beanpublic RSAAutoCertificateConfig rsaAutoCertificateConfig() {RSAAutoCertificateConfig config = new RSAAutoCertificateConfig.Builder().merchantId(properties.getConfigs().get(0).getMchid()).privateKeyFromPath(properties.getConfigs().get(0).getPrivateKeyPath()).merchantSerialNumber(properties.getConfigs().get(0).getMerchantSerialNumber()).apiV3Key(properties.getConfigs().get(0).getAppV3Secret()).build();return config;}
}
六、预支付和回调
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.*;
import com.wechat.pay.java.service.payments.model.Transaction;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;import static com.wechat.pay.contrib.apache.httpclient.constant.WechatPayHttpHeaders.WECHAT_PAY_SIGNATURE;
import static com.wechat.pay.java.core.http.Constant.WECHAT_PAY_NONCE;
import static com.wechat.pay.java.core.http.Constant.WECHAT_PAY_TIMESTAMP;/*** <p>* 微信支付 前端控制器* </p>** @author sunziwen* @since 2023-03-23*/
@Api(tags = {"微信支付"})
@Slf4j
@RestController
@RequestMapping("/wechatPay")
@Validated
public class PayController extends BaseController {/*** 配置文件*/@Autowiredprivate WxMaProperties properties;@Autowiredprivate RSAAutoCertificateConfig rsaAutoCertificateConfig;@Autowiredprivate IOrderMasterService iOrderMasterService;@ApiOperation(value = "预支付-委托")@PostMapping("preparePayment")@ApiImplicitParams({@ApiImplicitParam(name = "openid", value = "openid"),@ApiImplicitParam(name = "description", value = "商品描述"),@ApiImplicitParam(name = "outTradeNo", value = "商户订单号"),@ApiImplicitParam(name = "total", value = "订单总金额,单位为分")})public ServiceResult<?> preparePayment(String openid, String description, String outTradeNo, Integer total) {// 初始化服务JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(rsaAutoCertificateConfig).build();PrepayRequest request = new PrepayRequest();// 应用IDrequest.setAppid(properties.getConfigs().get(0).getAppid());// 直连商户号request.setMchid(properties.getConfigs().get(0).getMchid());// 商品描述request.setDescription(description);// 商户订单号request.setOutTradeNo(outTradeNo);// 交易结束时间:2018-06-08T10:34:56+08:00request.setTimeExpire(timeStampToRfc3339(System.currentTimeMillis() + properties.getConfigs().get(0).getTimeExpire()));// 附加数据:在查询API和支付通知中原样返回,可作为自定义参数使用request.setAttach("");// 回调地址:异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。 公网域名必须为httpsrequest.setNotifyUrl(properties.getConfigs().get(0).getPayCallBackUrl());// 商品标记,代金券或立减优惠功能的参数request.setGoodsTag("");// 限制支付类型
// request.setLimitPay(LimitPayEnum.);// 电子发票入口开放标识:传入true时,支付成功消息和支付详情页将出现开票入口。需要在微信支付商户平台或微信公众平台开通电子发票功能,传此字段才可生效request.setSupportFapiao(true);Amount amount = new Amount();amount.setTotal(total);amount.setCurrency("CNY");// 订单金额信息request.setAmount(amount);Payer payer = new Payer();payer.setOpenid(openid);// 支付者信息request.setPayer(payer);// 优惠功能request.setDetail(null);// 支付场景描述request.setSceneInfo(null);// 结算信息request.setSettleInfo(null);PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request);//重复支付判断TODO// 存储预付订单信息 TODOlog.info("发起预支付成功-" + response.toString());return success(response);}@ApiOperation(value = "预支付-回调(或退款)")@RequestMapping("payCallback")public synchronized String payCallback(HttpServletRequest request) throws IOException {log.info("收到支付回调-------------");// 请求头Wechatpay-nonceString nonce = request.getHeader(WECHAT_PAY_NONCE);// 请求头Wechatpay-TimestampString timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP);// 请求头Wechatpay-SignatureString signature = request.getHeader(WECHAT_PAY_SIGNATURE);// 微信支付证书序列号 TODO 这里千万不能搞错,不能是商家证书序列号!!!String serial = request.getHeader("Wechatpay-Serial");// 签名方式String signType = request.getHeader("Wechatpay-Signature-Type");// 构造 RequestParamRequestParam requestParam = new RequestParam.Builder().serialNumber(serial) // TODO 不能搞错!!!.nonce(nonce).signature(signature).timestamp(timestamp).signType(signType).body(getRequestBody()).build();// 初始化 NotificationParserNotificationParser parser = new NotificationParser(rsaAutoCertificateConfig);// 以支付通知回调为例,验签、解密并转换成 Transactionlog.info("验签参数:" + requestParam);Transaction transaction = parser.parse(requestParam, Transaction.class);log.info("验签成功!-支付回调结果:" + transaction.toString());
// RefundNotification refundNotification = parser.parse(requestParam, RefundNotification.class);// 修改订单之前,主动去微信支付主动查询订单是否已经支付成功,这一步不能少,防止有人假冒主动post接口。/*** 收到支付成功的回调:这里进行处理业务*/
// List<OrderMaster> orderMasters = iOrderMasterService.lambdaQuery().eq(OrderMaster::getOrderNo, transaction.getOutTradeNo()).list();
// Assert.isTrue(orderMasters.size() == 1, "根据订单编号未查到订单OR查到了多个订单!!!");
// if (Transaction.TradeStateEnum.SUCCESS.equals(transaction.getTradeState())) {
// //支付成功 0待付款1待发货2待收货3已完成4已取消
// orderMasters.get(0).setBuyStatus(1);
// // 1待送仓2待打款3已完成4已取消
// orderMasters.get(0).setSaleStatus(1);
// // 1现金,2余额,3网银,4支付宝,5微信
// orderMasters.get(0).setPaymentMethod(5);
// return "{\"code\": \"FAIL\",\"message\": \"失败\"}";
// } else {
// log.info("支付未成功:" + transaction.getTradeState());
// }
// // TODO 存储支付流水return "{\"code\": \"FAIL\",\"message\": \"失败\"}";}}
本文标签: 微信支付
版权声明:本文标题:微信支付 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1686607710a16440.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论