微信退款-SDK

微信退款这个功能还是挺复杂的,建议去看一下官方文档,理解了之后再写功能,官方文档:微信支付官方文档

首先去微信支付官网去下载各个版本的demo支付工具,我用的Java版本,地址:微信支付官方-SDK

下载完之后大概是这样

下面把我自己实现的这两类贴出来,直接就能用

MyWXPayDomainImpl 

/**
 * @ClassName : MyWXPayDomainImpl
 * @Author : Yanqiang
 * @Date : 2019/4/1
 * @Description :自己实现微信的abstract interface WXPayDomain接口,实现请求配置
 */
public class MyWXPayDomainImpl implements WXPayDomain {
    private MyWXPayDomainImpl(){}
    private static class WxpayDomainHolder{
        private static WXPayDomain holder = new MyWXPayDomainImpl();
    }
    public static WXPayDomain 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>();
}

 

/**
 * @ClassName : MyWXPayConfig
 * @Author : Yanqiang
 * @Date : 2019/4/1
 * @Description :微信支付/退款配置类 继承abstract WXPayConfig ,自己实现微信配置
 */
public class MyWXPayConfig extends WXPayConfig {

    private byte[] certData;

    private static MyWXPayConfig INSTANCE;

    private int profiles;//0是测试;1是正式

    public MyWXPayConfig(int profiles) throws Exception {
        this.profiles = profiles;
        String path;
        //不是沙箱环境要要下载证书,开出来
        //0是测试;1是正式
        if (profiles == 0){
            path = "这个是证书地址,以.p12结尾的那个文件";
        }else {
            path = "这个是证书地址,以.p12结尾的那个文件";
        }
        File file = new ClassPathResource(path).getFile();
        InputStream certStream = new FileInputStream(file);

        this.certData = new byte[(int) file.length()];

        certStream.read(this.certData);

        certStream.close();

    }

    @Override
    String getAppID() {
        return "这里是Appid";
    }

    @Override
    String getMchID() {
        //0是测试;1是正式
        if (profiles == 0){
            return "这个是Mch的码";
        }else {
            return "这个是Mch的码";
        }
    }

    @Override
    String getKey() {
        return "这个是项目私钥,不要泄露";
    }

    @Override
    InputStream getCertStream() {
        ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);
        return certBis;
    }

    @Override
    WXPayDomain getWXPayDomain() {
        return MyWXPayDomainImpl.instance();
    }
}

支付之类的最大的坑就是沙箱环境,那么什么是沙箱环境,其实就是在你去请求正式环境的时候,去(转换/加密....)一下,让服务商知道你这个请求是测试环境过来的请求

其次,微信退款需要的参数格式为XML格式,如果用微信支付官网下载的demo的话不需要自己转xml

/**
 * @Author : Yanqiang
 * @Date : 2019/4/9
 * @Description :
 *
 *      其实,真正需要自己去写的代码只有这几行,
 *      但是,是什么让我们写这一块的时候这么费劲的,还是你要去看懂官方文档,
 *      说道这儿,不得不说,微信支付的接口文档写的真够烂的,看一遍觉得很好理解,
 *      写的时候发现到处都是坑,再去看文档也没有写清楚,就让人二丈和尚摸不着头发
 *
 *   PS: 下面是真坑了!
 *
 *      1·参数必须按照文档上的,一模一样,不能大小写,也不能驼峰
 *      2·必须按照文档上的参数顺序一致!!! 除去忽略的参数,必传参数顺序依次往前排列
 *      3·如果你用微信官方SDK的话,sign:签名 这个参数可以不传,这个是工具类帮你做了,自己写的话要写!
 *      4·sign 的生成是将 除sign之外的参数,其他不为空的参数参与签名。详细介绍:签名生成算法
 */
//构造请求参数 不需要此时设置sign签名,wxPay.refund()接口 通过配置类自动配置
ConcurrentHashMap<String, String> requestMap = new ConcurrentHashMap();
requestMap.put("appid", shopsApiProperties.mpWeixinAppid);
requestMap.put("mch_id", mch_id);
requestMap.put("nonce_str", WXPayUtil.generateNonceStr());
requestMap.put("out_refund_no", afterSale.getSaleordernum());
requestMap.put("out_trade_no", afterSale.getOuttradeno());
requestMap.put("refund_fee", String.valueOf(refundFee * 100));
requestMap.put("total_fee", String.valueOf(actualPrice));

//MyWXPayConfig: 配置类 0是测试;1是正式; 
// "": 回调通知地址;
//autoReport: 这个没有用到
//useSandbox: 沙箱环境 (false为正式/true为沙箱环境)
WXPay wxPay = new WXPay(new MyWXPayConfig(0), "", true, false);

Map<String, String> refund = wxPay.refund(requestMap, 6*1000,8*1000);

转载于:https://my.oschina.net/u/3526783/blog/3034233

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python 微信支付 wechatsdk 是一个用于处理微信支付功能的 Python 第三方库。它提供了一系列的接口和方法,用于实现微信支付交易的各种功能,包括创建订单、查询订单状态、申请退款等。 使用 wechatsdk,我们可以方便地集成微信支付功能到 Python 项目中。首先,我们需要通过在微信商户平台上注册账号,并获得相应的密钥和证书文件。然后,在 Python 项目中引入 wechatsdk 库,并根据接口文档的要求设置好相关的配置参数,例如商户 ID、商户密钥等。 接下来,我们可以使用 wechatsdk 提供的接口进行各种支付交易操作。例如,创建订单时我们可以使用统一下单接口,传入必要的参数例如商品描述、订单金额等。wechatsdk 会自动将收到的参数进行签名,并生成一个支付链接。用户在微信客户端打开支付链接后,可以进行支付操作。 支付成功后,wechatsdk 提供了查询订单接口,用于查询订单的支付状态。根据订单号或其他标识,我们可以向微信服务器发起查询请求,获取订单的详细信息,例如支付状态、支付金额等。 退款功能也可以通过 wechatsdk 来实现。我们可以使用申请退款接口传入相应的参数,并进行退款操作。微信服务器会根据退款申请的参数进行处理,并返回相应的结果。 总之,Python 微信支付 wechatsdk 是一个方便易用的库,可以帮助开发者快速集成微信支付功能到他们的 Python 项目中。无论是处理支付交易、查询订单状态还是申请退款,都可以借助 wechatsdk 轻松实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值