账号i pk拾微信群怎么支付?

2903人阅读
【weixin pay】
1.支付授权目录设置
本人用的开发框架是:struts2(用了struts2的0配置,对于struts的0配置不熟悉的可以看看这个博客了解下)
本人做的是微信V3版本的微信支付,也是目前最新的微信支付接口。官方文档下载地址
微信支付成功后&&你的邮件会有以下信息:
1、 信息包括:商户ID(mch_id)、申请编号、登录帐号、登录密码、商户API密码(key)
2.、证书包括:商户API证书、证书密钥、CA证书
开发前,我们先登录自己的服务号,点击微信支付-----&开发配置。
如果这里的授权路径和下面参数的notify_url不对&&调用付款接口时会弹出access_denied。
比如,我的授权目录是http://183.33.212.175/wxweb/config/,那么我对应的notify_url的回调方法必须是String notify_url = &http://183.33.212.175:8016/wxweb/config/pay!paySuccess.action&;这样的
下图是微信支付JSAPI支付方法的流程图。
登陆Oauth2授权的问题,我会另外写篇博客。在此略过。需要注意一点的是,微信支付是微信5.0以上版本才能支持,所以,可能有些用户的微信版本是低版本无法进行微信支付而用户又不知道为什么就是不能支付,我们需要进行一个版本判断,如果用户的微信版本低于5.0就告知用户一些提示信息。那么,如何判断用户的微信版本是多少呢?我们可以通过这个方法可以获取一些信息然后进行判断:request.getHeader(&user-agent&)获取信息。
以 iPhone 版本为例,可以通过 user agent 可获取如下微信版本示例信息:
&Mozilla/5.0(CPU iphone OS 5_1_1 like Mac OS X) AppleWebKit/534.46(KHTML,like Geocko) Mobile/9B206 MicroMessenger/5.0&
其中 5.0 为用户安装的微信版本号,商户可以判定版本号是否高于或者等于 5.0。具体判断代码请留意后面代码。
流程图中,我们看到需要先调用一次统一接口,然后微信会返回一个prepayId给我们。那么我们先来调用统一接口。调用接口的URL地址:https://api.mch./pay/unifiedorder,调用统一接口需要以下参数。
看到这些参数,不难理解需要传入什么。那么参数中的sign需要以下规则进行生成。
下面是我生成sign的方法。注意,参数是必填项的必须加进去。sign的生成规则是,除了上除列表中sign字段为所有的参数都可以参与sign的生成且参与生成sign的参数值不为空.
&& & * @author 李欣桦
&& & * @date 下午2:29:34
&& & * @Description:sign签名
&& & * @param characterEncoding 编码格式
&& & * @param parameters 请求参数
&& & * @return
&& &public static String createSign(String characterEncoding,SortedMap&Object,Object& parameters){
&& &&& &StringBuffer sb = new StringBuffer();
&& &&& &Set es = parameters.entrySet();
&& &&& &Iterator it = es.iterator();
&& &&& &while(it.hasNext()) {
&& &&& &&& &Map.Entry entry = (Map.Entry)it.next();
&& &&& &&& &String k = (String)entry.getKey();
&& &&& &&& &Object v = entry.getValue();
&& &&& &&& &if(null != v && !&&.equals(v)&
&& &&& &&& &&& &&& &&& !&sign&.equals(k) && !&key&.equals(k)) {
&& &&& &&& &&& &sb.append(k + &=& + v + &&&);
&& &&& &&& &}
&& &&& &sb.append(&key=& + ConfigUtil.API_KEY);
&& &&& &String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
MD5Util工具类中相关的方法
public class MD5Util {
&& &private static String byteArrayToHexString(byte b[]) {
&& &&& &StringBuffer resultSb = new StringBuffer();
&& &&& &for (int i = 0; i & b. i++)
&& &&& &&& &resultSb.append(byteToHexString(b[i]));
&& &&& &return resultSb.toString();
&& &private static String byteToHexString(byte b) {
&& &&& &int n =
&& &&& &if (n & 0)
&& &&& &&& &n += 256;
&& &&& &int d1 = n / 16;
&& &&& &int d2 = n % 16;
&& &&& &return hexDigits[d1] + hexDigits[d2];
&& &public static String MD5Encode(String origin, String charsetname) {
&& &&& &String resultString =
&& &&& &try {
&& &&& &&& &resultString = new String(origin);
&& &&& &&& &MessageDigest md = MessageDigest.getInstance(&MD5&);
&& &&& &&& &if (charsetname == null || &&.equals(charsetname))
&& &&& &&& &&& &resultString = byteArrayToHexString(md.digest(resultString
&& &&& &&& &&& &&& &&& &.getBytes()));
&& &&& &&& &else
&& &&& &&& &&& &resultString = byteArrayToHexString(md.digest(resultString
&& &&& &&& &&& &&& &&& &.getBytes(charsetname)));
&& &&& &} catch (Exception exception) {
&& &&& &return resultS
&& &private static final String hexDigits[] = { &0&, &1&, &2&, &3&, &4&, &5&,
&& &&& &&6&, &7&, &8&, &9&, &a&, &b&, &c&, &d&, &e&, &f& };
各位需要记住,我们发送给微信服务器的参数是xml格式的string,微信返回来的信息也是xml格式的string。
我们提交的正确数据应该是这样的。
&appid&wx0ec43b&/appid&
&attach&&![CDATA[att1]]&&/attach&
&body&&![CDATA[JSAPI 支付测试]]&&/body&
&device_info&1000&/device_info&
&mch_id&&/mch_id&
&nonce_str&bd1d9ed8b2&/nonce_str&
&notify_url&http://wxpay./pub_v2/pay/notify.php&;/notify_url&
&out_trade_no&&/out_trade_no&
&spbill_create_ip&127.0.0.1&/spbill_create_ip&
&total_fee&1&/total_fee&
&trade_type&JSAPI&/trade_type&
&sign&&![CDATA[3CA89BCCF4]]&&/sign&
那么。我们来生成这样的post data
SortedMap&Object,Object& parameters = new TreeMap&Object,Object&();
parameters.put(&appid&, ConfigUtil.APPID);
parameters.put(&mch_id&, ConfigUtil.MCH_ID);
parameters.put(&nonce_str&, PayCommonUtil.CreateNoncestr());
parameters.put(&body&, &LEO测试&);
parameters.put(&out_trade_no&, &&);
parameters.put(&total_fee&, &1&);
parameters.put(&spbill_create_ip&,IpAddressUtil.getIpAddr(request));
parameters.put(&notify_url&, ConfigUtil.NOTIFY_URL);
parameters.put(&trade_type&, &JSAPI&);
parameters.put(&openid&, &o7W6yt9DUOBpjEYogs4by1hD_OQE&);
String sign = PayCommonUtil.createSign(&UTF-8&, parameters);
parameters.put(&sign&, sign);
String requestXML = PayCommonUtil.getRequestXml(parameters);
PayCommonUtil.getRequestXml(parameters)方法如下:
&& & * @author 李欣桦
&& & * @date 下午2:32:05
&& & * @Description:将请求参数转换为xml格式的string
&& & * @param parameters& 请求参数
&& & * @return
&& &public static String getRequestXml(SortedMap&Object,Object& parameters){
&& &&& &StringBuffer sb = new StringBuffer();
&& &&& &sb.append(&&xml&&);
&& &&& &Set es = parameters.entrySet();
&& &&& &Iterator it = es.iterator();
&& &&& &while(it.hasNext()) {
&& &&& &&& &Map.Entry entry = (Map.Entry)it.next();
&& &&& &&& &String k = (String)entry.getKey();
&& &&& &&& &String v = (String)entry.getValue();
&& &&& &&& &if (&attach&.equalsIgnoreCase(k)||&body&.equalsIgnoreCase(k)||&sign&.equalsIgnoreCase(k)) {
&& &&& &&& &&& &sb.append(&&&+k+&&&+&&![CDATA[&+v+&]]&&/&+k+&&&);
&& &&& &&& &}else {
&& &&& &&& &&& &sb.append(&&&+k+&&&+v+&&/&+k+&&&);
&& &&& &&& &}
&& &&& &sb.append(&&/xml&&);
&& &&& &return sb.toString();
最后我们要将这些参数以POST方式调用微信统一支付接口:代码如下
String result =CommonUtil.httpsRequest(ConfigUtil.UNIFIED_ORDER_URL, &POST&, requestXML);
CommonUtil.httpsRequest(ConfigUtil.UNIFIED_ORDER_URL, &POST&, requestXML);方法如下:
&& & * 发送https请求
&& & * @param requestUrl 请求地址
&& & * @param requestMethod 请求方式(GET、POST)
&& & * @param outputStr 提交的数据
&& & * @return 返回微信服务器响应的信息
&& &public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
&& &&& &try {
&& &&& &&& &// 创建SSLContext对象,并使用我们指定的信任管理器初始化
&& &&& &&& &TrustManager[] tm = { new MyX509TrustManager() };
&& &&& &&& &SSLContext sslContext = SSLContext.getInstance(&SSL&, &SunJSSE&);
&& &&& &&& &sslContext.init(null, tm, new java.security.SecureRandom());
&& &&& &&& &// 从上述SSLContext对象中得到SSLSocketFactory对象
&& &&& &&& &SSLSocketFactory ssf = sslContext.getSocketFactory();
&& &&& &&& &URL url = new URL(requestUrl);
&& &&& &&& &HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
&& &&& &&& &conn.setSSLSocketFactory(ssf);
&& &&& &&& &conn.setDoOutput(true);
&& &&& &&& &conn.setDoInput(true);
&& &&& &&& &conn.setUseCaches(false);
&& &&& &&& &// 设置请求方式(GET/POST)
&& &&& &&& &conn.setRequestMethod(requestMethod);
&& &&& &&& &conn.setRequestProperty(&content-type&, &application/x-www-form-urlencoded&);
&& &&& &&& &// 当outputStr不为null时向输出流写数据
&& &&& &&& &if (null != outputStr) {
&& &&& &&& &&& &OutputStream outputStream = conn.getOutputStream();
&& &&& &&& &&& &// 注意编码格式
&& &&& &&& &&& &outputStream.write(outputStr.getBytes(&UTF-8&));
&& &&& &&& &&& &outputStream.close();
&& &&& &&& &}
&& &&& &&& &// 从输入流读取返回内容
&& &&& &&& &InputStream inputStream = conn.getInputStream();
&& &&& &&& &InputStreamReader inputStreamReader = new InputStreamReader(inputStream, &utf-8&);
&& &&& &&& &BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
&& &&& &&& &String str =
&& &&& &&& &StringBuffer buffer = new StringBuffer();
&& &&& &&& &while ((str = bufferedReader.readLine()) != null) {
&& &&& &&& &&& &buffer.append(str);
&& &&& &&& &}
&& &&& &&& &// 释放资源
&& &&& &&& &bufferedReader.close();
&& &&& &&& &inputStreamReader.close();
&& &&& &&& &inputStream.close();
&& &&& &&& &inputStream =
&& &&& &&& &conn.disconnect();
&& &&& &&& &return buffer.toString();
&& &&& &} catch (ConnectException ce) {
&& &&& &&& &log.error(&连接超时:{}&, ce);
&& &&& &} catch (Exception e) {
&& &&& &&& &log.error(&https请求异常:{}&, e);
接着,我们来解析微信返回给我们的信息。返回信息是xml格式的String
XMLUtil.工具类如下:
public class XMLUtil {
&& & * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
&& & * @param strxml
&& & * @return
&& & * @throws JDOMException
&& & * @throws IOException
&& &public static Map doXMLParse(String strxml) throws JDOMException, IOException {
&& &&& &strxml = strxml.replaceFirst(&encoding=\&.*\&&, &encoding=\&UTF-8\&&);
&& &&& &if(null == strxml || &&.equals(strxml)) {
&& &&& &&& &
&& &&& &Map m = new HashMap();
&& &&& &InputStream in = new ByteArrayInputStream(strxml.getBytes(&UTF-8&));
&& &&& &SAXBuilder builder = new SAXBuilder();
&& &&& &Document doc = builder.build(in);
&& &&& &Element root = doc.getRootElement();
&& &&& &List list = root.getChildren();
&& &&& &Iterator it = list.iterator();
&& &&& &while(it.hasNext()) {
&& &&& &&& &Element e = (Element) it.next();
&& &&& &&& &String k = e.getName();
&& &&& &&& &String v = &&;
&& &&& &&& &List children = e.getChildren();
&& &&& &&& &if(children.isEmpty()) {
&& &&& &&& &&& &v = e.getTextNormalize();
&& &&& &&& &} else {
&& &&& &&& &&& &v = XMLUtil.getChildrenText(children);
&& &&& &&& &}
&& &&& &&& &
&& &&& &&& &m.put(k, v);
&& &&& &//关闭流
&& &&& &in.close();
&& & * 获取子结点的xml
&& & * @param children
&& & * @return String
&& &public static String getChildrenText(List children) {
&& &&& &StringBuffer sb = new StringBuffer();
&& &&& &if(!children.isEmpty()) {
&& &&& &&& &Iterator it = children.iterator();
&& &&& &&& &while(it.hasNext()) {
&& &&& &&& &&& &Element e = (Element) it.next();
&& &&& &&& &&& &String name = e.getName();
&& &&& &&& &&& &String value = e.getTextNormalize();
&& &&& &&& &&& &List list = e.getChildren();
&& &&& &&& &&& &sb.append(&&& + name + &&&);
&& &&& &&& &&& &if(!list.isEmpty()) {
&& &&& &&& &&& &&& &sb.append(XMLUtil.getChildrenText(list));
&& &&& &&& &&& &}
&& &&& &&& &&& &sb.append(value);
&& &&& &&& &&& &sb.append(&&/& + name + &&&);
&& &&& &&& &}
&& &&& &return sb.toString();
Map&String, String& map = XMLUtil.doXMLParse(result);//解析微信返回的信息,以Map形式存储便于取值
现在我们可以拿到想要拿的值,那么可以调用微信H5网页端调用支付接口。在微信浏览器里面打开 H5 网页中执行 JS 调起支付。接口输入输出数据格式为 JSON。
注意:WeixinJSBridge 内置对象在其他浏览器中无效;列表中参数名区分大小。
现在我们将返回的值传入到支付jsp页面,在支付jsp页面调用支付接口。
&&&&&& SortedMap&Object,Object& params = new TreeMap&Object,Object&();
&& &&& &params.put(&appId&, &wx0953bae287adfeee&);
&& &&& &params.put(&timeStamp&, Long.toString(new Date().getTime()));
&& &&& &params.put(&nonceStr&, PayCommonUtil.CreateNoncestr());
&& &&& &params.put(&package&, &prepay_id=&+map.get(&prepay_id&));
&& &&& &params.put(&signType&, ConfigUtil.SIGN_TYPE);
&& &&& &String paySign =& PayCommonUtil.createSign(&UTF-8&, params);
&& &&& &params.put(&packageValue&, &prepay_id=&+map.get(&prepay_id&));&&& //这里用packageValue是预防package是关键字在js获取值出错
&& &&& &params.put(&paySign&, paySign);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //paySign的生成规则和Sign的生成规则一致
&& &&& &params.put(&sendUrl&, ConfigUtil.SUCCESS_URL);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //付款成功后跳转的页面
&& &&& &String userAgent = request.getHeader(&user-agent&);
&& &&& &char agent = userAgent.charAt(userAgent.indexOf(&MicroMessenger&)+15);
&& &&& &params.put(&agent&, new String(new char[]{agent}));//微信版本号,用于前面提到的判断用户手机微信的版本是否是5.0以上版本。
&& &&& &String json = JSONObject.fromObject(params).toString();
下面是一个简洁的支付页面。代码如下:
&form action=&& method=&post& &
&input type=&button& value=&确认支付& name=&ajaxLoadId& id=&test&/&
&script type=&text/javascript&&
var basePath = &&%=basePath%&&;
$(&#test&).one(&click&,function(){
url:basePath+&config/pay!execute.action&
//&span style=&font-family:微软雅黑;&&ajax调用微信统一接口获取prepayId&/span&
}).done(function(data){
var obj = eval('(' + data + ')');
if(parseInt(obj.agent)&5){
alert(&您的微信版本低于5.0无法使用微信支付&);
WeixinJSBridge.invoke('getBrandWCPayRequest',{
&appId& : obj.appId,
//公众号名称,由商户传入
&timeStamp&:obj.timeStamp,
//时间戳,自 1970 年以来的秒数
&nonceStr& : obj.nonceStr,
&package& : obj.packageValue,
//&span style=&font-family:微软雅黑;&&商品包信息&/span&
&signType& : obj.signType,
//微信签名方式:
&paySign& : obj.paySign
//微信签名
},function(res){
alert(res.err_msg);
if(res.err_msg == &get_brand_wcpay_request:ok& ) {
window.location.href=obj.sendU
alert(&fail&);
window.location.href=&http://183.45.18.197:8016/wxweb/config/oauth!execute.action&;
//&span style=&font-family:微软雅黑;&&当失败后,继续跳转该支付页面让用户可以继续付款,贴别注意不能直接调转jsp,&/span&&span style=&font-size:10.5pt&&不然会报&/span&&span style=&font-size:12.0pt&& system:access_denied。&/span&
&/body&支付成功后,微信就会调用你填写的notify_url的方法,本人微信支付的开发配置中说明了我的notify_url为http://183.33.212.175:8016/wxweb/config/pay!paySuccess.action
对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败,微信会通过一定的策略(如 30 分钟共 8 次)定期重新发起通知,尽可能提高通知的成功率,
但微信不保证通知最终能成功。由于存在重新収送后台通知的情况,因此同样的通知可能会多次収送给商户系统。 商户系统必须能够正确处理重复的通知。
推荐的做法是,当收到通知进行处理时,首先检查对应业务数据的状态,判断该通知是否已经处理过,如果没有处理过再进行处理,如果处理过直接返回结果成功。在对业务数据
进行状态检查和处理之前,要采用数据锁进行幵収控制,以避免凼数重入造成的数据混乱。
判断完成后,我们需要通知微信,我们收到信息了,不然微信就会通过一定的策略定期重新发起通知。
怎么通知微信呢。方法如下。
public void paySuccess() throws Exception{
&& &&& &HttpServletRequest request = ServletActionContext.getRequest();
&& &&& &HttpServletResponse response = ServletActionContext.getResponse();
&& &&& &InputStream inStream = request.getInputStream();
&& &&& &ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
&& &&& &byte[] buffer = new byte[1024];
&& &&& &int len = 0;
&& &&& &while ((len = inStream.read(buffer)) != -1) {
&& &&& &&& &outSteam.write(buffer, 0, len);
&& &&& &System.out.println(&~~~~~~~~~~~~~~~~付款成功~~~~~~~~~&);
&& &&& &outSteam.close();
&& &&& &inStream.close();
&& &&& &String result& = new String(outSteam.toByteArray(),&utf-8&);//获取微信调用我们notify_url的返回信息
&& &&& &Map&Object, Object& map = XMLUtil.doXMLParse(result);
&& &&& &for(Object keyValue : map.keySet()){
&& &&& &&& &System.out.println(keyValue+&=&+map.get(keyValue));
&& &&& &if (map.get(&result_code&).toString().equalsIgnoreCase(&SUCCESS&)) {
&& &&& &&& &//TODO 对数据库的操作
&& &&& &&& &response.getWriter().write(PayCommonUtil.setXML(&SUCCESS&, &&));&& //告诉微信服务器,我收到信息了,不要在调用回调action了
&& &&& &&& &System.out.println(&-------------&+PayCommonUtil.setXML(&SUCCESS&, &&));
PayCommonUtil.setXML(&SUCCESS&,
&&))方法如下:
public static String setXML(String return_code, String return_msg) {
& && &&&return &&xml&&return_code&&![CDATA[& + return_code
& && && && && & + &]]&&/return_code&&return_msg&&![CDATA[& + return_msg
& && && && && & + &]]&&/return_msg&&/xml&&;
上面代码中工具类打包下载地址:http://download.csdn.net/detail/u54883
官方文档有少许常见错误解决方法,观众们可自行下载查阅,仍有不懂的可留言。
第一次写这么长的博客,不足之处请留言告之便于本人成长,再次感谢你的阅读。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:240887次
积分:5283
积分:5283
排名:第5533名
原创:201篇
转载:422篇
评论:61条
(2)(36)(8)(11)(8)(4)(4)(3)(3)(31)(30)(35)(73)(73)(40)(14)(14)(24)(50)(2)(2)(8)(3)(5)(7)(9)(5)(2)(2)(4)(19)(17)(9)(5)(15)(23)(24)
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'iOS微信支付的那些坑 - 简书
iOS微信支付的那些坑
一直以为支付宝的文档写的已经够烂了,后来我才发现我太年轻了,那是因为我还没有遇到微信的文档,简直坑爹。。。&心中一万只草泥马...&
支付业务流程
商户系统和微信支付系统主要交互说明:
步骤1:用户在商户APP中选择商品,提交订单,选择微信支付。
步骤2:商户后台收到用户支付单,调用微信支付统一下单接口。参见【[统一下单API](https://pay./wiki/doc/api/app.php?chapter=9_1)】。
步骤3:统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式为Sign=WXPay
步骤4:商户APP调起微信支付。api参见本章节【[app端开发步骤说明](https://pay./wiki/doc/api/app.php?chapter=8_5)】
步骤5:商户后台接收支付通知。api参见【[支付结果通知API](https://pay./wiki/doc/api/app.php?chapter=9_7)】
步骤6:商户后台查询支付结果。,api参见【[查询订单API](https://pay./wiki/doc/api/app.php?chapter=9_2)】
Paste_Image.png
1.微信支付现在已经很便捷了,提供了统一下单接口,自己的后台服务器调用该接口,获取prepayId2.最重要的一步,也是网上现在坑最多的一步,调用统一下单接口后,微信返回格式如下,而这么多数据中,真正对我们有用的只有 预支付订单号prepayId,微信返回的sign没有任何用,我们得根据签名规范重新生成签名(关于这点,上面的流程交互中就有提到),然后将重新生成的签名返回给APP端,用于APP端调用微信支付。(当然重新生成签名的步骤也可以放在APP端来做,不过为了安全考虑,建议放在服务端处理,下面也会给出APP端签名的代码)
调用统一下单接口 微信返回数据
一定要重新生成签名
很多人都遇到这样的问题,参数都处理好调用微信支付,结果进入微信界面后发现只有一个确定按钮,返回后错误码为 -2,造成这个原因的就是因为参数不对,而且大多是都是因为签名 sign 不对,没有进行二次签名,而直接拿微信返回的sign当作参数 , 所以调用微信支付接口时,一定要用 重新签名的sign!!!!
APP端调用支付时,sign不要用调用统一下单接口返回的sign,而要自己重新生成,生成规则见微信提供的签名生成算法
Paste_Image.png
相关代码如下:
APP端打开微信微信支付代码
#pragma mark -
- (void)wechatPay:(WechatOrderModel *)model
//调起微信支付 model 为自己服务器返回的参数
PayReq *req = [[PayReq alloc] init];
req.partnerId = model.
req.prepayId = model.
req.nonceStr = model.
req.timeStamp = model.timestamp.intV
req.package = model.
req.sign = model.//sign 为自己服务器获取到预支付订单号prepayId后,重新生成的签名,当然本地也可以生成签名,签名代码如下
[WXApi sendReq:req];
//日志输出
NSLog(@"微信支付请求参数 =====
appid=%@\npartid=%@\nprepayid=%@\nnoncestr=%@\ntimestamp=%ld\npackage=%@\nsign=%@",model.appid,req.partnerId,req.prepayId,req.nonceStr,(long)req.timeStamp,req.package,req.sign);
APP端重新生成签名(建议放在服务端处理)
#pragma mark -
微信支付本地签名
//创建发起支付时的sign签名
-(NSString *)createMD5SingForPayWithAppID:(NSString *)appid_key partnerid:(NSString *)partnerid_key prepayid:(NSString *)prepayid_key package:(NSString *)package_key noncestr:(NSString *)noncestr_key timestamp:(UInt32)timestamp_key{
NSMutableDictionary *signParams = [NSMutableDictionary dictionary];
[signParams setObject:appid_key forKey:@"appid"];//微信appid 例如wxfb2
[signParams setObject:noncestr_key forKey:@"noncestr"];//随机字符串
[signParams setObject:package_key forKey:@"package"];//扩展字段
参数为 Sign=WXPay
[signParams setObject:partnerid_key forKey:@"partnerid"];//商户账号
[signParams setObject:prepayid_key forKey:@"prepayid"];//此处为统一下单接口返回的预支付订单号
[signParams setObject:[NSString stringWithFormat:@"%u",timestamp_key] forKey:@"timestamp"];//时间戳
NSMutableString *contentString
=[NSMutableString string];
NSArray *keys = [signParams allKeys];
//按字母顺序排序
NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [obj1 compare:obj2 options:NSNumericSearch];
//拼接字符串
for (NSString *categoryId in sortedArray) {
![[signParams objectForKey:categoryId] isEqualToString:@""]
&& ![[signParams objectForKey:categoryId] isEqualToString:@"sign"]
&& ![[signParams objectForKey:categoryId] isEqualToString:@"key"]
[contentString appendFormat:@"%@=%@&", categoryId, [signParams objectForKey:categoryId]];
//添加商户密钥key字段
[contentString appendFormat:@"key=%@", @"商户密钥"];
NSString *result = [contentString md5String];//md5加密
MD5 加密方法
@return 加密后字符串
- (NSString *)md5String
if(self == nil || [self length] == 0)
unsigned char digest[CC_MD5_DIGEST_LENGTH],
CC_MD5([self UTF8String], (int)[self lengthOfBytesUsingEncoding:NSUTF8StringEncoding], digest);
NSMutableString *ms = [NSMutableString string];
for(i=0;i&CC_MD5_DIGEST_LENGTH;i++)
[ms appendFormat: @"%02x", (int)(digest[i])];
return [ms copy];
至此微信集成结束,坑的地方就是 app端调用微信支付时的签名参数sign一定要重新生成,不要使用统一下单接口返回的sign,切记!!!!
记录点滴,与君共勉。

我要回帖

更多关于 微信支付账号申请 的文章

 

随机推荐