后端即时通讯金融科技【免费下载链接】WeiXinMPSDK微信全平台 .NET SDK Senparc.Weixin for C#支持 .NET Framework 及 .NET Core、.NET 10.0。已支持微信公众号、小程序、小游戏、微信支付、企业微信/企业号、开放平台、JSSDK、微信周边等全平台。 WeChat SDK for C#.项目地址https://gitcode.com/gh_mirrors/we/WeiXinMPSDK点击查看免费下载Native 支付用于线下或微信环境以外的支付场景商户在服务端生成一个付款二维码用户使用微信扫一扫唤起个人微信支付完成付款整个支付过程无需用户身处微信 App 内。本文基于 WeiXinMPSDK 官方文档 docs/zh/guide/tenpayv2/nativepay.md 展开结合仓库中的 SDK 实现TenPayOldV3.NativePay、TenPay.NativePay与 TenPayV2 示例项目中的真实控制器代码完整讲解 Native 支付的两种接入模式直接生成weixin://付款码 URL 与统一订单 code_url模式、签名规则、回调处理流程以及回调地址的后台配置位置帮助开发者快速在 .NET 项目中落地扫码支付能力。Native 支付的两种接入模式从示例工程 TenPayV3Controller.cs 的原生支付区域可以看到WeiXinMPSDK 示例项目把 Native 支付组织为两个入口模式一Native()商户后端自己拼装weixin://wxpay/bizpayurl?sign...appid...product_id...time_stamp...nonce_str...付款链接并签名然后把该链接编码为二维码返回给前端。流程短、不依赖统一订单接口适合按商品 ID 计价的 Native 场景模式二NativeByCodeUrl()先调用统一订单接口trade_typeNATIVE拿到接口返回的code_url再生成二维码。官方注释明确指出该模式链接较短生成的二维码打印到结账小票上的识别率较高但code_url有效期为 2 小时过期后扫码不能再发起支付。用户扫码完成支付后微信服务器会请求商户预先配置的回调地址如/TenPayV3/NativeNotifyUrl商户在回调中确认支付并完成后续下单/业务处理。模式一签名 生成付款码 URL 二维码SDK 如何构造付款码 URL示例代码通过TenPayOldV3.NativePay(...)生成付款链接其底层实现在 TenPayV3.cs/// summary /// Native /// /summary /// param nameappId开放平台账户的唯一标识/param /// param nametimesTamp时间戳/param /// param namemchId商户Id/param /// param namenonceStr32 位内的随机串防重发/param /// param nameproductId商品唯一id/param /// param namesign签名/param public static string NativePay(string appId, string timesTamp, string mchId, string nonceStr, string productId, string sign) { var urlFormat weixin://wxpay/bizpayurl?sign{0}appid{1}mch_id{2}product_id{3}time_stamp{4}nonce_str{5}; var url string.Format(urlFormat, sign, appId, mchId, productId, timesTamp, nonceStr); return url; }从源码结构看SDK 只是按微信规定的参数顺序把 6 个字段格式化为weixin://wxpay/bizpayurl开头的深链 URL真正的防伪工作由sign字段承担。与之对应V2 命名空间下还有一个不带mch_id的版本 TenPay.NativePay两者签名与 URL 字段略有差异实际接入时以所用版本的微信接口文档为准示例工程使用的是带mch_id的TenPayOldV3.NativePay。示例工程中的完整实现在示例项目 TenPayV3Controller.cs 中创建Native()方法/// summary /// 原生支付 模式一 /// /summary public ActionResult Native() { try { RequestHandler nativeHandler new RequestHandler(null); string timeStamp TenPayV3Util.GetTimestamp(); string nonceStr TenPayV3Util.GetNoncestr(); //商品Id用户自行定义 string productId SystemTime.Now.ToString(yyyyMMddHHmmss); nativeHandler.SetParameter(appid, TenPayV3Info.AppId); nativeHandler.SetParameter(mch_id, TenPayV3Info.MchId); nativeHandler.SetParameter(time_stamp, timeStamp); nativeHandler.SetParameter(nonce_str, nonceStr); nativeHandler.SetParameter(product_id, productId); string sign nativeHandler.CreateMd5Sign(key, TenPayV3Info.Key); var url TenPayOldV3.NativePay(TenPayV3Info.AppId, timeStamp, TenPayV3Info.MchId, nonceStr, productId, sign); BitMatrix bitMatrix; bitMatrix new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, 600, 600); var bw new ZXing.BarcodeWriterPixelData(); var pixelData bw.Write(bitMatrix); var bitmap new System.Drawing.Bitmap(pixelData.Width, pixelData.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb); var fileStream new MemoryStream(); var bitmapData bitmap.LockBits(new System.Drawing.Rectangle(0, 0, pixelData.Width, pixelData.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb); try { // we assume that the row stride of the bitmap is aligned to 4 byte multiplied by the width of the image System.Runtime.InteropServices.Marshal.Copy(pixelData.Pixels, 0, bitmapData.Scan0, pixelData.Pixels.Length); } finally { bitmap.UnlockBits(bitmapData); } bitmap.Save(_fileStream, System.Drawing.Imaging.ImageFormat.Png); _fileStream.Seek(0, SeekOrigin.Begin); return File(_fileStream, image/png); } catch (Exception ex) { SenparcTrace.SendCustomLog(TenPayV3.Native 执行出错, ex.Message); SenparcTrace.BaseExceptionLog(ex); throw; } }上述过程将自动生成对应于指定商户、指定商品productId的付款二维码。关键步骤拆解如下步骤说明timeStamp/nonceStr分别用TenPayV3Util.GetTimestamp()和GetNoncestr()生成时间戳用于时效校验nonce 为 32 位内随机串防重发productId商品唯一 id示例中用时间戳yyyyMMddHHmmss生成实际业务中应由商户自行定义通常是商品编号sign将appid、mch_id、time_stamp、nonce_str、product_id五个参数放入RequestHandler后调用CreateMd5Sign(key, TenPayV3Info.Key)用商户 API 密钥生成 MD5 签名二维码渲染以 ZXing.Net 为例文档同时说明二维码控件可替换MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, 600, 600)生成 600×600 的BitMatrix再经BarcodeWriterPixelData转为像素数据通过LockBitsMarshal.Copy写入System.Drawing.Bitmap最终以 PNG 流返回返回结果return File(_fileStream, image/png)直接输出图片前端调用方式二维码接口就绪后前端 HTML 只需一个img标签即可加载动态生成的付款码img src/TenPayV3/Native alt扫码付款 /支付通知回调 NativeNotifyUrl用户扫码完成支付后微信服务器会自动请求回调地址如/TenPayV3/NativeNotifyUrl。示例工程中对应的实现位于 TenPayV3Controller.cs完整代码及流程说明如下public ActionResult NativeNotifyUrl() { ResponseHandler resHandler new ResponseHandler(null); //返回给微信的请求 RequestHandler res new RequestHandler(null); string openId resHandler.GetParameter(openid); string productId resHandler.GetParameter(product_id); if (openId null || productId null) { res.SetParameter(return_code, FAIL); res.SetParameter(return_msg, 回调数据异常); } //创建支付应答对象 //RequestHandler packageReqHandler new RequestHandler(null); var sp_billno SystemTime.Now.ToString(HHmmss) TenPayV3Util.BuildRandomStr(26);//最多32位 var nonceStr TenPayV3Util.GetNoncestr(); var xmlDataInfo new TenPayV3UnifiedorderRequestData(TenPayV3Info.AppId, TenPayV3Info.MchId, test, sp_billno, 1, HttpContext.UserHostAddress()?.ToString(), TenPayV3Info.TenPayV3Notify, TenPay.TenPayV3Type.JSAPI, openId, TenPayV3Info.Key, nonceStr); try { //调用统一订单接口 var result TenPayOldV3.Unifiedorder(xmlDataInfo); //创建应答信息返回给微信 res.SetParameter(return_code, result.return_code); res.SetParameter(return_msg, result.return_msg ?? OK); res.SetParameter(appid, result.appid); res.SetParameter(mch_id, result.mch_id); res.SetParameter(nonce_str, result.nonce_str); res.SetParameter(prepay_id, result.prepay_id); res.SetParameter(result_code, result.result_code); res.SetParameter(err_code_des, OK); string nativeReqSign res.CreateMd5Sign(key, TenPayV3Info.Key); res.SetParameter(sign, nativeReqSign); } catch (Exception) { res.SetParameter(return_code, FAIL); res.SetParameter(return_msg, 统一下单失败); } return Content(res.ParseXML()); }回调处理可以归纳为四个要点参数校验从微信推送中取出openid与product_id任一为空即应答return_codeFAIL、return_msg回调数据异常构造统一下单参数订单号sp_billno由HHmmss时间串拼接BuildRandomStr(26)随机串构成注释标明最多32位对应微信对out_trade_no的长度限制TenPayV3UnifiedorderRequestData封装了 AppId、MchId、商品描述示例为 test、订单号、金额示例为 1 分、终端 IP、支付通知地址TenPayV3Info.TenPayV3Notify等字段示例中交易类型传TenPayV3Type.JSAPI并结合openid体现的是回调确认后继续推进订单的演示路径调用统一订单接口TenPayOldV3.Unifiedorder(xmlDataInfo)将结果中的return_code、appid、mch_id、nonce_str、prepay_id、result_code等字段逐一回填到应答对象并用商户密钥CreateMd5Sign(key, TenPayV3Info.Key)生成签名写入signXML 应答return Content(res.ParseXML())以 XML 格式把应答返回给微信服务器下单异常时兜底返回FAIL / 统一下单失败。提示Native 支付的回调地址设置位置位于微信支付后台 产品中心 开发配置 Native 支付回调链接。模式二统一订单 code_url 生成二维码适合小票打印场景的第二种模式实现在 TenPayV3Controller.cs 的NativeByCodeUrl()方法中。与模式一的差异集中在两处先统一下单再出码构造TenPayV3UnifiedorderRequestData时交易类型传TenPay.TenPayV3Type.NATIVE并通过命名参数productId: productId把商品 id 带入请求调用TenPayOldV3.Unifiedorder(xmlDataInfo)后从result.code_url取得微信返回的短链接QR 内容换成 code_url后续同样用 ZXing 的MultiFormatWriter().encode(codeUrl, BarcodeFormat.QR_CODE, 600, 600)渲染 600×600 二维码并以image/png返回渲染细节与模式一一致示例此处用using包裹Bitmap与MemoryStream资源管理更规范。源码注释给出的适用前提值得注意模式二链接较短、小票打印识别率更高但code_url有效期为 2 小时过期后扫码不能再发起支付因此适合即时打印、即时扫码的线下收银场景而模式一的自签 URL 更适合由业务系统按订单动态生成码值的场景。小结与工程要点签名链路统一两个模式都依赖RequestHandler.CreateMd5Sign(key, 商户Key)生成 MD5 签名nonce_str用于防重放接入前需保证TenPayV3InfoAppId、MchId、Key、Notify 地址配置正确参数可替换示例中的productId、订单号、金额、商品描述均为演示值生产环境应替换为真实的商品/订单体系数据回调配置在微信支付后台的产品中心 开发配置 Native 支付回调链接处完成回调接口需以 XML 应答选型建议需要小票打印选模式二注意 2 小时时效需要按商品 id 灵活出码选模式一完整可运行代码可直接参考示例项目 Samples/TenPayV2/Senparc.Weixin.Sample.TenPayV2SDK 核心实现位于 src/Senparc.Weixin.TenPay。赞分享后端即时通讯金融科技【免费下载链接】WeiXinMPSDK微信全平台 .NET SDK Senparc.Weixin for C#支持 .NET Framework 及 .NET Core、.NET 10.0。已支持微信公众号、小程序、小游戏、微信支付、企业微信/企业号、开放平台、JSSDK、微信周边等全平台。 WeChat SDK for C#.项目地址https://gitcode.com/gh_mirrors/we/WeiXinMPSDK点击查看免费下载相关推荐WeiXinMPSDK 微信支付V2支付回调实战从 notify_url 到 ResponseHandler 签名验证的完整实现WeiXinMPSDK 微信支付V2支付回调实战从 notify_url 到 ResponseHandler 签名验证的完整实现 本文围绕 WeiXinM后端即时通讯金融科技如何快速修复损坏视频untrunc视频修复工具完全指南如何快速修复损坏视频untrunc视频修复工具完全指南 你是否曾因手机录制中断、行车记录仪断电或无人机信号丢失而面临珍贵视频无法播放的困境那些损坏的视频文件后端即时通讯EasyWeChat 4.x 付款码支付刷卡支付实战指南从下单到结果处理EasyWeChat 4.x 付款码支付刷卡支付实战指南从下单到结果处理 付款码支付又称刷卡支付是微信支付中用户出示付款码、收银设备扫码扣款的即时后端即时通讯上一篇BlockTube vs 其他YouTube拦截工具为什么它是最强大的内容过滤插件下一篇Jellium Desktop视频色彩空间设置选择适合你的显示设备创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
