在微信小程序中玩家需要对NPC角色进行打赏,打赏的方式是通过微信支付来完成的 如何实现可参考微信支付开发文档
逻辑实现:
1、小程序获取用户相关openId,然后调用商户后台统一下单接口,换取预支付id
2、根据预支付id,小程序发起支付请求
3、提供微信支付通知接口给微信进行回调(此时可以对相关订单状态进行更新操作)

1、打赏效果图

2、前期准备

1、申请小程序,然后在小程序管理后台,申请接入微信支付

2、接入微信支付之后,配置支付相关秘钥以及下载商户证书

3、代码实现

1、根据微信支付官方文档提供的SDK进行开发

Gradle

在你的build.gradle文件中加入如下的依赖

implementation 'com.github.wechatpay-apiv3:wechatpay-apache-httpclient:0.2.2'

Maven

加入以下依赖

<dependency><groupId>com.github.wechatpay-apiv3</groupId><artifactId>wechatpay-apache-httpclient</artifactId><version>0.2.2</version>
</dependency>
<!--2、如果需要用第三方库实现可添加以下依赖
此处借用了第三库的校验和响应返回工具类
参考文档:https://www.cnblogs.com/laifw/p/10388052.html
-->
<dependency><groupId>com.egzosn</groupId><artifactId>pay-java-common</artifactId><version>2.12.1</version></dependency>
<dependency><groupId>com.egzosn</groupId><artifactId>pay-java-wx</artifactId><version>2.12.1</version>
</dependency>

2、创建微信请求HttpClient工具类

​
public class WxHttpClient{public static String appid = "XX";                             // 小程序idpublic static String mchId = "XX";                             // 商户号public static String mchSerialNo = "XX";                       // 商户证书序列号private static String apiV3Key = "XX";                         // api密钥public static String notify_url="";                            //微信支付通知回调
​private static volatile CloseableHttpClient wxHttpClient;private static AutoUpdateCertificatesVerifier verifier;
​private WxHttpClient(){}public static CloseableHttpClient getWxHttpClient() {if(wxHttpClient==null){synchronized (WxHttpClient.class){if(wxHttpClient==null){//加载私钥PrivateKey merchantPrivateKey = loadPrivateKey();
​//使用自动更新的签名验证器,不需要传入证书try {verifier = new AutoUpdateCertificatesVerifier(new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),apiV3Key.getBytes("utf-8"));} catch (UnsupportedEncodingException e) {e.printStackTrace();System.out.println("构建签名验证器失败!!!");}
​//构建HttpClientwxHttpClient = WechatPayHttpClientBuilder.create().withMerchant(mchId, mchSerialNo, merchantPrivateKey).withValidator(new WechatPay2Validator(verifier)).build();}}}return wxHttpClient;}
​public static PrivateKey loadPrivateKey(){PrivateKey merchantPrivateKey = null;try {merchantPrivateKey = PemUtil.loadPrivateKey(new FileInputStream("apiclient_key.pem"));} catch (FileNotFoundException e) {System.out.println(DateUtil.getCurrentDate()+"商户私钥加载异常");e.printStackTrace();}return merchantPrivateKey;}
​//第三方工具类需要的配置public static WxPayConfigStorage getWxPayConfigStorage(){WxPayConfigStorage wxPayConfigStorage = new WxPayConfigStorage();wxPayConfigStorage.setMchId(mchId);//支付商户号wxPayConfigStorage.setAppid(appid);//小程序appid// wxPayConfigStorage.setKeyPublic("转账公钥,转账时必填");wxPayConfigStorage.setSecretKey("");// 商户支付密钥(之前设置的商户apiv3秘钥)wxPayConfigStorage.setSignType("MD5");wxPayConfigStorage.setInputCharset("utf-8");return wxPayConfigStorage;}
}

3、小程序调用下单及微信支付通知Controller

@RestController
@RequestMapping("/wxpay")
public class WxPayController {@Resourceprivate UserService userService;
​@Autowiredprivate WxPayService wxPayService;
​@Autowiredprivate UserCreditService userCreditService;
​private com.egzosn.pay.wx.api.WxPayService wxUserPayService=new com.egzosn.pay.wx.api.WxPayService(WxHttpClient.getWxPayConfigStorage());
​/*** @Desc 统一下单* @Date 2021/5/22 13:38*/@RequestMapping("/unifiedOrder")@SysLog(name="统一下单")public ResultVO unifiedOrder(@RequestBody UserCredit userCredit) throws IOException {//校验参数是否为空BeanValidator.validate(userCredit, Creation.class);
​//判断当前用户是否存在于系统中User user=new User();user.setId(userCredit.getUserId());user.setOpenId(userCredit.getOpenId());List<User> users = userService.selectAllData(user);if(CollectionUtils.isEmpty(users)){throw new BusinessException(0,"非系统用户,拒绝访问");}String outTradeNo=WxPayUtil.getOutTradeNo(userCredit.getUserId()+"");userCredit.setAddTime(DateUtil.getCurrentDate());userCredit.setOutTradeNo(outTradeNo);userCredit.setTradeStatus(0);
​//调用微信下单接口String prepay_id_str = wxPayService.unifiedOrder(userCredit);
​JSONObject rsobject=JSONObject.parseObject(prepay_id_str);return ResultVOUtil.success(rsobject,"下单成功");}
​
​/**** 微信用户支付回调接口*/@RequestMapping("/userPayCallBack")public String wxUserPaycallback(HttpServletRequest request) {try {Map<String, Object> params = wxUserPayService.getParameter2Map(request.getParameterMap(),request.getInputStream());if (null == params) {throw new Exception("回调参数为空");}// 校验if (!wxUserPayService.verify(params)) {throw new Exception("校验失败");}payDone(params);//支付处理return wxUserPayService.getPayOutMessage("SUCCESS", "成功").toMessage();
​} catch (Exception e) {e.printStackTrace();return wxUserPayService.getPayOutMessage("FALL", "失败").toMessage();}}
​/*** 支付结果处理*/private void payDone(Map<String, Object> dataMap) throws Exception {System.out.println("支付回调:" + JSON.toJSONString(dataMap));String result_code = dataMap.get("result_code").toString();   //支付结果codeString out_trade_no = dataMap.get("out_trade_no").toString(); //商户交易订单id,此为支付记录id
​if (!result_code.equals("SUCCESS")) {throw new Exception("支付回调失败:" + JSON.toJSONString(dataMap));}UserCredit userCredit=new UserCredit();userCredit.setOutTradeNo(out_trade_no);List<UserCredit> userCredits = userCreditService.selectAllData(userCredit);//获取打赏记录if (CollectionUtils.isEmpty(userCredits)) {throw new Exception("无支付记录,回调处理失败!!!");}userCredit.setTradeStatus(result_code.equals("SUCCESS") ? 1 : 2);userCredit.setOutTradeNo(out_trade_no);int updateFlag=userCreditService.updateCredit(userCredit);//根据回调结果更改支付结果状态if(updateFlag==0){throw new Exception("更新用户打赏表状态失败!!!");}}
}
​

4、创建微信支付服务类

@Service
public class WxPayServiceImpl implements WxPayService {@Autowiredprivate UserCreditService userCreditService;
​private CloseableHttpClient wxHttpClient=WxHttpClient.getWxHttpClient();
​/*** @Desc 统一下单接口* @Date 2021/5/22 15:39*/@Overridepublic String unifiedOrder(UserCredit userCredit)  throws IOException {//添加微信下单记录userCreditService.insertUserCredit(userCredit);
​HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");httpPost.addHeader("Accept", "application/json");httpPost.addHeader("Content-type","application/json; charset=utf-8");
​ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectMapper objectMapper = new ObjectMapper();
​ObjectNode rootNode = objectMapper.createObjectNode();rootNode.put("mchid", WxHttpClient.mchId).put("appid", WxHttpClient.appid).put("description", "Image形象店-深圳腾大-QQ公仔").put("notify_url", WxHttpClient.notify_url).put("out_trade_no", userCredit.getOutTradeNo());rootNode.putObject("amount").put("total", userCredit.getAmount());rootNode.putObject("payer").put("openid", userCredit.getOpenId());
​objectMapper.writeValue(bos, rootNode);
​httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));CloseableHttpResponse response = wxHttpClient.execute(httpPost);
​String prepay_id_str = EntityUtils.toString(response.getEntity());JSONObject object=JSONObject.parseObject(prepay_id_str);Object code = object.get("code");if(code!=null){if(code.toString().equals("PARAM_ERROR")){throw new BusinessException(0,"下单失败:"+object.get("message"));}}return prepay_id_str;}
}

springboot实现小程序打赏支付功能相关推荐

  1. 字节跳动小程序接入支付功能

    我个人博客文章地址:字节跳动小程序接入支付功能 这个文章只是我做完支付后的总结,尽量写的简单易懂,也是方便自己以后忘了看一眼就能懂

  2. 小程序 php wecahtpay,【PHP】laravel 实现微信小程序微信支付功能

    准备工作 准备来laravel框架,下载好 overtrue/laravel-wechat 第三方插件composerrequireovertrue/wechat:~4.0-vvv PHP代码 调用支 ...

  3. PHP完成微信小程序在线支付功能

    微信支付现在用到的地方越来越多,从公众号支付,扫码支付一直到现在的小程序支付等等六种快捷支付方式,公司要求开发小程序商城,就只能我上手处理接口支付问题了,使用最常规的第三方模式,第三方帮特约商户申请商 ...

  4. 小白也能看懂的教程:微信小程序在线支付功能开通详细流程(图文介绍)

    微信小程序不仅是一个展示平台,更多会用到小程序的电商功能,当然了,支付目前而言需要接入微信支付,那么具体而言,微信小程序要怎么开通支付功能呢?最近需要在微信小程序中用到在线支付功能,于是看了一下官方的 ...

  5. 微信小程序实现支付功能

    小程序支付,没有封装支付代码:直接上一段可用的流程代码吧: 微信小程序支付官网文档有详细的说明,这里我就不再赘述啦: 客户端js: wx.request({ url:'https://www.xxxx ...

  6. 小程序微信支付功能开发

    关于小程序内唤起微信支付功能,不同人有不同的思路,有嵌套H5页面的,也有跳转第三方链接网站的,也有放收钱码等图片的. 今天讲一下微信原生的微信支付功能基础版块,支付页面和支付逻辑. 先上个效果图: 页 ...

  7. 【Node.js】实现微信小程序在线支付功能

    实战项目名称:微信小程序实现在线支付功能 - 文章结尾附上微信小程序码,扫码登录后即可体验!! 文章目录 一.实战步骤 1. 前期准备 2. 添加`wechatpay-node-v3`和`fs`插件 ...

  8. uniapp小程序微信支付功能

    目录 字段说明 前置工作 获取openid 微信支付 报错问题 uniapp 开发小程序需要实现微信支付功能,下面对相关业务进行说明. 字段说明 AppID:小程序的身份证,微信客户端用来确认你的小程 ...

  9. SpringBoot实现小程序微信支付统一下单

    SpringBoot实现微信支付统一下单 最近做小程序有需要用到微信支付,而在页面拉起微信支付前需要先进行统一下单,然后再返回参数给前端调用微信支付wx.requestPayment.网上参考了很多代 ...

最新文章

  1. nn.embding()使用注意点
  2. 不使用框架的web项目中配置log4j
  3. c语言中,为什么%o、%d、%x输出的总是32位,如char占一个字节,但输出却是32位
  4. 机器学习算法之隐马尔可夫模型
  5. tif 高程_使用ArcGIS提取高程点
  6. JavaScript开发区块链只需200行代码 1
  7. 力扣236. 二叉树的最近公共祖先(JavaScript)
  8. HDFS基本命令及上传文件API
  9. ADO.NET 3.5 同SQL 2008的新的存储过程保存方式
  10. IS-IS详解(十七)——IS-IS 区域迁移与路由汇总
  11. Datagridview中的数据很多,加载完数据后滚动条自动到最下边,如何解决?
  12. 9008刷机模式写入超时刷机帮_【转】高通9008模式刷机,让小米刷机不再畏惧
  13. go语言读取xls表格xls文件操作替代解决方案
  14. ASM磁盘状态为forcing
  15. 空气质量指数计算公式
  16. T-SQL数据库修改、删除
  17. java程序调用时的调用规则,Java程序调用ILog规则出错
  18. 华为手机体验鸿蒙系统,再过40天,你就能在华为手机上,体验到鸿蒙系统了? - 区块网...
  19. python分析各因素之间的相关性
  20. wgc84 笛卡尔_从经纬度到笛卡尔坐标的转换

热门文章

  1. unity5.6滑雪游戏skiing源码DownhillSkiingGame。支持安卓+IOS双端 C#语言开发。
  2. cocos-js web开发泡泡龙游戏【一 加载游戏场景】
  3. Android 9.0系统源码_SystemUI(三)系统状态图标控制
  4. 一个小项目--银行项目
  5. python编写万年日历解析_python生成日历实例解析
  6. 艾美捷CpG ODN——ODN 1720 (TLRGRADE)说明书
  7. TiDB Sysbench 性能对比测试报告 - v5.1.4 对比 v6.0.0 DMR
  8. PHP调用Python失败的解决办法
  9. 对象问题(突然让我懵逼的问题)
  10. 颜值爆表功能强大,乐Pro3双摄AI版暗夜黑版5月17日预约