由于微信接口经常会调整,首次对接尽量参考官方文档,并以最新的文章为主,因为我试了好几种方法,最终发现都是老版有问题,用了最新版本就通了,最新版APIV3版本开发指引 - JSAPI支付 | 微信支付商户文档中心。
官方文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_1.shtml
小程序开通微信支付
微信小程序集成参考最新先程序集成文档
pom.xml
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
<version>0.4.9</version>
</dependency>
yml配置:
weixin-pay:
v3:
#微信关联的小程序的appid
appId: wx281xxxxxxxxxxx
#微信支付商户号
mchId: 16480333333333
#微信支付证书序列号 在配置api证书的界面可以找到
serialnumber: 43442BF
#微信支付apiv3的密钥
apiKey3: D321123456789
#微信支付证书
certKeyPath: /home/key/apiclient_key.pem
#微信支付回调商户线上地址api
notifyUrl: https:
#微信支付关闭订单api
closeOrderUrl: https:
#微信支付小程序预下单api
jsApiUrl: https:
#微信支付订单查询api
queryOrder: https:
配置类xie
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix="weixin-pay.v3")
public class WxPayConfig {
private String appId;
private String mchId;
private String serialnumber;
private String apiKey3;
private String certKeyPath;
private String notifyUrl;
private String jsApiUrl;
private String closeOrderUrl;
private String queryOrder;
}
servieImp实现
public class PayOrderServiceImpl extends ServiceImpl<PayOrderMapper, PayOrder> implements IPayOrderService {
@Autowired
private WxPayConfig wxPayConfig;
private static Sign sign;
private static CertificatesManager certificatesManager;
private static CloseableHttpClient httpClient;
private PrivateKey merchantPrivateKey;
private Verifier verifier;
@PostConstruct
public void init() throws Exception {
logger.info("微信支付获取支付二维码path:{} input:{}", wxPayConfig.getCertKeyPath(), new FileInputStream(wxPayConfig.getCertKeyPath()));
merchantPrivateKey = PemUtil.loadPrivateKey(new FileInputStream(wxPayConfig.getCertKeyPath()));
certificatesManager = CertificatesManager.getInstance();
sign = SecureUtil.sign(SignAlgorithm.SHA256withRSA, merchantPrivateKey.getEncoded(), null);
certificatesManager.putMerchant(wxPayConfig.getMchId(), new WechatPay2Credentials(wxPayConfig.getMchId(),
new PrivateKeySigner(wxPayConfig.getSerialnumber(), merchantPrivateKey)), wxPayConfig.getApiKey3().getBytes(StandardCharsets.UTF_8));
verifier = certificatesManager.getVerifier(wxPayConfig.getMchId());
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
.withMerchant(wxPayConfig.getMchId(), wxPayConfig.getSerialnumber(), merchantPrivateKey)
.withValidator(new WechatPay2Validator(verifier));
httpClient = builder.build();
}
@Override
public AjaxResult prePay(PayOrder payOrder) {
logger.info("微信小程序支付JSAPI预下单开始------");
AjaxResult ajaxResult = AjaxResult.success();
JSONObject obj = new JSONObject();
obj.put("appid", wxPayConfig.getAppId());
obj.put("mchid", wxPayConfig.getMchId());
obj.put("description", payOrder.getOrderRemark());
obj.put("out_trade_no", payOrder.getTradeNo());
obj.put("notify_url", wxPayConfig.getNotifyUrl());
Map<String, String> attach = new HashMap<>();
attach.put("orderCode", payOrder.getOrderName());
obj.put("attach", JSON.toJSONString(attach));
JSONObject amount = new JSONObject();
amount.put("total", payOrder.getOrderAmount().intValue());
obj.put("amount", amount);
JSONObject payer = new JSONObject();
payer.put("openid", payOrder.getOpenId());
obj.put("payer", payer);
logger.info("微信小程序支付JSAPI预下单请求参数:{}" + obj.toJSONString());
HttpPost httpPost = new HttpPost(wxPayConfig.getJsApiUrl());
httpPost.addHeader("Accept", "application/json");
httpPost.addHeader("Content-type", "application/json; charset=utf-8");
httpPost.setEntity(new StringEntity(obj.toJSONString(), "UTF-8"));
String bodyAsString;
try {
if (httpClient == null) {
logger.info("微信小程序支付JSAPI预下单请求失败");
return AjaxResult.error("预下单失败,请重试,无法连接微信支付服务器!");
}
CloseableHttpResponse response = httpClient.execute(httpPost);
bodyAsString = EntityUtils.toString(response.getEntity());
} catch (IOException e) {
logger.info("微信小程序支付JSAPI预下单请求失败{}", e.getMessage());
return AjaxResult.error("预下单失败,请重试!" + e.getMessage());
}
String prePayId = JSONObject.parseObject(bodyAsString).getString("prepay_id");
if (prePayId == null) {
String message = JSONObject.parseObject(bodyAsString).getString("message");
logger.info("微信小程序支付JSAPI预下单请求失败{}", message);
return AjaxResult.error("预下单失败,请重试!" + message);
}
ajaxResult.put("appId", wxPayConfig.getAppId());
String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
ajaxResult.put("timeStamp", timeStamp);
String nonceStr = IdUtil.fastSimpleUUID();
ajaxResult.put("nonceStr", nonceStr);
String packageStr = "prepay_id=" + prePayId;
ajaxResult.put("package", packageStr);
ajaxResult.put("signType", "MD5");
String signString = wxPayConfig.getAppId() + "n" + timeStamp + "n" + nonceStr + "n" + packageStr + "n";
Map<String, Object> resMap = new HashMap<>();
resMap.put("nonceStr", nonceStr);
resMap.put("timeStamp", timeStamp);
resMap.put("appId", wxPayConfig.getAppId());
resMap.put("package", packageStr);
String paySign = signRSA(signString);
ajaxResult.put("paySign", paySign);
return ajaxResult;
}
public String signRSA(String message) {
try {
Signer signer = new PrivateKeySigner(wxPayConfig.getSerialnumber(), merchantPrivateKey);
Signer.SignatureResult signature = signer.sign(message.getBytes(StandardCharsets.UTF_8));
return signature.getSign();
} catch (Exception e) {
e.printStackTrace();
logger.error("签名出错:{}", e);
return "";
}
}
}
controler代码:
@Log(title = "统一下单", businessType = BusinessType.INSERT)
@PostMapping("/unifiedOrder")
public AjaxResult unifiedOrder(@RequestBody PayOrder payOrder,
HttpServletRequest request) {
logger.info("payOrder:{} request:{}", payOrder, request);
String openId = payOrder.getOpenId();
if (StringUtils.isEmpty(openId)) {
return AjaxResult.error("openId不能为空");
}
String redisKey = "h5_order_add" + openId;
String redisValue = openId + "_" + System.currentTimeMillis();
try {
redisCache.lock(redisKey, redisValue, 60);
QueryWrapper<PayOrder> wrapper = new QueryWrapper<>();
wrapper.eq("trade_no", payOrder.getTradeNo());
wrapper.eq("order_status", OrderStatusEnum.PENDING_PAYMENT.getStatus());
PayOrder payOrder1 = iPayOrderService.getOne(wrapper);
if (payOrder1 == null) {
String orderNo = TenpayUtil.getTradeNoByPhone();
payOrder.setTradeNo(orderNo);
payOrder.setCreateTime(new Date());
payOrder.setOrderAmount(payOrder.getOrderAmount());
}
payOrder.setOrderUserName(payOrder.getOpenId());
payOrder.setPayWay(1L);
payOrder.setPayBrand(1L);
payOrder.setConsumeType(2L);
payOrder.setOperateType(1L);
payOrder.setOrderStatus(OrderStatusEnum.PENDING_PAYMENT.getStatus());
iPayOrderService.saveOrUpdate(payOrder);
return iPayOrderService.prePay(payOrder);
} catch (Exception e) {
logger.error("unifiedOrder error:{}", e);
return AjaxResult.error("运行异常,请联系管理员");
} finally {
try {
redisCache.unLock(redisKey, redisValue);
} catch (Exception e) {
e.printStackTrace();
}
}
}
相关知识
微信小程序之植物识别demo(百度开发接口)
鲜花微信小程序系统解析与核心功能展示
微信小程序期末大作业解析:打造花店小程序
鲜花微信小程序系统详解与核心代码展示
基于微信小程序的鲜花预定系统的设计与实现
对接支付宝、微信、第三方支付,超详细讲解+demo演示
鲜花下单预约系统源码小程序源码 微信小程序 公众号源码
花店怎么做微信小程序的功能开发
鲜花花店微信小程序—鲜花预定
鲜花订购微信下单商城店铺小程序
网址: 微信小程序集成V3支付接口 https://m.huajiangbk.com/newsview849397.html
上一篇: 最详细的 paypal 支付接口 |
下一篇: AliPay |