首先不得不吐槽下腾讯,升级微信支付为毛不兼容V2版本呢?V2算是白研究了。


V3预支付文档几个坑,不知道你们有没有中招

  1. 商户号 mch_id 是 String(32) 微信支付分配的商户号   其实是邮件的“微信支付商户号(接口文档中的商户号MCHID)” ,我一直都以为是商户号。
  2. 预支付提交的xml节点值都必须带有<![CDATA[]]>,如果根据文档开发只带部分。那么你就开心了,一直都是sign签名错误。

回到正文,以下为实现代码

public class PaymentHandler : RequestHandler
{ public PaymentHandler(HttpContext context)
: base(context, WX_V3_CONFIG.config.PartnerKey)
{ } /// <summary>
/// 获取预支付订单号
/// </summary>
/// <returns></returns>
public string GetUnifiedOrder(string body, string openid, string trade_type)
{ base.setParameter("appid", WX_V3_CONFIG.config.AppID);
base.setParameter("mch_id", WX_V3_CONFIG.config.MCHID);
base.setParameter("nonce_str", TenpayUtil.getNoncestr());
base.setParameter("body", body);
base.setParameter("out_trade_no", TenpayUtil.getOrderNo());
base.setParameter("total_fee", "");
base.setParameter("spbill_create_ip", "192.168.1.1");//base.httpContext.Request.UserHostAddress);
base.setParameter("notify_url", "www.111.com");
base.setParameter("trade_type", "JSAPI");
base.setParameter("openid", openid);
base.createSign(); string s = HttpHelper.OpenReadWithHttps("https://api.mch.weixin.qq.com/pay/unifiedorder", base.parseXML());//post请求 return "";
}
}

RequestHandler帮助类

/// <summary>
/// RequestHandler 的摘要说明。
/// </summary>
public class RequestHandler
{ public RequestHandler(HttpContext httpContext, string key)
{
parameters = new Hashtable();
this.key = key;
this.httpContext = httpContext; }
/** 密钥 */
private string key; protected HttpContext httpContext; /** 请求的参数 */
protected Hashtable parameters; /** debug信息 */
private string debugInfo; /** 初始化函数 */
public virtual void init()
{
}
/** 获取debug信息 */
public String getDebugInfo()
{
return debugInfo;
}
/** 获取密钥 */
public String getKey()
{
return key;
} /** 设置密钥 */
public void setKey(string key)
{
this.key = key;
} /** 设置参数值 */
public void setParameter(string parameter, string parameterValue)
{
if (parameter != null && parameter != "")
{
if (parameters.Contains(parameter))
{
parameters.Remove(parameter);
} parameters.Add(parameter, parameterValue);
}
} /** 获取参数值 */
public string getParameter(string parameter)
{
string s = (string)parameters[parameter];
return (null == s) ? "" : s;
} //获取package带参数的签名包
public string getRequestURL()
{
this.createSign();
StringBuilder sb = new StringBuilder();
ArrayList akeys = new ArrayList(parameters.Keys);
akeys.Sort();
foreach (string k in akeys)
{
string v = (string)parameters[k];
if (null != v && "key".CompareTo(k) != )
{
sb.Append(k + "=" + TenpayUtil.UrlEncode(v, getCharset()) + "&");
}
} //去掉最后一个&
if (sb.Length > )
{
sb.Remove(sb.Length - , );
} return sb.ToString(); } //创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。 protected virtual void createSign()
{
StringBuilder sb = new StringBuilder(); ArrayList akeys = new ArrayList(parameters.Keys);
akeys.Sort(); foreach (string k in akeys)
{
string v = (string)parameters[k];
if (null != v && "".CompareTo(v) !=
&& "sign".CompareTo(k) != && "key".CompareTo(k) != )
{
sb.Append(k + "=" + v + "&");
}
} sb.Append("key=" + this.getKey());
string sign = MD5Util.GetMD5(sb.ToString(), getCharset()).ToUpper(); this.setParameter("sign", sign); //debug信息
this.setDebugInfo(sb.ToString() + " => sign:" + sign);
} //创建package签名
public virtual string createMd5Sign()
{
StringBuilder sb = new StringBuilder();
ArrayList akeys = new ArrayList(parameters.Keys);
akeys.Sort(); foreach (string k in akeys)
{
string v = (string)parameters[k];
if (null != v && "".CompareTo(v) !=
&& "sign".CompareTo(k) != && "".CompareTo(v) != )
{
sb.Append(k + "=" + v + "&");
}
}
string sign = MD5Util.GetMD5(sb.ToString(), getCharset()).ToLower(); this.setParameter("sign", sign);
return sign;
} //创建sha1签名
public string createSHA1Sign()
{
StringBuilder sb = new StringBuilder();
ArrayList akeys = new ArrayList(parameters.Keys);
akeys.Sort(); foreach (string k in akeys)
{
string v = (string)parameters[k];
if (null != v && "".CompareTo(v) !=
&& "sign".CompareTo(k) != && "key".CompareTo(k) != )
{
if (sb.Length == )
{
sb.Append(k + "=" + v);
}
else
{
sb.Append("&" + k + "=" + v);
}
}
}
string paySign = SHA1Util.getSha1(sb.ToString()).ToString().ToLower(); //debug信息
this.setDebugInfo(sb.ToString() + " => sign:" + paySign);
return paySign;
} //输出XML
public string parseXML()
{
StringBuilder sb = new StringBuilder();
sb.Append("<xml>");
foreach (string k in parameters.Keys)
{
string v = (string)parameters[k];
if (Regex.IsMatch(v, @"^[0-9.]$"))
{ sb.Append("<" + k + ">" + v + "</" + k + ">");
}
else
{
sb.Append("<" + k + "><![CDATA[" + v + "]]></" + k + ">");
} }
sb.Append("</xml>");
return sb.ToString();
} /** 设置debug信息 */
public void setDebugInfo(String debugInfo)
{
this.debugInfo = debugInfo;
} public Hashtable getAllParameters()
{
return this.parameters;
} protected virtual string getCharset()
{
return this.httpContext.Request.ContentEncoding.BodyName;
}
}

V3 微信支付-预支付C#的更多相关文章

  1. V3微信支付开发笔录

    真是坑爹啊,微信支付到处都是坑,一不小心就栽里面了, 文档也不怎么全,经过一周的奋斗终于把微信支付功能搞定,在此写下自己当时走入的误区和一些需要注意的地方,希望后边开发的朋友们可以少走弯路,少被微信坑 ...

  2. 微信扫码支付 php

    仔细看了一遍官方的那幅流程图,我来简化理解一下(注意:我这里针对的是扫码支付模式一,模式二没什么说的)网站后台生成二维码,当然是跟据前台传来的参数有条件的生成买家扫描二维码,扫描过程中,微信后台系统回 ...

  3. 微信公众号支付(三):页面调用微信支付JS并完成支付

    一.调用微信的JS文件 1.首先要绑定[JS接口安全域名],“公众号设置”的“功能设置”中 2.引入JS文件 备注:支持使用 AMD/CMD 标准模块加载方法加载 <script type=&q ...

  4. 微信小程序支付步骤

    http://blog.csdn.net/wangsf789/article/details/53419781 最近开发微信小程序进入到支付阶段,一直以来从事App开发,所以支付流程还是熟记于心的.但 ...

  5. 微信公众号支付开发全过程 --JAVA

    按照惯例,开头总得写点感想 ------------------------------------------------------------------ 业务流程 这个微信官网说的还是很详细的 ...

  6. Java 后端微信小程序支付demo (网上说的坑里面基本上都有)

    Java 后端微信小程序支付 一.遇到的问题 1. 商户号该产品权限未开通,请前往商户平台>产品中心检查后重试 2.签名错误 3.已经调起微信统一下单接口,可以拿到预支付ID,但是前端支付的时候 ...

  7. php对接微信小程序支付

    前言:这里我就假装你已经注册了微信小程序,并且基本的配置都已经好了.注: 个人注册小程序不支持微信支付,所以我还是假装你是企业或者个体工商户的微信小程序,其他的商户号注册,二者绑定,授权,支付开通,就 ...

  8. java微信公众号支付示例

    开始之前,先准备好:appid.商家号.商户密匙. 工具类: MD5Util.java package com.yiexpress.core.utils.wechat; import java.sec ...

  9. java版微信公众号支付(H5调微信内置API)

    最近需要做微信公众号支付,网上找了大堆的代码,大多都只说了个原理,自己踩了太多坑,所有的坑,都会再下面的文章中标注,代码我也贴上最全的(叫我雷锋)!!! 第一步:配置支付授权目录 你需要有将你公司的微 ...

随机推荐

  1. 笑谈ArcToolbox (1) ArcToolbox 的发展方向

    笑谈ArcToolbox (1) ArcToolbox 的发展方向 by 李远祥 ArcGIS工具箱ArcToolbox具有非常多的工具,相信用过的人都非常惊叹,其功能完备并且强大,种类繁多,总能找到 ...

  2. Robot Framework的安装

    一.安装环境:Windows 64位操作系统64位2.7版本Python 二.简要步骤:1. 安装Python(RF是基于python 的,所以需要有python环境):2. 安装wxPython ( ...

  3. 情人节,教大家使用css画出一朵玫瑰花。

    情人节到了,给大家来一朵高端的玫瑰花. 在网上看到的一个canvas实现的玫瑰花,效果很好,但是代码被压缩过,也没有注释,看的云里雾里的. 今天我教大脚用CSS来实现一朵玫瑰花. 先看效果 首先我们画 ...

  4. 【译文】什么是Docker

    What is Docker? By Tim Butler • 14 May 2015 • https://www.conetix.com.au/blog/what-is-docker Unless ...

  5. iOS开发之App主题切换完整解决方案(Swift版)

    本篇博客就来介绍一下iOS App中主题切换的常规做法,当然本篇博客中只是提到了一种主题切换的方法,当然还有其他方法,在此就不做过多赘述了.本篇博客中所涉及的Demo完全使用Swift3.0编写完成, ...

  6. win8下 msvcr100d.dll文件缺失解决方法

    一.如果在运行某软件或编译程序时提示缺少.找不到msvcp100d.dll等类似提示,您可将从载来的msvcp100d.dll拷贝到指定目录即可(一般是system系统目录或放到软件同级目录里面),或 ...

  7. 《C++ Primer》读书笔记—第一章 开始

    声明: 文中内容收集整理自<C++ Primer 中文版 (第5版)>,版权归原书所有. 学习一门程序设计语言最好的方法就是练习编程. 1.一个函数的定义包含四个部分:返回类型(retur ...

  8. git合并别的分支某次提交或合并

    合并别的分支某次提交 master分支上改了一个bug.提交到master分支.现在在dev分支上开发,需要把master分支上改的那个bug合过来.步骤是:先在master分支上查改那个bug的SH ...

  9. hibernate系列笔记(3)---持久化对象

    持久化对象 再讲持久化对象之前,我们先来理解有关session中get方法与 load方法区别: 简单总结: (1)如果你使用load方法,hibernate认为该id对应的对象(数据库记录)在数据库 ...

  10. rhel 6.7 离线安装docker

    本机系统信息 [test@rhel67temp ~]$ uname -a Linux rhel67temp 2.6.32-573.el6.x86_64 #1 SMP Wed Jul 1 18:23:3 ...