SpringBoot2.0小程序支付功能实现weixin-java-pay
SpringBoot2.0小程序支付功能实现weixin-java-pay
WxJava - 微信开发 Java SDK(开发工具包); 支持包括微信支付、开放平台、公众号、企业微信/企业号、小程序等微信功能的后端开发。
第一步: SDK使用方式
Maven方式引入:
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>(不同模块参考下文)</artifactId>
<version>3.3.0</version>
</dependency>
各模块的artifactId:
- 微信小程序:
weixin-java-miniapp - 微信支付:
weixin-java-pay - 微信开放平台:
weixin-java-open - 公众号(包括订阅号和服务号):
weixin-java-mp - 企业号/企业微信:
weixin-java-cp
第二步:配置微信相关信息
application.yml
#微信小程序配置
wx:
miniapp:
configs:
- appid: #微信公众号或者小程序等的appid 必填
secret: #微信公众号或者小程序等的secret 必填
token: #微信小程序消息服务器配置的token
aesKey: #微信小程序消息服务器配置的EncodingAESKey
msgDataFormat: JSON
pay:
appId: #微信公众号或者小程序等的appid 必填
mchId: #微信支付商户号 必填
mchKey: #微信支付商户密钥
subAppId: #服务商模式下的子商户公众账号ID
subMchId: #服务商模式下的子商户号
keyPath: classpath:cert/apiclient_cert.p12 # p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头)
notifyUrl: https://www.xxx.com/wx/notify #微信支付回调地址 自己定义但是必须放到外网微信可以访问的到
第三步:编写统一订单接口业务
调用统一下单支付接口:wxService.createOrder(orderRequest)
/**
* @Title: WxUserVedioController.java
* @Package io.renren.modules.wx.controller
* @Description:
* Copyright: Copyright (c) 2019 www.codepeople.cn Inc. All rights reserved.
* Website: www.codepeople.cn
* 注意:本内容仅限于海南科澜技术信息有限公司内部传阅,禁止外泄以及用于其他的商业目
* @Author 刘仁
* @DateTime 2019年4月6日 上午11:54:08
* @version V1.0
*/
package io.renren.modules.wx.controller;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import io.renren.common.utils.DateUtils;
import io.renren.common.utils.IPUtils;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.R;
import io.renren.modules.soft.entity.AuthorizationEntity;
import io.renren.modules.soft.entity.HospitalEntity;
import io.renren.modules.soft.entity.OrderEntity;
import io.renren.modules.soft.entity.PayFlowEntity;
import io.renren.modules.soft.entity.PurchaseRecordEntity;
import io.renren.modules.soft.entity.RefundRecordEntity;
import io.renren.modules.soft.service.AuthorizationService;
import io.renren.modules.soft.service.BedBaseService;
import io.renren.modules.soft.service.DeviceService;
import io.renren.modules.soft.service.HospitalService;
import io.renren.modules.soft.service.OrderService;
import io.renren.modules.soft.service.PayFlowService;
import io.renren.modules.soft.service.PurchaseRecordService;
import io.renren.modules.soft.service.RefundRecordService;
import io.renren.modules.soft.service.StatementService;
import io.renren.modules.soft.service.ThirdUserService;
import io.renren.modules.soft.service.UserAuthorizationService;
import io.renren.modules.soft.service.UserService;
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;
/**
* @ClassName: WxUserVedioController
* @Description:
* @Author 刘仁
* @DateTime 2019年4月6日 上午11:54:08
*/
@Api(tags = "普通用户操作接口")
@RestController
@RequestMapping("/wx")
@Slf4j
public class WxxxxUserVedioController {
@Value("${wx.notifyUrl}")
private String notifyUrl;
@Autowired
private WxPayService wxService;
@Autowired
private HospitalService hospitalService;
@Autowired
private PayFlowService payFlowService;
@Autowired
private OrderService orderService;
/**
* @Title: createOrder
* @Description:
* @Author 刘仁
* @DateTime 2019年4月6日 下午12:12:11
* @param
* @return
*/
@PostMapping("/user/createOrder")
public R createOrder(HttpServletRequest request,@RequestBody Map<String,String> map) throws WxPayException{
String bed_id = map.get("bedId");
log.info("参数的bed_id:{}", bed_id);
if (StringUtils.isAnyBlank(bed_id)) {
return R.error("参数不能为null");
}
Long bedId = Long.valueOf(bed_id).longValue();
//根据bedId 查找所属医院的价格
HospitalEntity hospitalEntity = hospitalService.hospitalByBedId(bed_id.trim());
BigDecimal money = hospitalEntity.getCharge();
HttpSession session = request.getSession();
String mobile = (String) session.getAttribute("userphone");
String userId = (String) session.getAttribute("userId");
// TODO 插入订单记录
// TODO 记录用户的购买记录
// TODO 调用统一生成订单接口
WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
orderRequest.setSignType(WxPayConstants.SignType.MD5);
orderRequest.setBody("短信主体");
orderRequest.setOutTradeNo(order_No); //自己生成order_No
orderRequest.setTradeType(WxPayConstants.TradeType.JSAPI);
// orderRequest.setTotalFee(BaseWxPayRequest.yuanToFen(yuanMoney));//直接分
orderRequest.setTotalFee(money.intValue());//直接分
orderRequest.setOpenid(userEntity.getOpenid()); // 获取微信支付用户的openId
orderRequest.setSpbillCreateIp(IPUtils.getIpAddr(request));
Date now = new Date();
Date afterDate = DateUtils.addDateMinutes(now, 10);//10分钟后
orderRequest.setTimeStart(DateUtils.format(now, "yyyyMMddHHmmss"));
orderRequest.setTimeExpire(DateUtils.format(afterDate, "yyyyMMddHHmmss"));
orderRequest.setNotifyUrl(notifyUrl);
Object order = wxService.createOrder(orderRequest);
return R.ok().put("order", order);
}
@ApiOperation("微信支付回调地址")
@ResponseBody
@PostMapping("/notify")
public String payNotify(HttpServletRequest request, HttpServletResponse response) {
try {
/*HttpSession session = request.getSession();
String mobile = (String) session.getAttribute("userphone");
if (StringUtils.isBlank(mobile)) {
return R.error(401, "session获取不到授权手机号!");
}
//获取用户手机号,根据用户手机号获取用户ID
AuthorizationEntity user = authorizationService.getOneByMobile(mobile);*/
String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
WxPayOrderNotifyResult notifyResult = wxService.parseOrderNotifyResult(xmlResult);
// 结果正确 outTradeNo
String orderId = notifyResult.getOutTradeNo();
String tradeNo = notifyResult.getTransactionId();
String totalFee = BaseWxPayResult.fenToYuan(notifyResult.getTotalFee());
if("SUCCESS".equals(notifyResult.getResultCode())) {
PayFlowEntity entity = new PayFlowEntity();
entity.setPayFee(BigDecimal.valueOf(notifyResult.getCashFee()));
entity.setPayFlowNo(orderId);
entity.setPayUserInfo(notifyResult.getOpenid());
entity.setThreeInNo(tradeNo);
payFlowService.save(entity);
OrderEntity order_entity = new OrderEntity();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
order_entity.setCreateTime(new Date());
//更新订单信息
UpdateWrapper<OrderEntity> updateWrapper = new UpdateWrapper<>();
updateWrapper.set("order_status", "1");
updateWrapper.set("pay_id", notifyResult.getOpenid());
updateWrapper.set("pay_status", "1");
updateWrapper.set("pay_end_time", sdf.parse(notifyResult.getTimeEnd()));
updateWrapper.eq("order_no",notifyResult.getOutTradeNo());
orderService.update(updateWrapper);
}
//自己处理订单的业务逻辑,需要判断订单是否已经支付过,否则可能会重复调用
return WxPayNotifyResponse.success("成功");
} catch (Exception e) {
log.error("微信回调结果异常,异常原因{}", e.getMessage());
// WxPayNotifyResponse.fail(e.getMessage());
return WxPayNotifyResponse.success("code:"+9999+"微信回调结果异常,异常原因:"+e.getMessage());
}
}
}
第四步:小程序端可以操作了
小程序端主要先调用小程序接口获取用户信息主要是code,然后传给后台,后台通过code获取openid获取方式:
WxMaService wxService = WxMaConfiguration.getMaService(appid);
WxMaJscode2SessionResult wx_session = wxService.getUserService().getSessionInfo(code);
openId = wx_session.getOpenid();
log.info("通过微信获取用户的openId==>{}", openId);
然后根据回调地址返回的数据,小程序就可以对数据进行解析封装调用支付接口进行付款了。
这里主要讲的后端的使用方法
==================================================================
博客地址:https://www.codepeople.cn
==================================================================
SpringBoot2.0小程序支付功能实现weixin-java-pay的更多相关文章
- 微信小程序 --- 完成小程序支付功能
最近开发小程序,一直在看小程序的支付.经过一天的努力,小程序支付功能最终实现了. 下面感谢 csdn 博主:千堆雪惹尘埃 发布的 " 小程序与php 实现微信支付 " 原文地址: ...
- 微信小程序支付功能 C# .NET开发
微信小程序支付功能的开发的时候坑比较多,不过对于钱的事谨慎也是好事.网上关于小程序支付的实例很多,但是大多多少有些问题,C#开发的更少.此篇文档的目的是讲开发过程中遇到的问题做一个备注,也方便其他开发 ...
- 微信小程序支付功能前端流程
只是分享一下小程序支付功能的前端流程和代码, 仅供参考(使用的是uni app). handleCreate () { /** 第一步:前台将商品数据发送到后台,后台创建订单入库并返回订单id等信息 ...
- 微信小程序支付功能讲解(2)
小程序支付 业务流程时序图 官方文档 步骤: 1. Openid 在小程序初次加载的时候就已经获取(详情见 小程序登录) 2. 生成商户订单 1.商品信息由小程序端提供 2.提供支付统一下单接口所需参 ...
- Python实现微信小程序支付功能
由于最近自己在做小程序的支付,就在这里简单介绍一下讲一下用python做小程序支付这个流程.当然在进行开发之前还是建议读一下具体的流程,清楚支付的过程. 1.支付交互流程 当然具体的参数配置可以参考官 ...
- 微信小程序支付功能讲解(1)
前言:虽然小程序做过很多,但是一直觉得微信支付功能很是神秘,现在终于有机会接触心里还是有点小激动的,经过一番折腾发现支付也不过如此,在此记录下支付功能的实现过程 小程序的官方文档介绍到发起微信支付即调 ...
- 微信小程序支付功能讲解
前言:虽然小程序做过很多,但是一直觉得微信支付功能很是神秘,现在终于有机会接触心里还是有点小激动的,经过一番折腾发现支付也不过如此,在此记录下支付功能的实现过程 小程序的官方文档介绍到发起微信支付即调 ...
- 微信小程序 支付功能(前端)的实现
只提供微信小程序端代码: var app = getApp(); Page({ data: {}, onLoad: function (options) { // 页面初始化 options为页面跳转 ...
- 微信小程序 支付功能 服务器端(TP5.1)实现
首先下载微信支付SDK ,将整个目录的文件放在 /application/extend/WxPay 目录下 在使用SDK之前我们需要对 WxPay.Config.php 进行配置 <?php n ...
随机推荐
- JavaSE | 接口| 枚举| 注释| 异常
包: 1.包的作用:(1)避免类的同名(区分类):类的全名称:包.类名 回忆:java.util.Scannerjava.util.Arraysjava.lang.Stringj(2)可以限定某些类或 ...
- 实现判断条件中有in的判断
如果是简单的写sql,在where中写死就可以了,但是如果是不确定的参数呢,这个时候就需要一点处理方式了. 1.后台的写法 String[] operateResult=new String[]{&q ...
- tensorflow基础架构 - 处理结构+创建一个线性回归模型+session+Variable+Placeholder
以下仅为自己的整理记录,绝大部分参考来源:莫烦Python,建议去看原博客 一.处理结构 因为TensorFlow是采用数据流图(data flow graphs)来计算, 所以首先我们得创建一个数据 ...
- Python3.4+Django1.9+Bootstrap3
实现和原理 Python集成Django开发框架后,可以通过在cmd命令提示符下建立工程,工程名为learn_models 1 django-admin.py startproject learn_m ...
- linux文件打包并发送到其他服务器
scp /data/backup/mongodump/mongodb.$DATE.tar root@192.168.1.70:/home/iscsi/mongodb/
- JavaEE 之 log4j
1.log4j a.概念:一个非常优秀的开源日志记录工具 b.配置: ①src同目录下建立log4j.properties文件,书写: log4j.rootLogger=debug,appender1 ...
- Windows10家庭版如何升级至Windows10专业版
Windows10家庭版和专业版系统文件其实是一样的iso镜像文件,但是由于Microsoft某些限制导致一些用户无法享受到专业版的福利,说实话这是一种很让人蛋疼的操作... 接下来我来告诉各位如何把 ...
- 自己总结的C#编码规范--4.注释篇
注释 注释毫无疑问是让别人以最快速度了解你代码的最快途径,但写注释的目的绝不仅仅是"解释代码做了什么",更重要的尽量帮助代码阅读者对代码了解的和作者一样多. 当你写代码时,你脑海里 ...
- 错误类型“Microsoft.Office.Interop.Word.ApplicationClass”未定义构造函数
原文网址:http://zhidao.baidu.com/link?url=WcvaYFI1JeEGvbjD77nDbGp21sjaNCnCTRLGrU5YjwUGbHbhHJxQolKbsMZbZs ...
- 在Node.js中在保持目录结构的情况下压缩指定目录
最近在做一个文件升级的功能,需要从下载服务器中指定目录下的文件.在学习了zlib后发现这个模块达不到这个功能 在查找资料后发现后发现 archiver 模块很好用,不过我也发现大部分中文资料没有如果查 ...