Java实现微信小程序支付(准备)
Java语言开发微信小程序支付功能:
1.通过https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1路径到官方下载Java的支付SDK。
2.下载后将pom文件中需要用到的jar包导入自己的项目中,将demo全部导入到自己的工具包中,需导入的demo如下图:
3.此时缺少IWXPayDomain与WXPayConfig抽象类的具体实现,新建WXPayDomainSimpleImpl与WXPayConfigImpl来分别实现抽象类,代码如下:
WXPayDomainSimpleImpl代码:
- package com.karat.cn.util;
- import org.apache.http.conn.ConnectTimeoutException;
- import java.net.UnknownHostException;
- import java.util.HashMap;
- import java.util.Map;
- /**
- * Created by blaketang on 2017/6/16.
- */
- public class WXPayDomainSimpleImpl implements IWXPayDomain {
- private WXPayDomainSimpleImpl(){}
- private static class WxpayDomainHolder{
- private static IWXPayDomain holder = new WXPayDomainSimpleImpl();
- }
- public static IWXPayDomain instance(){
- return WxpayDomainHolder.holder;
- }
- public synchronized void report(final String domain, long elapsedTimeMillis, final Exception ex) {
- DomainStatics info = domainData.get(domain);
- if(info == null){
- info = new DomainStatics(domain);
- domainData.put(domain, info);
- }
- if(ex == null){ //success
- if(info.succCount >= 2){ //continue succ, clear error count
- info.connectTimeoutCount = info.dnsErrorCount = info.otherErrorCount = 0;
- }else{
- ++info.succCount;
- }
- }else if(ex instanceof ConnectTimeoutException){
- info.succCount = info.dnsErrorCount = 0;
- ++info.connectTimeoutCount;
- }else if(ex instanceof UnknownHostException){
- info.succCount = 0;
- ++info.dnsErrorCount;
- }else{
- info.succCount = 0;
- ++info.otherErrorCount;
- }
- }
- public synchronized DomainInfo getDomain(final WXPayConfig config) {
- DomainStatics primaryDomain = domainData.get(WXPayConstants.DOMAIN_API);
- if(primaryDomain == null ||
- primaryDomain.isGood()) {
- return new DomainInfo(WXPayConstants.DOMAIN_API, true);
- }
- long now = System.currentTimeMillis();
- if(switchToAlternateDomainTime == 0){ //first switch
- switchToAlternateDomainTime = now;
- return new DomainInfo(WXPayConstants.DOMAIN_API2, false);
- }else if(now - switchToAlternateDomainTime < MIN_SWITCH_PRIMARY_MSEC){
- DomainStatics alternateDomain = domainData.get(WXPayConstants.DOMAIN_API2);
- if(alternateDomain == null ||
- alternateDomain.isGood() ||
- alternateDomain.badCount() < primaryDomain.badCount()){
- return new DomainInfo(WXPayConstants.DOMAIN_API2, false);
- }else{
- return new DomainInfo(WXPayConstants.DOMAIN_API, true);
- }
- }else{ //force switch back
- switchToAlternateDomainTime = 0;
- primaryDomain.resetCount();
- DomainStatics alternateDomain = domainData.get(WXPayConstants.DOMAIN_API2);
- if(alternateDomain != null)
- alternateDomain.resetCount();
- return new DomainInfo(WXPayConstants.DOMAIN_API, true);
- }
- }
- static class DomainStatics {
- final String domain;
- int succCount = 0;
- int connectTimeoutCount = 0;
- int dnsErrorCount =0;
- int otherErrorCount = 0;
- DomainStatics(String domain) {
- this.domain = domain;
- }
- void resetCount(){
- succCount = connectTimeoutCount = dnsErrorCount = otherErrorCount = 0;
- }
- boolean isGood(){ return connectTimeoutCount <= 2 && dnsErrorCount <= 2; }
- int badCount(){
- return connectTimeoutCount + dnsErrorCount * 5 + otherErrorCount / 4;
- }
- }
- private final int MIN_SWITCH_PRIMARY_MSEC = 3 * 60 * 1000; //3 minutes
- private long switchToAlternateDomainTime = 0;
- private Map<String, DomainStatics> domainData = new HashMap<String, DomainStatics>();
- }
WXPayConfigImpl代码:
- package com.karat.cn.util;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.ByteArrayInputStream;
- import java.io.InputStream;
- public class WXPayConfigImpl extends WXPayConfig{
- /**==========================================================================**/
- private byte[] certData;
- private static WXPayConfigImpl INSTANCE;
- private WXPayConfigImpl() throws Exception{
- String certPath = WXPayConfigImpl.class.getClassLoader().getResource("").getPath();
- File file = new File(certPath + "apiclient_cert.p12");
- InputStream certStream = new FileInputStream(file);
- this.certData = new byte[(int) file.length()];
- certStream.read(this.certData);
- certStream.close();
- }
- public static WXPayConfigImpl getInstance() throws Exception{
- if (INSTANCE == null) {
- synchronized (WXPayConfigImpl.class) {
- if (INSTANCE == null) {
- INSTANCE = new WXPayConfigImpl();
- }
- }
- }
- return INSTANCE;
- }
- /**==========================================================================**/
- @Override
- public String getAppID() {
- // TODO Auto-generated method stub
- return "小程序AppId";
- }
- @Override
- public String getMchID() {
- // TODO Auto-generated method stub
- return "商户号";
- }
- @Override
- public String getKey() {
- // TODO Auto-generated method stub
- return "商户密钥";
- }
- @Override
- public InputStream getCertStream() {
- // TODO Auto-generated method stub
- ByteArrayInputStream certBis;
- certBis = new ByteArrayInputStream(this.certData);
- return certBis;
- }
- @Override
- public IWXPayDomain getWXPayDomain() {
- // TODO Auto-generated method stub
- return WXPayDomainSimpleImpl.instance();
- }
- }
4.向WXPayConstants.java中添加常量:
- public static final String TRANSFERS_URL_SUFFIX = "/mmpaymkttransfers/promotion/transfers";
- public static final String SANDBOX_SENDREDPACK_URL_SUFFIX = "/sandboxnew/mmpaymkttransfers/sendredpack";
- public static final String SANDBOX_TRANSFERS_URL_SUFFIX = "/sandboxnew/mmpaymkttransfers/promotion/transfers";
5.向WXPay.java中添加如下代码:
- /********************************************/
- // 企业付款
- public String transfers(Map<String, String> reqData) throws Exception {
- return this.transfers(reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
- }
- public String transfers(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
- String url;
- if (this.useSandbox) {
- url = WXPayConstants.SANDBOX_TRANSFERS_URL_SUFFIX;
- }
- else {
- url = WXPayConstants.TRANSFERS_URL_SUFFIX;
- }
- return this.requestWithCert(url, this.transfersRequestData(reqData), connectTimeoutMs, readTimeoutMs);
- }
- // 企业付款
- public Map<String, String> transfersRequestData(Map<String, String> reqData) throws Exception {
- // 商户号绑定的appid(小程序的appid)
- reqData.put("mch_appid", config.getAppID());
- // 商户号
- reqData.put("mchid", config.getMchID());
- // 随机字符串
- reqData.put("nonce_str", WXPayUtil.generateUUID());
- reqData.put("sign", WXPayUtil.generateSignature(reqData, config.getKey(), this.signType));
- return reqData;
- }
- /********************************************/
6.创建订单表以及返回给小程序端的参数vo
- package com.karat.cn.wxCommon;
- import java.util.Map;
- import org.springframework.data.annotation.Id;
- import org.springframework.data.mongodb.core.index.Indexed;
- import org.springframework.data.mongodb.core.mapping.Document;
- /**
- * 订单表
- * @author 开发
- *
- */
- @Document(collection = "wxWithdrawOrder")
- public class WxWithdrawOrder {
- /**
- * id
- */
- @Id
- private String id;
- /**
- * 会员id
- */
- @Indexed
- private String memberId;
- /**
- * 订单号
- */
- @Indexed(unique = true)
- private String orderNo;
- /**
- * 提现金额(分)
- */
- private int money;
- /**
- * 提现时间
- */
- private String createDate;
- /**
- * 订单状态(0:申请失败或异常 1:已申请成功)
- */
- private String orderStatus;
- /**
- * 扩展
- */
- private Map<String, String> remark;
- /**
- * 扩展2
- */
- private String remark2;
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
- public String getMemberId() {
- return memberId;
- }
- public void setMemberId(String memberId) {
- this.memberId = memberId;
- }
- public String getOrderNo() {
- return orderNo;
- }
- public void setOrderNo(String orderNo) {
- this.orderNo = orderNo;
- }
- public int getMoney() {
- return money;
- }
- public void setMoney(int money) {
- this.money = money;
- }
- public String getCreateDate() {
- return createDate;
- }
- public void setCreateDate(String createDate) {
- this.createDate = createDate;
- }
- public Map<String, String> getRemark() {
- return remark;
- }
- public void setRemark(Map<String, String> remark) {
- this.remark = remark;
- }
- public String getRemark2() {
- return remark2;
- }
- public void setRemark2(String remark2) {
- this.remark2 = remark2;
- }
- public String getOrderStatus() {
- return orderStatus;
- }
- public void setOrderStatus(String orderStatus) {
- this.orderStatus = orderStatus;
- }
- }
- package com.karat.cn.vo;
- /**
- * 调用微信支付相关信息
- * @author 开发
- *
- */
- public class VoUnifiedOrderWx {
- // 时间戳
- private String timeStamp;
- // 随机串
- private String nonceStr;
- // 数据包
- private String packageValue;
- // 签名
- private String sign;
- public String getTimeStamp() {
- return timeStamp;
- }
- public void setTimeStamp(String timeStamp) {
- this.timeStamp = timeStamp;
- }
- public String getNonceStr() {
- return nonceStr;
- }
- public void setNonceStr(String nonceStr) {
- this.nonceStr = nonceStr;
- }
- public String getPackageValue() {
- return packageValue;
- }
- public void setPackageValue(String packageValue) {
- this.packageValue = packageValue;
- }
- public String getSign() {
- return sign;
- }
- public void setSign(String sign) {
- this.sign = sign;
- }
- }
7.创建工具类(获取系统时间)
- package com.karat.cn.wxCommon;
- import java.text.ParseException;
- import java.util.Date;
- public class BaseToolsUtil {
- /**
- * 获取系统时间long
- *
- * @return
- * @throws ParseException
- */
- public static long systemtimeLong() {
- return new Date().getTime();
- }
- }
8.准备工作完毕,开始实现小程序支付,退款,提现功能。
Java实现微信小程序支付(准备)的更多相关文章
- Java 后端微信小程序支付demo (网上说的坑里面基本上都有)
Java 后端微信小程序支付 一.遇到的问题 1. 商户号该产品权限未开通,请前往商户平台>产品中心检查后重试 2.签名错误 3.已经调起微信统一下单接口,可以拿到预支付ID,但是前端支付的时候 ...
- Java实现微信小程序支付(完整版)
在开发微信小程序支付的功能前,我们先熟悉下微信小程序支付的业务流程图: 不熟悉流程的建议还是仔细阅读微信官方的开发者文档. 一,准备工作 事先需要申请企业版小程序,并开通“微信支付”(即商户功能).并 ...
- Java实现微信小程序支付(支付,提现,退款)
1.添加WXpayCommon类用以具体实现功能,代码如下: package com.karat.cn.wxCommon; import java.io.IOException; import jav ...
- 【原创】微信小程序支付java后台案例(公众号支付同适用)(签名错误问题)
前言 1.微信小程序支付官方接口文档:[点击查看微信开放平台api开发文档]2.遇到的坑:预支付统一下单签名结果返回[签名错误]失败,建议用官方[签名验证工具]检查签名是否存在问题.3.遇到的坑:签名 ...
- 微信小程序支付开发之申请退款
微信小程序支付跟微信公众号支付类似,这里不另做记录,如果没有开发过支付,可以查看我关于微信支付的文章 重点记录微信小程序申请退款开发过程中遇到一些坑. 退款接口比支付接口接口多了一个 双向证书 证书介 ...
- SpringBoot2.0微信小程序支付多次回调问题
SpringBoot2.0微信小程序支付多次回调问题 WxJava - 微信开发 Java SDK(开发工具包); 支持包括微信支付.开放平台.公众号.企业微信/企业号.小程序等微信功能的后端开发. ...
- 微信小程序支付步骤
http://blog.csdn.net/wangsf789/article/details/53419781 最近开发微信小程序进入到支付阶段,一直以来从事App开发,所以支付流程还是熟记于心的.但 ...
- 微信小程序支付及退款流程详解
微信小程序的支付和退款流程 近期在做微信小程序时,涉及到了小程序的支付和退款流程,所以也大概的将这方面的东西看了一个遍,就在这篇博客里总结一下. 首先说明一下,微信小程序支付的主要逻辑集中在后端,前端 ...
- php对接微信小程序支付
前言:这里我就假装你已经注册了微信小程序,并且基本的配置都已经好了.注: 个人注册小程序不支持微信支付,所以我还是假装你是企业或者个体工商户的微信小程序,其他的商户号注册,二者绑定,授权,支付开通,就 ...
随机推荐
- 获取Linux权限后安装rootkit
1.首先获得远程服务器的root权限,当然这是基本的也是最难的. 2.然后下载rootkit程序,本文用到的是mafix. 3.开始安装 wget http://godpock.googlecode. ...
- Howto Reboot or halt Linux system in emergency (ZT)
http://www.cyberciti.biz/tips/reboot-or-halt-linux-system-in-emergency.html Linux kernel includes ma ...
- 11-02SQLserver基础--字符串函数
数据库の函数 一.内置函数--字符串函数 1.--ASCII 返回字符串的首字母的ASCII编码 select ASCII('ame') select ASCII(xingming)from xues ...
- When install ”matplotlib” with ”pip”, if you get the following error, it means the “freetype” and “png” libraries needed by matplotlib are not installed:
============================================================================ * The following require ...
- leetcode319
public class Solution { public int BulbSwitch(int n) { var x = Math.Sqrt(n); var y = Convert.ToInt32 ...
- django的render的说明
return render(request,"homesite.html",locals()) homesite.html页面中的所有内容都可以被渲染,不论是标签还是js代码,包括 ...
- POJ 1187 陨石的秘密 (线性DP)
题意: 公元11380年,一颗巨大的陨石坠落在南极.于是,灾难降临了,地球上出现了一系列反常的现象.当人们焦急万分的时候,一支中国科学家组成的南极考察队赶到了出事地点.经过一番侦察,科学家们发现陨石上 ...
- ECMAScript 定义类、对象
使用预定义对象只是面向对象语言的能力的一部分,它真正强大之处在于能够创建自己专用的类和对象. ECMAScript 拥有很多创建对象或类的方法. 工厂方式 原始的方式 因为对象的属性可以在对象创建后动 ...
- 项目一:第九天 1、前台客户登录 2、Jquery citypicker省市区三级联动插件 4、业务受理(在线下单)
1. 前台客户登录 2. Jquery citypicker省市区三级联动插件 3. 百度地图介绍 4. 业务受理(在线下单) 1 实现前台系统登录功能 1.1 Md5加密 admin(明文)---- ...
- php学习笔记-for循环
for(init;condition;statement) { func(); } for循环的执行逻辑是先执行一次init语句,然后判断condition是否为true,是则执行func(),再执行 ...