微信小程序接入微信支付
微信小程序接入微信支付(代码部分)
准备
准备微信小程序
哈哈哈哈哈哈哈哈哈,这是废话,接着往下看
开通微信商户号,并和小程序绑定
具体可以看官方进行操作
最终会得到下面几个参数:
参数 | 解释 |
---|---|
mchId | 商户号:开通商户就有的参数 |
mchSerialNo | 证书序列号 |
apiKey | apiKey |
keyPath | 存放证书的电脑位置地址 |
这里把参数都丢到实体类里面
@Data
@ToString
@Component
// 这里读取配置文件(application.yml)wx-app 前缀的参数
@ConfigurationProperties(prefix = "wx-app")
public class PayInfoConfig {
//小程序appid
private String appId;
//小程序秘钥
private String appSecret;
//商户号
private String mchId;
//证书序列号
private String mchSerialNo;
// api秘钥
private String apiKey;
// 回调接口地址
private String notifyUrl;
// 证书地址
private String keyPath;
// 退款回调地址
private String refundNotifyUrl;
}
支付流程
微信官方支付时序流程图
服务器端
建立商户系统相关 订单表
CREATE TABLE `order` (
`order_id` bigint(20) NOT NULL AUTO_INCREMENT,
`order_number` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单编号',
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
`order_status` tinyint(4) NOT NULL COMMENT '订单状态',
`total_amount` decimal(12, 2) NOT NULL COMMENT '订单总金额',
`discount_amount` decimal(12, 2) NULL DEFAULT 0.00 COMMENT '优惠金额',
`payable_amount` decimal(12, 2) NOT NULL COMMENT '应付金额',
`payment_method` tinyint(4) NULL DEFAULT NULL COMMENT '支付方式',
`payment_status` tinyint(4) NULL DEFAULT NULL COMMENT '支付状态',
`payment_time` datetime NULL DEFAULT NULL COMMENT '支付时间',
`shipping_company` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '物流公司',
`tracking_number` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '物流单号',
`shipping_time` datetime NULL DEFAULT NULL COMMENT '发货时间',
`delivery_time` datetime NULL DEFAULT NULL COMMENT '收货时间',
`receiver_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '收货人姓名',
`receiver_phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '收货人电话',
`receiver_address` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '收货地址',
`order_note` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '订单备注',
`order_source` tinyint(4) NULL DEFAULT NULL COMMENT '订单来源',
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_deleted` tinyint(1) NULL DEFAULT 0 COMMENT '是否删除',
PRIMARY KEY (`order_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '订单表' ROW_FORMAT = Dynamic;
CREATE TABLE `order_item` (
`order_item_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '订单明细ID',
`order_id` bigint(20) NOT NULL COMMENT '订单ID',
`product_id` bigint(20) NOT NULL COMMENT '商品ID',
`product_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '商品名称',
`product_image` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '商品图片',
`unit_price` decimal(12, 2) NOT NULL COMMENT '商品单价',
`quantity` int(11) NOT NULL COMMENT '购买数量',
`subtotal_amount` decimal(12, 2) NOT NULL COMMENT '小计金额',
`after_sale_status` tinyint(4) NULL DEFAULT NULL COMMENT '售后状态',
PRIMARY KEY (`order_item_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '订单明细表' ROW_FORMAT = Dynamic;
对应表的相关CRUD代码
自己使用代码生成器生成
引入支付相关Maven包
<!-- 微信支付相关 -->
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-java</artifactId>
<version>0.2.14</version>
</dependency>
步骤三
生成商户系统平台订单,并请求微信下单接口,生成预付单
// Controller 下单接口
@PostMapping("/payment")
public AjaxResult payment(@RequestBody PaymentRequestVo vo) {
// ...
// 创建订单
SysOrder order = orderService.createOrder(vo,userId);
String openId = user.getOpenId();
// 发送请求下单接口
Map<String, Object> result = service.payment(order.getPayableAmount().intValue(), order.getOrderNumber(), openId,vo.getProductName());
return AjaxResult.success(result);
}
/**
*
* @author morris
* @date 2024/10/16 9:47
* 调起支付
*
*/
public static Map<String, Object> payment(Integer price, String orderId, String userId,String desc){
JsapiService service = getService(); // 构建支付请求SERVICE
PrepayRequest prepayRequest = buildParam(price, orderId, userId,desc); // 构建支付请求参数
PrepayResponse response = service.prepay(prepayRequest); // 向微信请求下单并返回结果
Map<String, Object> result = parsePay(response); // 解析支付结果
result.put("orderId",orderId);
return result;
}
/**
*
* @author morris
* @date 2024/10/16 9:35
* 构建支付请求SERVICE
*
*/
public static JsapiService getService(){
PayInfoConfig payInfoConfig = getConfig();
Config config = new RSAAutoCertificateConfig.Builder()
.merchantId(payInfoConfig.getMchId())
.privateKeyFromPath(payInfoConfig.getKeyPath())
.merchantSerialNumber(payInfoConfig.getMchSerialNo())
.apiV3Key(payInfoConfig.getApiKey())
.build();
JsapiService service = new JsapiService.Builder().config(config).build();
return service;
}
/**
*
* @author morris
* @date 2024/10/16 9:35
* 构建支付请求参数
*
*/
private static PrepayRequest buildParam(Integer price, String orderId, String openId ,String desc){
PayInfoConfig payInfoConfig = getConfig();
PrepayRequest prepayRequest = new PrepayRequest();
Amount amount = new Amount();
// 微信收款是以分位单位
BigDecimal multiply = BigDecimal.valueOf(price);
amount.setTotal(multiply.intValue());
prepayRequest.setAmount(amount);
prepayRequest.setAppid(payInfoConfig.getAppId());
prepayRequest.setMchid(payInfoConfig.getMchId());
prepayRequest.setNotifyUrl(payInfoConfig.getNotifyUrl());// 回调接口地址
prepayRequest.setDescription(desc);
prepayRequest.setOutTradeNo(orderId); // 订单号
prepayRequest.setAttach("activity"); // 订单类型(回调时可根据这个数据辨别订单类型或其他)
//根据下单用户拿到openid,指定该预支付订单的支付者身份
Payer payer = new Payer();
payer.setOpenid(openId);
prepayRequest.setPayer(payer);
return prepayRequest;
}
/**
*
* @author morris
* @date 2024/10/16 9:53
* 解析支付结果
*
*/
private static Map<String,Object> parsePay(PrepayResponse response){
PayInfoConfig payInfoConfig = getConfig();
Map<String, Object> params = new HashMap<>();
Long timeStamp = System.currentTimeMillis() / 1000;
String substring = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
String signatureStr = Stream.of(
payInfoConfig.getAppId(),
String.valueOf(timeStamp),
substring,
"prepay_id=" + response.getPrepayId()
).collect(Collectors.joining("\n", "", "\n"));
String sign = getSign(signatureStr, payInfoConfig.getKeyPath());
params.put("timeStamp", String.valueOf(timeStamp));
params.put("nonceStr", substring);
params.put("paySign", sign);
params.put("signType", "RSA");
params.put("package", "prepay_id=" + response.getPrepayId());
return params;
}
小程序端
根据服务器返回的参数,拉起微信支付
const params = {...}
payment(params).then(res => {
if(res.code === 200){
// 加载弹窗隐藏
uni.hideLoading();
data.orderNum = res.data.orderId
// 这里则是拉起微信支付,需要支付密码那个界面了
wx.requestPayment({
'timeStamp': res.data.timeStamp,
'nonceStr': res.data.nonceStr,
'package': res.data.package,
'signType': res.data.signType,
'paySign': res.data.paySign,
'success': function (res) {
// 支付成功的回调
console.log("支付成功:",res)
that.entryPxo(data)
},
'fail': function (res) {
console.log(JSON.stringify(res));
wx.showToast({title: '支付失败', icon: 'none',duration: 2000,mask: true})
}
})
}
}).catch(res => {
}).finally(res => {
uni.hideLoading()
this.isSubmitting = false
})
支付完成后,微信会有回调商户系统,也就是提供的那个回调地址
回调处理
/**
*
* @author morris
* @date 2024/10/15 16:57
* 微信支付回调
*
*/
@Anonymous
@PostMapping("/payNotify")
public void payNotify(HttpServletRequest request) throws Exception {
service.payNotify(request);
}
/**
* 退款回调通知
* @param request
* @throws Exception
*/
@Anonymous
@PostMapping("/refundNotify")
public void refundNotify(HttpServletRequest request) throws Exception {
service.refundNotify(request);
}
/**
*
* @author morris
* @date 2024/10/16 11:03
* 支付回调处理
* 1.更新订单状态
*
*/
public Map<String,Object> updateAccountDetail(Transaction parse, boolean active) {
String orderId = parse.getOutTradeNo();
Transaction.TradeStateEnum tradeState = parse.getTradeState();
if(tradeState==Transaction.TradeStateEnum.SUCCESS) {
System.out.println("支付成功");
String outTradeNo = parse.getOutTradeNo();
SysOrder order = orderMapper.selectSysOrderByOrderNum(outTradeNo);
order.setOrderStatus(1);
order.setPaymentStatus(1);
order.setPaymentTime(DateUtils.getNowDate());
orderMapper.updateSysOrder(order);
}
if(active){
return JSON.parseObject(buildParse(parse),Map.class);
}else{
// this.payNoticeMessage(parse,orderId);
}
return null;
}
至此,完成微信支付开发
原文地址:https://blog.csdn.net/weixin_40864434/article/details/143052823
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!