〇、前言

相较于支付宝,微信支付对 .Net 的支持就没那么充分,官方没有提供 SDK。

但值得庆幸的是,在社区有大佬封装了 v3 版 .Net SDK。

原文链接:https://developers.weixin.qq.com/community/develop/article/doc/00020aadc384a0a5f01c3526b56813

SDK 名称:SKIT.FlurlHttpClient.Wechat.TenpayV3,支持 .NET Core / Framework,完整封装全部 v3 API。

本文也将以此 SDK 来应用,主要介绍退款和退款状态查询两个接口。

一、接入准备

1.1 引入 SDK

名称:SKIT.FlurlHttpClient.Wechat.TenpayV3,支持 .Net Standard 2.0、.Net Framework 4.6.2-4.7.1、.Net 6.0 等版本。

NuGet 简介地址:https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.TenpayV3

简介:基于 Flurl.Http 的微信支付 API v3 版客户端,支持商户(直连)、合作伙伴(服务商、渠道商、机构、银行)模式,支持基础支付、代金券、商家券、委托营销、消费卡、支付有礼、银行定向促活、微信支付分、微信先享卡、支付即服务、点金计划、智慧商圈、电商收付通、平台收付通、二级商户进件、小微商户进件、消费者投诉、商户风控管理、商户违规通知、批量转账到零钱、银行组件、海关报关、融合钱包、微工卡、电子发票、电子小票、车主平台、教育续费通、校园轻松付等功能。

1.2 必要的账户信息

名称 示例 简介
商户号 110 ... ... 10 位,数字
商户 API 证书序列号 D566D2 ... ... 40 位,大写字母、数字,组合
商户 API v3 密钥 gSk0EA ... ... 32 位,数字、大写字母、小写字母,组合
商户 API 证书私钥 -----BEGIN PRIVATE KEY-----\r\nMIIEv ... ... 通常为 `apiclient_key.pem` 文件内容

关于微信的服务商和普通商户:

普通商户

资金由微信直接与商户结算,不涉及资金冻结和分账;
可独立申请,可自行通过接口进行支付、退款等操作;
适合大型企业或品牌商户,有自己技术团队和支付系统。

服务商

资金会先被微信冻结,服务商发起分账后微信才进行分账;
可免费申请不限个数的子商户,但服务商的商户号需要每年支付认证费用;
自身不能直接收款,需通过申请的“特约商户”才能收款;
“特约商户”可以像普通商户一样收款,但退款接口必须由服务商发起;
适合于提供支付解决方案给多个特约商户的第三方机构,特别是那些需要处理多商户分账或收取服务费的复杂场景。

特别注意:特约商户,也就是服务商下边的子商户,是没有权限直接调用退款接口的,只能根据服务商的账户信息加上子商户号来。

二、接口调用

2.1 根据账户信息创建共用客户端对象 client

var manager = new InMemoryCertificateManager();
var options = new WechatTenpayClientOptions()
{
MerchantId = "商户号", // 商户号
MerchantV3Secret = "商户 API v3 密钥", // 商户 API v3 密钥
MerchantCertificateSerialNumber = "商户 API 证书序列号", // 商户 API 证书序列号
MerchantCertificatePrivateKey = "-----BEGIN PRIVATE KEY-----\r\nMIIEv ... ... Q71AG\r\n-----END PRIVATE KEY-----", // 商户 API 证书私钥
PlatformCertificateManager = manager
};
var client = new WechatTenpayClient(options);

2.2 退款接口

以下是退款接口的代码,其中入参仅示例了必要的字段,其他详情见官方文档。

官方文档:https://pay.weixin.qq.com/docs/merchant/apis/refund/refunds/create.html

var request = new CreateRefundDomesticRefundRequest()
{
//OutTradeNumber = "商户订单号", // 【商户订单号】 原支付交易对应的商户订单号,与transaction_id二选一
TransactionId = "微信订单号", // 【微信支付订单号】 原支付交易对应的微信订单号,与out_trade_no二选一
// 商户自定义退款唯一标识,要做好记录,退款状态查询时入参必填
OutRefundNumber = $"WX{DateTime.Now.ToString("yyyyMMddHHmmssffffff")}",
Reason = "测试退款080611",
//NotifyUrl = "https://...", // 回调地址
Amount = new CreateRefundDomesticRefundRequest.Types.Amount()
{
Total = 100, // 单位:分
Refund = 99, // 单位:分
Currency = "CNY" // 【退款币种】 目前只支持人民币:CNY。
},
};
//string json = Json_Object.ObjectToJsonstr(request);
var response = await client.ExecuteCreateRefundDomesticRefundAsync(request);
if (response.IsSuccessful())
{
Console.WriteLine("RefundId:", response.RefundId); // 【微信支付退款号】 微信支付退款号
Console.WriteLine("OutRefundNumber:", response.OutRefundNumber); // 【商户退款单号】 商户系统内部的退款单号,商户系统内部唯一
Console.WriteLine("TransactionId:", response.TransactionId); // 【微信支付订单号】
Console.WriteLine("OutRefundNumber:", response.OutTradeNumber); // 【商户订单号】 原支付交易对应的商户订单号
}
else
{
Console.WriteLine("HTTP 状态:" + response.GetRawStatus());
Console.WriteLine("错误代码:" + response.ErrorCode);
Console.WriteLine("错误描述:" + response.ErrorMessage);
}

2.3 退款状态查询接口

以下是退款状态查询接口的代码,入参实际上就只有一个:商户退款单号。文档中是要求直接跟在接口请求路径之后,SDK 中是封装到 Request 模型中。

官方文档:https://pay.weixin.qq.com/docs/merchant/apis/refund/refunds/query-by-out-refund-no.html

var request = new GetRefundDomesticRefundByOutRefundNumberRequest()
{
OutRefundNumber = "WX20240806104450972506",
};
//string json = Json_Object.ObjectToJsonstr(request);
var response = await client.ExecuteGetRefundDomesticRefundByOutRefundNumberAsync(request);
if (response.IsSuccessful())
{
Console.WriteLine("RefundId:", response.RefundId); // 【微信支付退款号】 微信支付退款号
Console.WriteLine("OutRefundNumber:", response.OutRefundNumber); // 【商户退款单号】 商户系统内部的退款单号,商户系统内部唯一
Console.WriteLine("OutRefundNumber:", response.TransactionId); // 【微信支付订单号】
Console.WriteLine("OutRefundNumber:", response.OutTradeNumber); // 【商户订单号】 原支付交易对应的商户订单号
}
else
{
Console.WriteLine("HTTP 状态:" + response.GetRawStatus());
Console.WriteLine("错误代码:" + response.ErrorCode);
Console.WriteLine("错误描述:" + response.ErrorMessage);
}

2.4 接口的 Request、Response 模型的对应逻辑

下面列一下以上使用到的两个接口信息:

接口名称 接口地址 Request Response 
退款 【POST】/v3/refund/domestic/refunds CreateRefundDomesticRefundRequest CreateRefundDomesticRefundResponse
退款状态查询 【GET】/v3/refund/domestic/refunds/{out_refund_no} GetRefundDomesticRefundByOutRefundNumberRequest GetRefundDomesticRefundByOutRefundNumberResponse

由上表对照可以看出,对应的模型实际上就是以接口地址为基础的,其他接口就可以按照这个逻辑去一一对应。

微信支付退款和退款结果查询接口简单实现(.Net 7.0)的更多相关文章

  1. 微信支付v2开发(5) 订单查询

    本文介绍微信支付中订单查询功能的实现. 作者:方倍工作室 地址:http://www.cnblogs.com/txw1958/p/wxpay-order-query.html 一.订单查询 因为某一方 ...

  2. php微信支付接口开发程序(一)

    阅读对象 本文阅读对象:商户系统(在线购物平台.人工收银系统.自动化智能收银系统或其他)集成微信支付涉及的技术架构师,研发工程师,测试工程师,系统运维工程师. 支付模式 1. 刷卡支付 刷卡支付是用户 ...

  3. C#开发微信门户及应用(32)--微信支付接入和API封装使用

    在微信的应用上,微信支付是一个比较有用的部分,但也是比较复杂的技术要点,在微商大行其道的年代,自己的商店没有增加微信支付好像也说不过去,微信支付旨在为广大微信用户及商户提供更优质的支付服务,微信的支付 ...

  4. 【weixin】微信支付简介

    一.微信支付模式 1.付款码支付 付款码支付是用户展示微信钱包内的“刷卡条码/二维码”给商户系统扫描后直接完成支付的模式.主要应用线下面对面收银的场景. 2.Native支付 Native支付是商户系 ...

  5. iOS - WXPay 微信支付

    1.微信支付申请 微信支付官方集成指引 微信支付官方集成指导视频 微信 APP 支付开发者文档 微信公众平台 微信开放平台 微信商户平台 1.1 微信 APP 支付申请步骤 APP 支付:APP 支付 ...

  6. 支付顺序-->微信支付到公司账户-->待出票

    支付顺序-->微信支付到公司账户-->待出票-->查询所有待出票订单 -->遍历提交订单-->火车票接口放回订单id-->存入order订单表中 -->读取订 ...

  7. java对接微信支付

    对接微信扫码支付(模式2),前端使用velocity技术 (1)调用微信支付接口(view层)  此部分业务逻辑部分可以省略 @RequestMapping("/wxpay.htm" ...

  8. 微信支付开发(1) JS API支付

    关键字:微信支付 微信支付v3 jsapi支付 统一支付 Native支付 prepay_id 作者:方倍工作室原文: http://www.cnblogs.com/txw1958/p/wxpayv3 ...

  9. 微信支付开发(1) JS API支付V3版(转)

    http://www.cnblogs.com/txw1958/p/wxpayv3-jsapi.html 本文介绍微信支付下的jsapi实现流程 前言 微信支付现在分为v2版和v3版,2014年9月10 ...

  10. APP微信支付报错《商户号该产品权限未开通,请前往商户平台>产品中心检查后重试》

    问题 最近项目使用MUI,HBuilder.开发打包H5的app 在开发H5 plus支付的时候,遇到以下问题: App微信支付调官方的统一下单接口返回错误信息 {return_msg=商户号该产品权 ...

随机推荐

  1. Java基础:throw和throws的详解

    总结来说,throw是用来抛出一个具体的异常实例,而throws是用来声明方法可能会抛出哪些类型的异常,是对调用者的一种通知和要求. 1. throw 作用: throw关键字用于在方法体内实际抛出一 ...

  2. This app has crashed because it attempted to access privacy-sensitive data without a usage descripti

    运行环境 XCode 8.2.1 问题描述 当调取相册的时候APP崩溃并显示标题的错误:This app has crashed because it attempted to access priv ...

  3. 认识.NET 日志系统

    认识.NET 日志系统 基本概念 日志级别:Trace<Debug<Information<Waring<Error<Critical 日志提供者(LoggingProv ...

  4. 含税168元起!四核A53+NPU+PCIe+USB3.0,瑞芯微RK3562性价比真高!

     

  5. 我对《RAG/大模型/非结构化数据知识库类产品》技术架构的思考、杂谈

    1.前言 在6.28/29的稀土掘金开发者大会RAG专场上,我们公司CEO员外代表TorchV分享了我们在<RAG在企业应用中落地的难点与创新> 其中最后分享了两个观点: AI在应用场景落 ...

  6. 数据结构—包(Bag)

    数据结构中的包,其实是对现实中的包的一种抽象. 想像一下现实中的包,比如书包,它能做什么?有哪些功能?首先它用来装东西,里面的东西可以随便放,没有规律,没有顺序,当然,可以放多个相同的东西.其次,东西 ...

  7. LabVIEW Actor Framwork (1)________ 边学边做server&client

    初始需求: 现在要做一个类似聊天的demo,一个server端,若干个client端:首先是server启动,通过server可以打开若干个client端,然后每个client可以独立给server发 ...

  8. QCon 回顾 | Data Fabric:逻辑统一、物理分散

    Data Fabric(数据编织),自 2019 年开始就在 Gartner 年度技术趋势榜单上安家,并在 2022 年被列为数据分析领域十大技术趋势之首,它究竟有哪些价值?又如何在企业落地? 在近日 ...

  9. Vue源码剖析

    目录 Vue 响应式数据 Vue 中如何进行依赖收集 Vue 中模板编译原理 Vue 生命周期钩子 Vue 组件 data 为什么必须是个函数? nextTick 原理 set 方法实现原理 虚拟 d ...

  10. webpack4.15.1 学习笔记(二) — 配置及开发环境构建

    目录 基本安装 配置文件 管理资源 管理输出 构建一个开发环境 使用 source map 选择一个开发工具 观察模式 webpack-dev-server webpack-dev-middlewar ...