微信小程序调用微信支付
最近开发到小程序调用微信支付功能,看了下微信支付商户官网API文档再结合项目本身情况因是本人第一次接触走了很多弯路所以记录下开发的过程。
本次微信支付用的是老版本XML格式的,所有的支付功能直接复制就可以用了。无需大量改动把相应的商户appid 和商户支付秘钥修改
直接上代码。
框架是springboot maven
在pom.xml中添加依赖
-
<!--微信支付-->
-
<dependency>
-
<groupId>com.github.binarywang</groupId>
-
<artifactId>weixin-java-pay</artifactId>
-
<version>3.5.0</version>
-
</dependency>
yml配置文件
-
-
# 小程序
-
#appid: wxdc441d07e8130fa9
-
# secret: 4bcd53d721cd6f133d2471aa0fd33ee1
-
miniporgram:
-
appid: wx17f07c0f59e3d719e #需要换成自己的
-
secret: 51806f5515ea9619604daff93eb02bb3b #需要换成自己的
-
login-url: https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code
-
getUnlimited-url: https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s
-
access-token-url: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s
-
-
wx:
-
pay:
-
appId: wx17f07c0f59e3d719e #微信公众号或者小程序等的appid #需要换成自己的
-
secret: 51806f5515ea9619604daff93eb02bb3b #需要换成自己的
-
mchId: 1150801291151 #微信支付商户号 #需要换成自己的
-
mchKey: fa2182b3cee6ac930f493af9b6a8abd7f #微信支付商户密钥
-
# subAppId: #服务商模式下的子商户公众账号ID
-
# subMchId: #服务商模式下的子商户号
-
keyPath: classpath:/cert/apiclient_cert.p12 # p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头)
-
notifyUrl: https://1579lw7417.goho.co/wx/wxPay/payNotify #微信支付结果通知,微信支付回调地
微信公众号商户添加支付回调地址,支付成功后就会把信息推过来
配置已经完了现在看小程序支付页面源码:
添加一个支付按钮
<button class="weui-btn btn-radius" bindtap="confirm">支付</button>
js
-
//支付
-
confirm:function(){
-
console.log('支付')
-
wx.login({
-
success: res => {
-
request.creatOrdel({ code:res.code,money:'1'}).then(r => {
-
console.log(r)
-
wx.requestPayment({
-
timeStamp: r.data.timeStamp,
-
nonceStr: r.data.nonceStr,
-
package: r.data.package,
-
signType: r.data.signType,
-
paySign: r.data.paySign,
-
success (res) { },
-
fail (res) { }
-
})
-
})
-
}
-
})
-
}
支付的时候把code传到后台,还有金额,生成预支付流水成功后前端 wx.requestPayment 就唤起了微信支付界面,在小程序开发这个工具中可能看到的是二维码不过不要紧,在手机端就是这个正常界面
后端代码:
controller
-
package cn.umidata.nucleic.api.controller;
-
-
-
import cn.hutool.json.JSONObject;
-
import cn.umidata.nucleic.api.utils.Httprequests;
-
import cn.umidata.nucleic.wechat.domain.WechatPaymentRecord;
-
import cn.umidata.nucleic.wechat.domain.WxOrderParams;
-
import cn.umidata.nucleic.wechat.service.WxPlayService;
-
import com.ijpay.core.kit.HttpKit;
-
import com.ijpay.core.kit.WxPayKit;
-
import io.swagger.annotations.Api;
-
import io.swagger.annotations.ApiOperation;
-
import org.slf4j.Logger;
-
import org.slf4j.LoggerFactory;
-
import org.springframework.beans.factory.annotation.Autowired;
-
import org.springframework.beans.factory.annotation.Value;
-
import org.springframework.web.bind.annotation.PostMapping;
-
import org.springframework.web.bind.annotation.RequestMapping;
-
import org.springframework.web.bind.annotation.RestController;
-
import cn.umidata.nucleic.common.core.domain.AjaxResult;
-
-
import javax.servlet.http.HttpServletRequest;
-
import java.math.BigDecimal;
-
import java.util.HashMap;
-
import java.util.Map;
-
-
/**
-
* @BelongsProject: nucleic
-
* @BelongsPackage: cn.umidata.nucleic.api.controller
-
* @Author: zhanghui
-
* @CreateTime: 2022-09-13 19:05
-
* @Description: 订单支付
-
* @Version: 1.0
-
*/
-
@Api(tags = "订单支付")
-
@RestController
-
@RequestMapping(value = "wxPay")
-
public class wxOrderController {
-
@Value("${miniporgram.appid}")
-
private String appid;
-
@Value("${miniporgram.secret}")
-
private String secret;
-
@Value("${wx.pay.mchId}")
-
private String mchid;
-
-
@Value("${wx.pay.notifyUrl}")
-
private String notifyUrl;
-
@Value("${wx.pay.mchKey}")
-
private String mchKey;
-
-
@Autowired
-
private WxPlayService wxPlayService;
-
private final Logger log = LoggerFactory.getLogger(this.getClass());
-
/**
-
* 微信小程序支付
-
*oderBathNum 订单批号,在申领果树中/wx/ReceiveFruiter/getBathNum接口中获取
-
*/
-
@ApiOperation(value = "微信小程序支付",notes = "微信小程序支付")
-
@PostMapping("/placeOrder")
-
public AjaxResult miniAppPay(String openid,String money,String oderBathNum) {
-
/* String param = "appid=" appid "&secret=" secret "&js_code=" code "&grant_type=authorization_code";
-
String sendGet = Httprequests.sendGet("https://api.weixin.qq.com/sns/jscode2session", param); //发起请求拿到key和openid
-
JSONObject json = new JSONObject(sendGet);
-
String openid=json.get("openid").toString(); //用户唯一标识*/
-
WxOrderParams params = new WxOrderParams();
-
params.setAttach("预约");
-
params.setBody("预约单支付");
-
params.setDetail("");
-
params.setOpenid(openid);
-
params.setOrderType("1");
-
params.setOutTradeNo("FSA" String.valueOf(System.currentTimeMillis()));
-
params.setTotalFee(new BigDecimal(money));
-
params.setAppid(appid);
-
params.setMchid(mchid);
-
params.setNotifyUrl(notifyUrl);
-
params.setMchKey(mchKey);
-
params.setOderBathNum(oderBathNum);
-
Map<String, String> stringStringMap = wxPlayService.placeOrder(params);
-
return AjaxResult.success(stringStringMap);
-
}
-
/**
-
* 支付回调异步通知
-
*/
-
@ApiOperation(value = "支付回调异步通知",notes = "支付回调异步通知")
-
@RequestMapping(value = "/payNotify")
-
public String payNotify(HttpServletRequest request) {
-
execPayNotify(request);
-
Map<String, String> xml = new HashMap<String, String>(2);
-
xml.put("return_code", "SUCCESS");
-
xml.put("return_msg", "OK");
-
return WxPayKit.toXml(xml);
-
}
-
-
/**
-
* 支付回调异步通知
-
*/
-
public synchronized void execPayNotify(HttpServletRequest request) {
-
String xmlMsg = HttpKit.readData(request);
-
log.info("支付通知:" xmlMsg);
-
Map<String, String> params = WxPayKit.xmlToMap(xmlMsg);
-
WechatPaymentRecord record = wxPlayService.payNotify(params,mchKey);
-
System.out.println("微信支付通知:" record);
-
-
}
-
}
WxPlayService:
-
package cn.umidata.nucleic.wechat.service;
-
-
import cn.umidata.nucleic.wechat.domain.RefundParams;
-
import cn.umidata.nucleic.wechat.domain.WechatPaymentRecord;
-
import cn.umidata.nucleic.wechat.domain.WxOrderParams;
-
-
import java.util.Map;
-
-
public interface WxPlayService {
-
-
/**
-
* 下单:
-
* @param params
-
* @return 微信调用微信支付的所需要的参数
-
*/
-
public Map<String, String> placeOrder(WxOrderParams params);
-
-
-
/**
-
* 微信支付通知
-
* @param params 微信通知xml转map的参数
-
*/
-
public WechatPaymentRecord payNotify(Map<String, String> params,String mchKey );
-
-
-
-
/**
-
* 退款
-
* @param refundParams
-
*/
-
public String refund(RefundParams refundParams);
-
-
-
/**
-
* 退款通知
-
* @param params 微信通知xml转map的参数
-
*/
-
public void refundNotify(Map<String, String> params);
-
}
WxPlayServiceImpl:
-
package cn.umidata.nucleic.wechat.service.impl;
-
-
import cn.umidata.nucleic.common.utils.DateUtils;
-
import cn.umidata.nucleic.common.utils.ip.IpUtils;
-
import cn.umidata.nucleic.wechat.domain.RefundParams;
-
import cn.umidata.nucleic.wechat.domain.WechatPaymentRecord;
-
import cn.umidata.nucleic.wechat.domain.WxOrderParams;
-
import cn.umidata.nucleic.wechat.enums.WxPlayStatus;
-
import cn.umidata.nucleic.wechat.service.IWechatPaymentRecordService;
-
import cn.umidata.nucleic.wechat.service.WxPlayService;
-
import com.ijpay.core.enums.SignType;
-
import com.ijpay.core.enums.TradeType;
-
import com.ijpay.core.kit.WxPayKit;
-
import com.ijpay.wxpay.WxPayApi;
-
import com.ijpay.wxpay.WxPayApiConfigKit;
-
import com.ijpay.wxpay.enums.WxDomain;
-
import com.ijpay.wxpay.model.UnifiedOrderModel;
-
import org.slf4j.Logger;
-
import org.slf4j.LoggerFactory;
-
import org.springframework.beans.factory.annotation.Autowired;
-
import org.springframework.stereotype.Service;
-
import com.ijpay.wxpay.WxPayApiConfig;
-
-
import java.util.Date;
-
import java.util.Map;
-
-
/**
-
* @BelongsProject: nucleic
-
* @BelongsPackage: cn.umidata.nucleic.wechat.service.impl
-
* @Author: zhanghui
-
* @CreateTime: 2022-09-15 15:59
-
* @Description: TODO
-
* @Version: 1.0
-
*/
-
@Service
-
public class WxPlayServiceImpl implements WxPlayService {
-
private final Logger log = LoggerFactory.getLogger(this.getClass());
-
@Autowired
-
private IWechatPaymentRecordService recordService;
-
/*
-
* @description:下单:
-
* @author: zhanghui
-
* @date: 2022/9/15 0015 下午 4:00
-
* @param params
-
* @return 微信调用微信支付的所需要的参数
-
**/
-
@Override
-
public Map<String, String> placeOrder(WxOrderParams params) {
-
// 获取openId一般情况下用户登录的时候openId是和用户关联的 所以openId可以通过当前的userId去查询openId
-
String ip = IpUtils.getHostIp();
-
Map<String, String> wxparams = UnifiedOrderModel.builder().appid(params.getAppid())
-
.mch_id(params.getMchid()).nonce_str(WxPayKit.generateStr()).body(params.getBody()).attach(params.getAttach())
-
.out_trade_no(params.getOutTradeNo())
-
.mch_id(params.getMchid()).fee_type(params.getFeeType())
-
// 注意 微信单位是分 我的数据库存的是元 需要转换
-
.total_fee(String.valueOf(params.getTotalFee().intValue())).spbill_create_ip(ip)
-
.notify_url(params.getNotifyUrl()).trade_type(TradeType.JSAPI.getTradeType()).openid(params.getOpenid()).build()
-
.createSign(params.getMchKey(), SignType.MD5);
-
String xmlResult = WxPayApi.pushOrder(false, WxDomain.CHINA, wxparams);
-
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
-
String returnCode = result.get("return_code");
-
String returnMsg = result.get("return_msg");
-
if (!WxPayKit.codeIsOk(returnCode)) {
-
throw new SecurityException(returnMsg);
-
}
-
String resultCode = result.get("result_code");
-
if (!WxPayKit.codeIsOk(resultCode)) {
-
throw new SecurityException(returnMsg);
-
}
-
//实例化
-
installRecord(params);
-
// 以下字段在 return_code 和 result_code 都为 SUCCESS 的时候有返回
-
String prepayId = result.get("prepay_id");
-
Map<String, String> packageParams = WxPayKit.miniAppPrepayIdCreateSign(params.getAppid(), prepayId,
-
params.getMchKey(), SignType.MD5);
-
log.info("小程序支付统一下单返回参数:" packageParams.toString());
-
return packageParams;
-
-
}
-
-
/*
-
* @description:微信支付记录流水
-
* @author: zhanghui
-
* @date: 2022/9/16 0016 下午 4:32
-
**/
-
private void installRecord(WxOrderParams params){
-
System.out.println("入库");
-
WechatPaymentRecord record1 = recordService.selectByOutTradeNo(params.getOutTradeNo());
-
if(null==record1){
-
WechatPaymentRecord record = new WechatPaymentRecord();
-
record.setId(WxPayKit.generateStr());
-
record.setAttach(params.getAttach());
-
record.setBody(params.getBody());
-
record.setDetail(params.getDetail());
-
record.setFeeType(params.getFeeType());
-
record.setNickname(params.getNickname());
-
record.setOpenid(params.getOpenid());
-
record.setOrderType(params.getOrderType());
-
record.setOutTradeNo(params.getOutTradeNo());
-
record.setSpbillCreateIp(IpUtils.getHostIp());
-
record.setStatus(WxPlayStatus.PLACED.getCode());
-
record.setTradeType(TradeType.JSAPI.getTradeType());
-
record.setCreateBy(params.getOpenid());
-
record.setTotalFee(params.getTotalFee());
-
record.setOderBathNum(params.getOderBathNum());
-
record.setCreateTime(new Date());
-
recordService.insertWechatPaymentRecord(record);
-
}
-
}
-
-
// public WxPayApiConfig getApiConfig() {
-
// WxPayApiConfig apiConfig;
-
//
-
// try {
-
// apiConfig = WxPayApiConfigKit.getApiConfig();
-
// } catch (Exception e) {
-
// apiConfig = WxPayApiConfig.builder().appId(systemParamsConfig.getSpappid()).mchId(systemParamsConfig.getMchid())
-
// .partnerKey(systemParamsConfig.getPartnerKey()).certPath(systemParamsConfig.getCertPath())
-
// .domain(systemParamsConfig.getDomain()).build();
-
// }
-
// notifyUrl = apiConfig.getDomain().concat("/wxPay/payNotify");
-
// refundNotifyUrl = apiConfig.getDomain().concat("/wxPay/refundNotify");
-
// return apiConfig;
-
// }
-
-
/*
-
* @description:微信支付通知
-
* @author: zhanghui
-
* @date: 2022/9/15 0015 下午 4:00
-
*
-
* @param params 微信通知xml转map的参数
-
**/
-
@Override
-
public WechatPaymentRecord payNotify(Map<String, String> params,String mchKey) {
-
// 支付回调的code
-
String returnCode = params.get("return_code");
-
WechatPaymentRecord record= null;
-
if (WxPayKit.verifyNotify(params, mchKey, SignType.MD5)) {
-
if (WxPayKit.codeIsOk(returnCode)) {
-
String resultCode = params.get("result_code");
-
if (WxPayKit.codeIsOk(resultCode)) {
-
String outTradeNo = params.get("out_trade_no");
-
String transactionId = params.get("transaction_id");
-
-
String bankType = params.get("bank_type");
-
// 支付时间
-
String payTime = params.get("time_end");
-
String isSubscribe = params.get("is_subscribe");
-
record = recordService.selectByOutTradeNo(outTradeNo);
-
if(record!=null && record.getStatus()==WxPlayStatus.PLACED.getCode()){//订单不为空并且订单状态为已下单
-
record.setTransactionId(transactionId);
-
record.setBankType(bankType);
-
record.setTimeEnd(DateUtils.dateTime("yyyyMMddHHmmss",payTime));
-
record.setIsSubscribe(isSubscribe);
-
record.setStatus(WxPlayStatus.PAID.getCode());
-
record.setUpdateBy(record.getCreateBy());
-
recordService.updateWechatPaymentRecord(record);
-
}
-
}
-
-
}
-
}
-
return record;
-
}
-
-
/*
-
* @description:退款
-
* @author: zhanghui
-
* @date: 2022/9/15 0015 下午 4:01
-
**/
-
@Override
-
public String refund(RefundParams refundParams) {
-
return null;
-
}
-
-
/*
-
* @description:退款通知
-
* @author: zhanghui
-
* @date: 2022/9/15 0015 下午 4:01
-
**/
-
@Override
-
public void refundNotify(Map<String, String> params) {
-
-
}
-
}
数据库表:
-
CREATE TABLE `wechat_payment_record` (
-
`id` varchar(32) NOT NULL,
-
`transaction_id` varchar(50) DEFAULT NULL COMMENT '微信支付订单号',
-
`body` varchar(100) DEFAULT NULL COMMENT '商品描述',
-
`detail` varchar(100) DEFAULT NULL COMMENT '商品详情',
-
`attach` varchar(50) DEFAULT NULL COMMENT '附加数据',
-
`out_trade_no` varchar(20) DEFAULT NULL COMMENT '商户订单号',
-
`fee_type` varchar(10) DEFAULT NULL COMMENT '标价币种',
-
`total_fee` double DEFAULT NULL COMMENT '标价金额',
-
`spbill_create_ip` varchar(32) DEFAULT NULL COMMENT '终端IP',
-
`trade_type` varchar(10) DEFAULT NULL COMMENT '交易类型',
-
`openid` varchar(50) DEFAULT NULL COMMENT '用户标识',
-
`nickname` varchar(30) DEFAULT NULL COMMENT '微信昵称',
-
`is_subscribe` varchar(32) DEFAULT NULL COMMENT '是否关注公众账号',
-
`bank_type` varchar(32) DEFAULT NULL COMMENT '付款银行',
-
`time_end` datetime DEFAULT NULL COMMENT '支付时间',
-
`status` bigint(20) DEFAULT NULL COMMENT '1:已下单2:已关闭 3:已支付 4:退款中 5:已退款',
-
`order_type` varchar(20) DEFAULT NULL COMMENT '订单类型',
-
`refund_total_amount` varchar(20) DEFAULT NULL COMMENT '退款总金额',
-
`create_by` varchar(50) DEFAULT NULL COMMENT '创建者',
-
`create_time` datetime DEFAULT NULL,
-
`update_by` varchar(50) DEFAULT NULL,
-
`update_time` datetime DEFAULT NULL,
-
`receive_fruiter_batch_num` bigint(32) DEFAULT NULL COMMENT '申领果树批次',
-
PRIMARY KEY (`id`)
-
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='微信支付记录流水对象';
-
就这些后面有时间了再更新
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgbjfba
系列文章
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01